STM32F407串口IAP远程升级程序

这篇具有很好参考价值的文章主要介绍了STM32F407串口IAP远程升级程序。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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


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相关的电路会占用单板上的体积,所以一般会把这部分电路给删去,删去之后就无法使用仿真器进行程序更新和调试。
        
STM32F407串口IAP远程升级程序

图1 JTAG电路

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

STM32F407串口IAP远程升级程序

图2 STM32程序运行顺序
        

STM32F407串口IAP远程升级程序

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

STM32F407串口IAP远程升级程序

图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大。
STM32F407串口IAP远程升级程序

图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. */
                                   

        

STM32F407串口IAP远程升级程序
STM32F407串口IAP远程升级程序
STM32F407串口IAP远程升级程序

STM32F407串口IAP远程升级程序

图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<appsize;t+=4)
	{						   
		temp=(u32)dfu[3]<<24;   
		temp|=(u32)dfu[2]<<16;    
		temp|=(u32)dfu[1]<<8;
		temp|=(u32)dfu[0];	  
		dfu+=4;//偏移四个地址
		iapbuf[i++]=temp;	    
		if(i==512)
		{
			i=0; 
			STMFLASH_Write(fwaddr,iapbuf,512);
			fwaddr+=2048;//偏移2048,512*4
		}
	} 
	if(i)STMFLASH_Write(fwaddr,iapbuf,i);//将最后的一些内容字节写进去
}

        同理,这个if语句也是用于简单地判断地址是否合法,FLASH_APP1_ADDR为0x08010000,是用户程序的起始地址,0x08010004是复位中断向量,存放着复位中断服务函数的入口地址,进行一个按位与运算,判断是否为0x08xxxxxx。如果是0x08xxxxxx,则启动用户应用程序。

if(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX.
{	 
	printf("开始执行用户程序\r\n");
	iap_load_app(FLASH_APP1_ADDR);//执行FLash中用户程序
}
//跳转到用户程序段
//appxaddr:用户程序起始地址
void iap_load_app(u32 appxaddr)
{
	if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000)	//检查栈顶地址是否合法
	{ 
		jump2app=(iapfun)*(vu32*)(appxaddr+4);		//用户代码区第二个字为程序开始地址
		MSR_MSP(*(vu32*)appxaddr);					//初始化app堆栈指针(用户代码区的第一个字用于存放栈顶地址)
		jump2app();									//跳转到app
	}
}		 

6 实验

        先向这款STM32F407板子中烧写BootLoader部分程序,然后用micro-usb数据线将板子的串口和电脑连接,打开串口调试助手,可以查看板子打印的信息,如图7所示。
        
STM32F407串口IAP远程升级程序

图6 STM32F407单板

        
        程序运行后10s内发送“yes”进入BootLoader程序,否则直接开始运行用户应用程序。
        
STM32F407串口IAP远程升级程序

图7 BootLoader程序启动打印信息

        
        先发送yes,然后会提示发送应用程序文件,这个时候选择应用程序工程生成的bin文件,用串口助手发送。发送完成后,会显示接收完成,然后开始运行程序。这里写了一个简单的定时器定时LED灯闪烁的程序。
        
STM32F407串口IAP远程升级程序

图8 BootLoader程序启动打印信息

        
        会看见板子上的LED0以100ms的间隔闪烁。
        

STM32F407串口IAP远程升级程序

图9 LED0闪烁
        

        下面是用户程序代码,LED灯闪烁,可以看见设置了偏移地址0x10000,如果不设置这个偏移地址,就无法进入定时器3中断服务函数,LED就不会闪烁。

int main(void)
{ 
 
	delay_init(168);		  //
	LED_Init();		        //
	
	SCB->VTOR = FLASH_BASE | 0x10000;
 	TIM3_Int_Init(1000-1,8400-1);	//100ms   
	
	while(1)
	{
		
	}
}

//定时器3中断服务函数
void TIM3_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) 
	{
		LED0=!LED0;//翻转
	}
	TIM_ClearITPendingBit(TIM3,TIM_IT_Update);  
}

7 生成bin文件

        生成bin文件如图所示,会使用到一个命令

E:\KEIL5\ARM\ARMCC\bin\fromelf.exe --bin -o  ..\OBJ\LED.bin ..\OBJ\LED.axf

        E:\KEIL5\ARM\ARMCC\bin\fromelf.exe改成自己keil目录下的fromelf.exe。
        …\OBJ\LED.bin是将要生成的bin文件的位置。
        …\OBJ\LED.axf是axf文件的位置。
        
STM32F407串口IAP远程升级程序文章来源地址https://www.toymoban.com/news/detail-494871.html

到了这里,关于STM32F407串口IAP远程升级程序的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 串口通信——stm32F407实现串口发送坐标,输出x坐标和y坐标

    通过串口助手发送一个(a,b),需要输出x = a,y = b; 初始化串口; 编写接收数据中断函数; 编写转换函数; 编写main函数。 2.1 初始化串口 2.2 编写接收数据中断函数 2.3 编写转换函数 2.4 main.c函数 如下图所示: 在数据的类型上,x和y的坐标值类型是 int16_t ,就是有正负号

    2024年02月14日
    浏览(45)
  • STM32F1 IAP在线升级功能实现(使用串口)及心得

    公司产品要求,需要做一个能远程升级程序的功能,找了很多例程,大多都是需要按键来完成操作的,而我需要的是通过串口发送指令来完成,于是东拼西凑最后还是用了四天的时间勉强做出来 整个功能需要的程序是两个部分。一个是IAP程序,一个是APP程序。对于IAP程序和

    2024年02月10日
    浏览(59)
  • stm32F407学习DAY.14 在DMA模式下进行USART串口数据收发(正点原子例程为例)

    目录 一、DMA配置 1、DMA1和DMA2的请求映射 2、DMA挂载总线 3、DMA相关库函数 ​4、DMA配置过程(以串口1为例) 1)进行时钟使能 2)等待DMA可配置 3)初始化DMA(串口1的TX为DMA2 数据流7 通道4,RX为DMA2 数据流5 通道4) a.DMA外设地址par: b.DMA存储器0地址mar: c.数据传输量ndtr: 4)

    2024年02月04日
    浏览(49)
  • 从STM32F407到AT32F407(一)

    雅特力公司的MCU有着性能超群,价格优越的巨大优势,缺点是相关资料少一些,我们可以充分利用ST的现有资源来开发它。 我用雅特力的STM32F437开发板,使用原子 stm32f407的开发板自带程序,测试串口程序,原设定串口波特率为115200,但是输出乱码,波特率改成230400,串口输

    2024年02月02日
    浏览(60)
  • 关于STM32F407ZGT6的USB损坏后使用ST-Link和USART1实现串口功能

    开发板:STM32F407ZGT6; 目标:想使用软件“串口调试助手” 情况:开发板上的USB_UART口所在器件损坏或者直接没有;   解决办法:查看该开发板的原理图,可得:串口1的RX接TXD,串口1的TX接RXD,那么按如下步骤操作: 1、现在使用USB转TTL模块,将串口1的RX接USB转TTL模块的TXD,

    2024年02月08日
    浏览(49)
  • 关于STM32F407ZGT6的USB_UART端口损坏后使用ST-Link和USART1实现串口功能

    开发板:STM32F407ZGT6; 目标:想使用软件“串口调试助手” 情况:开发板上的USB_UART口所在器件损坏或者直接没有;   解决办法:查看该开发板的原理图,可得:串口1的RX接TXD,串口1的TX接RXD,那么按如下步骤操作: 1、现在使用USB转TTL模块,将串口1的RX接USB转TTL模块的TXD,

    2024年02月07日
    浏览(51)
  • STM32F407的时钟

    时钟源用来为环形脉冲发生器提供频率稳定且电平匹配的方波时钟脉冲信号。它通常由石英 晶体振荡器和与非门组成的正反馈振荡电路组成,其输出送至环形脉冲发生器。 F4开发指南P107 F4开发指南P108 HSI高速内部时钟源 High Speed Internal。RC 振荡器,频率为 16MHz。可以直接作为

    2024年02月10日
    浏览(55)
  • STM32F407的介绍

    内核 32位 高性能ARM Cortex-M4处理器 时钟: 高达168MHz,实际还可以超频一点点 stm32f407的主频通过PLL倍频后能够达到168MHz,而且芯片内置一个16MHz的晶振和一个32KHz的晶振,可以满足不同功耗的需求。 支持FPU(浮点运算)和DSP指令 144引脚 114个IO口 存储器容量: 1024K FLASH, 192K

    2024年02月10日
    浏览(58)
  • 初识 STM32和STM32F407简介

    2007 年 6 月,ST 在北京发布了全球第一款基于 ARM Cortex M3 内核的 32 位通用微控制 器芯片:STM32F103,以优异的性能,丰富的资源,超高的性价比,迅速占领市场,从此一鸣 惊人,一发不可收拾,截止到 2020 年 6 月,STM32 累计出货量超过 45 亿颗。 战舰开发板使用的 STM32F103ZET6

    2023年04月08日
    浏览(74)
  • STM32F407 移植 FreeRTOS

    本实验是基于正点原子 STM32F407ZG 探索者开发板完成的,所以需要一个STM32F407ZG 探索者开发板 用于移植的基础工程(下面会讲) FreeRTOS源码(下面会讲) 本实验所有用到的代码:基于正点原子STM32F407的FreeRTOS移植工程.zip 1.1 移植前准备 1.1.1 基础工程 由于后续需要用到 LED、

    2024年02月08日
    浏览(70)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包