本文来简要介绍一下如何在EB中配置AUTOSAR Fls和Fee模块。Fls模块是Flash的驱动,执行具体的Flash擦写读取等操作。Fee模块的全称是FlashEEPROMEmulation,即Flash模拟EEPROM,是为了解决Flash擦写寿命比较短的问题,通过算法实现各个Flash块的交替擦写,以延长寿命。
1. Fls
(1)FlashSector(扇区)
Fls模块中最重要的一点就是配置FlsSector,如下图所示,一共配置了8个Sector,每个Sector可以选择对应的Flash物理扇区,配置好后,这几个Sector就会被用来模拟EEPROM。S32K1XX系列芯片带有专门用来存储数据的Flash——FlexNVM,地址从0x10000000处开始。每个扇区的大小是2K。
![在这里插入图片描述](https://img-blog.csdnimg.cn/f5951d46a8ab43d7984b4b1a694a0e6e.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6ICB5a2fXw==,size_20,color_FFFFFF,t_70,g_se,x_16)
(2)回调函数
注意结合Fee模块一起使用的时候,要配置以下两个回调函数,否则数据存储会有问题:
![在这里插入图片描述](https://img-blog.csdnimg.cn/bc21662b7e754046abec1532ebccbef9.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6ICB5a2fXw==,size_20,color_FFFFFF,t_70,g_se,x_16)
2. Fee
Fee模块是基于Fls模块的,不可单独使用。
配置Fee时首先要配置Fee Cluster,每个Cluster可以包含一个以上的FlashSector。
Cluster越多,Flash的平均擦写次数越少;每个Cluster包含的Sector越多,能够同时存储的数据量越大。
(上面是我初步分析的,大家有不同的看法可以交流一下,互相学习)
![在这里插入图片描述](https://img-blog.csdnimg.cn/2accf53c5e5048469cca2189dcad9524.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6ICB5a2fXw==,size_20,color_FFFFFF,t_70,g_se,x_16)
配置完Cluster之后就可以配置Block了,如下图所示,每个Block有一个唯一的序号——BlockNumber,作为该Block的索引,用于写入数据和读取数据。写入数据时要整个Block一起写入,读取的时候可以指定偏移量和数据长度,读取该Block中某个地址处的某几个字节数据。
每个Block可以分别配置大小,即可存储的数据长度。
![在这里插入图片描述](https://img-blog.csdnimg.cn/53633b7bd65d41439de051781c234ecd.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6ICB5a2fXw==,size_19,color_FFFFFF,t_70,g_se,x_16)
如果结合Nvm模块一起使用的话,要配置下面两个回调函数:
![在这里插入图片描述](https://img-blog.csdnimg.cn/6e56a9bc244c437489a8fbebe1b09e90.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6ICB5a2fXw==,size_19,color_FFFFFF,t_70,g_se,x_16)
再注意一下Fee Buffer Size这个概念,可以参考下面的注释,简单说就是Buffersize越大性能越好。
![在这里插入图片描述](https://img-blog.csdnimg.cn/54e01aaf1b5540aaadff5f5666602168.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6ICB5a2fXw==,size_20,color_FFFFFF,t_70,g_se,x_16)
3. 测试代码
下面的测试代码参考了NXP官方提供的Mcal Sample中的代码。
创建一个Task,每100ms调度一次,代码如下:
static CONST (uint8, AUTOMATIC) FeeTest_WriteBuff[32]={0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA};
static VAR (uint8, AUTOMATIC) FeeTest_ReadBuff[32]={0};
TASK( OsTask_FeeTest )
{
volatile StatusType status;
Std_ReturnType stdRet = E_NOT_OK;
MemIf_StatusType memif_status;
memif_status = Fee_GetStatus();
switch(FeeState)
{
case FEE_ERASE_STATE:
{
if (MEMIF_IDLE == memif_status)
{
stdRet = Fee_EraseImmediateBlock(FeeBankIdx);
if (stdRet != E_OK)
{
Can_PduInfo_0_0.sdu[0] = 0x01;
FeeState = FEE_ERROR_STATE;
}
else
{
FeeState = FEE_ERASE_BUSY_STATE;
Can_PduInfo_0_0.sdu[0] = 0x00;
stdRet = E_OK;
}
}
else
{
stdRet = E_OK;
}
}
break;
case FEE_ERASE_BUSY_STATE:
if (MEMIF_IDLE == memif_status)
{
FeeState = FEE_WRITE_STATE;
}
stdRet = E_OK;
break;
case FEE_WRITE_STATE:
{
if (MEMIF_IDLE == memif_status)
{
stdRet = Fee_Write(FeeBankIdx, (uint8 *)FeeTest_WriteBuff);
if (stdRet != E_OK)
{
Can_PduInfo_0_0.sdu[0] = 0x02;
FeeState = FEE_ERROR_STATE;
}
else
{
FeeState = FEE_WRITE_BUSY_STATE;
stdRet = E_OK;
}
}
else
{
stdRet = E_OK;
}
}
break;
case FEE_WRITE_BUSY_STATE:
if (MEMIF_IDLE == memif_status)
{
FeeState = FEE_READ_STATE;
}
stdRet = E_OK;
break;
case FEE_READ_STATE:
{
if (MEMIF_IDLE == memif_status)
{
stdRet = Fee_Read(FeeBankIdx, 0, FeeTest_ReadBuff, 32u);
if (stdRet != E_OK)
{
Can_PduInfo_0_0.sdu[0] = 0x03;
FeeState = FEE_ERROR_STATE;
}
else
{
FeeState = FEE_READ_BUSY_STATE;
}
}
else
{
stdRet = E_OK;
}
}
break;
case FEE_READ_BUSY_STATE:
if (MEMIF_IDLE == memif_status)
{
FeeState = FEE_VALIDATE_STATE;
}
stdRet = E_OK;
break;
case FEE_VALIDATE_STATE:
{
stdRet = SampleAppFee_memcmp((uint8 *)FeeTest_WriteBuff, FeeTest_ReadBuff, 32u);
if (stdRet != E_OK)
{
Can_PduInfo_0_0.sdu[0] = 0x04;
FeeState = FEE_READ_ERROR_STATE;
}
else
{
FeeState = FEE_FINAL_STATE;
Can_PduInfo_0_0.sdu[0] = 0xFF;
if(FeeBankIdx < 4)
{
FeeBankIdx++;
FeeState = FEE_ERASE_STATE;
}
}
}
break;
case FEE_ERROR_STATE:
{
}
default:
{
stdRet = E_NOT_OK;
}
break;
}
status = TerminateTask();
}
在main函数中初始化Fls和Fee模块:
……
Fls_Init(&FlsConfigSet_0);
Fee_Init();
FeeState = FEE_ERASE_STATE;
FeeBankIdx = 1;
StartOS( Mode01 );
在一个5ms为周期的函数中调用两个模块的主调度函数:
TASK( OsTask_5ms )
{
volatile StatusType status;
……
Fls_MainFunction();
Fee_MainFunction();
status = TerminateTask( );
}
即可完成4个Fee Block的简单测试。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)