车载ECU软件刷新flash driver制作
概述
车载ECU刷新基于UDS协议刷写,大大提高了软件更新的便利性。主机厂会对刷写流程及校验算法做出规定,并且刷写流程基本没有太多差别。 刷写前准备
- 进入扩展会话
- 解锁安全密钥
- 检查预编程条件
- 85关闭DTC记录
- 28停发APP报文及NM报文
以上4-5步骤的目的在于增加下载带宽
刷写主流程
- 进入编程会话
- 解锁boot级别的安全密钥
- 写指纹信息
- 请求下载flash driver
- 下载flash driver
- 完成flash driver下载
- 检查flash driver有效性
- 擦除pflash
- 请求下载app file
- 下载app file
- 完成app file 下载
- 检查app file程序有效性
刷写完成流程
- 进入扩展会话
- 28使能APP和NM
- 85打开DTC记录
- 进入默认会话
什么是flash driver
如何制作flash driver
flash driver其实并非所有的flash驱动的集合,在S32K系列芯片以及MC9S12系列芯片中,flash的读取和擦除遵循一个主要的流程:通过FTFC模块FSTAT寄存器CCIF来判断command是否完成,然后在FCCOB(Flash Common Command Object Registers)寄存器中写入指令(擦除,写入等等)及目标操作地址以及要写入的数据,然后通过给CCIF写1去执行操作,判断FSTAT寄存器故障标志位无异常之后就标志着操作完成。可以在SDK中看到上述的操作都是在FLASH_DRV_CommandSequence静态函数中完成的,擦除和写入都要调用该函数,所以flash driver就是该函数编译生成的s19文件了
START_FUNCTION_DEFINITION_RAMSECTION
static status_t FLASH_DRV_CommandSequence(const flash_ssd_config_t * pSSDConfig)
{
status_t ret = STATUS_SUCCESS; /* Return code variable */
/* Clear CCIF to launch command */
FTFx_FSTAT |= FTFx_FSTAT_CCIF_MASK;
while (0U == (FTFx_FSTAT & FTFx_FSTAT_CCIF_MASK))
{
/* Wait till CCIF bit is set
* Serve callback function as often as possible
*/
if (NULL_CALLBACK != pSSDConfig->CallBack)
{
/* Temporarily disable compilers check for ROM access call from within a ram function.
* The use of a function pointer type makes this check irrelevant.
* Nevertheless, it is imperative that the user-provided callback be defined in RAMSECTION */
DISABLE_CHECK_RAMSECTION_FUNCTION_CALL
(pSSDConfig->CallBack)();
ENABLE_CHECK_RAMSECTION_FUNCTION_CALL
}
}
/* Check if an error is occurred */
if ((FTFx_FSTAT & (FTFx_FSTAT_MGSTAT0_MASK | FTFx_FSTAT_FPVIOL_MASK | FTFx_FSTAT_ACCERR_MASK | FTFx_FSTAT_RDCOLERR_MASK)) != 0U)
{
ret = STATUS_ERROR;
}
return ret;
}
END_FUNCTION_DEFINITION_RAMSECTION
可以看到其实该函数已经定义在RAM中运行了,打开S32自带的demo工程flash_partitioning并编译,打开map文件就可以看到该函数起始地址和大小了,如下在flash中的起始地址为0x820,大小为0x38个字节:
.text.FLASH_DRV_CommandSequence
0x00000820 0x38 ./SDK/platform/drivers/src/flash/flash_driver.o
0x00000820 FLASH_DRV_CommandSequence
用hexview打开该工程编译生成的S19文件,并拷贝该文件起始地址为0x820,长度0x38的内容,另存为一个S Record文件,双击0x820修改为将要拷贝到ram中的地址保存即可。在擦除和写入函数调用FLASH_DRV_CommandSequence处,使用指向FLASH_DRV_CommandSequence的函数类型的指针强转S Record中的ram地址即可。源代码中的FLASH_DRV_CommandSequence函数即可删掉,满足了安全需求。
