嵌入式IAP开发笔记之一:面向STM32的BootLoader程序
对于很多人来说,BootLoader并不是一个陌生的词,甚至会经常用到它。因为在很多情况下我们都需要BootLoader程序,比如我们需要对系统在线升级时就需要它,还有当我们需要在外部存储器中运行程序时也需要用到它。在这里我们就来设计一个应用于STM32系列MCU的BootLOader程序。
1、BootLoader的基本原理
既然我们想要实现一个面向STM32的BootLOader程序,那么首先我们必须来了解一下BootLOader程序的基本原理。
顾名思义,BootLOader程序肯定是要实现系统的引导,这是BootLOader程序的基本功能。对于STM32系列MCU来说,系统启动后都会从内部Flash存储器的起始地址开始执行程序。然后进入应用程序并按既定的顺序执行下去,这时BootLoader与应用程序是一体的,具体如图所示:
但有些时候,我们希望应用程序并不是直接运行,如我们希望对系统实现IAP的时候;或者我们希望应用程序并不在我们的内部Flash中运行;又或者应用程序虽然在内部Flash运行,但我们希望应用程序从我们指定的内部Flash地址运行等等。在这些时候我们就需要一个单独的BootLoader程序。系统首先启动BootLoader程序,系统准备就绪后进入到应用程序执行,具体如图所示:
在上图中,我们实际上将应用程序存储在内部Flash的指定位置,这样做当然是为了实现我们某种需求,如系统IAP。当然我们也可以让应用程序存储于外部Flash中,然后BootLoader程序跳转到外部Flash去执行应用程序,不过前提是外部Flash内购执行程序。具体过程如下:
当然,这只是一种示例,对于不同的存储器我们只需要修改地址就可以了。至于在BootLoader程序中要实现的功能就看使用情况了。原则上我们可以添加我们任意想要的功能,如硬件检测、系统升级等等。
2、目标BootLoader设计
我们的目标是实现一个面向STM32的BootLoader程序。那么接下来我们就设计如何实现一个面向STM32的BootLoader程序。
2.1、Flash规划
我们以STM32F407IGT6为目标MCU,这款MCU具有1M的Flash和192K的SRAM。我们将Flash划分为2个部分,一个是启动程序区(0x0800 0000 - 0x0800 3FFF )大小为16K Bytes,剩下的为应用程序区(0x0800 4000 - 0x080F FFFF)。具体分配如下图:
我们让BootLoader程序占用16K的存储空间。但它是可以操作整个Flash存储空间的。
2.2、BootLoader程序结构
我们来考虑一下BootLoader程序的结构问题。我们设计BootLoader程序的主要目的就是为了对应用程序进行升级。那么在BootLoader程序中主要需要实现哪些功能呢?有几个方面是必须要包括的,一是基本的配置,如时钟等,我们在主程序中实现;二是对Flash的操作,我们升级应用程序肯定会对Flash进行查处和写入操作;三是跳转控制程序,我们最终是需要去执行应用程序的,跳转功能必不可少。当然根据不同的需求可能会有其它的需要。具体如下图所示:
上图中,我们除了签署的三项基本实现外,还添加了IAP文件的获取功能。这部分功能也是需要的,但在不同的模式下可能会有较大区别。因为获取文件的方式可以是各类通讯如以太网口、串口等。也可以是各类存储器,如SD卡、U盘等。所以这一功能虽然必不可少但实现方式则非常灵活,在后续实现中,我们具体问题具体分析。
3、目标BootLoader实现
我们已经确定了Flash的划分,也基本明白了BootLoader的基本工作流程。在接下来我就来讨论一下究竟怎么实现一个BootLoader程序。
3.1、BootLoader编码
我们知道芯片上电时先运行BootLoader程序,然后跳转到应用程序区执行应用程序。所以我们在编写BootLoader程序时我们首先判断系统是否有IAP的需求,如果有IAP请求则进入IAP模式,完成后再跳转到应用程序执行,如果没有IAP请求则直接跳转到应用程序执行。具体流程如下:
关于IAP的处理在不同的情况下会有不同的处理方式,在这里我们主要看一看跳转控制程序。首先定义应用程序的首地址并声明一个函数指针类型。具体如下:
#define ApplicationAddress 0x08004000 //应用程序首地址定义
typedef void (*pFunction)(void); //定义跳转函数指针类型
可能有人要问问什么定义这样一个函数指针类型,因为我们最终是跳转到Reset_Handler函数,所以必须要一个可以指向这个函数的函数指针。接下来我们就可以实现跳转程序了。
/*跳转到应用程序处理函数*/
static void JumpToApplication(void)
{uint32_t StackAddr; //应用程序栈地址uint32_t ResetVector; //应用程序中断向量表的地址pFunction JumpToApp; //定义跳转函数指针__set_PRIMASK(1); //关闭全局中断StackAddr = *(__IO uint32_t*)ApplicationAddress; //0x08004000;ResetVector = *(__IO uint32_t*)(ApplicationAddress + 4); //0x08004004;if((StackAddr&0x2FFC0000)==0x20000000) //检查栈顶地址是否合法.{__set_MSP(StackAddr); //初始化应用程序栈指针JumpToApp = (pFunction)ResetVector; JumpToApp();}
}
3.2、应用程序处理
实现了BootLoader的编码后,要想正确的跳转到App运行,我们还需要对App作相应的修改。重要的修改有2处。如果应用程序是裸机程序则在配置时钟前我们需要打开全局中端。
/*开启全局中断,在BootLoader中关闭的*/
__set_PRIMASK(0);
同时,还需要修改中端向量表的偏移量地址。对于我们所使用的STM32F07可直接在system_stm32f4xx.c文件中修改就可以了。
#define VECT_TAB_OFFSET 0x4000 /*!< Vector Table base offset field.
实现了上述修改并不能达到我们想要的目的,我们还需要在开发环境中做必要的修改。以我们使用的IAR EWARM V8.4为例。修改icf文件中对中断向量表和Flash存储区域的设定。具体如下图:
完成上述配置后我们下载应用程序和BootLoader程序就可以实现正确的跳转了。
4、小结
本篇中,我们只是实现了一个简单的BootLoader程序。下载到目标MCU后实现了跳转,应用程序也正常运行,说明我们的设计是正确的,后续可在次基础上添加各种功能实现相应的IAP应用。
需要注意的是在BootLoader程序中我们关闭了全局中断,在应用程序初始化系统时钟之前一定要记得打开全局中断,否则SystemTick不能工作会产生硬件故障(hardfault)。不过如果App是运行在RTOS上,则打开中断可能会出错,这一点需要注意。
欢迎关注:
嵌入式IAP开发笔记之一:面向STM32的BootLoader程序相关推荐
- 嵌入式系统开发笔记0_0:目录
本系列文章将向大家介绍嵌入式系统开发的各方面知识. 本系列文章所介绍的知识和内容,除电路图设计外,其它均采用开源系统,所以你不会在这个系列文章中看到Keil.IAR等软件. 本系列文章涉及C.C++. ...
- 嵌入式系统开发笔记2:Linux的主流发行版本
本系列文章将向大家介绍嵌入式系统开发的各方面知识. 本文将向大家介绍Linux的主流发行版本. 本文为转载文章,原文网址:Linux各个发行版本对比与简介 首先我们要能够清晰的区分Linux系统内核与 ...
- 嵌入式系统开发笔记80:应用Qt Designer进行主界面设计
前言 本篇文章讲解PyQt的基本使用方法,我们将应用Qt Designer来设计一个主界面,学习完本篇文章的内容后,你将获得如下技能. (1)在VS Code中启动Qt Designer ...
- 设备文件BSP及嵌入式驱动开发笔记
PS:今天上午,非常郁闷,有很多简单基础的问题搞得我有些迷茫,哎,代码几天不写就忘.目前又不当COO,还是得用心记代码哦! BSP及嵌入式驱动开辟笔记 第一讲嵌入式系统基本概念 以应用为中央,以计算机 ...
- 嵌入式系统开发笔记25:win10防火墙打开特定端口
本系列文章将向大家介绍嵌入式系统开发的各方面知识. 本文将向大家介绍dakaiwin10防火墙特定端口的方法. 1.引言 win10上位机编写程序,启动TCP服务器应用程序,并绑定1000端口:lin ...
- 嵌入式系统开发笔记105:下载程序到STM32开发板
文章目录 前言 1.启动FlyMcu 2.倒入映像文件 3.设置选项 4.连接开发板 5.下载程序 6.复位后运行 前言 本文介绍如何将编译好的映像文件下载到STM32开发板. 1.启动FlyMc ...
- USB应用开发笔记之一:STM32上实现USB主机读写U盘
在项目应用中,经常会有对外交换数据的需求.USB接口读写U盘无疑是一种颇为方便的选择.在这一篇中,我们就来讨论如何在STM32上实现USB主机读写U盘文件的方法. 1.应用概述 在我们的产品上 ...
- 嵌入式系统开发笔记91:认识ARM微控制器架构
文章目录 前言 一.ARM 二.ARM微控制器的市场占有率 1.95%的智能手机 2.90%的平板电脑 3.96%的硬盘驱动器 4.85%的无人机 5.83%的数字电视 6.75%的工业机器人 三.A ...
- iOS开发笔记--基于面向协议MVP模式下的软件设计
传统模式下的开发 MVC MVVM 基于面向协议MVP的介绍 MVP实战开发 说在前面: 相信就算你是个iOS新手也应该听说过MVC的,MVC是构建iOS App的标准模板.随着时间的推移,在iOS ...
最新文章
- RecyclerView嵌套TextView时显示文字不全的解决方法之一
- sql 以a开头的所有记录_#9#猴子聊数据分析之常见的SQL笔试题和面试题(下)
- Android system server之WatchDog看门狗分析
- Android自定义View实践 空气质量检测 pm2.5
- 打印机可以打印不能扫描怎么弄_为什么打印机可以通过电脑打印可不能扫描呢...
- Linux 权限、磁盘操作命令-Linux基础环境命令学习笔记
- 产品经理须知 | API接口知识小结
- c3p0与dbcp的异同
- python安装软件win10_在win10上安装Python和Tensorflow
- Rust : async、await 初探
- 千元喜提“随身影院”荣耀8x Max,告诉你移动刷剧是种什么体验?
- 史上最全的数据链路层基础知识详解
- 网络技术-Cisco路由器
- wps的ppt放映时不能完全全屏的解决方法
- 小米市场魅力所在?你读懂小米了么?
- 如何用pycharm将.ui文件转换为.py文件(内含出错解决方法)
- 咸鱼Micropython— machine库
- pytorch:如何从头开始训练一个CNN网络?
- 批量图片格式转化——gif、jpg、png三种格式的图片相互转化
- 如何光盘启动安装操作系统