|
@@ -0,0 +1,105 @@
|
|
|
|
+#include "gd32f30x.h"
|
|
|
|
+#include "gd32_flash.h"
|
|
|
|
+#include "string.h"
|
|
|
|
+#include "FreeRTOS.h"
|
|
|
|
+#include "task.h"
|
|
|
|
+/*
|
|
|
|
+ *gd32f307RCT6的flash内存总共有256K的空间现在要对齐进行相应的分区
|
|
|
|
+ *前30K空间用于BOOTLOADER区
|
|
|
|
+ *后30K空间用于json字符串数据保存,其中前4字节保存数据长度
|
|
|
|
+ *剩下空间用于正常程序
|
|
|
|
+ */
|
|
|
|
+#define FMC_READ(addrx) (*(volatile uint32_t *)(uint32_t)(addrx))
|
|
|
|
+void GD32_WriteFlash(uint32_t saddr, uint32_t *wdata, uint32_t wnum);
|
|
|
|
+/*-------------------------------------------------*/
|
|
|
|
+/*函数名:保存数据到flash中 */
|
|
|
|
+/*参 数:params保存的字符串数据 */
|
|
|
|
+/*返回值:无 */
|
|
|
|
+/*前4个字节用于保存字符串长度后面全是字符串数据 TODO:最大长度的限制 */
|
|
|
|
+/*-------------------------------------------------*/
|
|
|
|
+int save_config_params(char *params)
|
|
|
|
+{
|
|
|
|
+ uint32_t paramsLen = strlen(params);
|
|
|
|
+ volatile uint32_t flashDataLen = FMC_READ(FMC_WRITE_START_ADDR);
|
|
|
|
+ if (paramsLen % 4 != 0)
|
|
|
|
+ {
|
|
|
|
+ paramsLen = (paramsLen / 4 + 1) * 4;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (flashDataLen != paramsLen)
|
|
|
|
+ {
|
|
|
|
+ GD32_WriteFlash(FMC_WRITE_START_ADDR, (uint32_t *)¶msLen, 4);
|
|
|
|
+ GD32_WriteFlash(FMC_WRITE_START_ADDR + 4, (uint32_t *)params, paramsLen);
|
|
|
|
+ return 1;
|
|
|
|
+ }
|
|
|
|
+ for (int i = 1; i < paramsLen / 4; i++)
|
|
|
|
+ {
|
|
|
|
+ uint32_t flashWord = FMC_READ(FMC_WRITE_START_ADDR + i * 4);
|
|
|
|
+ uint32_t paramsWord = *(uint32_t *)(params + (i - 1) * 4);
|
|
|
|
+ vTaskDelay(100); // 解决flash速度缓慢判断错误问题
|
|
|
|
+ if (flashWord != paramsWord)
|
|
|
|
+ {
|
|
|
|
+ GD32_WriteFlash(FMC_WRITE_START_ADDR + i * 4, ¶msWord, 4);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+/*-------------------------------------------------*/
|
|
|
|
+/*函数名:从flash中读出字符串数据 */
|
|
|
|
+/*参 数:params保存的字符串数据 */
|
|
|
|
+/*返回值:无 */
|
|
|
|
+/*前4个字节用于保存字符串长度后面全是字符串数据 */
|
|
|
|
+/*-------------------------------------------------*/
|
|
|
|
+int read_data_from_flash(void *buffer)
|
|
|
|
+{
|
|
|
|
+ uint32_t length = FMC_READ(FMC_WRITE_START_ADDR);
|
|
|
|
+ vTaskDelay(100);
|
|
|
|
+ if (length == 0xFFFFFFFF)
|
|
|
|
+ {
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ for (uint32_t i = 0; i < length; i += 4)
|
|
|
|
+ {
|
|
|
|
+ *(uint32_t *)((uint8_t *)buffer + i) = FMC_READ(FMC_WRITE_START_ADDR + 4 + i);
|
|
|
|
+ }
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*-------------------------------------------------*/
|
|
|
|
+/*函数名:擦除FLASH */
|
|
|
|
+/*参 数:start:擦除起始扇区 num:擦几个扇区 */
|
|
|
|
+/*返回值:无 */
|
|
|
|
+/*-------------------------------------------------*/
|
|
|
|
+void GD32_EraseFlash(uint16_t start, uint16_t num)
|
|
|
|
+{
|
|
|
|
+ uint16_t i;
|
|
|
|
+
|
|
|
|
+ fmc_unlock();
|
|
|
|
+ for (i = 0; i < num; i++)
|
|
|
|
+ {
|
|
|
|
+ fmc_page_erase((0x08000000 + start * 1024) + (1024 * i));
|
|
|
|
+ }
|
|
|
|
+ fmc_lock();
|
|
|
|
+}
|
|
|
|
+/*---------------------------------------------------------------------*/
|
|
|
|
+/*函数名:写入FLASH */
|
|
|
|
+/*参 数:saddr:写入地址 wdata:写入数据指针 wnum:写入多少个字节 */
|
|
|
|
+/*返回值:无 */
|
|
|
|
+/*---------------------------------------------------------------------*/
|
|
|
|
+void GD32_WriteFlash(uint32_t saddr, uint32_t *wdata, uint32_t wnum)
|
|
|
|
+{
|
|
|
|
+ fmc_unlock();
|
|
|
|
+ while (wnum > 0)
|
|
|
|
+ {
|
|
|
|
+ fmc_word_program(saddr, *wdata);
|
|
|
|
+ wnum -= 4;
|
|
|
|
+ saddr += 4;
|
|
|
|
+ wdata++;
|
|
|
|
+ }
|
|
|
|
+ fmc_lock();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void gd32_flash_test()
|
|
|
|
+{
|
|
|
|
+ char *p = "hello,word/r/n";
|
|
|
|
+ save_config_params(p);
|
|
|
|
+}
|