在汽车ECU软件运行中,软件代码运行安全性是第一,在代码中尽可能的不要固化有flash_erase、flash_write操作存在,主要是防止当出现异常情况时,程序跑飞,误调用erase、write对flash操作,使得原软件受到破坏,以致ECU不能正常工作。

Bootloader也称为启动引导加载程序,这段程序是硬件设备在上电复位之后执行的第一段软件代码。

方式一、为了实现在线更新功能,Bootloader程序需要对flash进行操作。一般情况下,我们将FLASH操作程序作为Bootloader组件的一部分固化在存储器中,在需要执行flash擦除或烧写操作时,先将该部分代码复制到RAM中,再做调用。操作代码的复制工作也可以在Bootloader启动阶段完成。

方式二、两级Bootloader方案,没有在flash存储器中固化flash擦写代码,而是通过通讯口将该部分代码从上位机下载到指定的RAM出,在需要指出flash擦除或烧写操作时,再调用RAM中的该代码。

方式三、Bootloader制作下载引导程序,此软件不固化flash擦写代码,通过通讯口下载另外Bootloader(包含flash擦写操作)到指定的RAM中,跳转到RAM运行升级流程。

现在我们做简单的测试,按照方式二测试,Bootloader中没有擦写falsh操作代码,我们把flash_erase和flash_write编译后生成的bin信息保存在Bootloader软件的一个数组中(PS:RAM中就是存放全局变量等信息,通过上位机下载也是存放在指定RAM中,我们可以使下载保存在数组中,效果一样)。

1、新建flash工程;
2、flash.c文件中主要包含:uint32_t flash_erase(uint32_t u32addr)和uint32_t flash_write(uint32_t u32addr, uint32_t u32data),两个函数,注意:这两个函数中不能存在调用外部函数、全局变量信息;

3、编译生成bin文件,通过.map文件查看这两个函数的位置;

4、在生成的bin文件中提取出这两个函数信息,重新生成新的bin文件;注意地址是偶数

或者上位机直接下载此bin文件(原始bin文件),在MCU端需要从0x218地址处提取数据;

5、在boot中开辟擦、写两个函数code长度的数组,为下载擦、写函数的数据存放在RAM中做准备,以数组形式放在ram中;
6、 将数组地址强制类型转换为函数指针;

7、在调用这个函数的地址,用函数指针来调;

  1.  
    #define FMC_ISPCMD_PROGRAM 0x21 /*!< ISP Command: Program Flash */
  2.  
    #define FMC_ISPCMD_PAGE_ERASE 0x22 /*!< ISP Command: Page Erase Flash */
  3.  
     
  4.  
    uint32_t flash_erase(uint32_t u32addr)
  5.  
    {
  6.  
    FMC->ISPCMD = FMC_ISPCMD_PAGE_ERASE; /* Set ISP Command Code */
  7.  
    FMC->ISPADR = u32addr; /* Set Target ROM Address. The address must be page alignment. */
  8.  
    //__set_PRIMASK(1);
  9.  
    __asm("CPSID I");
  10.  
    FMC->ISPTRG = 0x1; /* Trigger to start ISP procedure */
  11.  
    __ISB(); /* To make sure ISP/CPU be Synchronized */
  12.  
    while(FMC->ISPTRG); /* Waiting for ISP Done */
  13.  
    //__set_PRIMASK(0);
  14.  
    __asm("CPSIE I");
  15.  
     
  16.  
    /* Check ISPFF flag to know whether erase OK or fail. */
  17.  
    if(FMC->ISPCON & FMC_ISPCON_ISPFF_Msk) {
  18.  
    FMC->ISPCON |= FMC_ISPCON_ISPFF_Msk;
  19.  
    return 1;
  20.  
    }
  21.  
    return 0;
  22.  
    }
  23.  
    uint32_t flash_write(uint32_t u32addr, uint32_t u32data)
  24.  
    {
  25.  
    FMC->ISPCMD = FMC_ISPCMD_PROGRAM; /* Set ISP Command Code */
  26.  
    FMC->ISPADR = u32addr; /* Set Target ROM Address. The address must be word alignment. */
  27.  
    FMC->ISPDAT = u32data; /* Set Data to Program */
  28.  
    // __set_PRIMASK(1);
  29.  
    __asm("CPSID I");
  30.  
    FMC->ISPTRG = 0x1; /* Trigger to start ISP procedure */
  31.  
    __ISB(); /* To make sure ISP/CPU be Synchronized */
  32.  
    while(FMC->ISPTRG); /* Waiting for ISP Done */
  33.  
    //__set_PRIMASK(0);
  34.  
    __asm("CPSIE I");
  35.  
     
  36.  
    if(FMC->ISPCON & FMC_ISPCON_ISPFF_Msk) {
  37.  
    FMC->ISPCON |= FMC_ISPCON_ISPFF_Msk;
  38.  
    return 1;
  39.  
    }
  40.  
    return 0;
  41.  
    }

下面我们来是测试代码:

  1. <code class="language-cpp">//编译生成的擦、写文件,此处直接加载到数组中,而非通过上位机下载
  2. //__align(4) :对齐方式
  3. __align(4) uint8_t flash_erase_buf[]={
  4. 0x01,0x46,0x22,0x20,0x11,0x4A,0xD0,0x60,0x10,0x46,0x41,0x60,0x72,0xB6,0x01,0x20,
  5. 0x10,0x61,0x00,0xBF,0x00,0xBF,0x00,0xBF,0xBF,0xF3,0x6F,0x8F,0x00,0xBF,0x00,0xBF,
  6. 0x00,0xBF,0x00,0xBF,0x09,0x48,0x00,0x69,0x00,0x28,0xFB,0xD1,0x62,0xB6,0x07,0x48,
  7. 0x00,0x68,0x40,0x22,0x10,0x40,0x00,0x28,0x06,0xD0,0x04,0x48,0x00,0x68,0x10,0x43,
  8. 0x02,0x4A,0x10,0x60,0x01,0x20,0x70,0x47,0x00,0x20,0xFC,0xE7,0x00,0xC0,0x00,0x50,
  9. };
  10. __align(4) uint8_t flash_write_buf[]={
  11. 0x02,0x46,0x21,0x20,0x12,0x4B,0xD8,0x60,0x18,0x46,0x42,0x60,0x81,0x60,0x72,0xB6,
  12. 0x01,0x20,0x18,0x61,0x00,0xBF,0x00,0xBF,0x00,0xBF,0xBF,0xF3,0x6F,0x8F,0x00,0xBF,
  13. 0x00,0xBF,0x00,0xBF,0x00,0xBF,0x0A,0x48,0x00,0x69,0x00,0x28,0xFB,0xD1,0x62,0xB6,
  14. 0x07,0x48,0x00,0x68,0x40,0x23,0x18,0x40,0x00,0x28,0x06,0xD0,0x04,0x48,0x00,0x68,
  15. 0x18,0x43,0x03,0x4B,0x18,0x60,0x01,0x20,0x70,0x47,0x00,0x20,0xFC,0xE7,0x00,0x00,
  16. 0x00,0xC0,0x00,0x50
  17. };
  18. typedef void (*flash_erase_handler)(uint32_t u32addr);
  19. typedef void (*flash_write_handler)(uint32_t u32addr, uint32_t u32data);
  20. flash_erase_handler flash_erase = (flash_erase_handler)(flash_erase_buf + 1); // cortex-mo 使用thumb指纹,函数地址低位为1
  21. flash_write_handler flash_write = (flash_write_handler)(flash_write_buf + 1);
  22. int main(void)
  23. {
  24. main_powerOnInit();
  25. SYS_UnlockReg();
  26. DrvFMC_Open();
  27. DrvFMC_EnableAPUpdate();
  28. DrvFMC_Erase(SPIFLAG_ADDR);
  29. DrvFMC_Write(SPIFLAG_ADDR,0x88776655);
  30. DrvFMC_DisableAPUpdate();
  31. DrvFMC_Close();
  32. SYS_LockReg();
  33. //DisableInterrupts;
  34. SYS_UnlockReg();
  35. DrvFMC_Open();
  36. DrvFMC_EnableAPUpdate();
  37. flash_erase(SPIFLAG_ADDR);
  38. flash_write(SPIFLAG_ADDR,0xAABBCCDD);
  39. DrvFMC_DisableAPUpdate();
  40. DrvFMC_Close();
  41. SYS_LockReg();
  42. //EnableInterrupts;
  43. for (;;);
  44. }</code>

测试结果显示,的确能够写法flash中。

下面附上车载诊断升级示意流程图:

Bootloader升级方式一————擦、写flash在RAM中运行的更多相关文章

  1. NOR flash和NAND flash区别,RAM 和ROM区别

    ROM和RAM指的都是半导体存储器,ROM是Read Only Memory的缩写,RAM是Random Access Memory的缩写.ROM在系统停止供电的时候仍然可以保持数据,而RAM通常都是 ...

  2. NOR flash和NAND flash区别,RAM 和ROM区别d

    ROM和RAM指的都是半导体存储器,ROM是Read Only Memory的缩写,RAM是Random Access Memory的缩写.ROM在系统停止供电的时候仍然可以保持数据,而RAM通常都是 ...

  3. NOR Flash擦写和原理分析

    NOR Flash擦写和原理分析 1. NOR FLASH 的简单介绍 NOR FLASH 是很常见的一种存储芯片,数据掉电不会丢失.NOR FLASH支持Execute On Chip,即程序可以直 ...

  4. NOR Flash擦写和原理分析 (二)

    Nor Flash上电后处于数据读取状态(Reading Array Data).此状态可以进行正常的读.这和读取SDRAM/SRAM/ROM一样.(要是不一样的话,芯片上电后如何从NorFlash中 ...

  5. NOR Flash擦写和原理分析 (一)

    1. NOR FLASH 的简单介绍 NOR FLASH 是很常见的一种存储芯片,数据掉电不会丢失.NOR FLASH支持Execute On Chip,即程序可以直接在FLASH片内执行(这意味着存 ...

  6. 【转】NOR Flash擦写和原理分析

    1. NOR FLASH 的简单介绍 NOR FLASH 是很常见的一种存储芯片,数据掉电不会丢失.NOR FLASH支持Execute On Chip,即程序可以直接在FLASH片内执行(这意味着存 ...

  7. 如何提高单片机Flash的擦写次数

    所谓提高flash的擦写次数,并不是真正的提高flash擦写次数,而是通过以"空间换时间"概念,在软件上实现“操作的次数大于其寿命”.详见链接: http://bbs.eeworl ...

  8. 转载:NOR Flash擦写和原理分析

    1. NOR FLASH 的简单介绍 NOR FLASH 是很常见的一种存储芯片,数据掉电不会丢失.NOR FLASH支持Execute On Chip,即程序可以直接在FLASH片内执行(这意味着存 ...

  9. nrf52——DFU升级USB/UART升级方式详解(基于SDK开发例程)

    摘要:在前面的nrf52--DFU升级OTA升级方式详解(基于SDK开发例程)一文中我测试了基于蓝牙的OTA,本文将开始基于UART和USB(USB_CDC_)进行升级测试. 整体升级流程: 整个过程 ...

随机推荐

  1. [转帖]xserver相关知识汇总

    xserver相关知识汇总 https://blog.csdn.net/QTVLC/article/details/81739984   本文主要是从以下几个方面介绍xorg-xserver 相关的知 ...

  2. CMake--变量

    1.一般变量 1)CMake变量引用的方式 使用${}进行变量的引用.例如: ${PROJECT_NAME} #返回项目名称 在 IF 等语句中,是直接使用变量名而不通过${}取值. 2)cmake自 ...

  3. spring初始化bean时执行某些方法完成特定的初始化操作

    在项目中经常会在容器启动时,完成特定的初始化操作,如资源文件的加载等. 一 实现的方式有三种: 1.使用@PostConstruct注解,该注解作用于void方法上 2.在配置文件中配置init-me ...

  4. CLOUD SQL跟踪

    CLOUD会自动在后台执行一些sql语句,所以追踪起来比较麻烦,需要加入一些过滤条件. 比如关键的CLIENTPROCESSID,加入后 ,就能过滤是哪个客户度执行的数据. 过滤数据.

  5. Python实现百度贴吧自动顶贴机

    开发这款小工具,我们需要做一些准备: url.txt:多个需要顶起的帖子地址. reply:多条随机回复的内容. selenium:浏览器自动化测试框架 首先,我们先使用pip完成selenium的安 ...

  6. 八、.net core 通过数据库配置文件连接操作数据库

    一.创建DotNetCore项目 直接创建core项目并不勾选docker支持  二.nuget进行连接MySQL程序集的下载安装 1.MySql.Data.EntityFrameworkCore方式 ...

  7. github---无命令可视化界面操作

    最近工作需要,研究了一下git,这个东西挺实用,给我的感觉并不是那么简单使用,我认为还可以再深入的研究一下,挺好玩的~ 说一下我的学习路线: 1.先看的廖老师的博客:https://www.liaox ...

  8. Lodop打印如何隐藏table某一列

    Lodop打印超文本,既可以打印页面上存在的某些部分,也可以自己组织超文本和css样式传入,有些需要打印的页面表格里,会有一列有编辑删除等按钮,用于对于数据库数据的操作,在打印的时候,这一列由于不属于 ...

  9. C-Lodop设置页面一加载就打印

    C-Lodop由于是服务不是np插件,调用打印语句(print或preview等)时机太早,在页面第一次加载完成后有几百毫秒时间等待WebSocket通讯服务准备完成,在没完成的时候会提示“C-Lod ...

  10. Unable to resolve target 'android-15'

    SDK 15没有加载造成的,在SDK Manager.exe下安装以下文件 Android SDK Tools (25.2.5) Android SDK Platform-tools (28.0.1) ...