gd32_flash.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. #include "gd32f30x.h"
  2. #include "gd32_flash.h"
  3. #include "string.h"
  4. #include "FreeRTOS.h"
  5. #include "task.h"
  6. /*
  7. *gd32f307RCT6的flash内存总共有256K的空间现在要对齐进行相应的分区
  8. *前30K空间用于BOOTLOADER区
  9. *后30K空间用于json字符串数据保存,其中前4字节保存数据长度
  10. *剩下空间用于正常程序
  11. */
  12. #define FMC_READ(addrx) (*(volatile uint32_t *)(uint32_t)(addrx))
  13. static void GD32_EraseFlash(uint16_t start, uint16_t num);
  14. void GD32_WriteFlash(uint32_t saddr, uint32_t *wdata, uint32_t wnum);
  15. /*-------------------------------------------------*/
  16. /*函数名:保存数据到flash中 */
  17. /*参 数:params保存的字符串数据 */
  18. /*返回值:无 */
  19. /*前4个字节用于保存字符串长度后面全是字符串数据 TODO:最大长度的限制 */
  20. /*-------------------------------------------------*/
  21. int save_config_params(char *params)
  22. {
  23. uint32_t paramsLen = strlen(params);
  24. volatile uint32_t flashDataLen = FMC_READ(FMC_WRITE_START_ADDR);
  25. vTaskDelay(100);
  26. if (paramsLen % 4 != 0)
  27. {
  28. paramsLen = (paramsLen / 4 + 1) * 4;
  29. }
  30. if (flashDataLen != paramsLen)
  31. {
  32. GD32_EraseFlash(113,paramsLen/2048+1);
  33. GD32_WriteFlash(FMC_WRITE_START_ADDR, (uint32_t *)&paramsLen, 4);
  34. GD32_WriteFlash(FMC_WRITE_START_ADDR + 4, (uint32_t *)params, paramsLen);
  35. return 1;
  36. }
  37. for (int i = 1; i < paramsLen / 4; i++)
  38. {
  39. uint32_t flashWord = FMC_READ(FMC_WRITE_START_ADDR + i * 4);
  40. uint32_t paramsWord = *(uint32_t *)(params + (i - 1) * 4);
  41. vTaskDelay(100); // 解决flash速度缓慢判断错误问题
  42. if (flashWord != paramsWord)
  43. {
  44. GD32_EraseFlash(113,paramsLen/2048+1);
  45. GD32_WriteFlash(FMC_WRITE_START_ADDR + 4, (uint32_t *)params, paramsLen);
  46. return 1;
  47. }
  48. }
  49. }
  50. /*-------------------------------------------------*/
  51. /*函数名:从flash中读出字符串数据 */
  52. /*参 数:params保存的字符串数据 */
  53. /*返回值:无 */
  54. /*前4个字节用于保存字符串长度后面全是字符串数据 */
  55. /*-------------------------------------------------*/
  56. int read_data_from_flash(void *buffer)
  57. {
  58. uint32_t length = FMC_READ(FMC_WRITE_START_ADDR);
  59. vTaskDelay(100);
  60. if (length == 0xFFFFFFFF)
  61. {
  62. return -1;
  63. }
  64. for (uint32_t i = 0; i < length; i += 4)
  65. {
  66. *(uint32_t *)((uint8_t *)buffer + i) = FMC_READ(FMC_WRITE_START_ADDR + 4 + i);
  67. }
  68. return 0;
  69. }
  70. /*-------------------------------------------------*/
  71. /*函数名:擦除FLASH */
  72. /*参 数:start:擦除起始扇区 num:擦几个扇区 */
  73. /*返回值:无 */
  74. /*-------------------------------------------------*/
  75. void GD32_EraseFlash(uint16_t start, uint16_t num)
  76. {
  77. uint16_t i;
  78. fmc_unlock();
  79. for (i = 0; i < num; i++)
  80. {
  81. fmc_page_erase((0x08000000 + start * 2048) + (2048 * i));
  82. }
  83. fmc_lock();
  84. }
  85. /*---------------------------------------------------------------------*/
  86. /*函数名:写入FLASH */
  87. /*参 数:saddr:写入地址 wdata:写入数据指针 wnum:写入多少个字节 */
  88. /*返回值:无 */
  89. /*---------------------------------------------------------------------*/
  90. void GD32_WriteFlash(uint32_t saddr, uint32_t *wdata, uint32_t wnum)
  91. {
  92. fmc_unlock();
  93. while (wnum > 0)
  94. {
  95. fmc_word_program(saddr, *wdata);
  96. wnum -= 4;
  97. saddr += 4;
  98. wdata++;
  99. }
  100. fmc_lock();
  101. }
  102. void gd32_flash_test()
  103. {
  104. char *p = "hello,word,test/r/n";
  105. save_config_params(p);
  106. char *t=pvPortMalloc(100);
  107. read_data_from_flash(t);
  108. }