STM32的IAP实现
STM32的IAP实现
IAP,全称是“In-Application Programming”,中文解释为“在程序中编程”。IAP是一种对通过微控制器的对外接口(如USART,IIC,CAN,USB,以太网接口甚至是无线射频通道)对正在运行程序的微控制器进行内部程序的更新的技术(注意这完全有别于ICP或者ISP技术)。ICP(In-Circuit Programming)技术即通过在线仿真器对单片机进行程序烧写,而ISP技术则是通过单片机内置的bootloader程序引导的烧写技术。无论是ICP技术还是ISP技术,都需要有机械性的操作如连接下载线,设置跳线帽等。若产品的电路板已经层层密封在外壳中,要对其进行程序更新无疑困难重重,若产品安装于狭窄空间等难以触及的地方,更是一场灾难。但若进引入了IAP技术,则完全可以避免上述尴尬情况,而且若使用远距离或无线的数据传输方案,甚至可以实现远程编程和无线编程。这绝对是ICP或ISP技术无法做到的。某种微控制器支持IAP技术的首要前提是其必须是基于可重复编程闪存的微控制器。STM32微控制器带有可编程的内置闪存,同时STM32拥有在数量上和种类上都非常丰富的外设通信接口,因此在STM32上实现IAP技术是完全可行的。
实现IAP技术的核心是一段预先烧写在单片机内部的IAP程序。这段程序主要负责与外部的上位机软件进行握手同步,然后将通过外设通信接口将来自于上位机软件的程序数据接收后写入单片机内部指定的闪存区域,然后再跳转执行新写入的程序,最终就达到了程序更新的目的。
在STM32微控制器上实现IAP程序之前首先要回顾一下STM32的内部闪存组织架构和其启动过程。STM32的内部闪存地址起始于0x8000000,一般情况下,程序文件就从此地址开始写入。此外STM32是基于Cortex-M3内核的微控制器,其内部通过一张“中断向量表”来响应中断,程序启动后,将首先从“中断向量表”取出复位中断向量执行复位中断程序完成启动。而这张“中断向量表”的起始地址是0x8000004,当中断来临,STM32的内部硬件机制亦会自动将PC指针定位到“中断向量表”处,并根据中断源取出对应的中断向量执行中断服务程序。最后还需要知道关键的一点,通过修改STM32工程的链接脚本可以修改程序文件写入闪存的起始地址。
在STM32微控制器上实现IAP方案,除了常规的串口接收数据以及闪存数据写入等常规操作外,还需注意STM32的启动过程和中断响应方式。图1显示了STM32常规的运行流程。

对图1解读如下:
1、STM32复位后,会从地址为0x8000004处取出复位中断向量的地址,并跳转执行复位中断服务程序,如图1中标号○1所示。
2、复位中断服务程序执行的最终结果是跳转至C程序的main函数,如图1中标号○2所示,而main函数应该是一个死循环,是一个永不返回的函数。
3、在main函数执行的过程中,发生了一个中断请求,此时STM32的硬件机制会将PC指针强制指回中断向量表处,如图1中标号○3所示。
4、根据中断源进入相应的中断服务程序,如图1中标号○5所示。
5、 中断服务程序执行完毕后,程序再度返回至main函数中执行,如图1中标号○6所示。
若在STM32中加入了IAP程序,则情况会如图2所示。

对图2的解读如下:
1、STM32复位后,从地址为0x8000004处取出复位中断向量的地址,并跳转执行复位中断服务程序,随后跳转至IAP程序的main函数,如图2中标号○1、○2所示。这个过程和图1相应部分是一致的。
2、执行完IAP过程后(STM32内部多出了新写入的程序,图2中以灰色底纹方格表示,地址始于0x8000004+N+M)跳转至新写入程序的复位向量表,取出新程序的复位中断向量的地址,并跳转执行新程序的复位中断服务程序,随后跳转至新程序的main函数,其过程如图2的标号○3所示。新程序的main函数应该也具有永不返回的特性。同时应该注意在STM32的内部存储空间在不同的位置上出现了2个中断向量表。
3、在新程序main函数执行的过程中,一个中断请求来临,PC指针仍会回转至地址为0x8000004中断向量表处,而并不是新程序的中断向量表,如图2中标号○5所示。注意到这是由STM32的硬件机制决定的。
4、根据中断源跳转至对应的中断服务,如图2中标号○6所示。注意此时是跳转至了新程序的中断服务程序中。
5、中断服务执行完毕后,返回main函数。如图2中标号○8所示。
从上述两个过程的分析可以得知,对将使用IAP过程写入的程序要满足2个要求:
1、新程序必须从IAP程序之后的某个偏移量为x的地址开始;
2、必须将新程序的中断向量表相应的移动,移动的偏移量为x。
而设置程序起始位置的方法是(keil uvision4集成开发环境)在工程的“Option for Target….”界面中的“Target”页里将“IROM”的“Start”列改为欲使程序起始的地方,如将程序起始位置设为0x8002000。
将中断向量表移动的方法是在程序中加入函数:
void NVIC_SetVectorTable(u32 NVIC_VectTab, u32 Offset);
其中参数NVIC_VectTab为中断向量表起始位置,而参数Offset则为地址偏移量,如将中断向量表移至0x8002000处,则应调用该函数如下:
void NVIC_SetVectorTable(0x8000000, 0x2000);
同时有必要提醒读者注意的是,此函数只会修改STM32程序中用于存储中断向量的结构体变量,而不会实质地改变中断向量表在闪存中的物理位置,详情请研究该程序原型。
有了以上准备后就可以着手设计一个IAP方案了,如下:
1、STM32复位后,利用一个按键的状态进行同步,当按键按下时表示将要进行IAP过程;
2、IAP过程中,通过上位机软件向STM32的USART1设备发送所要更新的程序文件,STM32接收到数据后转而从0x8002000地址开始写入收到的数据;
3、STM32借助定时器来判断数据是否完全接收,完全接收后IAP过程结束;
4、再次复位后,跳转0x8002004地址开始运行新写入的程序;
最后提出几点注意事项:
1、具体实现的工程见附件;
2、利用IAP写入的程序文件最好是.bin格式的文件,但不能是.hex格式的文件;
3、向STM32发送程序文件时尽量慢一些,因为STM32对FLASH的写入速度往往跟不上通讯外设接口的速度;
4、建议在STM32和上位机之间设计一套握手机制和出错管理机制,这样可以大幅提高IAP的成功率;
5、附件中的IAP工程具体运行现象为,按着连接于GPIOA.0引脚上的按键后对STM32进行复位操作,若连接于GPIOA.4引脚上的LED被点亮则表示进入了IAP程序,等待从USART1接口传入欲更新的程序文件。程序文件更新完毕后,LED被熄灭。此时再度对STM32进行复位,就开始运行新写入的程序了。
STM32的IAP实现的更多相关文章
- STM32的IAP方案
from: http://bbs.eeworld.com.cn/thread-294115-1-1.html 几乎所有的同类书籍都介绍综合性的应用示例如“万年历 + 温度显示 + 闹钟响铃 + 计 ...
- STM32串口IAP实验笔记
STM32的IAP功能确实方便,以前对此如何实现有所了解,但是一直没去测试,这两天来练了下,可谓困难重重,搞了两天问题也一一解决,下面做些简要的笔记 IAP就是在线应用编程,方便程序升级,可以不用打开 ...
- 关于STM32的IAP与APP互相跳转
关于STM32的IAP与APP互相跳转 之前做了一个不带系统的IAP与APP互相跳转,在网上找了资料后,很顺畅就完成了,后来在IAR集成开发环境下,IAP无系统,APP用UCOS系统做互相跳转出现了很 ...
- can总线实现stm32的IAP
使用stm32f105rct6的can通信做IAP,实现固件的远程更新功能.IAP的实现包括两个程序:BootLoader和应用程序.启动过程先启动BootLoader,等待1s,若接收到烧写指令则开 ...
- stm32实现iap远程固件更新
前提 想来做iap升级了,应该不是什么新手. 下面的程序需要用到一些简单的功能 串口收发数据开关总中断虽然本文标题是实现远程固件更新,但是具体远程方案本文不做详细说明,重点在于介绍mcu接收到新的固件 ...
- STM32串口IAP分享
什么是IAP? IAP是In Application Programming的首字母缩写,IAP是用户自己的程序在运行过程中对User Flash的部分区域进行烧写,目的是为了在产品发布后可以方便地通 ...
- STM32 IAP docs
/********************************************************************************* * STM32 IAP docs ...
- 【转】stm32 IAP升级程序
一.什么是IAP,为什么要IAP IAP即为In Application Programming(在应用中编程),一般情况下,以STM32F10x系列芯片为主控制器的设备在出厂时就已经 ...
- stm32之存储系统
一.STM32系统结构 要想深刻理解STM32的存储器,需要首先知道STM32的系统结构. 如Figure 1,是STM32系统结构框图. 根据STM32 Reference manual (RM00 ...
随机推荐
- Oracle-04:DDL语言数据表的操作
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- DDL操作: --创建学生表 create table student( sno number(4) not ...
- Linux时间子系统之(一):时间的基本概念
专题文档汇总目录 Notes:Linux时间基准点:Linux时间和broken-down time(struct tm):不同精度的时间表示time_t.timeval.timespec. 原文地址 ...
- Linux时间子系统之七:定时器的应用--msleep(),hrtimer_nanosleep()
我们已经在前面几章介绍了低分辨率定时器和高精度定时器的实现原理,内核为了方便其它子系统,在时间子系统中提供了一些用于延时或调度的API,例如msleep,hrtimer_nanosleep等等,这些A ...
- Kali Linux虚拟机安装完整安装过程及简单配置(视频)
点击播放视频 附:视频中出现的两个txt文本,包含了大致的安装与配置过程: 文本1:KaliLinux虚拟机安装和初步配置 Kali Linux虚拟机安装和初步配置 大家好,今天给大家演示一下在VMw ...
- Git协作流程
Git 作为一个源码管理系统,不可避免涉及到多人协作. 协作必须有一个规范的流程,让大家有效地合作,使得项目井井有条地发展下去."协作流程"在英语里,叫做"workflo ...
- python获取日期加减之后的日期
python语言中的datetime模块可以利用其中的方法获取不同的日期,比如获取当前日期.明天.昨天.上个月.下个月和明年.下面利用几个实例说明这些日期的获取方法,操作如下: 第一步,利用d ...
- win10想开测试模式,提示“设置元素数据时出错
系统中按WIN键,搜索栏输入'CMD',右键点击找到的cmd.exe,选择'以管理员身份运行'.输入:"bcdedit -set loadoptions DDISABLE_INTEGRITY ...
- jQuery的入口函数四种写法
1.第一种: $(document).ready(function(){ }); 2.第二种(最简洁的写法,推荐): $(function(){ }); 3.第三种: jQuery(document) ...
- Flask开发微电影网站(三)
页面完成后的最终布局 可以看到,页面共同的部分是顶部导航和底部导航 所以我们可以把页面顶部导航和底部导航部分单独定义一个文件home.html,然后让需要使用顶部导航和底部导航的页面都继承home.h ...
- client.go
package)*time.Second) ], { hasConn := false waitc := time.After(cfg.DialTimeout) ...