车载ECU软件刷新flash driver制作

概述

车载ECU刷新基于UDS协议刷写,大大提高了软件更新的便利性。主机厂会对刷写流程及校验算法做出规定,并且刷写流程基本没有太多差别。 刷写前准备

  1. 进入扩展会话
  2. 解锁安全密钥
  3. 检查预编程条件
  4. 85关闭DTC记录
  5. 28停发APP报文及NM报文

以上4-5步骤的目的在于增加下载带宽

刷写主流程

  1. 进入编程会话
  2. 解锁boot级别的安全密钥
  3. 写指纹信息
  4. 请求下载flash driver
  5. 下载flash driver
  6. 完成flash driver下载
  7. 检查flash driver有效性
  8. 擦除pflash
  9. 请求下载app file
  10. 下载app file
  11. 完成app file 下载
  12. 检查app file程序有效性

刷写完成流程

  1. 进入扩展会话
  2. 28使能APP和NM
  3. 85打开DTC记录
  4. 进入默认会话

什么是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函数即可删掉,满足了安全需求。

经验分享 程序员 微信小程序 职场和发展