在汽车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. Squid配置之使用帐号密码验证

      转自: https://blog.csdn.net/atco/article/details/43448885   1.安装squid使用root用户进行操作.先使用rpm检测是否已经安装了sql ...

  2. spark、standalone集群 (1)

    1.配置 spark/apache/org 下载解压, 安装jdk1.8 2.准备服务器 3.设置hostname 4.关闭防火墙 开启: service iptables start 关闭: ser ...

  3. Linux中各个目录作用

    对于linux新手来说,最感到迷惑的问题之一就是文件都存在哪里呢?特别是对于那些从windows转过来的新手来说,linux的目录结构看起来有些奇怪哦.比如没有C盘,没有分盘符,一大堆不知道用途的文件 ...

  4. Angular 过滤器

    <!DOCTYPE html><html ng-app="myApp"><head lang="en"> <meta ...

  5. Angular 基本指令

    <!DOCTYPE html><html ng-app><head lang="en"> <meta charset="UTF- ...

  6. CodeForces 126B Password

    题目链接:http://codeforces.com/problemset/problem/126/B 题目大意: 多组数据每组给定1个字符串S,问是否存在S的一个尽量长的子串,同时是S的前缀和后缀, ...

  7. C程序运行时的内存分布

    该篇博客是自己学习的总结,如果有哪里理解的不对的地方,希望大家可以指点. 一.C内存空间分布图 二.各内存区域详解 1.代码区(.text): 该区域主要存放二进制可执行文件. 2.数据区(.data ...

  8. java学习之—链表(3)

    /** * 使用链表实现队列 * Create by Administrator * 2018/6/19 0019 * 下午 4:37 **/ public class Link { public l ...

  9. python之路--FTP 上传视频示例

    # 服务端 import json import socket import struct server = socket.socket() server.bind(('127.0.0.1',8001 ...

  10. centos安装Tesseract

    yum安装(推荐) yum search tesseract yum install tesseract.x86_64 -y pip3 install pytesseract pip3 install ...