简介
IAP,即在线应用编程,目的是为了在产品发布后可以方便地通过预留的通信口对产品中的固件程序进行更新升级,那么怎么理解呢?假如芯片内部有一定大小的flash,我们将其空间划分为A和B两部分,A用来存储一段启动程序,简称bootloader,作用是通过某种方式如USB,USART接收程序或者数据,执行对第二部分的更新,即对B空间存储代码的更新;B空间存储的代码是我们真正实现功能的代码,简称function code.
原理
代码烧录
bootloader代码必须通过其他手段烧录,比如JTAG,ISP,function code可以使用第一部分IAP功能烧录,也可以和第一部分代码一起烧入,以后需要程序更新时再通过IAP进行代码更新。另外要说明的是:
1.这两段程序存放在flash的不同地址范围,一般从最低地址存放启动程序(空间一定留够),后面某段地址开始存放功能代码(如果空间足够大,可以存放多套功能代码)
2.stm32的功能代码不仅能够放在flash里面,也可以放在sram里面,
执行流程
当芯片上电后,首先是bootloader代码开始运行,检查是否需要对function code进行更新,若需要更新则更新代码之后,跳到功能代码开始运行,若不需要更新,则直接跳到功能代码开始运行。下面是加入IAP之后的程序运行流程图
stm32复位后,还是从0X8000004地址取出复位中断向量的地址,并跳转到复位中断服务程序,在运行完复位中断服务程序之后跳转到bootloader的main函数,执行完bootloader之后跳转到功能函数的复位中断向量地址处,随后跳转到新程序的main函数。注意:在main函数执行过程中,如果CPU得到一个中断请求,PC指针仍强制跳转到地址0x8000004中断向量表处(而不是新的中断向量表),程序再根据我们设置的中断向量表偏移量,跳转到对应中断源新的中断服务程序中,再执行完中断服务函数后,程序返回main函数继续运行。
function code的生成方法
以stm32f103作为主控芯片,KEIL作为开发环境
1.软件配置
f103C8片内flash一共64k,对应地址范围:0x8000000~0x8010000,此处配置意思是将从0x008000处开始的32kflash空间用于存储function code.
2.中断向量表偏移量设置方法
打开文件system_stm32f10x.c,在系统初始化函数 SystemInit()的末尾有这样几句代码
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif
从代码可以看出VTOR寄存器存放的是中断向量表的起始地址,默认VECT_TAB_SRAM没有定义,所以执行 SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET;
FLASH_BASE是基地址0x08000000,VECT_TAB_OFFSET是偏移量,默认值为0,所以我们需要在function code main函数开头处加上如下代码:
SCB->VTOR = FLASH_BASE | 0x8000;
意思是将64kflash空间的后一半用作功能函数的存储空间
3.生成.bin文件
MDK默认是不生成.bin文件的,我们可以通过MDK自带的格式转换工具fromelf.exe来生成(具体怎么设置,网上随便一搜就能搜到,此处不详细论述),生成之后就可以通过IAP来进行代码更新了
总结
其实IAP资料一大堆,上面这些东西无论是通过看正点原子的教程还是百度都可以搜的到,而之所以写上面那些是为了对IAP做一些介绍吧,不然各位看官还要去别的地方查资料来获取对IAP的基本认识,下面是IAP相关的其他链接可以参考下(别人的)
1.http://www.51hei.com/stm32/4315.html
2.https://blog.csdn.net/super_demo/article/details/32133257
3.https://blog.csdn.net/super_demo/article/details/32086541
4.https://blog.csdn.net/chen244798611/article/details/51365150
5.https://blog.csdn.net/lrmlrm/article/details/51382579
6.https://blog.csdn.net/flydream0/article/details/52486849
7.https://blog.csdn.net/lijing198997/article/details/22314783
8.https://blog.csdn.net/gang_life/article/details/50819726
9.https://blog.csdn.net/xiaobai20131/article/details/50890275
ISP和IAP的比较
ISP 即通常说的串口下载,通讯限定死了只能用串口,且只能边擦边写,上位机给下位机传一段,下位机擦除并写入一段,边擦边写有很大风险,中途掉线的话ISP进不去
,应用程序又不完整,就比较麻烦。stm32芯片内嵌了串口下载的引导程序,不过需要将BOOT1设为低,boot0设为高。
IAP可以实现远程升级,需要单片机支持,不需要改变boot引脚配置,IAP通信接口可以是SPI,I2C,UART,USB,CAN,以太网,IAP可以做到先不擦除flash,仅仅接收到程序数据,将其存到其他区域,等接受完毕后再一口气将程序区域擦除并写入。
其他
1.编写bootloader的时候,肯定用到flash编程,flash可以直接读,写的时候需要解锁,擦除,写数据,上锁,所以bootloader不能将接收数据的数组定位在flash,再说一般flash不存变量。
2.使用MDK进行bootloader和function code的编译器设置时,IRAM设成一样的大小不冲突,因为一旦程序跳转到function code,bootloader程序就失效,RAM空间重新分配,除非复位才能回到bootloader.
3.使用st库函数进行flash编程移植时,stmflash.h库文件关于所用芯片flash容量的一个宏也要随着芯片改变而改变