今儿这个是flash的读写测试。
闪存控制器(FMC),提供了片上闪存需要的所有功能。一般而言,MCU的Flash包括4个部分:
Flash读写的流程和注意事项在芯片手册中写的清清白白,就不赘述了;如果大家感兴趣,可以对着厂家给的API接口比对着看,理解会更好一点。
GD32L233 Flash结构
GD32F450 Flash结构
在flash分区的专用名称中,记住下面这个公式可以很好的理解分区:
页(Page)< 扇区(Sector) < 块(Block,bank)< 芯片(Chip)
一般容量小的就是分页,容量大就分块+扇区。
FMC的操作实际上比较简单,厂家给的API都很成熟,需要注意的几个点:
代码:
static void fmc_test(void)
{
#ifdef FMC_TEST
#define FMC_TEST_DATA_COUNT 5
static uint8_t fmc_test_flag = 0;
uint32_t index = 0;
#if defined(GD32)
uint32_t addr = 0x08100000;
uint32_t sector = CTL_SECTOR_NUMBER_12;
#endif
#if defined(GD32M0)
uint32_t addr = 0x0803E000;
uint32_t sector = addr;
#define fmc_sector_erase fmc_page_erase
#endif
#ifdef STM32
uint32_t addr = 0x08040000;
uint32_t sector = addr;
#endif
uint32_t *pdata = (uint32_t *)addr;
int32_t fmc_state;
if (fmc_test_flag)
{
return;
}
fmc_test_flag = 1;
/* 1. before erase */
printf("before erase,\tdata = ");
for (index = 0; index < FMC_TEST_DATA_COUNT; index++)
{
printf("0x%X ", pdata[index]);
}
printf("\r\n");
/* 2. after erase */
fmc_unlock();
fmc_state = fmc_sector_erase(sector);
fmc_lock();
printf("after erase[%d]\tdata = ", fmc_state);
for (index = 0; index < FMC_TEST_DATA_COUNT; index++)
{
printf("0x%X ", pdata[index]);
}
printf("\r\n");
/* 2. after program */
fmc_unlock();
for (index = 0; index < FMC_TEST_DATA_COUNT; index++)
{
fmc_state = fmc_word_program(addr, index+9);
addr += 4;
printf("programing [0x%0X] state = [%d]\r\n", addr, fmc_state);
}
fmc_lock();
printf("after program,\tdata = ");
for (index = 0; index < FMC_TEST_DATA_COUNT; index++)
{
printf("0x%X ", pdata[index]);
}
printf("\r\n");
#endif
}
测试结果(GD32L233,正常状态返回值是0):
before erase, data = 0x9 0xA 0xB 0xC 0xD
after erase[0] data = 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
programing [0x803E004] state = [0]
programing [0x803E008] state = [0]
programing [0x803E00C] state = [0]
programing [0x803E010] state = [0]
programing [0x803E014] state = [0]
after program, data = 0x9 0xA 0xB 0xC 0xD
通过Keil的调试功能可以查看Flash地址的数据,当然也可以直接在程序中读取。
GD32L233 OB数据: