STM32单片机实现串口IAP升级

一.概述

1.要实现串口IAP升级,首先要编写一个bootloader程序,然后再写支持IAP的app程序;

2.keil下bootloader的程序rom和ram设置

3.app程序要用bin文件

注:本文以STM32H743举例,其他stm32单片机IAP升级原理类似。

二.实现

1.bootloder程序实现

(1)基本知识

stm32的flash地址起始于0x0800 0000,结束地址是0x0800 0000加上芯片实际的flash大小,不同的芯片flash大小不同。

RAM起始地址是0x2000 0000,结束地址是0x2000 0000加上芯片的RAM大小。不同的芯片RAM也不同。

(2)STM32H743 bootloader设置

说明: 由于 STM32H7 的扇区大小固定为 128KB 一个,最小擦除单位也是以扇区为单位的,因此,至少分配一个扇区给 Bootloader,否则后续擦写 APP 的时候,可能把 Bootloader 也给擦了!所以,我们使用 128K(0X20000)字节来存放 Bootloader。

(3)代码实现

int main(void)

{

u8 t;

u16 wait_s = 0;

u8 key;

u32 applenth=0; //接收到的app代码长度

u8 clearflag=0;

u32 Buffer4;

Cache_Enable(); //打开L1-Cache

HAL_Init(); //初始化HAL库

Stm32_Clock_Init(160,5,2,4); //设置时钟,400Mhz

delay_init(400); //延时初始化

uart_init(115200); //串口初始化

LED_Init(); //初始化LED

KEY_Init(); //初始化按键

SDRAM_Init(); //初始化SDRAM

while(1)

{

if(USART_RX_STA&0x8000)

{

USART_RX_STA=0; //清空

applenth=USART_RX_CNT; // applenth

USART_RX_CNT=0;

printf("用户程序接收完成!\r\n");

printf("代码长度:%dBytes\r\n",applenth);

}

else

{

if(wait_s >= 500)

{

wait_s = 0;

printf("等待用法发送程序... \r\n");

}

}

t++;

wait_s ++;

delay_ms(10);

if(t==30)

{

LED0_Toggle;

t=0;

if(clearflag)

{

clearflag--;

}

}

key=KEY_Scan(0);

if(key==WKUP_PRES) //WK_UP按键按下

{

if(applenth)

{

printf("开始更新固件...\r\n");

if(((*(vu32*)(0x24001000+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX.

{

iap_write_appbin(FLASH_APP1_ADDR,USART_RX_BUF,applenth);//更新FLASH代码 #define FLASH_APP1_ADDR 0x08020000

printf("固件更新完成!\r\n");

}else

{

printf("非FLASH应用程序!\r\n");

}

}else

{

printf("没有可以更新的固件!\r\n");

}

clearflag=7;//标志更新了显示,并且设置7*300ms后清除显示

}

if(key==KEY1_PRES) //KEY1按下

{

if(applenth)

{

printf("固件清除完成!\r\n");

applenth=0;

}else

{

printf("没有可以清除的固件!\r\n");

}

clearflag=7;//标志更新了显示,并且设置7*300ms后清除显示

}

if(key==KEY2_PRES) //KEY2按下

{

printf("开始执行FLASH用户代码!!\r\n");

if(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX.

{

iap_load_app(FLASH_APP1_ADDR);//执行FLASH APP代码

}else

{

printf("非FLASH应用程序,无法执行!\r\n");

}

clearflag=7;//标志更新了显示,并且设置7*300ms后清除显示

}

}

}

(4)代码功能逻辑:

需要先按下 KEY_UP 按键,将串口接收到的 APP 程序存放到 STM32 的内部 FLASH;

再按 KEY2 既可以执行这个 FLASH APP 程序。

通过 KEY1 按键,可以手动清除串口接收到的APP 程序。

DS0 用于指示程序运行状态。

2.app程序及逻辑

(1)IAP流程逻辑

(2)keil设置

(3)代码实现

int main(void)

{

SCB->VTOR = FLASH_BASE|0x20000;//设置偏移量 FLASH_BASE : (uint32_t)0x08000000

RTC_TimeTypeDef RTC_TimeStruct;

RTC_DateTypeDef RTC_DateStruct;

u8 tbuf40;

u8 t=0;

HAL_Init(); //初始化HAL库

Stm32_Clock_Init(160,5,2,4); //设置时钟,400Mhz

delay_init(400); //延时初始化

uart_init(115200); //串口初始化

usmart_dev.init(200); //初始化USMART

printf("RTC APP running\r\n");

LED_Init(); //初始化LED

KEY_Init(); //初始化按键

SDRAM_Init(); //初始化SDRAM

RTC_Init(); //初始化RTC

RTC_Set_WakeUp(RTC_WAKEUPCLOCK_CK_SPRE_16BITS,0); //配置WAKE UP中断,1秒钟中断一次

while(1)

{

t++;

if((t%100)==0) //每100ms更新一次显示数据

{

HAL_RTC_GetTime(&RTC_Handler,&RTC_TimeStruct,RTC_FORMAT_BIN);

sprintf((char*)tbuf,"Time:%02d:%02d:%02d",RTC_TimeStruct.Hours,RTC_TimeStruct.Minutes,RTC_TimeStruct.Seconds);

printf("RTC time=%s\r\n",tbuf);

HAL_RTC_GetDate(&RTC_Handler,&RTC_DateStruct,RTC_FORMAT_BIN);

sprintf((char*)tbuf,"Date:20%02d-%02d-%02d",RTC_DateStruct.Year,RTC_DateStruct.Month,RTC_DateStruct.Date);

printf("RTC date=%s\r\n",tbuf);

sprintf((char*)tbuf,"Week:%d",RTC_DateStruct.WeekDay);

printf("RTC week=%s\r\n",tbuf);

}

if((t%20)==0)LED0_Toggle; //每200ms,翻转一次LED0

delay_ms(10);

}

}

说明: 重点是程序开始要有语句:****SCB->VTOR = FLASH_BASE|0x20000;****后面代码和普通app程序无区别

3.app生成bin文件

通过在 User 选项卡,设置编译后调用 fromelf.exe,根据.axf 文件生成.bin 文件,用于

IAP 更新。

具体见之前文章:

STM32多种开发环境及生成hex及bin文件介绍_stm32 cubeide fromelf-CSDN博客文章浏览阅读758次,点赞29次,收藏23次。STM32多种开发环境及生成hex及bin文件介绍keil5 STM32CubeIDE EWARM如果不考虑商业应用keil的比较好,如果考虑商业付费用STM32CubeIDE更好一些,毕竟是免费的。_stm32 cubeide fromelfhttps://blog.csdn.net/xieliru/article/details/139849283?spm=1001.2014.3001.5501

4.串口升级app

(1)首先用keil把bootloader程序用烧写器烧写到单片机中

(2)通过串口IAP升级app程序

相关推荐
省四收割者10 小时前
一文详解信号完整性(1)
python·嵌入式硬件·数学建模·信息与通信·信号处理·智能硬件
崇山峻岭之间11 小时前
单片机无感FOC驱动之ADC
单片机·嵌入式硬件
Ligocious11 小时前
1.点亮一颗小小的LED
单片机·嵌入式硬件
KaifuZeng15 小时前
通信与接口协议面试八、CAN通信
单片机·嵌入式硬件·面试·通信与接口协议
智源单片机设计16 小时前
基于单片机的直流电机双闭环调速系统设计
单片机·嵌入式硬件
kebidaixu16 小时前
两轮车换电 BMS 的模拟前端中颖 SH367306 AFE 芯片详解
stm32
kebidaixu17 小时前
两轮车换电 BMS 的模拟前端中颖 SH367306 AFE 芯片调试实录:四个关键问题与解决方案
stm32
KaifuZeng1 天前
通信与接口协议面试一、基本概念
嵌入式硬件·通信与接口协议
wuyk5551 天前
24. C 语言模块化:不是拆几个.c 文件那么简单
c语言·开发语言·stm32·单片机