IAP
是In Application Programming
的首字母缩写,IAP是用户本身的程序在运行过程当中对User Flash的部分区域进行烧写,目的是为了在产品发布后能够方便地经过预留的通讯口对产品中的固件程序进行更新升级。git
在从新编程过程当中可使用任意类型的通讯协议,如UART、I2S、SPI等。这篇笔记分享的是使用UART方式IAP。github
先理一理流程(本实验是以STM32F103ZET6
为例):编程
一、实验说明微信
作这个实验须要准备两个keil
工程,一个工程用于编写IAP程序,另外一个工程用于编写咱们的应用程序(要实现某些功能的程序),这里咱们以一个点灯程序为例。最终,两份工程编译出来的可执行文件都须要烧写到芯片的FLASH
中。只不过须要烧写到不一样的地址,简单的示意图以下:app
这里,使用的STM32的型号为STM32F103ZET6,其FLASH大小是512KB,0x08000000为其FLASH被映射的地址,程序被烧写到的就是这个地址。此处,咱们的IAP程序烧写到这个地址,根据IAP程序的大小,咱们在keil里能够设置合适的IAP结束地址。electron
注意:在没有IAP程序的状况下,0x08000000这个地址就是应用程序烧写的地址。函数
二、工程说明工具
本实验用到的两个工程可按照文末的方式获取,其中IAP工程移植至ST官方例程。下面对两个工程进行简单的说明ui
IAP工程:命令行
(1)须要在target
选项卡里设置咱们IAP程序的起始地址与大小,如:
这里咱们的IAP程序起始地址设为0x08000000,大小设为0x3000,即IAP所能用的FLASH空间为12KB。其中IAP所能占的占空间的大小可根据IAP的实际大小进行修改。
(2)须要修改程序中咱们须要跳转到的应用程序的地址(即IAP程序的结束地址):
LED工程:
(1)须要在target
选项卡里设置咱们LED程序的起始地址与大小,如:
这里咱们的LED程序起地址设为0x08003000,大小设为0x10000,即LED所能用的FLASH空间为64KB。其中结束地址可根据LED应用程序的实际大小进行修改。
(2)生成对应的.bin
文件。这须要在User
选项卡里添加以下命令(即编译后执行的命令):
其中,fromelf.exe
是咱们keil安装目录下的一个可执行程序,能够把.axf
文件转换成.bin
文件。要在keil中直接调用fromelf命令,必需要把fromelf.exe
所在目录添加到环境变量中。添加环境变量的方法以下(该方法来自于《【野火】零死角玩转STM32—F429挑战者V2.pdf》):
本文以 Win7 系统为例添加工具链的路径到 PATH 环境变量,其它系统是相似的。
(1) 右键电脑系统的计算机图标
,在弹出的菜单中选择属性
,如图:
(2) 在弹出的属性页面依次点击高级系统设置 ->环境变量
,在用户变量一栏中找到名为PATH
的变量,若没有该变量,则新建一个。编辑PATH
变量,在它的变量值中输入工具链的路径,如本机的是;D:\work\keil5\ARM\ARMCC\bin
,注意要使用分号;
让它与其它路径分隔开,输入完毕后依次点肯定
,如图:
(3) 打开 Windows 的命令行,点击系统的开始菜单
,在搜索框输入cmd
,在搜索结果中点击cmd.exe
便可打开命令行, 如图:
(4) 在弹出的命令行窗口中输入fromelf
回车,若窗口打印出 formelf
的帮助说明,那么路径正常,就能够开始后面的工做了;若提示不是内部名外部命令,也不是可运行的程序…
信息,说明路径不对,请从新配置环境变量,并确认该工做目录下有编译工具链。
这个过程本质就是让命令行经过“PATH”路径找到fromelf.exe
程序运行 。
三、IAP源码说明
(1)主函数:
int main(void) { FLASH_Unlock(); /* FLASH解锁 */ KEY_Init(); /* 按键初始化 */ IAP_Init(); /* IAP初始化 */ /* 按键按下则进入主菜单开始更新程序(注意:须要按下复位键的同时按下该按键触发程序更新) */ if (GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2) == 0x00) { SerialPutString("\r\n======================================================================"); SerialPutString("\r\n= (C) COPYRIGHT 2010 STMicroelectronics ="); SerialPutString("\r\n= ="); SerialPutString("\r\n= In-Application Programming Application (Version 3.3.0) ="); SerialPutString("\r\n= ="); SerialPutString("\r\n= By MCD Application Team ="); SerialPutString("\r\n======================================================================"); SerialPutString("\r\n\r\n"); Main_Menu (); } /* 保持运行用户应用程序 */ else { /* Test if user code is programmed starting from address "ApplicationAddress" */ if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000) { /* Jump to user application */ JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4); Jump_To_Application = (pFunction) JumpAddress; /* Initialize user application's Stack Pointer */ __set_MSP(*(__IO uint32_t*) ApplicationAddress); Jump_To_Application(); } } while (1){} return 0; }
可见,咱们按下复位的同时按下PE2
对应的按键便可触发应用程序更新操做,不然跳转到应用程序的起始地址执行应用程序(断点重启也是默认执行应用程序),这里的ApplicationAddress
就是咱们上面设置的0x08003000
。
(2)主菜单函数Main_Menu
这个函数里就是该IAP程序的功能,根据其中的打印信息:
能够知道,该IAP有三个功能(分别输入键盘上的数字一、二、3进行选择):一是下载程序(电脑->STM32);二是上传程序(STM32->电脑);三是执行新程序(即刚下载完成的程序)。
(3)下载程序功能函数SerialDownload
首先,上位机使用Ymodem协议进行数据下发,STM32根据协议解析数据,拿到有用的数据,并把这些数据写入FLASH对应的地址中,即ApplicationAddress。关于Ymodem协议及SerialDownload函数这里不展开讨论。
四、下载验证
(1)下载IAP程序
可使用J-link等调试器进行下载,也可用串口ISP
进行下载,咱们选用的是串口ISP
进行下载,借用的工具是FlyMcu
:
这里下载的是.hex
文件,若是下载.bin
文件,则会提示以下错误:
程序文件不是0x8000000和0x20000000区域的
使用ISP方式下载须要进行的硬件操做是:BOOT0引脚拉高,BOOT1引脚接地
。即系统存储器被选为启动区域:
在点击开始编程
按钮后,须要按下板子上的复位键,便可下载程序。
(2)经过IAP程序引导下载LED程序
上面提到下载程序使用的是Ymodem协议,因此得选用带有Ymodem协议传输方式的上位机软件来把应用程序下载到板子里。能够选用SecureCRT
,也能够选用超级终端。这里选用的是超级终端:
首先按下数字键1触发下载程序操做,此时会不断打印CCCCC...
。而后点传送->发送文件
,选择要下载的.bin
文件及Ymodem
协议。下载完成后按下数字3便可执行新下载得应用程序:
终于,LED闪烁起来了,点灯项目成功~。断电重启以后默认执行的是这个点灯程序,要想下载新的程序,按下复位的同时按下PE2
所对应的按键(须要必定的手速,哈哈)便可触发更新程序操做。
以上就是本次笔记分享的内容,若有错误,欢迎指出!
个人我的博客:https://zhengnianli.github.io/
个人微信公众号:嵌入式大杂烩,关注并回复【1024】获取1TB大杂烩资料。