在汽车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. MySQL 5.7默认ONLY_FULL_GROUP_BY语义介绍

    mysql 5.7版本 出现 ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corre ...

  2. 在linux上安装MySQL数据库,并简单设置用户密码,登录MySQL

    在新装的Centos系统上安装MySQL数据库. <p><a href="http://www.cnblogs.com/tijun/">提君博客原创< ...

  3. Antd & ice

    Antd & ice Angular https://github.com/NG-ZORRO/ng-zorro-antd https://ng.ant.design/docs/introduc ...

  4. Java多线程之单例模式(线程安全)

    package org.study2.javabase.ThreadsDemo.sync; /** * @Auther:GongXingRui * @Date:2018/9/20 * @Descrip ...

  5. Lodop删除语句Deleted只能内嵌设计维护可用

    有些人想用类似如下的语句删除打印项,或判断后把不需要的打印项删除,这种删除语句只能在打印设计或打印维护内嵌的时候使用,打印预览内嵌也不能使用.LODOP.SET_PRINT_STYLEA(2,'Del ...

  6. faster rcnn训练自己的数据集

    采用Pascal VOC数据集的组织结构,来构建自己的数据集,这种方法是faster rcnn最便捷的训练方式

  7. codeforces630C

    Lucky Numbers CodeForces - 630C 小希称只含7和8的数是幸运数,那么不超过n位的幸运数有多少个? Input 一个整数 n (1 ≤ n ≤ 55) Output 输出幸 ...

  8. 前端es6基础语法

    1.let.const.var var是声明全局的变量,作用域是全局,const是声明全局的常量,不能修改,而let是块级变量只在当前声明的作用域中生效: { var a = 10; let b = ...

  9. memcached安装报错 error while loading shared libraries: libevent-2.0.so.5: cannot open shared object file: No such file or directory解决

    我是从其他服务器scp来的memcached(~~~整个文件夹的那种,windows用多了的后遗症) 在准备运行 ./memcached -d -u root -l localhost -m 800 ...

  10. BZOJ3438小M的作物——最小割

    题目描述 小M在MC里开辟了两块巨大的耕地A和B(你可以认为容量是无穷),现在,小P有n中作物的种子,每种作物的种子 有1个(就是可以种一棵作物)(用1...n编号),现在,第i种作物种植在A中种植可 ...