S32K3学习笔记---S32K3之Fls & MemAcc & Fee

S32K3学习笔记—S32K3之Fls & MemAcc & Fee模块

1.前言

​ 对于嵌入式开发Flash是及其重要的,本文主要介绍一下S32K3的Flash模拟EE的操作,对于RTD3.0以后的版本相对于之前的版本有一个很大的架构变化,主要是根据最新Autosar的变化,也是一种趋势吧,可能后续我们看到芯片的Flash都是外挂的吧。就使用情况来说,RTD3.0的版本有bug且操作flash的速度也很慢,建议用目前最新的版本(RTD4.0 P12),修复了很多Bug。具体原因可以参考官方给出的变更记录。

2.原理

几个基本术语:

​ 1.sector:一个最小可擦除单元,定义为区

​ 2.Page:一个最小可编程单元,定义为页

​ 3.block: 模拟EE滚动的最小单元,称最小储存单元

​ 4.Cluster: 模拟EE滚动的最大单元,一个Cluster由多个sector组成且必须为连续扇区。由Cluster头(ID、状态、起始地 址、大小)+Block头(ID、状态、起始地址偏移、长度)+Block Data组成

​ 5.ClusterGroup:由多个Cluster组成的空间,出于Flash寿命原因,一般用双扇区算法,一个ClusterGroup两个Cluster

​ 6.Swap:当前Cluster没有空间继续存储时,会进行swap操作,把当前有效的数据拷贝到下一个Cluster

3.EB配置

​ 主要依赖于FLS、MemAcc、Fee、Mcl模块

3.1Fls

​ 相比与之前的FLS模块,此版本Fls是直接操作的物理地址,以及区分了INFLs和EXFLS,支持两种Flash的配置,再加上MemAcc模块对二者进行管理,当然如果用的简单也可以直接不适用MemAcc以及FEE模块,此案例是内部Dflash模拟EE使用Fls+MemAcc+FEE,Pflash直接使用Fls+MemAcc,包含两种情况

image-20240310184611480

​ 1、2.使能需要使用的API的开关

​ 3.在闪存块被擦除之后,擦除空白检查将寻址的存储器区域的内容与擦除的闪存单元的值进行比较,以检查该块是否已被完全擦除

​ 4.在写入闪存块之后,写入验证检查将重新编程的存储器区域的内容与所提供的应用缓冲区的内容进行比较,以检查该块是否已被完全重新编程。

​ 5.每当擦除或写入作业启动时,flash driver应将闪存访问代码加载到RAM,并在该作业完成或取消后卸载(覆盖)该代码

​ 6.允许在将AccessCode加载到RAM后清理缓存,以确保缓存和RAM内存之间的同步

​ 注意:5和6使能需要注意链接文件划分合理的范围

​ 7.使能MemAcc的回调通知

​ 8.启用超时监控

​ 9.超时时间可以自行配置

image-20240303204114579

​ 1.在每次闪存硬件操作后,通过使缓存无效来同步内存。如果使用burst需要打开

​ MEM驱动程序需要通过三种方法来保持内存一致性:

​ a.禁用数据缓存

​ b.将驱动器操作的闪存区域配置为不可缓存

​ c.启用MemSynchronizeCache功能

image-20240303182924888

​ 1.此处的sector可以按照连续的地址分配一个就行,例如此处:两个DFlash,每个8x8K,主要是用来模拟EE。以及PFlash 8x512K,三个就能将所有内存划分完。

image-20240303185631996

​ 1、2.物理地址和其实地址,相比于之前版本RTD,RTD 3.0之后的版本Fls都是可以直接操作物理地址

​ 3.MemSectorSize和MemPageSize值相同的连续扇区数,此处将64k,在一个block,所以此处设置为8

​ 4.扇区是最小的可擦除单元,所以是0x2000

​ 5、6.读写取页的大小(byte)

​ 7.为存储器设备指定的擦除周期数(通常在设备数据表中给出),默认不使用

​ 8.Burst用于提高性能,使能之后可以大批量的擦除读写,对于提高速度建议使能,如图是支持的最大的硬件参数

剩下的sector都类似的配置就行,注意起始地址就行。

3.2MemAcc

image-20240303205332792

​ 1.是否使用Mem函数指针表API调用Mem驱动程序函数

​ 2.如果使能,则地址类型应以64位实现

​ 3.使能MemAcc_Compare(),允许将存储在缓冲器中的数据与存储在存储器中的数据进行比较

​ 4.指定MemAccmodule在一个Mem比较请求中请求的最大字节数

​ 5.指定MemAcc_MainFunction()的固定调用周期

image-20240303210508990

​ 1.指定AddressArea的ID。以便区分具有相同逻辑地址的多个AddressArea

​ 2.对于每个AddressArea,一次只能处理一个作业。MemAcc基于优先级处理作业。0(最低)-65535(最高),在上层请 求具有更高优先级的作业的情况下,较低优先级的作业被挂起,直到较高优先级的作业完成

​ 3.MemAcc上层模块继承的缓冲区对齐值

​ 4.在MemAcc作业完成后触发,通知上层完成

image-20240303210805156

​ 1.配置所需要的SubAddressArea的相关属性,包括逻辑地址可做偏移、Fls类型等

image-20240303212134251

​ 1.指定SubAddressArea的逻辑起始地址

​ 2.指定子地址区域的扇区偏移量,以防子地址区域不以参考的MemSectorBatch的第一个扇区开始

​ 3.此值指定子地址区域的物理扇区数

​ 4.定义如何访问Mem驱动程序服务,以及如何调度和激活/初始化Mem驱动

​ a.DIRECT_STATIC:Mem驱动程序与应用程序链接。Mem服务函数由MemAcc直接调用。Mem_Init由EcuM调用,Mem_MainFunction由SchM触发

​ b.INDIRECT_DYNAMIC:Mem驱动程序作为一个单独的二进制程序链接,并被动态激活。MemAcc将使用Mem驱动程序头表来调用Mem服务功能。Mem_Init和Mem_MainFunction的调用由MemAcc处理。

​ c.INDIRECT_STATIC:Mem驱动程序与应用程序链接。MemAcc将使用Mem驱动程序头表来调用Mem服务功能。Mem_Init和Mem_MainFunction的调用由MemAcc处理

​ 5.根据MemAccUseMemFuncPtrTable配置,此前缀用于引用Mem驱动程序头结构或相应的Mem API函数。

​ 6.指定失败的擦除、写作业的重试次数

​ 7.如果Mem中使能了Burst,此处三个Burst必须使能

​ 8.对映射到子地址区域的MemSectorBatch的引用

3.3 FEE

image-20240303215118489

​ 1.调用主函数的周期

​ 2.通知上层(NVM)FEE的状态,如果不是能NVM需要周期轮询FEE的状态

​ 3.逻辑块应与之对齐的大小

​ 4.FEE最小读取页是最小页的倍数

​ 5.参数确定费缓冲器需要的起始地址的对齐方式

​ 6.数据缓冲区的大小。当Fee将数据从一个Group复制到另一个Group时,以及当Fee在启动时读取块头信息时,数据缓 冲区用于缓冲数据

​ 7.当写入操作开始时,相应的块被标记为不一致。成功写入后,它被标记为一致。这意味着当写入操作中断(取消、重 置)时,应用程序无法再访问块数据

​ 8.如果启用,Fee_EraseImmediateBlock函数将使已写入的引用块无效。否则,块将保持原样

​ 9.不建议开启

​ 10.如果启用了该参数,Fee将未写入的块标记为INVALID,否则Fee将未写入的块标为INCONSISTENT

image-20240303215322584

​ 1.配置ClusterGroup,此处只配置一个组

image-20240303215418262

​ 1.配置Cluster,此处是配置两个,平分Dflash,每个Cluster64K,双扇区算法。

image-20240303215632535

​ 1.对MemAcc地址的引用,对应MemAcc中的SubAddressArea

​ 2.其值应等于配置的子地址区域在配置的子寻址区域列表中的位置,对应MemAcc中的SubAddressArea Index

image-20240303215950888

​ 1.根据我们的需求,来配置所需要的block

image-20240303220202130

​ 1.选择ClusterGroup ID

​ 2.配置blcok ID

​ 3.配置block的大小(字节)

​ 4.是否支持立即写

​ 5.此块所需的写入周期数。

​ 6.对应MemAcc中的SubAddressArea Index

3.4 Mcl

image-20240303220752883

​ 1.需要使用到cache,因此需要在此使能

至此,配置全部完成

4.代码调试

​ 可以通过写入再读取的方式、结合IDE的界面查看对应内存的值来验证正确性。

const uint8 DataBlock0[4] = {0x00,0x01,0x02,0x03};
uint8 DataReceive[2] = {0x0,0x0};
int main_c0(void)
{
   MemIf_StatusType status = MEMIF_IDLE;
    Std_ReturnType RetValue = E_NOT_OK;

    /* Init MemAcc */
    MemAcc_Init(NULL_PTR);

    /* Init Fee */
    Fee_Init(NULL_PTR);
    do
    {
        Fee_MainFunction();
        MemAcc_MainFunction();
        status = Fee_GetStatus();
    } while (status != MEMIF_IDLE);
    /* Init fee success */

    /*Write data to block 0*/
    RetValue = Fee_Write(FeeConf_FeeBlockConfiguration_FeeBlockConfiguration_0, DataBlock0);
    /*Perform write data to Block 0*/
    do
    {
        Fee_MainFunction();
        MemAcc_MainFunction();
        status = Fee_GetStatus();
    } while (status != MEMIF_IDLE);
    /* Write operation success */

    /*Read data block 0, from offset 2 and length is 2*/
    RetValue = Fee_Read(FeeConf_FeeBlockConfiguration_FeeBlockConfiguration_0, 2, DataReceive, 2);


    /*Perform read data form Block 0*/
    do
    {
        Fee_MainFunction();
        MemAcc_MainFunction();
        status = Fee_GetStatus();
    } while (status != MEMIF_IDLE);
    Fee_ExampleAssert(MEMIF_JOB_OK  == Fee_GetJobResult());
    /*Check Data*/
    if((DataReceive[0] != DataBlock0[2])|| (DataReceive[1] != DataBlock0[3]))
    {
        /*error*/;
    }
    else
    {
        /*do nothing*/
    }
  }

5.展望

​ 对于原理处写的很简陋,基本就那几个操作,后面有必要再展开记录一下,或者再后续记录NVM的时候再详细写一下。

### S32K144 Flash Emulation of EEPROM Configuration For the S32K144 microcontroller, configuring the internal flash to emulate an EEPROM involves several steps that ensure reliable data storage and retrieval mechanisms are implemented. The process leverages specific features provided by NXP for this purpose. The S32 Design Studio offers a set of tools specifically designed for managing non-volatile memory operations on devices like the S32K144 series[^1]. These include utilities for wear leveling, which is crucial when using flash as pseudo-EERPOM because it prevents certain sectors from wearing out faster than others due to repeated write cycles. To configure the flash to act similarly to EEPROM: - Define regions within the available flash space where variables will be stored persistently. - Implement functions responsible for reading/writing these designated areas while handling necessary error checking and correction procedures. - Utilize built-in hardware support or software algorithms for implementing wear-leveling across multiple pages/sectors allocated for emulated EEPROM functionality. A typical implementation might look something like below in C code targeting such configurations: ```c #include "S32K144.h" // Function prototypes void initEmulatedEeprom(void); uint8_t readFromEmulatedEeprom(uint16_t address); void writeToEmulatedEeprom(uint16_t address, uint8_t value); int main() { // Initialize system clock and other peripherals here... initEmulatedEeprom(); // Main application loop goes here... } void initEmulatedEeprom(){ /* Code initializing flash settings */ } uint8_t readFromEmulatedEeprom(uint16_t address){ /* Implementation details omitted */ return 0; } void writeToEmulatedEeprom(uint16_t address,uint8_t value){ /* Implementation details omitted */ } ``` This example provides placeholders for critical routines but does not contain actual implementations since those depend heavily upon project requirements including how much data needs storing, frequency of writes, etc.[^1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值