AUTOSAR Memory Stack之FEE模块
AUTOSAR Memory Stack之Nvm模块-优快云博客
前言
此文章参考大佬“小猫爪”的文章,以及AUTOSAR官方文档,前文大部分为摘录,详情可参考:小猫爪:S32K3学习笔记08-S32K3之MCAL中的FEE_s32k3 fee-优快云博客,后文则是自己对AUTOSAR的API功能函数的部分理解,仅为总结记录所用,如有不足欢迎指正。再次感谢小猫爪大佬文章对我的帮助!!!
FEE模块框架及常见操作步骤
可参考小猫爪大佬的文章,这里不在做详细解释。
相关函数(后面有时间更新)
总结
FEE底层状态机相关总结
FEE的状态机是有一定讲究的,当然可以有不同的底层状态机,我总结一下我用到的。
首先,小猫爪的文章里面介绍了cluster扫描、BLOCK写、BLOCK读以及Cluter swap四个主要的常见操作步骤。因此,Fee_MainFunction主要实现这四个功能,这四个功能都是外部接口调用之后,会标记Fee_eJob标志位为相应状态,在之后的Fee_MainFunction状态机调用时,产生相关调度工作。
Cluster 扫描:
在使用Fee模块之前,Fee在初始化操作中会启动Cluster Scan操作,而这个操作就是为了找到有效Cluster,并且找到当前有效Block的地址指针,以及写操作的指针。其实就是前期的初始化工作,引发了扫描工作,不然怎么去读写。主要分为以下两步
- 扫描有效的Cluster,如果扫描到两个及以上的有效Cluster,则取Cluster ID大的那个区域为有效Cluster。如果没有有效cluster,那么就会擦除相关区域创建并格式化一个cluster。
- 依次扫描Block头,在扫描的过程中会把FLASH中的信息读取出来,同步BLOCK里面的数据,同时记录最后一个有效Block头。直到扫描到无Block头的区域,标记写指针地址,并结束扫描。
BLOCK读:
FEE层会提供特有的Fee_Read接口给外部调用,这个是相对于其他功能来说比较简单的,在状态机中没有太多复杂的调用,只要一个读取操作就行了。
BLOCK写:
这个也是提供外部接口Fee_Write给其他接口调用,在状态机中,它的流程如下:
- 新建Block头(如果我当前要写的BLOCK是immediateData类型的话,则可以立即执行第二步)
- 写数据到目标地址
- 标记Blcok头为有效
Cluster swap:
以下四种情况会触发Swap操作:
这里涉及到引发Swap的函数就比较多了,Fee_Write、扫描函数等。
- 当前Cluster没有空余空间
- FEE初始化操作失败
- Scan发现Header不合法(Checksum有误,未知的Block ID,Blcok与配置的不匹配)
- 立即数检查到有已有立即数操作
Cluster Swap操作的流程如下:
- 擦除下一个Cluster所在的扇区 (ERASING stage 1)
- 在下一个Cluster所在的扇区中新建Cluster头,不包括Valid Flag(FORMATTING stage 2)
- 将当前Cluster中的最后一个有效Blcok头和所对应的数据复制到新Cluster中(COPYING stage 3)
- 写新Cluster头中的Valid Flag,标记新Cluster为有效 (ACTIVE stage 4)
- 在新的Cluster完成Fee读写操作(UPDATING stage 5)
调试相关总结
- 一个Cluster由Cluster头,Block头和Block Data组成;其中Cluster头表明了其ID,状态,起始地址和大小;而Block头表明了其ID,状态,长度,起始地址偏移,而每个Block则是指向了其对应的data存储区。这里需要注意的是Invalid Flag,这一部分是没有被使用的,是保留的。至于checksum是用来检测头的数据正确性的,而Block Assignment是给下面的Fee Swap Foreign Blocks功能使用的。
- 还有一点很容易让人忽略,就是在Fee更新数据的时候,Block头的增长方向是由上而下的,而Data的更新方向其实是自下而上的,最终两者会在中间相遇。
重点:在调试过程中,例如我的FLASH大小为512KB,我只使用最后32KB作为模拟EEPROM来存储数据,那么两个cluster分别为16KB(一般都设置2个cluster即可)。换算一下第一个cluster的起始地址则为512KB-32KB = 0x78000,这时候数据data地址就为512KB-16KB = 0x7C000,当我们要验证一下数据是否写进去的时候,打开Memory观察器参考地址0x7C000里面的数据是否一样就行,同时可以观察0x78000是否有cluster头数据且有效。同时要注意,FLASH的最小擦写大小,以免数据观察错误造成误判。 - 重点:NvM的Block编号叫做Block Handle,Fee和Ea的Block编号叫做Block ID,也就是说APP通过Block Handle(类似于Linux中的文件描述符FD,比较抽象)来索引NvM的数据,而NvM则是通过Block ID来索引Fee和Block的Block数据。这里我们调试时要往BLOCK里面写数据时,用的就是Block Handle了,不要用错。
- 在移植的时候,要记得将Nvm_MainFunction函数添加到相应TASK当中去只有周期的调度状态机才会有状态的实现,同时要在main函数里面添加好NvM_Init函数,不然没有初始化干不了接下来的工作的。