IAP
是 In Application Programming
的首字母缩写,IAP是用户自己的程序在运行过程中对 User Flash 的部分区域进行烧写,目的是为了在产品发布后可以方便地通过预留的通信口对产品中的固件程序进行更新升级。
在重新编程过程中可以使用任意类型的通信协议,如 UART、I2S、SPI 等。这篇笔记分享的是使用 UART方式IAP 。
先理一理流程(本实验是以 STM32F103ZET6
为例):
做这个实验需要准备两个 keil
工程,一个工程用于编写IAP程序,另一个工程用于编写我们的应用程序(要实现某些功能的程序),这里我们以一个点灯程序为例。最终,两份工程编译出来的可执行文件都需要烧写到芯片的FLASH
中。只不过需要烧写到不同的地址,简单的示意图如下:
这里使用的STM32型号为 STM32F103ZET6 ,其FLASH大小是512KB,0x08000000为其FLASH被映射的地址,程序被烧写到的就是这个地址。此处,我们的IAP程序烧写到这个地址,根据IAP程序的大小,我们在keil里可以设置合适的IAP结束地址。
注意:在没有IAP程序的情况下,0x08000000这个地址就是应用程序烧写的地址。
本实验用到的两个工程可按照文末的方式获取,其中IAP工程移植至ST官方例程。下面对两个工程进行简单的说明。
(1)需要在 target
选项卡里设置我们IAP程序的 起始地址与大小 ,如:
这里我们的IAP程序起始地址设为 0x08000000,大小设为 0x3000,即IAP所能用的FLASH空间为12KB。其中IAP所能占的占空间的大小可根据IAP的实际大小进行修改。
(2)需要修改程序中我们需要跳转到的应用程序的地址(即IAP程序的结束地址):
(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
程序运行 。
学会配置 fromelf.exe
,也就学会配置了 MinGW
。MinGW是一个工具集,包含编译C与C++的gcc、g++,使用它就可以在Windows命令行下编译C程序。
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){}
return0;
}
可见,我们按下复位的同时按下 PE2
对应的按键即可触发应用程序更新操作,否则跳转到应用程序的起始地址执行应用程序(断点重启也是默认执行应用程序),这里的 ApplicationAddress
就是我们上面设置的 0x08003000
。
这个函数里就是该 IAP 程序的功能,根据其中的打印信息:
可以知道,该IAP有三个功能(分别输入键盘上的数字1、2、3进行选择):
首先,上位机使用Ymodem协议进行数据下发,STM32根据协议解析数据,拿到有用的数据,并把这些数据写入FLASH对应的地址中,即ApplicationAddress。关于Ymodem协议及SerialDownload函数这里不展开讨论。
可以使用J-link等调试器进行下载,也可用串口ISP
进行下载,我们选用的是 串口ISP
进行下载,借用的工具是 FlyMcu
:
这里下载的是 .hex
文件 ,如果下载 .bin
文件 ,则会提示如下错误:
程序文件不是 0x8000000 和 0x20000000 区域的
使用 ISP 方式下载需要进行的硬件操作是:BOOT0引脚拉高,BOOT1引脚接地
。即系统存储器被选为启动区域:
在点击 开始编程
按钮后,需要按下板子上的复位键,即可下载程序。
上面提到下载程序使用的是 Ymodem 协议,所以得选用带有Ymodem协议传输方式的上位机软件来把应用程序下载到板子里。可以选用 SecureCRT
,也可以选用超级终端。这里选用的是超级终端:
首先,按下数字键1触发下载程序操作,此时会不断打印 CCCCC...
。然后点 传送 -> 发送文件
,选择要下载的 .bin
文件 及 Ymodem
协议 。下载完成后按下 数字3 即可执行新下载得应用程序:
终于LED闪烁起来了,点灯项目成功!断电重启之后,默认执行的是这个点灯程序,要想下载新的程序,按下复位的同时按下PE2
所对应的按键(需要一定的手速)即可触发更新程序操作。
本文来源网络,免费分享知识,版权归原作者所有。如涉及作品版权问题,请联系我进行删除!