#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); }