本帖最后由 onemoren 于 2025-5-14 17:29 编辑
#技术资源# #有奖活动# #申请原创# @21小跑堂
在APM32F407上使用EasyFlash库函数卡死的解决方法 问题描述: 原本使用STM32F407开发的程序,替换为APM32F407后,出现了 EasyFlash 库函数运行异常。具体表现为在执行 sector_iterator 函数时进入无限 while 循环,程序卡死。程序在执行到 while ((sec_addr = get_next_sector_addr(sector)) != FAILED_ADDR) 这一行时,get_next_sector_addr 函数返回非 FAILED_ADDR 的值,导致循环无法正常退出,程序陷入死循环,无法继续执行后续逻辑。 复现失效: 按前面的描述,在STM32F407芯片上烧录代码,经Debug可以正常运行EasyFlash库代码; 再使用APM32F407VGT6芯片烧录代码,芯片会卡死在“HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, addr, *buf_8);”处。具体的,表现为在执行 sector_iterator 函数时进入无限 while 循环,程序卡死。程序在执行到 while ((sec_addr = get_next_sector_addr(sector)) != FAILED_ADDR) 这一行时,进入死循环。 分析过程: 1、 检查写入地址0x08040000确认写入信息失败,检查相关寄存器发现PGSEQERR和PGPRLERR错误标志置位。 2、 可以初步判断是由编程顺序差异导致的错误.根据先擦后写的原则,检查上一步擦除操作.发现在擦除操作后写入操作前SER已被置位。 3、 检查Program函数发现在PG使能时未能成功置1,且反而导致SER位清零。 4、 在擦除操作结束后,对SER位清零,检查寄存器操作成功。 5、 继续运行写操作,检查写操作成功,程序可以正常继续运行后续任务。 6、对比ST与APM芯片SER和PG都置1的差异 APM32F407芯片: 1).SER置位: 2).PG和SER都清除: 可以看到APM芯片无法将PG位置起,而且还使SER清除。这一点与ST芯片表现不一样。 STM32F407芯片: 1).SER置位: 2).SER/PG都置位: 在STM32F407芯片上,对flash擦除后SER置位。此时程序如对PG置位,PG会被成功置位且保持SER位置位,从而程序会判定扇区擦除成功,然后继续运行。ST芯片表现运行正常。
分析结论: 在APM32F407芯片上,对flash擦除后SER置位。此时程序如对PG置位,PG置位操作无法完成并且会清除SER位。程序运行时会判断对目标扇区擦除完成后再写入,但因SER位被清除,程序无法正常判定被擦除的Flash扇区状态,就会将其认定为未擦除,最终导致MCU对同一扇区反复擦除而陷入死循环。解决方法:在擦除完成后手动置位SER位,即可使程序认定扇区擦除完成,程序继续正常运行。 在STM32F407芯片上,对flash擦除后SER置位。此时程序如对PG置位,PG会被成功置位且保持SER位置位,从而程序会判定扇区擦除成功,然后继续运行。所以ST芯片表现正常。 检查ST标准库函数、HAL库与Geehy标准库,发现是HAL库存在不同,HAL需要修改代码来规避(在擦除完成后增加手动置位SER位的代码即可)。 另外,SER在手册中是RW的(可读可写位),用户在擦除完FLASH后应该手动去清SER位,才比较规范。
总之: APM32F407的Flash操作表现与ST芯片有差异,在APM32F407芯片Flash擦除(SER、SNB置位)或Flash编程(PG置位)后,都需要增加清除这些功能位的操作代码。否则会出现擦除报错、编程无效等异常。
|
对比ST和APM在使用EasyFlash库时的不同表现,对APM执行相同函数时卡死问题深入探索,分析细致,解决方法高效。对于遇到类似问题的开发者来说是很重要的经验。