STM32F407串口IAP远程升级程序

您所在的位置:网站首页 fa远程更新代码 STM32F407串口IAP远程升级程序

STM32F407串口IAP远程升级程序

2024-07-12 15:29| 来源: 网络整理| 查看: 265

相关代码和工程文件链接:https://pan.baidu.com/s/1wN4THWJwqzjjIe7e2TENBA?pwd=o86o 提取码:o86o

目录 1 STM32代码烧录方式2 IAP介绍3 Flash地址划分4 中断向量表设置5 关键代码6 实验7 生成bin文件

1 STM32代码烧录方式

        STM32代码烧录主要有三种:ICP、ISP、IAP。         ICP(In Circuit Programing),在电路编程,通过JTAG或者SWD接口进行程序的烧录,就是平时利用ST-Link或者J-Link烧录程序;         ISP(In System Programing),在系统编程,借助MCU厂家预置的BootLoader,然后通过UART、232、CAN等接口进行下载,这个BootLoader程序是厂家已经设置在内部存储区间里面的,无法修改;         IAP( In Application Programming)是用户自己的BootLoader程序在运行过程中对Flash的部分区域进行烧写。

2 IAP介绍

        在产品研发阶段,可以采用ICP烧录程序,能通过仿真器进行调试快速找出bug,但是需要相关硬件电路,如图1所示。在产品研发完成后,由于JTAG相关的电路会占用单板上的体积,所以一般会把这部分电路给删去,删去之后就无法使用仿真器进行程序更新和调试。         

图1 JTAG电路

                 烧录的程序存放在Flash中,STM32程序启动或复位时,起始地址是0x08000000,然后按既定顺序依次运行程序,如图2所示。ICP就是将程序烧录到Flash中,以STM32F407ZGT6为例,片内Flash地址映射范围是从0x08000000开始到0x08100000的1M bytes空间。如果要更改程序烧录的地址,可以在Keil->Options->Target中更改烧录位置,如图3所示。         

在这里插入图片描述

图2 STM32程序运行顺序         

在这里插入图片描述

图3 查看片内Flash大小与地址范围         

在这里插入图片描述

图4 修改程序烧写地址          3 Flash地址划分

        如果有一个引导程序,在运行的时候,能接收UART传过来的数据,然后写到Flash中指定的区域,再更改程序的启动地址,这样就可以完成在线升级,不再需要仿真器。这个引导程序就是BootLoader,通过UART烧写的程序就是用户的应用程序,这就是IAP方式烧录程序。         把0x08000000-0x08100000分为两个部分,一部分存放BootLoader程序,另一部分存放应用程序,例如,0x08000000-0x08010000,64K bytes存放BootLoader,0x08010000-0x08100000,960K bytes存放应用程序。具体如何划分空间,可以先编译一下BootLoader程序,查看生成的 .map 文件就能知道这部分程序占用多少空间,然后再进行分配,如果超过了划分的空间,则会报错。如图5所示,这个程序就占用了0x1924,6436 bytes空间,设置BootLoader程序在Flash中范围的时候就必须比6436大。 在这里插入图片描述

图5 BootLoader程序大小         

        根据以上讲解,我们可以大体知道IAP在线升级的大致流程,在STM32的Flash中,存储空间被划分为了两部分,一部分存放BootLoader引导程序,一部分存放应用程序,这也意味这会有两个main函数。STM32启动时,从0x08000000开始运行BootLoader程序,进入BootLoader的main函数,如果此时接收到串口传来的应用程序的二进制文件,就会向Flash中存放应用程序的空间写入数据,等数据接收并写入完成后,让MSP指针指向应用程序开始运行的地址,这样程序就从设定的应用程序的起始地址开始运行,例如上面假设的起始地址为0x08010000,MSP指针指向这个地址后就开始运行应用程序。

4 中断向量表设置

        发生复位或者产生中断时,MSP会重新指向0x08000000,会根据中断向量表找到相应的中断服务程序入口。中断向量表的设置是在程序最开始的阶段初始化,在运行BootLoader程序时会初始化一次,在运行应用程序时,又会初始化一次;存放BootLoader程序的起始地址是0x08000000,这和Flash起始地址相同,所以中断向量表的偏移地址为0,但是应用程序的起始地址为0x08010000,如果不改变中断向量表的偏移地址,取出的中断服务程序入口地址就是BootLoader中的入口地址,造成程序无法正常运行,所以就需要重新设置中断向量表的偏移地址为0x10000(必须为0x200的整数倍,STM32F407一共有92个中断,占用的地址需要进行对齐补充到128个,每个中断占用4个字节,所以就是512,即0x200,例如,最后一个中断FPU的偏移地址为0x184,就需要对齐到0x200,具体可以查看中断向量表,,如图6所示)。

#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field. This value must be a multiple of 0x200. */

        

在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

在这里插入图片描述

图6 STM32F407中断向量表         

        在system_stm32f4xx.c文件中, VECT_TAB_OFFSET就是设置中断向量表偏移地址的一个宏定义,然后在初始化中断向量表的时候写入寄存器SCB->VTOR中。设置偏移地址时,就可以直接改变宏定义的值;也可以不改变系统文件,直接在用户程序的某个地方直接改变寄存器的值。

/* Configure the Vector Table location add offset address ------------------*/ #ifdef VECT_TAB_SRAM SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ #else SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ #endif SCB->VTOR = FLASH_BASE | 0x10000;//修改中断向量表偏移地址 5 关键代码

        代码参考了正点原子IAP实验,这里只放出部分代码,详细请查看项目文件。         先定义用于接收串口数据的数组USART_RX_BUF,然后指定起始地址为0x20001000(将这个数组存放在片内RAM区域)

#define USART_REC_LEN 120*1024 //数组大小120K u8 USART_RX_BUF[USART_REC_LEN] __attribute__ ((at(0X20001000)));//指定起始地址为0X20001000.

        这个if语句主要是用于简单地判断地址是否合法,用户应用程序会存放在0x08010000-0x08100000这个范围内,FLASH_APP1_ADDR为0x08010000,是用户程序的起始地址,0x08010004是复位中断向量,存放着复位中断服务函数的入口地址,USART_RX_BUF则是用来缓冲应用程序的二进制数据,0X20001000+4这个地址就是存放的用户程序的复位中断服务函数的入口地址,进行一个按位与运算,判断是否为0x08xxxxxx。如果是0x08xxxxxx,则会向Flash写入数据,applenth是用户数据长度,用于计算程序会占用多少内存空间,依次向Flash写入。

if(((*(vu32*)(0X20001000+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX. { printf("%x \r\n",(*(vu32*)(0X20001000+4))); //打印这个地址的值 iap_write_appbin(FLASH_APP1_ADDR,USART_RX_BUF,applenth);//更新Flash代码 printf("用户程序更新完成\r\n"); } //appxaddr:用户程序起始地址 //appbuf:应用程序 //appsize:应用程序大小(字节) void iap_write_appbin(u32 appxaddr,u8 *appbuf,u32 appsize) { u32 t; u16 i=0; u32 temp; u32 fwaddr=appxaddr;//当前写入地址 u8 *dfu=appbuf; for(t=0;t


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3