解决STM32写入FLASH出现hard fault异常

近期项目为了增加程序的健壮性,将IAP的逻辑进行了修改,使用双APP空间,前一个为运行空间,后一个为更新程序临时存储空间,这样通过IAP或者APP本身,都可以对程序进行更新,以实现可靠的程序刷新过程。但这其中flash写入,出现了一个奇怪的现象,导致浪费几天时间用来排错,最终找到问题原因,以下经历做个记录,以便同病相怜者参考。

先说结论:

USART的DMA功能,会导致FLASH写入出现hard fault错误异常。

具体原因还没有分析,粗浅的猜测,是DMA对RAM中的地址进行了保护,在flash写入过程中,访问dma指向的ram会使芯片产生错误。

处理方案:

生成一个临时数组,将DMA接收的数据重新做一份拷贝,使用拷贝数组进行flash写入,就没有问题了。


过程:

之前由于程序优化不足,程序尺寸过于臃肿,没有足够的空间进行双APP备份,同时,总线挂载设备过多,导致IAP更新稳定性很低。

为了解决这个问题,将IAP逻辑修改为双APP空间,前一个APP空间用于正常运行,后一个APP空间用于更新程序存储,当更新程序版本号高于运行程序时,IAP执行更新操作。同时,正常运行的APP,还可以通过USART进行接收、验证、写入临时APP空间,这样可以保证始终有一个可靠的程序能在芯片上运行,也能保证最新版本的APP能够可靠刷入flash中。

但麻烦接踵而来。

使用USART接收的数据,无法写入FLASH!

这里出现了一个令人费解的现象:正常运行的APP开头,会有一个flash写入的片段,这个片段用于将系统参数等数据更新到flash中。这部分写入flash的程序,可以非常完美的将数据写入指定的FLASH地址,但是,到了USART部分,就完全无法写入flash,哪怕是一个64位的word。

将uasrt部分的程序挪到主程序部分,依然无效,试着多次修改flash写入程序,内部屏蔽中断、修改等待超时、先擦除后写入等操作,也无法解决问题。

通过反复思考 写入成功和写入失败 两者的区别,最终发现,只有源数据数组的差异,成功写入的源数据数组是一个全局常量数组,而失败写入程序的数组,是DMA指向RAM的全局变量数组。

想到马上进行测试,将DMA接收的数据,用一个临时变量数组buffer[]进行转存,然后通过buffer[]数组进行flash写入,测试结果成功!


异常的情况,其实很多是没有注意到的细节导致,解决问题的几天,一直反复翻阅芯片的应用手册,但是flash操作部分,完全没有提及到DMA指向的数组,会对flash写入造成影响。

小问题造成大影响,细微之处见真章。

谨以此文纪念浪费的宝贵时间,也为同病相怜者鉴。

  • 9
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值