STM32 IAP Ymodem

STM32 IAP采用Ymodem协议升级固件

公司最近软件需要通过IAP来升级所有板卡的固件,其中板卡有2块,一块主控板卡,一块子控板卡。其中,主控板卡与子控板卡之间采用RS485通信,PC与主控板卡采用RS232通信。

具体框架:
在这里插入图片描述

一、PC端与主控板卡

首先,PC端与主控板卡之间的升级采用常规的 Ymodem 协议传输,IAP 升级。可以参考ST官方的IAP工程
另外安福莱硬汉哥进行了整理可具体可参考 STM32-V5开发板串口IAP操作说明

1.工作流程:

这里,使用的STM32的型号为STM32F407ZET6 ,其FLASH大小是512KB,0x08000000为其FLASH被映射的地址,程序被烧写到的就是这个地址。此处,我们的IAP程序烧写到这个地址,根据IAP程序的大小,我们在keil里可以设置合适的IAP结束地址。
在这里插入图片描述

2. 工程说明:

本项目用到的两个工程可按照文末的方式获取,其中IAP工程移植至ST官方例程。下面对两个工程进行简单的说明

IAP工程:
(1)需要在target选项卡里设置我们IAP程序的起始地址与大小,如:
在这里插入图片描述
这里我们的IAP程序起始地址设为0x08000000,大小设为0x4000,即IAP所能用的FLASH空间为16KB。其中IAP所能占的占空间的大小可根据IAP的实际大小进行修改。

(2)需要修改程序中我们需要跳转到的应用程序的地址(即IAP程序的结束地址):
在这里插入图片描述
APP工程:
(1)需要在target选项卡里设置我们LED程序的起始地址与大小,如:在这里插入图片描述
这里我们的APP程序起地址设为0x08004000,大小设为0x7C000,即APP所能用的FLASH空间为496KB(总容量为512K,IAP占用16K)。其中结束地址可根据APP应用程序的实际大小进行修改。

(2). 设置中断向量表的偏移(依据实际情况设置)
在这里插入图片描述
(3). bin文件生成。
在这里插入图片描述

3.IAP软件流程

在这里插入图片描述
代码:

while (1)
	{
        if(!Check_App_Flag())
        {
            SerialDownload();
        }
        else if (RTC_ReadBackupRegister(RTC_BKP_DR0) == UPDATA_APP)
        {
            updata_fpga_flag = RTC_ReadBackupRegister(RTC_BKP_DR0);
            RTC_WriteBackupRegister(RTC_BKP_DR0,0);
            SerialDownload();
        }
        else if (RTC_ReadBackupRegister(RTC_BKP_DR0) == UPDATA_FPGA)
        {
            updata_fpga_flag = RTC_ReadBackupRegister(RTC_BKP_DR0);
            RTC_WriteBackupRegister(RTC_BKP_DR0,0);
            SerialDownload();
        }
        else if (RTC_ReadBackupRegister(RTC_BKP_DR0) == UPDATA_DRIVER)
        {
            updata_fpga_flag = RTC_ReadBackupRegister(RTC_BKP_DR0);
            RTC_WriteBackupRegister(RTC_BKP_DR0,0);
            printf("\r\nUpdata Driver open USART_IT_RXNE and USART_IT_IDLE\n\r");
			
			USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);/* 使能接收完成中断 */
			USART_ITConfig(USART1,USART_IT_IDLE,ENABLE); //开启串口空闲中断
			
            while (1)
            {
				//判断数据是否进入驱动板APP
				if(g_ucDriverUpdataSuccess == 1)
				{
					printf("exit yi ci \r\n");
					break;
				}  
				LED4_Out() = 1;
				delay_ms(500);
				LED4_Out() = 0;
				delay_ms(500);
            }
			USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);/* 关闭接收完成中断 */
			USART_ITConfig(USART1,USART_IT_IDLE,DISABLE); //关闭串口空闲中断
			
			USART_ITConfig(RS485_USART, USART_IT_TC, DISABLE);
			USART_ITConfig(RS485_USART, USART_IT_RXNE, DISABLE);
        }
        else
        {
            printf("\r\nLoad APP");
            Iap_Load_App(APPLICATION_ADDRESS);
        }
	}

其中判断校验位置处是否有APP应用程序,采用 flash 地址的最后4个字节作为校验位,正常烧录正确以后,在 flash 地址的最后4个字节处写入 0x5A5A。
在这里插入图片描述
然后开机的时候 首先读取该地址处的校验位是否正确,不正确,则表示上一次烧录错误,需要重新升级。正确则判断是否有升级标志。
在这里插入图片描述

这里的升级标志采用“备份域寄存器”中读取数据。“备份域寄存器”是 可以用于存储掉电不丢失的数据(需要RTC纽扣电池支持)。当我们从APP中接收到需要升级APP的指令,这个时候,我们往“备份域寄存器”中写入 0x5050 表示需要升级APP。如果是接收到升级FPGA的指令,则写入0x7070。然后执行软件复位操作,从APP跳转IAP。IAP中判断“备份域寄存器”的值,然后执行响应的升级操作。
-------------------------------------------------------------------------------------------------------------------------------------------

二、PC端与子控制板卡

pc端升级子控板卡有2种方案:

  • Ymodem协议校验发生在PC端与子控板卡,这个时候,主控板卡指示做一个数据的转发,说白了:串口1从PC端接收到了什么数据,就通过串口2发生出去给子控制板。串口2从子控制板中接收到什么数据,就从串口1发送给PC端。
  • Ymodem协议校验发生在PC端与主控板卡。主控板卡接收到正确的一帧数据后,启动485 发送给子控板卡。子控板卡接收以后直接写入flash。

方案一:
我们先来说说第一种情况,具体框图如下:
在这里插入图片描述
这里有一个点需要注意的地方就是,主控板卡与子控板卡通信是采用485通信,因此需要严格的控制 RS485_EN 使能引脚的时序。否则会导致数据发送错误。
目前,我采用的方案是通过开启几个中断来控制 RS485_En 使能引脚的时序,
开启主控板卡串口1 的接收完成中断,和串口1的空闲中断。
在这里插入图片描述
开启子控制板卡的接收完成中断,和发送完成中断。
在这里插入图片描述
主控板卡中,串口1接收到一个字节后,进入中断,使能RS485_En引脚,控制发送,将数据转发给串口2发送出去,并且清零标志。
当检测到串口空闲中断后,485数据发送完成标志置1。
在这里插入图片描述

在子控制板卡中,发送完成中断用来将 RS485_En 使能切换为接收模式。其中,前提是需要判断接收完成标志是否置一。
子控制板的接收完成中断,是用来判断,子控制板是否烧录完成进入 APP。进入APP以后,会发送指令“$Load Driver”。
主控板接收到指令后,标志置一。跳出IAP 。进入APP。
在这里插入图片描述
经过测试,第一种方案可行。并且稳定性还可以,协议发生需要写入的控制板卡中,这样不容易出现数据丢失的问题。

方案二:
Ymodem 协议传输校验发生在PC端与控制板卡之间,校验通过后,将解析出的一帧数据包,通过启动485发生给子控制板卡,子控制板卡接收后,写入flash。

这种方案的好处是,控制板卡 与 子控制板卡之间没有校验,因此可以同时烧录多个子控制板卡。

发布了61 篇原创文章 · 获赞 89 · 访问量 20万+

猜你喜欢

转载自blog.csdn.net/qq_33559992/article/details/103027196