STM32G474单片机开发入门(二十)单片机IAP(在应用编程)详解及Ymodem实战
文章目录
- 一.概要
- 二.STM32G474RET6单片机IAP介绍
- 1.STM32G474RET6单片机IAP基本原理
- 2.STM32G474RET6单片机IAP基本流程
- 3.Ymodem协议介绍
- 三.配置一个BOOT工程
- 四.配置一个APP工程
- 五.IAP实验操作
- 六.小结
一.概要
单片机上电或系统复位后,ARM® Cortex®-M4处理器先从0x0000 0000地址获取栈顶值,再从0x0000 0004地址获得引导代码的基地址,然后从引导代码的基地址开始执行程序。
所选引导源对应的存储空间会被映射到引导存储空间,即从0x0000 0000开始的地址空间。如果片上SRAM(开始于0x2000 0000的存储空间)被选为引导源,用户必须在应用程序初始化代码中通过修改NVIC异常向量表和偏移地址将向量表重置到SRAM中。当主FLASH存储器被选择作为引导源,从0x0800 0000开始的存储空间会被映射到引导存储空间。
STM32G4系列微控制器提供了三种引导源,BOOT0(PB8)引脚(也可以用nBOOT0 FLASH配置位)与nBOOT1 FLASH配置位的高低组合,配置单片机启动模式,一般我们都选主闪存存储器作为引导源。
STM32单片机程序升级方法有很多种,主要有以下几种:
1.将编译生成的hex/bin文件使用ST-Link/J-Link工具直接下载进 Flash 即可,Keil中点击下载就能下载,下载后的代码会存放在Flash的起始地址0x08000000处,就是上图中的第一种启动方式。
2.ISP(In System Programing),这个是利用了STM32单片机自带的 Bootloader 升级程序。一般可通过USART串口对Flash重新编程,再通过电脑上的ISP下载软件导入程序。ISP就是修改nBOOT1 FLASH配置位信号为0,BOOT0引脚为1,单片机就进入ISP模式,就是上图中的第二种启动方式。
- IAP(In Application Programing),即在应用编程,与之相对应的叫做ISP,两者的不同是ISP需要依靠烧写器在单片机复位离线的情况下编程,需要人工的干预,而IAP则是用户自己的程序在运行过程中对Flash 的部分区域进行烧写,目的是为了在产品发布后可以方便地通过预留的通信口对产品中的固件程序进行更新升级,这个还是采用上图中的第一种启动方式,不需要改变BOOT信号。
使用IAP技术能很好地降低现场工作量,实现IAP有两个很重要的前提
1.单片机程序能对自身的内部Flash 进行擦写。
2.单片机要有能够和外部进行通讯的方式,无论是网络还是别的方式,只要能传输数据就行。
二.STM32G474RET6单片机IAP介绍
1.STM32G474RET6单片机IAP基本原理
以STM32G474RET6单片机为例,每次程序复位是从0x08000000的位置开始执行主程序,如果不做IAP则这512KB(0x80000)空间都可以用来存放应用程序,但为了实现IAP,需要有划出一部分空间存放BOOT程序,BOOT程序跟应用程序是两个独立的工程,BOOT程序主要功能是来接收外部通讯(串口,485等)协议传输的应用程序代码文件(bin文件),并调用FLASH写入函数把bin文件分成N个64Bit数据,写入到应用程序地址空间,就实现对应用程序的升级。
2.STM32G474RET6单片机IAP基本流程
单片机先在BOOT工程的程序中跑,BOOT程序通过串口接收上位机发来的.bin文件(应用程序工程),检查后将.bin文件写入到Flash特定位置(0x08004000开始的地址),bin文件写完后,单片机就从BOOT程序的空间跳转到应用程序的空间运行。
3.Ymodem协议介绍
YMODEM协议介绍
YModem协议是一种高效的文件传输协议,广泛应用于嵌入式系统中的文件传输。YModem协议是一种发送并等待的协议,它基于XModem协议演变而来,但提供了更高的传输效率。YModem协议每包数据可以达到1024字节,相比XModem的128字节,大大提高了文件传输的速度。此外,YModem协议还支持批处理模式,允许一次传输多个文件,非常适合嵌入式系统中的文件传输需求。
YModem协议的基本操作流程:
• 传输启动:传输由接收方发起,接收方通过串口发送一个字符’C’来请求开始传输。
• 发送文件头:发送方收到’C’后,发送第一个数据包(包含文件名、文件大小等信息)。这个数据包通常使用SOH(Start of Header)作为起始标志。发送方等待接收方的确认(ACK)。
• 接收方确认:接收方收到文件头后,如果准备接收文件,则再次发送字符’C’。
• 发送文件数据:发送方开始发送文件数据包,每个数据包包含1024字节的数据(除了最后一个数据包可能小于1024字节)。每个数据包后都等待接收方的ACK确认。
• 传输结束:数据传输完毕后,发送方发送EOT(End of Transmission)信号表示传输结束。接收方首次以NAK应答进行二次确认,发送方重发EOT后,接收方以ACK应答。
• 结束传输:若无其他文件需传输,发送方发送一个全零数据包,接收方应答ACK后,正式结束数据传输。
数据包格式解析
YModem协议的数据包格式如下:
• 起始标志:数据包以SOH(0x01)或STX(0x02)作为起始标志,表示数据块的大小。SOH用于128字节的数据块,而STX用于1024字节的数据块。
• 发送序号和反码:数据包中的编号用于标识数据包的顺序,而反码则是编号的二进制反码,用于确保数据包的正确性。
• 数据字段:数据字段包含实际传输的数据。对于文件名和文件大小等信息,它们通常被编码为ASCII字符并填充到数据字段中。
• 校验字段:数据包包含CRC(Cyclic Redundancy Check)校验码,用于验证数据的完整性。CRC校验码通常附加在数据字段的末尾。
YModem协议基本格式如下所示。
三.配置一个BOOT工程
本实验配置一个包含跳转的程序工程,包含FLASH写入以及Y-Modem协议。
如下图所示,打开STM32CubeMX软件,新建工程。
如下图所示,Part Number处输入STM32G474RE,再双击就创建新的工程。
如下图所示,配置下载口引脚,PA13为SWD的SWDIO脚,PA14为SWD的SWCLK脚。
如下图所示,配置USART1,PA9,PA10为串口通讯引脚,波特率115200bps。
如下图所示,配置外部8M晶振。
如下图所示,配置系统主频170Mhz,使用外部8MHZ晶振。
配置工程文件名,保存路径,KEIL5工程输出方式,生成工程。
添加代码
定义应用程序起始地址,就是升级代码刷写的地址。
修改ymodem协议中的串口收发函数。
确认ymodem协议中的FLASH擦除与写入驱动代码。
定义BOOT代码地址空间为0x08000000~0x08004000。
确认应用程序的跳转
主要代码如下:
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();//SysTick配置成1ms中断/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();//8M外部晶振,170M主频,串口通讯最好用外部晶振,内部晶振精度不够/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_USART1_UART_Init();//115200波特率,8位数据,1位停止,无校验/* USER CODE BEGIN 2 *//* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */Main_Menu();//实现程序升级并跳转,Ymodem协议}/* USER CODE END 3 */
}
void SerialDownload(void)
{int32_t Size = 0;Size = Ymodem_Receive(&tab_1024[0]);if (Size > 0){SerialPutString("\r\n Programming Completed Successfully!\r\n ");HAL_Delay(10);SerialPutString("----------Jump To App-------------\r\n");JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);//定义跳转地址是0x08004000JumpToApplication = (pFunction) JumpAddress;/* Initialize user application's Stack Pointer */__set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);JumpToApplication();//跳转到应用程序}else if (Size == -1){SerialPutString("\n\n\rThe image size is higher than the allowed space memory!\n\r");}else if (Size == -2){SerialPutString("\n\n\rVerification failed!\n\r");}else if (Size == -3){SerialPutString("\r\n\nAborted by user.\n\r");}else{SerialPutString("\n\rFailed to receive the file!\n\r");}
}
四.配置一个APP工程
如下图所示,打开STM32CubeMX软件,新建工程。
如下图所示,Part Number处输入STM32G474RE,再双击就创建新的工程。
如下图所示,配置下载口引脚,PA13为SWD的SWDIO脚,PA14为SWD的SWCLK脚。
如下图所示,配置PC8为输出。
如下图所示,配置外部8M晶振。
如下图所示,配置系统主频170Mhz,使用外部8MHZ晶振。
配置工程文件名,保存路径,KEIL5工程输出方式,生成工程。
配置应用程序起始地址为0x08004000。
生成.bin文件配置,配置完,编译的时候就会生成G474.bin文件。
中断向量表偏移配置
主要代码如下:
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();//SysTick配置成1ms中断/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();//外部8M晶振,170M系统主频/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();//PC8配置成输出/* USER CODE BEGIN 2 *//* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */HAL_Delay(100);//等待100ms,基于SysTick的延时HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_8);//PC8引脚翻转输出}/* USER CODE END 3 */
}
五.IAP实验操作
BOOT程序:主要实现YMODEM协议以及内部FLASH编程,程序烧录完之后,由APP程序生成的G474.bin文件烧录到APP程序的FLASH地址空间,再实现程序跳转。
接线:
通过杜邦线把板子与USB转TTL模块相连,板子的PA9,PA10,GND分别与USB 转 TTL 的 RXD,TXD,GND 相连,USB转TTL模块的USB口接电脑。
实验过程:
1.Keil5打开BOOT工程,编译,并用STLINK烧录BOOT程序。
2.Keil5打开APP程序,编译,生成G474.bin文件,文件在工程G474目录下。
3. 打开超级终端软件,配置好串口参数,115200波特率,无校验,硬件流控制选择无,COM口号是根据电脑自动识别,再点确认,完成超级终端打开。
4.选择YMODEM传输,选择G474.bin文件。
5.板子重新上电,会有很多C符号提示,当C符号提示一出来后,点击“发送”,如下图所示。
6.选择文件传输后,进度条会有进度,而且最终屏幕显示Successfully,说明IAP升级成功,板子LED灯闪烁。
六.小结
在单片机应用中,在线升级功能是必不可少的,它可以让我们在不破坏硬件的情况下对程序进行升级和修正,提高了开发效率。