嵌入式IAP开发笔记之一:面向STM32的BootLoader程序

对于很多人来说,BootLoader并不是一个陌生的词,甚至会经常用到它。因为在很多情况下我们都需要BootLoader程序,比如我们需要对系统在线升级时就需要它,还有当我们需要在外部存储器中运行程序时也需要用到它。在这里我们就来设计一个应用于STM32系列MCU的BootLOader程序。

1BootLoader的基本原理

既然我们想要实现一个面向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.1Flash规划

我们以STM32F407IGT6为目标MCU,这款MCU具有1M的Flash和192K的SRAM。我们将Flash划分为2个部分,一个是启动程序区(0x0800 0000 - 0x0800 3FFF )大小为16K Bytes,剩下的为应用程序区(0x0800 4000 - 0x080F FFFF)。具体分配如下图:

我们让BootLoader程序占用16K的存储空间。但它是可以操作整个Flash存储空间的。

2.2BootLoader程序结构

我们来考虑一下BootLoader程序的结构问题。我们设计BootLoader程序的主要目的就是为了对应用程序进行升级。那么在BootLoader程序中主要需要实现哪些功能呢?有几个方面是必须要包括的,一是基本的配置,如时钟等,我们在主程序中实现;二是对Flash的操作,我们升级应用程序肯定会对Flash进行查处和写入操作;三是跳转控制程序,我们最终是需要去执行应用程序的,跳转功能必不可少。当然根据不同的需求可能会有其它的需要。具体如下图所示:

上图中,我们除了签署的三项基本实现外,还添加了IAP文件的获取功能。这部分功能也是需要的,但在不同的模式下可能会有较大区别。因为获取文件的方式可以是各类通讯如以太网口、串口等。也可以是各类存储器,如SD卡、U盘等。所以这一功能虽然必不可少但实现方式则非常灵活,在后续实现中,我们具体问题具体分析。

3、目标BootLoader实现

我们已经确定了Flash的划分,也基本明白了BootLoader的基本工作流程。在接下来我就来讨论一下究竟怎么实现一个BootLoader程序。

3.1BootLoader编码

我们知道芯片上电时先运行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上,则打开中断可能会出错,这一点需要注意。

欢迎关注:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/499364.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

外设驱动库开发笔记9:SHT1x系列温湿度传感器驱动

在我们的产品中&#xff0c;经常需要检测温湿度数据。有很多检测温湿度的方法和模块&#xff0c;其中SHT1x系列温湿度传感器就是一种成本较低使用方便的温湿度检测模块。下面我们就来说一说如何实现SHT1x系列温湿度传感器的驱动。 1、功能概述 SHT1x包括 SHT10&#xff0c; S…

Modbus协议栈应用实例之一:Modbus RTU主站应用

自从开源了我们自己开发的Modbus协议栈之后&#xff0c;有很多朋友建议我针对性的做几个示例。所以我们就基于平时我们的应用整理了几个简单但可以说明基本的应用方法的示例&#xff0c;在这一篇中我们先来使用协议栈实现Modbus RTU主站的示例。 1、何为RTU主站 Modbus协议是…

uCOS-III应用开发笔记之一:uCOS-III在STM32的移植

uCOS-III实时操作系统在MCU平台被广泛使用&#xff0c;在这里我们将简单的记录如何将uCOS-III实时操作系统移植到目标平台上并运行。 1、必要的准备 在开始uCOS-III实时操作系统的移植前&#xff0c;我们还需要做一些必要的准备&#xff0c;如确定目标板、准备目标工程及uCOS…

外设驱动库开发笔记10:SHT2x系列温湿度传感器驱动

温湿度检测是嵌入式编程中经常应用到的一项功能。在我们的产品中亦经常使用。SHT2x系列温湿度传感器作为一种高精度低成本的集成模块&#xff0c;一直应用于我们的产品中。在这里我们讨论如何封装SHT2x系列温湿度传感器的驱动。 1、功能概述 SHT20配有一个全新设计的CMOSens芯…

Modbus协议栈应用实例之二:Modbus RTU从站应用

自从开源了我们自己开发的Modbus协议栈之后&#xff0c;有很多朋友建议我针对性的做几个示例。所以我们就基于平时我们的应用整理了几个简单但可以说明基本的应用方法的示例&#xff0c;这一篇中我们将使用协议栈实现一个Modbus RTU从站应用。 1、何为RTU从站 Modbus协议是一…

外设驱动库开发笔记11:SHT3x系列温湿度传感器驱动

在我们的产品中经常会遇到温湿度检测的需求。可以用于检测温湿度的传感器元件也有很多。我们经常使用的SHT各系列数字温湿度传感器来实现应用需求。在这里我们将设计并实现SHT3x系列温湿度传感器的驱动。 1、功能概述 SHT3x系列温湿度传感器是适用于各种应用的高品质湿度传感…

LwIP应用开发笔记之十:LwIP带操作系统基本移植

现在&#xff0c;TCP/IP协议的应用无处不在。随着物联网的火爆&#xff0c;嵌入式领域使用TCP/IP协议进行通讯也越来越广泛。在我们的相关产品中&#xff0c;也都有应用&#xff0c;所以我们结合应用实际对相关应用作相应的总结。 1、技术准备 我们采用的开发平台是STM32F407…

ThreadX应用开发笔记之一:移植ThreadX到STM32平台

现在一些小型系统中也往往有多任务处理的需求&#xff0c;这就为实时操作系统提供了用武之地。事实上国内外各种各样的RTOS有很多&#xff0c;而且基本都在走开源的路线&#xff0c;ThreadX也不例外&#xff0c;在这一篇中我们就来学习ThreadX初步应用并将其移植到STM32平台中。…

外设驱动库开发笔记12:TSEV01CL55红外温度传感器驱动

有时候我们需要检测一些无法直接接触的器件的温度。为了实现这一需求&#xff0c;我们通常会选择红外温度传感器来实现这一功能。考虑到复用的问题&#xff0c;我们一般会将操作元器件的代码抽象为驱动函数以备调用。这里我们就来设计并实现TSEV01CL55红外温度传感器的驱动。 …

FreeRTOS应用开发笔记之一:FreeRTOS在STM32的移植

FreeRTOS是如今在小型嵌入式领域应用比较广泛的一种实时操作系统。它是一种开源且免费的操作系统&#xff0c;而且移植和使用都非常的简单。在这里我们将学习并移植FreeRTOS。 1、必要的准备 工欲善其事&#xff0c;必先利其器&#xff0c;在开始学习和移植之前&#xff0c;相…

外设驱动库开发笔记13:MLX90614红外温度传感器驱动

红外温度传感器一般用于非接触式的温度检测。在我们的系统中经常会有这样的需求。所以我们将其设计为通用的驱动库以备复用。这一篇我们将讲述MLX90614红外温度传感器驱动的设计与实现。 1、功能概述 MLX90614是一种红外温度计&#xff0c;用于非接触式温度测量。红外测温是根…

Modbus协议栈应用实例之三:Modbus TCP客户端应用

自从开源了我们自己开发的Modbus协议栈之后&#xff0c;有很多朋友建议我针对性的做几个示例。所以我们就基于平时我们的应用整理了几个简单但可以说明基本的应用方法的示例&#xff0c;这一篇中我们将解说如何使用协议栈实现一个Modbus TCP客户端。 1、何为TCP客户端 Modbus…

Modbus协议栈应用实例之四:ModbusTCP服务器应用

自从开源了我们自己开发的Modbus协议栈之后&#xff0c;有很多朋友建议我针对性的做几个示例。所以我们就基于平时我们的应用整理了几个简单但可以说明基本的应用方法的示例&#xff0c;这一篇中我们来简述如何使用协议栈实现一个Modbus TCP服务器应用。 1、何为TCP服务器 Mo…

外设驱动库开发笔记14:DS18B20温度变送器驱动

在一时候我们需要相对简单的检测温度信号&#xff0c;而DS18B20就是一款功能和应用都相对简单的温度传感器&#xff0c;通过单线就可以实现检测温度信号的需求。这一篇我们就来实现操作DS18B20获取温度数据的驱动。 1、功能概述 DS18B20是常用的数字温度传感器&#xff0c;其…

Modbus协议栈应用实例之五:Modbus ASCII主站应用

自从开源了我们自己开发的Modbus协议栈之后&#xff0c;有很多朋友建议我针对性的做几个示例。所以我们就基于平时我们的应用整理了几个简单但可以说明基本的应用方法的示例&#xff0c;这一篇中我们来使用协议栈实现Modbus ASCII主站应用。 1、何为ASCII主站 我们知道Modbus…

Modbus协议栈应用实例之六:Modbus ASCII从站应用

自从开源了我们自己开发的Modbus协议栈之后&#xff0c;有很多朋友建议我针对性的做几个示例。所以我们就基于平时我们的应用整理了几个简单但可以说明基本的应用方法的示例&#xff0c;这一篇中我们来使用协议栈实现Modbus ASCII从站应用。 1、何为ASCII从站 我们知道Modbus…

外设驱动库开发笔记15:DHT11温湿度传感器驱动

与DS18B20一样DHT11也是采用单总线&#xff0c;但所不同的是DHT11可同时实现温度和湿度的检测。在我们的产品中经常使用它来检测环境的温湿度信息。这一篇我们将设计并封装DHT11的驱动程序&#xff0c;以方便重复使用。 1、功能概述 DHT11数字温湿度传感器是一款含有已校准数…

外设驱动库开发笔记16:MS5536C压力变送器驱动

压力检测也是经常会遇到的需求&#xff0c;比如环境压力或者低压气体等都会用到压力检测。这类检测压力都比较低&#xff0c;一般不会超过大气压&#xff0c;有时甚至是负压。这一篇我们要讨论的MS5536C就属于这类器件。接下来我们将设计并实现MS5536C的驱动。 1、功能概述 M…

外设驱动库开发笔记17:MS5803压力变送器驱动

很多时候我们需要检测被控对象的绝对压力&#xff0c;而且在我们的多款产品中也有这样的需求。当然检测绝对压力的传感器有很多&#xff0c;我们经常使用MS5803来实现压力检测。本篇中我们将设计并实现MS5803系列压力传感器的驱动。 1、功能概述 MS5803系列产品包含压阻传感器…

通讯接口应用笔记1:RS485通讯上下拉电阻的选择

RS485是一种常见的通讯接口方式&#xff0c;在我们的实际产品中也是多次使用。但我们平常并不会去过多考虑某一实现的细节问题&#xff0c;不过最近我们遇到了一个因如上下拉电阻的选择问题而造成的通讯故障&#xff0c;所以在这一片中我们来讨论一下RS485总线上下拉电阻的选择…