01
NvM 老规矩 先给同志们舞一个。
看完了读和写的调试过程,本质上就是通过对NvM、MemIf、Fee、Fls模块的层层封装和状态机跳转,最终操作指针实现对dflash的读和写。
但是光调试我们就跳过一大半的函数内容没看,而且对于 Fee_Cache、扇区的换页、擦除好像也是未知的。
接下来通过调试 Fee_Init() 和写测试代码来继续我们的调试。
02
Fee初始化
Fee初始化主要就是通读DFlash来确认扇区的状态来判断之后
Fee_MainFunction() 需要做些什么事。说到扇区,先看一下和本文匹配的Isolar配置。
其实就是简单的分了2个扇区,每个扇区大小为0xF000。
回到Fee_Init(),它都做了些什么呢。
首先就是初始化模块的变量,
如:Fee_GlobInfoLastRdHeader_st、
Fee_LLSectorOrder_st、Fee_RdWrOrder_st 、Fee_GlobInfoWrBlock_st
接下来就是从0xAF000000开始读起了。
调用 Fee_LLDetectActiveSector(),确认当前活跃的扇区。
首先通过一系列调用,将扇区的log信息读取到结构体 Fee_LLSectorOrder_st 上。
那么过程是如何呢?咱们看这个调试图:
通过对Readadress+8,做到一页一页将log区信息(一共96个字节)读取到
Fls_lMainBlankCheck[]上。
那么图中相应区域的数字都是什么含义呢?附上log信息的结构体:
当前扇区的状态:
01代表 FEE_ERASED_MARKER_ID_E;
02代表 FEE_USED_MARKER_ID_E;
05代表 FEE_START_MARKER_ID_E。
确认扇区之后,就要通读整个扇区0xF000,来确定Fee_Cache,为之后的ReadAll确认block的位置。
从Data窗口看,首先读取0xaf000060区域,找到了Block header 0xA53C96
通过Fee_Id为05,然后将0x60的地址赋值到Fee_Cache_au32[2],即FEE_Blo
ckPropertise_st[2]的存储位置为0x60。
之后通读全部数据(0xaf000000-0xaf00effff),即得到所有FEE_Block的位置信息了。
03
换页、扇区处理
首先,使用miniwiggle清空DFLASH。
然后就可以看到ChangeCnt变成了1,2,即是扇区第一次使用。
然后写点压力测试代码,循环写入FEE,让第一个扇区存满。如下视频:
在如下区域打上断点,默默等待扇区写满。
当第一个扇区即将写满时,我们看看栈区的函数调用,
扇区的log区域信息变更:
可以看到多了信息0x03,对应
扇区已满。
之后则会调用扇区重组函数:
启用第二片扇区:
启用扇区之后,开始依次去拷贝Fee_Cache_au32中的内容到新的扇区中,即做备份。可以看下状态机、RdAdress、WrAdress的变化
最后再去更新Fee_Cache_au32,
整个备份过程结束后,开始擦除第一个扇区,
在函数Fee_LLEraseSector() 执行完之后:
原来的扇区1变成了现在的扇区3,并更新扇区3的log区域的log信息。
之后就可以在扇区2继续做NvM的读写了。
突发奇想:
如果在备份的过程中断电会怎样呢?!
经过调试后发现,Fee会根据Log信息中存储的状态,判断当前处于什么状态,然后接着备份。
>>谢谢阅读<<
原文始发于微信公众号(汽车与基础软件):CP Autosar – NvM之flash
请问这个状态信息是存放在哪里的呢
可以给原文公众号留言