目录
一、硬件设计
二、软件设计
三、上位机设计
四、IAP说明
五、下载验证
资料下载地址:STM32F4 IAP升级 Bootloader程序+上位机下载程序源码
一、硬件设计
- 指示灯DS6
- 一根短接线,优化硬件后 可用跳帽
- 串口(共地)
二、软件设计
总共涉及三部分代码:1、Bootloader;2、Flash App;3、上位机程序
三、上位机设计
主要代码:
四、IAP说明
- 检查是否需要对第二部分代码进行更新
- 如果不需要更新,则运行第二部分代码
- 若需要更新,执行更新操
- 更新完成,执行第二部分代码
- 新程序必须在IAP程序之后的某个偏移量为x 的地址开始;
- 必须将新程序的中断向量表相应的移动,移动的偏移量为x;
在pbdr_v110版本中在mian.c中设置如下:
MDK编译默认生成.hex文件,而升级程序需要生成.bin文件。MDK自带的格式转换工具fromelf.exe,来实现.axf文件到.bin文件的转换。该工具在MDK的安装目录\ARM\BIN40文件夹下。通过下一步设置,可以在MDK编译成功之后,调用fromelf.exe (注意,MDK的安装路径,我的路径D:\Keil_v5\ARM\ARMCC\bin),根据当前工程pbdr.axf,生成一个pbdr.bin文件。存放在OBJ文件夹下。在得到.bin文件后,我们只需要将这个bin文件通过串口传送给单片机,即可执行代码的下载以及升级。
五、下载验证
将JTDO(PB4)与GND短接,上电后,LED灯D6开始闪烁,说明进入下载更新状态。
通过TTL转usb连上电脑端串口,打开IAP更新软件(打开应用程序IAP_Download_USART\IAP_Download_USART\obj\Debug文件夹中IAP_Download_USART.exe文件或直接打开附件中IAP_Download_USART.exe应用程序),打开串口即可选则发送BIN文件进行代码下载。
关闭下载窗口,断开短接线即可运行更新后的程序。
stm32 IAP Bootloader V1.4源码:
/*--------------------------------------------------------------------------------------
@file: IAP_Serial
@version: V1.0
@author: Shanwu.5_W && Potter_lv
@Introduction : Unlock flash load_app from serial
--------------------------------------------------------------------------------------*/
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "stmflash.h"
#include "iap.h"
void Button_Switch_DFU_Init(void) //按键升级初始化
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
#define GET_BUTTON_STATE GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_3)
int main(void)
{
u8 t;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
uart_init(115200); //初始化串口波特率为115200
LED_Init(); //初始化LED
Button_Switch_DFU_Init(); //初始化跳转APP程序接口
while(1)
{
t++;
delay_ms(10);
if(t==30)
{
LED0=!LED0; //D6闪烁 等待更新状态
t=0;
}
if(GET_BUTTON_STATE != 0x00) //悬空进入更新进程
{
if(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x08000000) //判断是否为0X08XXXXXX.
{
USART_Cmd(USART2, DISABLE); //失能串口2 ,防止跳转到App程序时死机
iap_load_app(FLASH_APP1_ADDR); //执行FLASH APP代码
}else
{
printf("非FLASH应用程序,无法执行!\r\n");
}
}
}
}