在线时间1 小时
UID3866003
注册时间2022-8-13
NXP金币0
该用户从未签到
新手上路

- 积分
- 6
- 最后登录
- 2022-9-6
|
问题现象:使用IAP接口操作Flash时,先擦除整片(4K)数据后,按256字节的缓存写入数据,可以正常操作,读写数据都正常。但如果不执行擦除,直接把相同数据覆盖写入时,会有某个位出错。
现在的操作逻辑是这样子的,还是定义一个256字节的缓存,用作写Flash。先判断当前写入的区域数据是否为FF,不是则进行擦除操作。然后写入数据之前,先把要写入地址能被256整除的地址区域数据读出来,把要写入的数据覆盖到当前这256的缓存里,然后再整体把这256字节写回去,这时候写某些数据时会出错。具体看下面代码。
void Flash_WriteByte(uint32_t addr,
uint8_t* data,
uint16_t len)
{
uint32_t i;
uint32_t start, end = 0;
uint32_t cur_size, diff = 0;
uint32_t data_add = 0;
uint32_t start1 = 0;
/* 判断当前是否需要擦除 */
for (i = 0; i < len; i++)
{
if (0xFF != *((volatile uint8_t *)addr + i))
{
/* 判断当前地址处在哪个扇区 */
Flash_GetSector(addr + i, &start, &end);
/* 擦除整片Flash */
Lpc17xx_Flash_Erase(start,
end,
FLASH_CCLK);
}
}
while (1)
{
start = (addr / FLASH_OP_MIN_SIZE * FLASH_OP_MIN_SIZE);
diff = addr - start;
if (diff + len < FLASH_OP_MIN_SIZE)
{
cur_size = len;
}
else
{
cur_size = FLASH_OP_MIN_SIZE - diff;
}
/* 先读出256字节数据 */
for (i = 0; i < FLASH_OP_MIN_SIZE; i++)
{
FlashData = *(volatile uint8_t *)(start + i);
}
/* 擦除 */
#warning "测试代码"
TestFlashErr++;
if (TestFlashErr == 4)
{
TestFlashErr = 0;
}
/* 覆盖数据 */
for (i = 0; i < cur_size; i++)
{
FlashData[diff++] = data[data_add++];
len--;
addr++;
}
/* 写入数据 */
Lpc17xx_Flash_Write((start),
(FlashData),
FLASH_OP_MIN_SIZE,
FLASH_CCLK);
#warning "测试代码"
/* 再判断写入是否有误 */
for (i = 0; i < FLASH_OP_MIN_SIZE; i++)
{
if (FlashData != *((volatile uint8_t *)start + i))
{
TestFlashErr++;
}
}
if (0 == len)
{
break;
}
}
}
其中擦除跟写入的函数里,都有调用准备写的那个IAP指令,这一部分查过手册对比过,应该不会异常操作。现在是给这个写函数传入addr = 0x000093B5,data[0] = 0xE8,len = 1。然后再调一次写函数,传入addr = 0x000093B6,data[0] = 0x0F,len = 1。写入后发现0x000093B8地址的数据变成0xFB(理论应该保持0xFF的)。调试看调用写入函数之前,FlashData缓存里的数据也是对的,写完就错了一个位。
是因为这个芯片不支持不擦除重复写入的操作么?这同样的操作在ST芯片上没出过这样的问题。
|
|