|
7 Y. C; H4 x9 h& ? 一、前言/ O! [& ~, J0 |! D 随着微电子产品的应用越来越广泛,同时,系统对可靠性和安全性的要求也越来越高。而在实际应用中系统存储单元可能发生故障,因此存储器完整性保护变得愈加重要。ECC【Error correction Code】技术被广泛用于防止数据损坏,确保数据的准确性,提高系统的可靠性和安全性。 在STM32H7系列微控制器配备了大容量的内部FLASH存储器,用于存储程序代码和数据,有些型号STM32H7 MCU其容量高达2MB。因此在FALSH操作过程中不可避免的会遇到FLASH ECC问题。) b! P7 @, B6 o. M 本文介绍了STM32H7的FLASH ECC结构及原理,并且通过软件方法模拟了FLASH ECC故障,以及发生故障后的处理方法,最后总结了STM32H7的FALSH操作的注意事项。 ! t9 W4 \4 y( Q9 Q; X# r 9 J1 k x4 K! n. u% b 二、STM32H7 Flash介绍 ECC(Error Correction Code)由数学家Richard Hamming发明,第一个Hamming码使用7位存储4位信息,冗余位用于纠正和检测错误。在STM32H7系列器件中,RAM和Flash存储器均使用基于Hamming原理的SEC/DED(Single-Error Correction/DoubleError Detection)算法进行保护。ECC码能够检测并纠正存储的数据字中的一位错误,并对两位错误进行检测。 对于STM32H72x/3x/4x/5x型微控制器,Flash Word(最小可编程内存量)为256位,而在STM32H7Ax/Bx型上为128位。这也是在Flash Word上实现SEC和DED功能所需的10个ECC位(STM32H7Ax/Bx型为9个ECC位)保护的存储器部分。只有在读取-修改-写入的基础上才能对任何较小的内存单元进行写访问,这种操作会对内存硬件造成更大的压力。 ECC功能集成在Flash控制器中,不能禁用。如果应用并不适用于ECC,则可禁用相关的中断功能并忽略Flash状态寄存器中的标志位。 ' h' C4 z5 ^& g8 C: [ 三、STM32H743的Flash. Z$ I" J7 g0 g2 i: ~ z 以STM32H743为例,Flash中的数据为266位字:每256位的Flash字增加了10个ECC位。ECC机制基于SEC/DED算法。它支持:SEC(Single-Error Correction)以及DED(Double-Error Detection)。+ {# x8 Y* @+ R! }( \ 检测到错误并进行校正后,FLASH_SR1/2寄存器中的SNECCERR1/2标志会置1。如果FLASH_CR1/2寄存器中的SNECCERRIE位置1,将生成中断。如果检测到两个错误,FLASH_SR1/2寄存器中的DBECCERR1/2标志会置1,并会生成总线错误。在这种情况下,将不会对接收到的数据进行校正。如果FLASH_CR1/2寄存器中的DBECCERRIE1/2位置1,将生成中断。 如果检测到ECC错误,出错Flash字的地址会保存到FLASH_ECC_FA1/2R寄存器中。如果连续检测到错误,将只会存储第一个错误对应的地址。当生成错误的相关标志复位后,该寄存器会自动清空。9 o' J* l$ R1 Z* c2 b" Z+ u 2 T+ _3 X1 I) r7 } 四、试验-Flash ECC故障注入4 Z) h4 c* d7 H7 o* i2 \ 对于STM32H7的FLASH ECC验证,我们可以采用软件的方法模拟ECC故障注入,其原理是一次擦除后对FLASH进行两次连续写入不同值。然后再通过读取该Flash地址的数据来触发ECC故障。 在这里,我们使用NUCLEO-H743板子进行测试,它有三个状态指示灯,我们利用这三个状态指示灯来指示目前程序状态。LED1亮代表触发了SEC故障,LED2亮代表触发了DED故障,LED3闪烁代表程序正常运行,LED3常亮代表程序进去了HardFault_Handler(void) 。9 A- [: P" z+ q$ P" \2 |7 N8 j 首先,如图1所示,使能ECC中断,并且在FLASH中断回调函数中加入对ECC错误的状态指示灯。5 F. s: v" ]) t" M
▲ 图1. 使能ECC中断以及加入ECC回调函数
▲ 图2. HardFault处理函数
▲ 图3. main函数 在main函数中,首先对Flash进行了擦除操作,然后对Flash进行Single ECC错误故障注入或Double ECC错误故障注入,然后通过读取该地址内容触发ECC故障。5 y8 O5 r1 n6 b+ D% ?3 Y( N( B 4.1. Single ECC注入 首先我们定义了两个数组(如图4所示),用来完成一个FLASH Word写入。两个数组差异为1个bit。8 J& h2 ?, o+ |8 e9 j" o
▲ 图4. Single ECC写入Flash Word定义 然后,我们运行图5函数来模拟Single ECC故障发生。然后再读取这个Flash地址的内容去触发ECC错误。这时我们可以看到板子LED1灯亮,LED3灯闪烁。: z" x5 D7 Q* n
▲ 图5. 模拟Single ECC故障发生 通过STM32 CubeProgrammer观察FLASH寄存器状态(图6)。可以看到SR1寄存器中的SNECCERR已经被置位“1”,并且ECC_FA1R寄存器已经将发生错误的地址记录了下来。(该地址为Flash Word地址,需要转换一下才是Flash地址)1 i: p2 d+ r2 j- T4 U& T0 T" a
▲ 图6. Flash寄存器状态 " f. I2 p. u, y ?5 a2 A- x9 k9 u" v& j( Z$ X 4.2. Double ECC注入 Double ECC故障注入方法类似,只不过两个数组差异为两个bit,如图7所示。
▲ 图7. Double ECC写入Flash Word定义 然后,我们运行图8函数来模拟Single ECC故障发生。然后再读取这个Flash地址的内容去触发ECC错误。这是我们可以看到程序已经进入HardFault_Handler(void)。* v) ~8 T! H1 ?- a3 }
▲ 图8. 模拟Double ECC故障发生 通过STM32CubeProgrammer观察FLASH寄存器状态(图9)。可以看到SR1寄存器中的DBECCERR已经被置位“1”,并且ECC_FA1R寄存器已经将发生错误的地址记录了下来。(该地址为Flash Word地址,需要转换一下才是Flash地址), n* n5 m& p* S
▲ 图9. Flash寄存器状态 : u% `( j! m5 C7 P( h4 @ e 五、FLASH使用小结 5.1. FLASH操作注意事项 a) FLASH操作过程中不应该被其他操作打断,如掉电,复位; b) FLASH应遵循先擦后写,不建议在同一地址连续写两次;: v% u) |2 Y# _7 l J. f% O6 e c) 不能对FLASH寄存器解锁两次,否则FLASH寄存器将被锁定,直至下一次复位; d) FLASH擦除前先清故障标志;" r; j! G; ]5 ]6 \3 Z, p9 A; G% D e e) 对option bytes的错误操作可以导致bus error,ECC double error detection event也会导致bus error;& ?" |- G+ @. G! K! h9 Z q; P4 D) Q r 5.2. 常见的导致ECC错误的原因 a) 闪存的典型故障是由于存储单元磨损和电荷泄漏导致的。可能导致故障的一些因素包括来自相邻单元的干扰或编程期间电压不稳定; b) 与SRAM不同,某些内存地址的故障可能表明同一页面中随后的故障概率略高在两次erase之间,向同一个Flash地址写入两次不同的值;! h# a7 g8 a6 D* ?( H6 ]- Z- L c) 在Flash program或者Flash erase过程中突然断电或异常终止; d) 电磁辐射; R9 T) O- x8 i" J% k0 M, y 5.3. FLASH ECC总结 a) 在Flash存储器中,数据寿命会随时间衰减,尤其是在高温下。存储温度会对Flash存储器数据寿命产生影响; b) 对FLASH进行循环(编程)时温度的影响会更大; c) 由于10位ECC码关联到每个256位数据Flash字,因此只支持按256位进行的写操作;/ J+ L7 ~! B7 o5 s& l) v% \. c) C d) Flash不同于SRAM,其Erase过程是写“1”,其Program过程是写“0”。因此正确的操作过程是先要对FLASH先进行Erase操作再进行Program操作,不可以对FLASH同一地址连续program不同值;: f- A* C o8 \. Z e) Flash的SEC(Single-Error Correction)仅仅是读纠错,其Flash的错误不能被自动纠正回来; f) ECC是Memory的一种保护机制,产生了ECC错误并不代表Flash/RAM内存物理上损坏; g) 对Flash进行擦除也可以修复ECC错误,或者不再去读内容被破坏的内存,也可以规避掉ECC错误的产生;4 z% T2 `8 m, m% f0 m8 {0 y A; y h) Flash存储器只能对每个存储字进行一定量的重写,这就需要在数据存储的情况下实现平均抹写存储区块;: x& E$ w8 ^ o1 S( J $ q( x6 v! o6 J, I9 r# { # _7 b; B5 l% O1 }2 T5 `+ q1 r 详细内容点击下载>>" U+ V# r: o# G1 V! { * E. |* B" n* N |
【 逢7发帖赢大礼】1、利用CubeMX生成正点原子H7R7开发板的STM32CubeIDE工程
【STM32H735G-DK测评】ADC3+TIMER1+DMA 采样模拟信号
【STM32H735DK测评】Ethernet+lwip DHCP获取IP地址
STM32H743基于CubeMx5.0配置手册
【STM32H735G-DK测评】lvgl移植
【STM32H735G-DK 测评】STM32H735G-DK External Loder 编译和测试
【福利三:逢7发帖赢大礼】使用MPU6050模块、img_dsc、img_btn机制实现一些简单有趣的动画效果
【福利三:逢7发帖赢大礼】使用arc弧形拉条控件控制PWM舵机及使用SPI3接口操作NRF24L01模块进行无线通信
【福利三:逢7发帖赢大礼】调试nucleo-WBA65RI工程测试样板的一些心得
【福利三:逢7发帖赢大礼】lv_timer和BME680实现温度、湿度、气压数据读取
微信公众号
手机版