1)实验平台:正点原子APM32F407最小系统板
2)平台购买地址:https://detail.tmall.com/item.htm?id=609294757420
3)全套实验源码+手册+视频下载地址: http://www.openedv.com/thread-340252-1-1.html##
第六十章 串口IAP实验
本章将介绍在APM32F407上使用串口进行IAP,以实现简单的IAP功能。通过本章的学习,读者将学习到IAP的使用。
本章分为如下几个小节:
60.1 硬件设计
60.2 程序设计
60.3 下载验证
60.1 硬件设计
60.1.1 例程功能
- 程序运行后进入等待接收APP的bin数据的状态
- 接收到APP的bin数据后,先后按下KEY0按键和KEY_UP按键,可分别进行将APP的bin数据加载到Flash和跳转到APP的位置执行APP的操作
- LED0闪烁,指示程序正在运行
60.1.2 硬件资源 - LED
LED0 - PF9 - 按键
KEY0 - PE4
KEY_UP - PA0 - USART1(PA9、PA10连接至板载USB转串口芯片上)
- 正点原子 2.8/3.5/4.3/7/10寸TFTLCD模块(仅限MCU屏,16位8080并口驱动)
60.1.3 原理图
本章实验使用的IAP为软件算法,因此没有对应的连接原理图。
60.2 程序设计
60.2.1 IAP的实现
本章实验提供了用于IAP的驱动代码,如下图所示:
图60.2.1.1 IAP驱动代码
IAP的实现最主要分为两个步骤,分别为加载APP固件至Flash和跳转到APP中运行,为此本实验实现了以上两个函数,如下所示:
void iap_write_appbin(uint32_t appxaddr,uint8_t *appbuf,uint32_t applen);
void iap_load_app(uint32_t appxaddr);
以上两个函数就分别实现了加载APP固件至Flash和跳转到APP运行的功能,这两个函数的使用示例,如下所示:
#include "apm32f4xx.h"
#include "./IAP/iap.h"#define FLASH_APP_ADDR (0x08010000)
#define APP_MAX_SIZE (120*1024)static uint8_t appbin[APP_MAX_SIZE];void example_fun(void)
{uint32_t appsize;/* 通过串口等方式获取APP的二进制数据 */appsize = get_app_bin(appbin);/* 将APP的二进制数据写入Flash的指定地址中 */iap_write_appbin(FLASH_APP_ADDR, appbin, appsize);/* 跳转到APP在Flash中的起始地址运行 */iap_load_app(FLASH_APP_ADDR);
}
60.2.2 APP工程修改
APP程序要能够在指定的Flash起始地址运行,需要编译器在编译APP的时候知道APP将被保存在Flash的那个位置,对于MDK软件,可以在Options for Target窗口中设置,如下图所示:
图60.2.2.1 配置MDK中的Flash空间
上图中将APP程序保存在Flash中的空间配置为0x8010000~(0x8010000+0xF0000),通过这样的配置便可以使APP被保存在指定Flash位置中执行。读者可以自行配置“Start”和“Size”参数,但要注意不能超过Flash的范围,并且也不要覆盖IAP程序(Bootloader)。
上一小节中将APP保存到Flash中的操作操作的是二进制数据,因此APP也应当被编译为二进制文件,然后MDK软件中并没有直接编译出二进制文件的选项,因此需要配置MDK在编译完成后执行指定的命令,如下图所示:
图60.2.2.2 配置MDK生成二进制文件
完成以上配置后,便可在APP程序编译完成后在工程的Output目录下得到正确的二进制文件。
60.2.3 实验应用代码
本章实验的应用代码,如下所示:
int main(void)
{/* 仅保留关键代码,其余代码省略 *//* 初始化串口 */usart_init(115200);while (1){/* 串口已接收到数据 */if (g_usart_rx_cnt != 0){/* 新的一次循环串口还没有接收到新数据,* 则断定串口接收完毕*/if (lastcount == g_usart_rx_cnt){/* 记录APP固件大小 */applenth = g_usart_rx_cnt;lastcount = 0;g_usart_rx_cnt = 0;}else{lastcount = g_usart_rx_cnt;}}key = key_scan(0);switch (key){case KEY0_PRES:{/* 将串口接收到的APP二进制数据写入Flash中的指定位置 */iap_write_appbin(FLASH_APP1_ADDR, g_usart_rx_buf, applenth);break;}case WKUP_PRES:{/* 跳转到Flash的指定位置执行APP程序 */iap_load_app(FLASH_APP1_ADDR);break;}}delay_ms(100);}
}
从上面的代码中可以看出,程序是通过串口接收APP的二进制数据的,因此串口驱动中的串口接收缓存因该设置的足够大,以能够容纳APP的二进制数据,本实验中串口接收缓存的配置如下所示:
/* 定义最大接收120KB数据 */
#define USART_REC_LEN (120 * 1024)
在判断APP二进制数据接收完毕后,便可通过KEY0按键调用函数iap_write_appbin()将APP的二进制数据写入Flash中的FLASH_APP1_ADDR位置中,FLASH_APP1_ADDR是一个宏,该宏的定义如下所示:
#define FLASH_APP1_ADDR 0x08010000
需要注意的是,APP写入的位置应当与上一小节中配置MDK软件的指定Flash位置相同。
将APP的二进制数据写入到Flash中后,此时运行的依旧是IAP(Bootloader)程序,此时可以按下KEY_UP按键来跳转到Flash中APP的位置执行APP程序。
60.3 下载验证
在完成编译和烧录操作后,可以看到LCD上显示了本实验的相关实验信息,此时程序正在等待串口接收APP的二进制数据,此时便可通过串口调试助手将实现编译生成的APP二进制文件发送给MCU,待发送完毕后按下KEY0按键,将APP的二进制数据写入到Flash中,若写入成功,LCD上将会有相应的提示,此时便可按下KEY_UP按键将程序跳转到APP的保存位置中运行,若指定的Flash位置保存了正确的APP固件,那么便可看到MCU正在运行APP程序,而非IAP(Bootloader)程序。