使用STM32F103的串口实现IAP程序升级功能

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

使用STM32F103的串口实现IAP程序升级功能


  • 🎬IAP程序烧录全过程演示:
    使用STM32F103的串口实现IAP程序升级功能
✨这几天折腾IAP升级功能,狂补了很多相关BootLoader相关的知识。本来最想实现IAP升级程序的方式是,基于SPI通讯的SD卡,借助挂载的FatFS文件系统,来实现对目标stm32芯片的自身程序的升级,奈何没有实现,只能求其次,先来通过官方现有的串口实现IAP程序升级功能的学习作为跳板。加深对flash读写操作流程的熟悉。
  • 🔧支持串口Ymodem传输协议的工具推荐:SecureCRT(建议安装9.0以下的,有和谐版本的,当然如果支持作者可以付费购买此工具使用)
  • 📍ST官方相关应用文档:文件编号:AN2557 《使用STM32F10xxx的USART实现在应用中编程》:https://www.st.com/resource/en/application_note/cd00161640-stm32f10x-in-application-programming-using-the-usart-stmicroelectronics.pdf
  • 🌿论坛下载地址https://www.stmcu.com.cn/Designresource/detail/document/705747
  • 📍ST官方相对应的示例程序包:https://www.st.com/content/st_com/en/search.html#q=AN2557-t=tools-page=1
    使用STM32F103的串口实现IAP程序升级功能
  • 🌿📖相关文档阅读推荐:《STM32 MCU IAP例程跳转到APP代码简要分析》

📓BootLoader相关知识

  • 🌿系统在上电或复位时通常都CPU是从地址0x00000000处开始执行,ARM内核把0x00000000地址上的存储单元映射到了新的地址0x08000000上。CPU存取0x08000000就是存取0x00000000上的物理存储单元。而在这个地址处安排的通常就是系统的BootLoader程序。
    使用STM32F103的串口实现IAP程序升级功能
  • 🌿程序所占空间大小

🔖在每个工程通过编译后所产生的.map文件中可以找到相关的信息:

==============================================================================


Memory Map of the image

  Image Entry point : 0x08000131

  Load Region LR_IROM1 (Base: 0x08000000, Size: 0x00001cac, Max: 0x00040000, ABSOLUTE)

    Execution Region ER_IROM1 (Exec base: 0x08000000, Load base: 0x08000000, Size: 0x00001c28, Max: 0x00040000, ABSOLUTE)

    Exec Addr    Load Addr    Size         Type   Attr      Idx    E Section Name        Object

    0x08000000   0x08000000   0x00000130   Data   RO         1821    RESET               startup_stm32f10x_hd.o
    0x08000130   0x08000130   0x00000000   Code   RO         1826  * .ARM.Collect$$$$00000000  mc_w.l(entry.o)
    0x08000130   0x08000130   0x00000004   Code   RO         1833    .ARM.Collect$$$$00000001  mc_w.l(entry2.o)
    0x08000134   0x08000134   0x00000004   Code   RO         1836    .ARM.Collect$$$$00000004  mc_w.l(entry5.o)
    0x08000138   0x08000138   0x00000000   Code   RO         1838    .ARM.Collect$$$$00000008  mc_w.l(entry7b.o)
    0x08000138   0x08000138   0x00000000   Code   RO         1840    .ARM.Collect$$$$0000000A  mc_w.l(entry8b.o)
    0x08000138   0x08000138   0x00000008   Code   RO         1841    .ARM.Collect$$$$0000000B  mc_w.l(entry9a.o)
    0x08000140   0x08000140   0x00000000   Code   RO         1843    .ARM.Collect$$$$0000000D  mc_w.l(entry10a.o)
    0x08000140   0x08000140   0x00000000   Code   RO         1845    .ARM.Collect$$$$0000000F  mc_w.l(entry11a.o)
    0x08000140   0x08000140   0x00000004   Code   RO         1834    .ARM.Collect$$$$00002712  mc_w.l(entry2.o)
  • 其中Load Region LR_IROM1 (Base: 0x08000000, Size: 0x00001cac, Max: 0x00040000, ABSOLUTE)描述了程序所占起始位置,以及空间。

  • ⚡要实现IAP功能,不仅需要原目标芯片里面的程序做好程序运行地址部署,还要在带准备升级的程序地址上,做好相对应的匹配才行。

  • 🌿已经写入程序的目标芯片,复位后,在从主闪存存储器启动模式下,程序都是地址:0x08000000开始运行。

使用STM32F103的串口实现IAP程序升级功能

  • 🌿IAP升级程序中,需要重新映射的偏移地址以及中断向量表。
    使用STM32F103的串口实现IAP程序升级功能
    使用STM32F103的串口实现IAP程序升级功能

🛠程序配置

  • 🌿对stm32目标芯片使用ST-linkV2烧录程序时,烧录地址时默认:0x8000000

使用STM32F103的串口实现IAP程序升级功能

  • 🌿对stm32目标芯片IAP升级程序:需要调用ASF转BIN文件指令,用于通过串口给目标芯片升级使用的程序文件。(当然这个程序可以是上面的原始工程,修改程序后(修改程序运行的起始地址,以及程序代码中重映射中断向量表偏移地址),生成BIN文件。来作为IAP升级文件,这里使用的是另外一个示例工程生成的IAP升级文件)
    使用STM32F103的串口实现IAP程序升级功能
    • 👉🏻调用asf转BIN文件指令:(需要指定fromelf.exe程序的绝对路径,根据个人安装Keil目录而定)
C:\Keil_v5\ARM\ARMCC\bin\fromelf.exe  --bin -o  ./STM32100E-EVAL/test.bin  ./STM32100E-EVAL/test.axf

使用STM32F103的串口实现IAP程序升级功能
使用STM32F103的串口实现IAP程序升级功能

⛳IAP升级和SecureCRT使用

  • 🔨SecureCRT配置串口以及参数:
    使用STM32F103的串口实现IAP程序升级功能

使用STM32F103的串口实现IAP程序升级功能

  • 📐Ymodem协议模式配置:
    使用STM32F103的串口实现IAP程序升级功能
    使用STM32F103的串口实现IAP程序升级功能

  • 🏳‍🌈本例程烧录原始程序后,如需进入IAP升级界面,需要在硬件复位的时候,按住PB9按键让其下拉到GND,原始程序时复位后,检测PB9如果是低电平,则进入IAP升级模式。

    • 🍁没有进入升级模式下,打印信息就是跑的主循环while中的代码。
      使用STM32F103的串口实现IAP程序升级功能
    • 🍁复位后,检测PB9如果是低电平,则进入IAP升级模式:
      使用STM32F103的串口实现IAP程序升级功能
  • 在进入IAP模式后,输入数字1,则进入等待上传升级文件模式:

  • 使用STM32F103的串口实现IAP程序升级功能

  • 🌿在SecureCRT界面菜单上找到Tranfer菜单下的Send Ymodem,进行BIN文件的上传。
    使用STM32F103的串口实现IAP程序升级功能

  • 🌿BIN文件上传成功后,打印信息:
    使用STM32F103的串口实现IAP程序升级功能

  • 🌿输入字符C,将程序跳转到新的目标程序地址。

  • 🌿到此已完成对芯片的IAP升级。文章来源地址https://www.toymoban.com/news/detail-499185.html

📝IAP main主程序

/**
  ******************************************************************************
  * @file    IAP/src/main.c
  * @author  MCD Application Team
  * @version V3.3.0
  * @date    10/15/2010
  * @brief   Main program body
  ******************************************************************************
  * @copy
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * <h2><center>&copy; COPYRIGHT 2010 STMicroelectronics</center></h2>
  */

/** @addtogroup IAP
  * @{
  */

/* Includes ------------------------------------------------------------------*/
#include "common.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
extern pFunction Jump_To_Application;
extern uint32_t JumpAddress;

static u8  fac_us=0;							//us延时倍乘数			   
static u16 fac_ms=0;							//ms延时倍乘数,在ucos下,代表每个节拍的ms数
/* Private function prototypes -----------------------------------------------*/
static void IAP_Init(void);
void delay_init(u8 SYSCLK);//延时初始化函数
void delay_us(u32 nus);//微秒延时
void delay_ms(u16 nms);//毫秒延时
/* Private functions ---------------------------------------------------------*/
void delay_init(u8 SYSCLK)
{
 	SysTick->CTRL&=~(1<<2);					//SYSTICK使用外部时钟源	 
	fac_us=SYSCLK/8;						//不论是否使用OS,fac_us都需要使用
	fac_ms=(u16)fac_us*1000;				//非OS下,代表每个ms需要的systick时钟数   
}	

//延时nus
//nus为要延时的us数.		    								   
void delay_us(u32 nus)
{		
	u32 temp;	    	 
	SysTick->LOAD=nus*fac_us; 				//时间加载	  		 
	SysTick->VAL=0x00;        				//清空计数器
	SysTick->CTRL=0x01 ;      				//开始倒数 	 
	do
	{
		temp=SysTick->CTRL;
	}while((temp&0x01)&&!(temp&(1<<16)));	//等待时间到达   
	SysTick->CTRL=0x00;      	 			//关闭计数器
	SysTick->VAL =0X00;       				//清空计数器	 
}
//延时nms
//注意nms的范围
//SysTick->LOAD为24位寄存器,所以,最大延时为:
//nms<=0xffffff*8*1000/SYSCLK
//SYSCLK单位为Hz,nms单位为ms
//对72M条件下,nms<=1864 
void delay_ms(u16 nms)
{	 		  	  
	u32 temp;		   
	SysTick->LOAD=(u32)nms*fac_ms;			//时间加载(SysTick->LOAD为24bit)
	SysTick->VAL =0x00;           			//清空计数器
	SysTick->CTRL=0x01 ;          			//开始倒数  
	do
	{
		temp=SysTick->CTRL;
	}while((temp&0x01)&&!(temp&(1<<16)));	//等待时间到达   
	SysTick->CTRL=0x00;      	 			//关闭计数器
	SysTick->VAL =0X00;       				//清空计数器	  	    
} 
/**
  * @brief  Main program.
  * @param  None
  * @retval None
  */
int main(void)
{
    /* Flash unlock */
    FLASH_Unlock();

    /* Initialize Key Button mounted on STM3210X-EVAL board */
    STM_EVAL_PBInit(BUTTON_KEY, BUTTON_MODE_GPIO);
//    STM_EVAL_LEDInit(LED1);	//PC6
//    STM_EVAL_LEDInit(LED2);	//PC7
//    STM_EVAL_LEDInit(LED3);	//PC8
    STM_EVAL_LEDInit(LED4);  //PC9
		delay_init(72);		//延时初始化
    IAP_Init();	//这里其实做的就是对串口1进行初始化
    SerialPutString("Hello world \r\n");
    /* Test if Key push-button on STM3210X-EVAL Board is pressed PB7*/
    if(STM_EVAL_PBGetState(BUTTON_KEY)  == 0x00)	//GPIOB --> PB9
    {
        /* If Key is pressed */
        /* Execute the IAP driver in order to re-program the Flash */
//    IAP_Init();
        SerialPutString("\r\n======================================================================");
        SerialPutString("\r\n=              (C) COPYRIGHT 2010 STMicroelectronics                 =");
        SerialPutString("\r\n=                                                                    =");
        SerialPutString("\r\n=     In-Application Programming Application  (Version 3.3.0)        =");
        SerialPutString("\r\n=                                                                    =");
        SerialPutString("\r\n=                                   By MCD Application Team          =");
        SerialPutString("\r\n======================================================================");
        SerialPutString("\r\n\r\n");
        Main_Menu();
    }
    /* Keep the user application running */
    else
    {
        /* Test if user code is programmed starting from address "ApplicationAddress" */
      if(((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000) == 0x20000000)//检查栈顶地址是否合法.
				{
            /* Jump to user application */
            JumpAddress = *(__IO uint32_t*)(ApplicationAddress + 4);//用户代码区第二个字为程序开始地址(复位地址)	
            Jump_To_Application = (pFunction) JumpAddress;
            /* Initialize user application's Stack Pointer */
            __set_MSP(*(__IO uint32_t*) ApplicationAddress);//初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
            Jump_To_Application();//跳转到APP.
					
        }
    }
		
    while(1)
    {

    delay_ms(500);
		SerialPutString("IAP main test!\r\n");
		STM_EVAL_LEDToggle(LED4);

    }
}

/**
  * @brief  Initialize the IAP: Configure RCC, USART and GPIOs.
  * @param  None
  * @retval None
  */
void IAP_Init(void)
{
    USART_InitTypeDef USART_InitStructure;

    /* USART resources configuration (Clock, GPIO pins and USART registers) ----*/
    /* USART configured as follow:
          - BaudRate = 115200 baud
          - Word Length = 8 Bits
          - One Stop Bit
          - No parity
          - Hardware flow control disabled (RTS and CTS signals)
          - Receive and transmit enabled
    */
    USART_InitStructure.USART_BaudRate = 115200;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

    STM_EVAL_COMInit(COM1, &USART_InitStructure);
}

#ifdef USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{
    /* User can add his own implementation to report the file name and line number,
       ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

    /* Infinite loop */
    while(1)
    {
    }
}
#endif

/**
  * @}
  */

/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

📚程序源码

链接:https://pan.baidu.com/s/1bw2gjSS6_Vq48_PtkxakLQ 
提取码:298k

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

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

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

相关文章

  • 使用串口烧写程序到STM32F103C8T6最小板(CH340)

    商家没给ST‐LINK V2下载器,故使用串口将程序烧录到最小板,使用仿真软件Flymcu进行。(默认安装过CH340的驱动) 联机下载时的程序文件:编译生成的.hex文件; 编程前重装文件:当选中该项后,flymcu会在每次编程之前将Hex文件重新装载一遍,这对于代码调试的时候比较有用

    2024年02月01日
    浏览(50)
  • 【STM32】STM32F103ZET6程序下载(串口方式)

    STM32 的程序下载有多种方法:USB、串口、JTAG、SWD 等,这几种方式,都可以用来给 STM32 下载代码。不过,我们最常用的,最经济的,就是通过串口给 STM32 下载代码。我们将向大家介绍,如何利用串口给 STM32 下载代码。 STM32 的串口下载一般是通过串口 1 下载的,STM32开发板,

    2024年02月04日
    浏览(55)
  • 【STM32】STM32F103C8T6串口通信,实现3个串口收发数据

    串口通信(Serial Communications)实现单片机与电脑或者其它外设进行通信,通信时只需两根线(TX,RX)就可以实现数据传输。STM32f103有三个串口,分别为串口1(RX PA10, TX PA 9),串口2(RX PA3,TX PA2),串口3(RX PB11,TX PB10)。 以下代码是配置三个串口: usart.c usart.h main.c 注意,

    2024年02月12日
    浏览(48)
  • [嵌入式软件][启蒙篇][仿真平台] STM32F103实现串口输出输入、ADC采集

    上一篇:[嵌入式软件][启蒙篇][仿真平台] STM32F103实现LED、按键 学C语言时,使用的printf()函数,就是通过串口打印出来的。 跟外部器件通信,比如GPS模块、蓝牙模块、wifi模块; 两个开发板之间通信,制定私有协议。 PC电脑通信,使用上位机显示数据或控制下位机。 操作:打

    2024年01月22日
    浏览(65)
  • stm32f103与openmv串口通信

    串口通信是指通过串行通信接口进行数据传输的一种通信方式。在串口通信中,数据被分成一个个的字节,按照一定的顺序依次发送和接收。串口通信通常使用UART(通用异步收发传输)协议进行数据传输。 串口通信在嵌入式系统中应用非常广泛,其主要用途包括: 调试和监

    2024年02月13日
    浏览(48)
  • gd32f103vbt6 串口OTA升级5-combin部分

    本文主要是bin文件的组成进行一些简单介绍,方便理解升级的过程。 2.1 rk3399cpu+gd32f103 2.2 连接方式:串口(115200,8N1)或者iic(本文没有介绍iic) 3.1 单片机端分两个部分:iap(用于升级)和app(自己的应用)部分(这两个部分本文不做介绍)。 3.2 linux端做一个升级的app软件

    2024年02月16日
    浏览(55)
  • 野火指南者(STM32F103VET6)应用:实现USB虚拟串口(CDC_VPC)

    MCU:STM32F103VET6 开发环境:STM32CubeMX+MDK5   实现USB的虚拟串口不需要去理解USB的底层驱动,只需要STM32CubeMX去配置生成工程即可。在野火的指南者中,是没有这一类的视频和示例的,博主使用这款开发板实现USB虚拟串口。 首先需要打开STM32CubeMX工具。输入开发板MCU对应型号,找

    2024年02月08日
    浏览(43)
  • gd32f103vbt6 串口OTA升级3-linux端的部分

    本文主要是对linux端升级单片机程序的功能部分做一些介绍,包括一些软件流程。 2.1 rk3399cpu+gd32f103 2.2 连接方式:串口(115200,8N1)或者iic(本文没有介绍iic) 3.4.1  0 ~(0x5c00-1) : iap程序区,用于存放iap程序 3.4.2  0x5c00~(0x6000-1) : 这个1k用于存放一些标志位,以及程序的

    2024年02月17日
    浏览(67)
  • 基于STM32F103——AS608指纹模块+串口打印

    最近用STM32F103做一个智能门锁小玩意,其中用到指纹模块,我这里也单独的写一下笔记,不过我只是了解了基本的,就是我做门禁卡要用到的几个东西,其它还没了解。为了方便,做一下记录。我这里没有用到按键和显示屏,所以还是串口输出输入来控制了 哈哈哈哈 这里就

    2023年04月09日
    浏览(45)
  • STM32F103C8T6串口通信

      首先来看一下需要操作的函数,以及配置的步骤: 图1                                                  图2   Code: usart.c #include \\\"usart.h\\\" void ustart_Init(void ) { GPIO_InitTypeDef GPIO_Init_Ustar ; // 定义输出端口TX的结构体对象 USART_InitTypeDef USTART_Init; // 定义串口初始化结构体对象

    2024年02月16日
    浏览(50)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包