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 Buffer[4];

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 tbuf[40];

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程序

相关推荐
逼子格1 小时前
十三种物联网/通信模块综合对比——《数据手册--物联网/通信模块》
嵌入式硬件·物联网·音视频·硬件工程师·硬件测试·硬件笔试真题·通信模块
Wythzhfrey2 小时前
51单片机Day03---让一个LED灯闪烁
c语言·单片机·嵌入式硬件·c#·51单片机
双叶8362 小时前
(51单片机)串口通讯(串口通讯教程)(串口接收发送教程)
c语言·开发语言·c++·单片机·嵌入式硬件·microsoft·51单片机
琢磨先生David4 小时前
探索 OpenHarmony 开源硬件的学习路径:从入门到实战的全攻略
嵌入式硬件·开源·鸿蒙
美好的事情总会发生4 小时前
电容详解:定义、作用、分类与使用要点
嵌入式硬件·硬件工程·智能硬件
FreakStudio13 小时前
【电子DIY神器】通吃各种5线步进电机!I2C接口控制28BYJ-48五线四相步进电机
stm32·单片机·mcu·嵌入式·arm·技术栈·电子diy
学渣6765615 小时前
【GPIO8个函数解释】
stm32·单片机·嵌入式硬件
weixin_4465042216 小时前
通信协议详解(十):PSI5 —— 汽车安全传感器的“抗干扰狙击手”
嵌入式硬件·fpga
mcupro17 小时前
TQTT_KU5P开发板教程---文件的烧写与程序固化
嵌入式硬件·fpga开发
zd84510150017 小时前
proteus OLED12864仿真
单片机·嵌入式硬件·proteus