调试H7-TOOL产品的BOOT固件升级程序,大数据连续编程flash时会出现编程失败问题,扇区中只有部分数据会成功写入。
写入失败的现象是:硬件报错 PGSERR1或PGSERR2
PGSERR1:存储区 1 编程顺序错误标志
PGSERR12:存储区2 编程顺序错误标志
ST固件库中的范例是可以正常运行的,它太简单了,擦除128K扇区,写入32字节数据。只有连续写入8K以上数据才会出问题。
STMH750只有128KB容量,但是强行按H743编程算法使用2MB空间一直未发现运行问题。出现些flash问题后以为芯片问题,毕竟128KB以外的区域是不保证OK的。
但是编程器仿真下载程序正常,只是代码中执行编程会失败。尝试过增加连续编程语句之间的延迟,无法解决。后跟踪库函数代码,添加1条DSB执行解决问题。
库文件:stm32h7xx_hal_flash.c 问题函数:HAL_FLASH_Program
HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress, uint64_t Data)
{
... 省略
__DSB(); /* 2019-10-04 armfly : 数据同步指令,等待上面指令执行完毕才执行下面的指令,否则大批量连续编程会失败 */
/* Program the 256 bits flash word */
do
{
*dest_addr++ = *src_addr++;
} while (--row_index != 0);
__DSB();
... 省略
}
添加红色代码行解决问题。
测试代码如下:
#if 1 /* 测试写flash */
{
uint32_t addr = 0x08100000;
uint16_t i;
uint16_t j;
uint8_t buf0[1024];
uint8_t buf1[1024];
uint8_t err = 0;
for (i = 0; i < 1024; i++)
{
buf0 = i;
}
addr = 0x08100000;
err = 0;
for (i = 0; i < 8; i++)
{
if (bsp_EraseCpuFlash(addr + i * 128 * 1024) != 0)
{
err = 1;
break;
}
for (j = 0; j < 128; j++)
{
if (bsp_WriteCpuFlash(addr + j * 1024, buf0, 1024) != 0)
{
err = 2;
break;
}
}
for (j = 0; j < 128; j++)
{
memcpy(buf1, (uint8_t *)(addr + j * 1024), 1024);
if (memcmp(buf0, buf1, 1024) != 0)
{
err = 3;
break;
}
}
if (err != 0)
{
break;
}
}
while(1);
}
#endif |