在测试代码中运行写入再次读取数据担保是精确的,也没有其他副浸染。但是到真端正上用场的时候却挂了。在一上电的初始化过程中我会存储一些参数,而从程序打印的log信息来看,百分之八九十的情形都会运行到写入eeprom的时候程序卡去世。当然还有百分之十的情形便是程序正常的跑起来了。
这么看来这种去世机肯定和写eeprom有关,但是并不是一定会发生的,有一定的概任性。

为什么会涌现这种情形,可以先看下STM32L071的芯片内部架构图:
cortex M0+便是单片机中的CPU,memory interface便是连接存储掌握器和总线之间的接口。而读写flash和eeprom便是通过NVM memory掌握器来的。以是终极cpu读写flash或者eeprom的数据流如下所示赤色线标注:
eeprom和flash是共用的NVM掌握器。以是现在会涌现一种情形,当正在写eeprom时NVM会处于繁忙状态,就导致了这个时候cpu再从NVM取指令取不到,以是CPU要处于挂起等待的状态。等到eeprom写完了,才可以连续往下实行。
这样来看写eeprom会造成cpu壅塞,代码无法实行。这时候再来一个中断,中断做事函数(也是代码指令)也无法实行。
到目前就可以阐明我项目中一上电为什么卡去世。由于在上电的时候我串口也会通过中断办法吸收比较多的数据,而此刻在写eeprom,cpu壅塞在那无法实行串口吸收中断进而产生了串口吸收数据缺点中断。在写完eeprom往后,cpu就进入串口吸收中断,但是我没有打消缺点中断标志就会一贯卡去世在中断做事函数中。实际上如果我打消串口吸收缺点中断,也会由于cpu壅塞导致的串口吸收数据丢失。
办理思路肯定也有,如果想让写eeprom的时候串口数据不丢失,也可以利用DMA来处理。如果想让在写eeprom的时候同时可以相应中断也可以把中断向量表和中断做事函数放在ram中运行。
不过这些方法觉得都不足完美,觉得有点过于繁芜。实则有更简便的方法。从上面剖析导致cpu壅塞等待,中断无法相应的根本缘故原由还在于NVM掌握器在写的时候就无法读取了。
光彩的是STM32L071CB设计之初可能已经考虑这个问题,它的NVM一共有两个,但是须要把稳的是并不是所有L0系列都有两个NVM,详细这个型号有几个还是要看下数据手册。两个NVM的架构如下图:
每个NVM中都包含了一块flash和一块儿eeprom。根据手册里面描述NVM1和NVM2中各占一半。对应的flash和eeprom地址如下:
两个NVM好处呢便是可以实现一个NVM在写的时候,另一个NVM进行读取的时候不会受影响。而我的代码是放在NVM1的 flash中的,那么我就把要存的数据写入NVM2 的eeprom中。只要读写不同时在一个nvm中,这个问题就办理了。以是终极我只用把我存储参数的eeprom基地址修正到0x8080c00就可以了。
写eeprom的操作代码就很大略:
HAL_FLASHEx_DATAEEPROM_Unlock();for(uint8_t i=0;i<20;i++){ HAL_FLASHEx_DATAEEPROM_Program( FLASH_TYPEPROGRAMDATA_WORD,EEPROM_BANK2_BASE+i4);}HAL_FLASHEx_DATAEEPROM_Lock();
还有两个问题须要描述一下:
在写eeprom之前需不须要擦除?
根据参考手册描述,在写eeprom,掌握器会自动检测写入的地址需不须要擦除,如果须要会自动进行。但是可以设定FIX位来逼迫在每一次写入之前都擦除。以是我们在写eeprom的时候完备没必要再手动擦写一遍,并且为了节省写的韶光也不用设置FIX位。而设置FIX位可以担保每次写入数据时用的韶光会相同(由于都会自动逼迫实行擦除再写入的动作)。
写eeprom的时候要不要关中断?
如果在写eeprom,你又须要同时用中断吸收串口数据,或者用定时器中断来捕获电平时长。你关了还行不?串口数据不会丢?捕获的韶光还准确?
如果你的型号只有一个NVM,写的时候又壅塞到了cpu,这时候默认中断到来也是不会实行的。也必须等到写完eeprom才能连续运行,实际上关中断的意义已经不大。
最好的办理办法便是还是用有两个nvm的型号,从根本上办理不会影响中断运行的问题。或者你不怕麻烦,把关键代码放进ram去运行了。







