STM32 bootloader设计

使用的是STM32f103C8T6:64Kflash,在应用程序中通过CAN把接受到的bin写到外置 flash的指定地址处。在bootloader中判断一个单独的标志位看程序是否需要升级,如果需要升级,则复制外置flash处的内容到STM32的内置flash的指定地址处。

如:

bootloader地址:0x08000000UL   大小:10K——0x2800——STM32的内置flash

应用程序地址:0x08002800UL   大小:45K——0xB400——STM32的内置flash

升级信息表:0x720000UL   大小:8K——0x2000——外置flash

升级的bin文件地址:0x08012400  大小:45K——0xB400——外置flash

升级信息表主要有:更新标志,程序大小等;

bootloader设计思想:(bootloader是一个引导程序,复杂的CAN接收升级文件部分在应用程序中实现, 它只起一个拷贝和跳转的功能)

1、判断“升级信息表”中的标志位是否更新,是更新,则复制“升级的bin文件地址”的内容到“应用程序地址”处;

2、跳转到应用程序处。

bootloader:BootLoader 就是在操作系统内核运行之前运行的一段小程序。通过这段小程序,我们可以初始化硬件设备、建立内存空间映射图,从而将系统的软硬件环境带到一个合适状态,以便为最终调用操作系统内核准备好正确的环境。这里我们所说的Bootloader也是系统开机前的一段小程序,其主要任务是用来初始化串口和IAP 端口(网口CAN 接口等)的,通过判断状态是否需要从IAP 端口进行更新应用程序,若需要更新则从端口接收应用程序,并存放到指定的Flash 里面,更新完成后则跳入到指定的Flash 里面执行应用程序。

应用程序:即我们需要开发板实现功能的程序,其中应用程序主要分为两种:hex 文件和bin 文件。在我们经常使用的KEIL 中默认编译生成的可执行文件(应用程序)为hex 格式的,若需要编译生成bin 格式需要做如下修改,加入 “D:\Keil\ARM\ARMCC\bin\fromelf.exe--bin--output ./Obj/Can_Updata.bin ./Obj/test.axf” ,重新编译生成的 Can_Updata.bin文件存放在 Obj 文件夹下。

有几点需要注意的:

1、中断向量的重映射(应用程序中要设置,否则无法使用中断)

  1. NVIC_VectTab_FLASH —— 0x8002800

  2. NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x2800);

2、跳转到指定地址处;

  1. static voidjump_to_app(void)

  2. {

  3. app_cb app_start = (app_cb)(*(uint32_t*)(APP_START_ADDR + 4));

  4. all_nvic_disabled();

  5. //all_gpio_disabled();

  6. delay_ms(100);

  7. __set_PSP(*(u32 *)(APP_START_ADDR));

  8. __set_CONTROL(0);

  9. __set_MSP(*(uint32_t *)(APP_START_ADDR));

  10. NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x2800);

  11. app_start();

  12. }

部分代码:

  1. #include <stdio.h>

  2. #include "usart.h"

  3. #include "delay.h"

  4. #include "iap.h"

  5. #include "misc.h"

  6. typedef void (*app_cb)(void);

  7. static void all_nvic_disabled(void)

  8. {

  9. int i = 0;

  10. for(i = 19; i < 59; i++)

  11. {

  12. NVIC->ICER[i >> 0x05] = (unsigned int )0x01 << (i & (unsigned char)0x1F);

  13. }

  14. }

  15. static void all_gpio_disabled(void)

  16. {

  17. GPIO_InitTypeDef gpio_init;

  18. gpio_init.GPIO_Pin = 0xffff;

  19. gpio_init.GPIO_Speed = GPIO_Speed_50MHz;

  20. gpio_init.GPIO_Mode = GPIO_Mode_IN_FLOATING;

  21. GPIO_Init(GPIOA, &gpio_init);

  22. GPIO_Init(GPIOB, &gpio_init);

  23. GPIO_Init(GPIOC, &gpio_init);

  24. GPIO_Init(GPIOD, &gpio_init);

  25. }

  26. static void jump_to_app(void)

  27. {

  28. app_cb app_start = (app_cb)(*(uint32_t *)(APP_START_ADDR + 4));

  29. all_nvic_disabled();

  30. //all_gpio_disabled();

  31. delay_ms(100);

  32. __set_PSP(*(u32 *)(APP_START_ADDR));

  33. __set_CONTROL(0);

  34. __set_MSP(*(uint32_t *)(APP_START_ADDR));

  35. NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x2800);

  36. app_start();

  37. }

  38. int main(void)

  39. {

  40. iap_t iap;

  41. uint8_t flag; // 0:未升级 1:已升级

  42. DelayInit();

  43. UARTInit(9600);

  44. GD25Q32BConfig();

  45. printf("uart ok...\r\n");

  46. delay_ms(100);

  47. flag = FlashIAPReadFlag(&iap);

  48. printf("flag: %d\n", flag);

  49. printf("iap.version: %d\n", iap.version);

  50. printf("iap.size: %d\n", iap.size);

  51. if(0 == flag)

  52. {

  53. FlashCopy(APP_START_ADDR, IAP_APP_START, &iap);

  54. printf("copy ok!\n");

  55. }

  56. jump_to_app();

  57. return 0;

  58. }

  1. #include <string.h>

  2. #include "app_flash_manager.h"

  3. #include "iap.h"

  4. #include "debug.h"

  5. // 读取升级状态,0: 未升级; 1: 已经升级

  6. uint8_t FlashIAPReadFlag(iap_t *update)

  7. {

  8. uint8_t flag;

  9. spiFlashRead(IAP_INFO_START, sizeof(iap_t), (uint8_t *)update);

  10. flag = update->flag;

  11. return flag;

  12. }

  13. // 从backup_addr拷贝info->size的大小到app_addr地址处

  14. boolean FlashCopy(uint32_t app_addr, uint32_t backup_addr, iap_t *info)

  15. {

  16. uint8_t upgrade_buffer[FLASH_SECTOR_SIZE];

  17. uint16_t pageremain = FLASH_SECTOR_SIZE - backup_addr % FLASH_SECTOR_SIZE; // 单页剩余字节

  18. if(((app_addr + info->size - 1) > APP_END_ADDR) || (app_addr < APP_START_ADDR))

  19. {

  20. return COPY_FALSE;

  21. }

  22. if(info->size <= pageremain) // 程序总大小小于等于单页大小

  23. {

  24. pageremain = info->size;

  25. }

  26. FlashErase(app_addr, APP_BLOCK);

  27. while(1)

  28. {

  29. // 分页写入

  30. memset(upgrade_buffer, 0, sizeof(upgrade_buffer));

  31. spiFlashRead(backup_addr, pageremain, upgrade_buffer); // 从备份区读出pageremain字节数

  32. FlashWrite(app_addr, upgrade_buffer, pageremain); // 写到程序运行的地址处

  33. if(info->size == pageremain)

  34. {

  35. break; // 写入结束

  36. }

  37. else

  38. {

  39. backup_addr += pageremain;

  40. app_addr += pageremain;

  41. info->size -= pageremain; // 减去已经写入了的字节数,地址都往后面偏移

  42. if(info->size > FLASH_SECTOR_SIZE)

  43. {

  44. pageremain = FLASH_SECTOR_SIZE; // 超过1页数据,一页一页写入

  45. }

  46. else

  47. {

  48. pageremain = info->size; // 不够1页数据

  49. }

  50. }

  51. }

  52. return COPY_OK;

  53. }

  1. #include "mcu_flash.h"

  2. #include <string.h>

  3. #include "stm32f10x_flash.h"

  4. // STM32f103内置flash的读写擦除

  5. // addr:地址 count:块数量

  6. flash_status_t FlashErase(uint32_t addr, uint8_t count)

  7. {

  8. uint8_t i;

  9. for(i = 0; i < count; ++i)

  10. {

  11. if(FLASH_ErasePage(addr + i * FLASH_SECTOR_SIZE) != FLASH_COMPLETE)

  12. {

  13. return FLASH_FAILURE;

  14. }

  15. }

  16. return FLASH_SUCCESS;

  17. }

  18. uint32_t FlashWrite(uint32_t addr, uint8_t *buffer, uint32_t length)

  19. {

  20. uint16_t i, data = 0;

  21. FLASH_Unlock();

  22. for(i = 0; i < length; i += 2)

  23. {

  24. data = (*(buffer + i + 1) << 8) + (*(buffer + i));

  25. if(FLASH_ProgramHalfWord((uint32_t)(addr + i), data) != FLASH_COMPLETE)

  26. {

  27. return i;

  28. }

  29. }

  30. FLASH_Lock();

  31. return length;

  32. }

  33. uint32_t FlashRead(uint32_t addr, uint8_t *buffer, uint32_t length)

  34. {

  35. memcpy(buffer, (void *)addr, length);

  36. return length;

  37. }

STM32f103C8T6 bootloader设计相关推荐

  1. 浅析STM32 Bootloader设计

    不需要拆机就能对产品进行固件升级是很多人想要的效果,不仅方便而且节省精力和成本.那么如何完成这项工作呢?接下来所介绍的Bootloader就可以完成这项工作,通过Bootloader引导程序完成固件的 ...

  2. DSP 程序远程升级 / Bootloader设计指南(三)—— CMD文件与DSP存储空间

    技术交流 & 最新设计指南获取方法 步骤1) 扫描下方二维码,进入微信公众号 步骤2) 获取最新指南,在公众号后台回复以下关键字:[bootloader] 步骤3) 有疑问,在公众号后台回复以 ...

  3. DSP 程序远程升级 / Bootloader设计指南(二)—— 详解c_int00

    技术交流 & 最新设计指南获取方法 步骤1) 扫描下方二维码,进入微信公众号 步骤2) 获取最新指南,在公众号后台回复以下关键字:[bootloader] 步骤3) 有疑问,在公众号后台回复以 ...

  4. stm32 Bootloader设计(YModem协议)

    相信很多人都希望,不开盖就可以对固件进行升级吧,就像手机那些.下文中的bootload就来实现这样的功能. 前段时间有项目关于Bootload设计.所以就仔细的去了研究了一翻.以前都是用的stm32官 ...

  5. 基于UDS的BootLoader设计——架构设计及规范

    1 BootLoader概述         1.1 Boot Loader设计目的         1.2 Boot Loader基本功能     2 BootLoader基本需求设计        ...

  6. 单片机简易bootloader设计

    1.设计原则: bootloader方便移植,且足够轻量化. 2.方案设计 从内存角度来看,芯片的内部flash空间可以进行如下规划: flag为升级标志位,当升级标志位使能时,程序进入boot,当升 ...

  7. S12ZVM Bootloader设计开发

    S12ZVM Bootloader开发设计 文章目录 S12ZVM Bootloader开发设计 1 开发环境下载 2 CodeWarrior安装 3 工程创建 4 驱动开发 4.1 Cpu配置 4. ...

  8. s12xep100 bootloader设计要点总结

    这里总结下在写s12xep100 bootloader时的一些要点. 先说说中断向量吧 中断向量总结:s12xep100 总共有(0xfe-0x10)/2+1=120 个中断通道,对应的地址分别为0x ...

  9. 博世(BOSCH) ECU BootLoader设计思路

    目录 1. Memory Layout - Hardware View 2. Memory allocation in PFLASH 3. Start-up Block(SB) 4. Customer ...

最新文章

  1. 你们是不是也是开一堆shell. » 社区 | Ruby China
  2. 汇编语言第二课作业2.1
  3. 最短路径算法----Dijkstra (转)
  4. 开源Math.NET基础数学类库使用(04)C#解析Matrix Marke数据格式
  5. Maven精选系列--过滤不同环境配置文件
  6. web站点性能测试经验点滴
  7. 操作手册模板_挂蓝悬臂浇筑箱梁施工技术操作手册
  8. Extjs formpanel加载数据的两种方式
  9. [Linux] - 网速测试命令
  10. oracle数据库sga用途_oracle数据库的SGA和PGA,及分配指导
  11. 《Go语言实战》William Kennedy中文版学习笔记
  12. kettle入门教程
  13. SSM汽车维修中心管理系统
  14. 【qq机器人】发送表情包
  15. 资源集成视角解读项目管理-合同类型
  16. 开源终端上网行为管理服务器编译环境搭建
  17. win10制作软盘,xp下进行编译,最后回到win10运行
  18. Python Flask Web 框架入门
  19. Codevs 3729==洛谷P1941 飞扬的小鸟
  20. shopex mysql 数据库服务器_win2003以isapi的方式配置php+mysql环境(安装了shopEX) 毕竟我是杨小飞i...

热门文章

  1. 成为Apache顶级项目核心贡献者是一种什么样的体验?
  2. Android开发,Error: Failed to find Build Tools revision 24.0.2
  3. Prometheus 初探
  4. Go语言TCP网络编程(详细)
  5. Java 用float时,数字后面加f,这样是为什么?
  6. java判断一个数是不是质数(素数)
  7. vue的post请求data可以传两个参吗_我知道的HTTP请求
  8. 计算机网络技术及应用 课程 英语,计算机网络应用—现代英语课堂中的第三种语言...
  9. 调研机构称明年全球数据中心基础设施支出将增长6%
  10. HighNewTech:2021阿里云开发者大会-大咖来了(更新中)