STM32单片机Flash直写案例分析与实践

项目场景:

产品跳闸前需保存致使产品动作的故障类型和具体的故障分析数据,并在产品二次上电后读取故障类型,进行相应指示;之后清除故障类型的相关Flash,但故障分析数据仍保存,以便后续读出分析。然而,Flash扇区擦除时间较长,会影响程序正常运行、判断。


问题描述

Flash的编程原理都是只能将1写为0,而不能将0写为1,所以在进行Flash编程之前,必须将对应的块擦除,而擦除的过程就是把所有位都写为1的过程,块内的所有字节变为0xFF。

STM32内部Flash和外部Flash芯片类似,都是以页(或块)为最小擦除单元。因此,要擦除Flash数据,就是需要最小单元(1K/2K不等)。下图为STM32L431xx:

然而,一页(2Kbyte)的最大擦除时间为24.47ms,典型擦除时间为22.02ms,远大于64-bit的数据写入时间,81.69us。
在擦除Flash期间,中断是不会被响应的。相当于进入了一个等级很高的中断,这个中断无法被其他可屏蔽中断所中断。
对于高速、连续信号采样和处理类应用而言,需要尽可能减少扇区擦除对程序本身运行的影响。


解决方案:

网上都说“Flash在写之前必须先进行擦除操作,否则会使得写入数据与读出数据不一致”。

但其实,写Flash不一定非要先擦除。首先,需要明白擦除的目的是将Flash恢复为0xFF,而恢复为0xFF的原因是:写Flash只能将“1”改为“0”,不能由“0”改为“1”,而擦除就是将“0”改为“1”。所以,如果将要写的地方原来的内容为0xFF,那么就不用擦除。

基于上述分析,还可以进行如下探索:
比如擦除后是0xFF(1111 1111), 第一次写入0xFE(1111 1110), 第二次写入0xFA(1111 1010),第三次写入0x42(0100 0010),第四次写入0x00(0000 0000)。

因此,将产品跳闸前需保存致使产品动作的故障类型和具体的故障分析数据保存至同一扇区(故障类型在前,故障分析数据在后)。
记故障类型A为,0x01;
记故障类型B为,0x02;
记故障类型C为,0x03;
当产品二次上电后,读取故障类型进行相应指示;之后清除故障类型(0x00),但故障分析数据仍保存,以便后续读出分析。

该解决方案避免了程序运行过程中对Flash进行擦除操作所需要的擦除时间为22.02ms,减少对程序运行的影响,尤其对高速、连续信号采样和处理类应用效果明显。

此外,单片机Flash均有擦除次数上限,单片机的Flash擦写次数,用户本身是无法控制的,与其本身质量有关,当然电源环境很好,纹波较小,不出现高压对芯片的损害,Flash擦写次数就不会降低。但太过频繁擦写容易超过擦除次数上限,会损坏Flash,且结果不可预测,可能能写,但下一次就写不进去了;可能能写一半,后一半写不进去。擦除、读都一样没有规律。采用这种方案也可以在一定程度上提高内部Flash的修改次数。

注意:本文所介绍的单片机Flash不擦除直写方法,仅在STM32L431xx系列验证通过,别的系列、别的品牌单片机暂待验证。该方法是否具有通用性尚不明确,谢谢!


物联沃分享整理
物联沃-IOTWORD物联网 » STM32单片机Flash直写案例分析与实践

发表评论