AutoSar FlashDriver
4 限制约束
• Flash驱动擦除或者编程的时候,都是按Flash页中一个完整的扇区为单位;不提供任何重写策略,因为没有内部缓存区。
• Flash驱动不会提供用于数据完整性的处理机制,比如checks
um、冗余存储等;
5 与其他模块的关系
5.1 头文件
• 定义Flash驱动实体的内容应该包含在MemIf_Type.h中,比如Flash1、Flash2等。
• 一个Flash的类型和特性在Fls.h中定义。
5.2 系统时钟
• 如果硬件的内部Flash存储由系统时钟提供,那么系统时钟的改变也会影响到Flash存储硬件的时钟设置;比如PLL on ->PLL off。
5.3 通讯或者IO驱动
• 如果是外挂的Flash,则通过相应的I/O驱动来进行通讯。(并不是真正意思上的IO,实际是SPI等通讯总线).
7 功能规范
7.1 通用设计准则
• FLS模块应该为flash存储提供异步服务(读/写/擦除)
• FLS模块不会缓存数据。FLS模块应使用通过API传递的指针指向应用数据缓冲区进行数据缓存。
• FLS模块不保证给应用缓冲区数据的一致性。
• FLS模块的环境需要保证在flash读/写操作过程中数据的一致性。
• FLS模块应静态检查静态配置参数(最迟在编译时检查)是否正确。
• FLS模块应验证FLS模块头文件和源文件中的版本信息是否一致,比如将头文件和源文件中的版本信息与预处理器宏进行比较。
• FLS模块应将所有可用的flash存储区域组合到一个线性地址空间中,由参数FlsBaseAddress和FlsTotalSize表示
• FLS模块应根据flash存储区域的物理结构,将“虚拟"地址中的读/写/擦除和比较功能的地址和长度参数映射到物理地址。
• 只要满足有关这些地址对齐的限制,就允许读,写或擦除作业越过物理flash存储的边界。
• FLS模块应在内部处理数据缓冲区对齐,而不是对RAM缓冲区的对齐施加任何要求,它应该将传递的指针当作字节对齐来处理。
• 如果在ECU中使用了多个flash,必须为各个flash模块赋予唯一的实例ID。通过配置为参数FlsDriverIndex来配置Flash的ID。如果只有1个flash,那么这个参数配置为0;
7.2 错误处理机制
7.2.1 开发错误
开发错误包括:
1、API服务调用时发生参数错误,包括(配置、地址、长度、数据)
2、API服务调用时模块未初始化
3、Flash Driver busy
4、API服务调用了空指针
7.2.2 运行错误
1、擦除验证失败(通过空白检查),预编译开关FlsEraseVerificationEnabled打开
2、写验证失败(比较),预编译开关FlsWriteVerificationEnabled打开
3、超时,预编译开关FlsTimeoutSupervisionEnabled打开
7.2.3 瞬时错误
1、擦除Flash失败
2、写Flash失败
3、读Flash失败
4、比较Flash失败
5、Flash ID未匹配
7.3 外置Flash Driver
在初始化外部Flash时,FLS模块应根据相应的配置参数检查外部Flashd 硬件ID。若硬件ID不匹配,则FLS模块应该报告FLS_E_UNEXPECTED_FLASH_ID给DET。然后将FLS模块的状态置为FLS_E_UNINIT。并且不得初始化其自身。
SPI处理程序/驱动程序软件规范中指定了所需参数的完整列表(“Configuration Specification”一章,标记为“ SPI User”)
7.4 加载,执行和删除Flash访问代码
因为flash在编程时,是不允许读取flash–读取执行代码所需的指令,所以需要从RAM中执行访问flash硬件的程序(内部擦除/写程序)。
- 应该将Flash访问程序代码放在单独的Fls_ac.c文件中。
- FLS模块的flash访问程序只能disable中断,和等待擦除/写命令完成,如果必要的话。(即确保同一时间没有其他代码在执行)。
- FLS模块的实施者应使Flash访问代码的执行时间尽可能短。
- 如果FLS模块被配置为在job开始的时候将flash访问代码载入到RAM中,则 FLS模块的擦除程序应该通过flash 驱动配置集中的擦除函数指针,载入flash访问代码,来擦除RAM中指向地址的flash memory。
- 如果FLS模块被配置为在job开始的时候将flash访问代码载入到RAM中,则 FLS模块的写程序应该通过flash 驱动配置集中的写函数指针,载入flash访问代码,来写RAM中指向地址的flash memory。
- FLS模块的主要处理程序中应该包含执行flash访问代码的程序。
- FLS的主要处理程序应该能够借助FLS模块配置集(编译后参数)中包含的各个功能指针,来访问flash访问无论闪存访问代码程序是否已加载到RAM或是否可以直接从(flash)ROM执行。
- 如果flash访问代码(内部擦除/写程序)被flash驱动载入到RAM中,在擦除或者写任务完成/取消后,FLS模块的主程序应该从RAM中将其移除。
- 如果访问代码不能在flash ROM的外部执行,那么FLS模块应该其载入到RAM中。
8 API函数
8.1 输入类型
8.2类型定义
8.2.1 Fls_ConfigType
通过flash驱动的初始化函数进行drvier和flash memory hardware配置时,使用指向该结构体的指针。
8.2.2 Fls_AddressType
- Fls_AddressType的最低值为0;
- 如果有必要的话,FLS模块应将设备特定的基本地址添加到地址类型Fls_AddressType中。
在Fls_17_Pmu,h中,eg:
typedef uint32 Fls_AddressType;
8.2.3 Fls_LengthType
指定了read/write/erasw/compare的字节长度。
在Fls_17_Pmu,h中,eg:
typedef uint32 Fls_LengthType;
8.3 函数定义
FLS模块一共有11个函数,如下:
序号 | 函数名 | 作用 |
---|---|---|
1 | Fls_Init | 初始化flash driver |
2 | Fls_Erase | 擦除flash sector |
3 | Fls_Write | 写flash,完整的一页或者多页 |
4 | Fls_Cancel | 取消正在运行的job |
5 | Fls_GetStatus | 返回driver的状态 |
6 | Fls_GetJobResult | 返回上一次job的结果 |
7 | Fls_Read | 从flash存储中读取数据 |
8 | Fls_Compare | 比较flash的一个区域和应用数据buffer中的内容 |
9 | Fls_SetMode | 设置flash driver的工作模式 |
10 | Fls_GetVersionInfo | 返回该模块的版本信息 |
11 | Fls_BlankCheck | 验证给定的存储区是否已被擦除但尚未(尚未)编程 |
12 | Fls_MainFunction | 处理各种job |
8.3.1 Fls_Init
- Fls_Init函数应该用配置出的参数初始化FLS模块(软件)和所有与flash memory相关的寄存器(硬件)。
- Fls_Init应将指向配置集的指针存储在变量中,以允许FLS模块在运行时访问配置集内容。
Fls_17_Pmu_StateType *StatePtr;
- Fls_Init将初始化所有FLS模块的全局变量以及控制flash设备所需的,不影响或不依赖于其他(硬件)模块的控制器寄存器。可能影响或依赖其他模块的寄存器应由通用系统模块初始化。
- 如果FLS模块使能了“开发错误检测”功能,Fls_Init函数应检查Flash驱动程序配置集的给定规范的(特定于硬件的)内容是否在允许的范围内。如果不在给定的范围内,则引发开发错误FLS_E_PARAM_CONFIG。
- 在完成FLS模块初始化之后,函数Fls_Init将FLS模块状态设置为MEMIF_IDLE。
- 在完成FLS模块初始化之后,函数Fls_Init会将flash job的结果设置为MEMIF_JOB_OK。
- 如果启用了模块Fls的“开发错误检测”功能:函数Fls_Init应当检查FLS模块当前不忙(FLS模块状态不是MEMIF_BUSY)。 如果该检查失败,则函数Fls_Init将引发开发错误FLS_E_BUSY。
- 如果硬件支持,函数Fls_Init将按照配置集中的设置设置为flash 擦除/写保护。
Fls_Erase
- Fls_Erase函数擦除时,擦除的是完整的一个或多个扇区(flash sectors);
- Fls_Erase函数将传入的参数复制到内部的变量,同时启动擦除job。
- 开始擦除的job后,Fls_Erase应该将FLS模块的状态置为 MEMIF_BUSY。
- 开始擦除的job后,Fls_Erase应该将Job结果置为 MEMIF_JOB_PENDING。
- 开始擦除的job后,Fls_Erase函数的返回值应置为 E_OK。
- 在FLS模块的main function中,应该异步去执行Fls_Erase函数。
- Fls_Erase函数应该从FlsBaseAddress + TargetAddress 的地址开始,进行擦除长度为Length大小的存储块。
eg.由于只能擦除完整的闪存扇区,因此长度将四舍五入到下一个完整的扇区边界 - 如果启用了模块Fls的“开发错误检测”功能:函数Fls_Erase必须检查擦除起始地址(FlsBaseAddress + TargetAddress)是否与Flash扇区边界对齐,并且是否位于指定的Flash上下边界之内。如果该检查失败,则函数Fls_Erase将拒绝擦除请求,并引发开发错误 FLS_E_PARAM_ADDRESS并返回E_NOT_OK。
- 如果启用了模块Fls的“开发错误检测”功能:Fls_Erase函数应检查擦除长度是否大于0,擦除结束地址(擦除起始地址+长度)是否与闪存扇区边界对齐,并位于指定的较高闪存地址边界内。如果检查失败,函数Fls_Erase将拒绝擦除请求,引发开发错误FLS_E_PARAM_LENGTH并返回E_NOT_OK。
- 如果启用了模块Fls的“开发错误检测”功能:Fls_Erase函数应该检查当前FLS模块是否busy,如果检查失败,函数Fls_Erase将拒绝擦除请求,引发开发错误 FLS_E_BUSY并返回E_NOT_OK。
- 如果可能,例如 通过中断控制的实现,FLS模块应直接在函数Fls_Erase中启动擦除作业的第一轮,以减少总体运行时间。
Fls_Write
与Fls_Erase类似。
Fls_Cancle
- 取消正在运行的read/write/erase/compare
- 同步处理方式
Fls_GetStatus
- 同步处理机制
- FlsGetStatusApi可以在预编译的时候ON/OFF。
Fls_Read
与Fls_Erase类似。
Fls_Compare
Fls_SetMode
- fast mode / slow mode
- MEMIF_MODE_SLOW: Slow read access / normal SPI access.
- MEMIF_MODE_FAST: Fast read access / SPI burst access.
Fls_GetVersionInfo
Fls_BlankCheck
函数Fls_BlankCheck将验证给定的存储区是否已被擦除但尚未(尚未)编程。 该功能应将每个主功能周期中已检查的闪存单元的最大数量分别限制为配置值FlsMaxReadNormalMode或FlsMaxReadFastMode。