STM32 ——bootloader IAP

本文使用单片机型号:STM32F104xx

1. IAP 简介

IAP(In Application Programming) 是用户自己的程序在运行过程中对 User Flash 的部分区域进行烧写,目的是为了在产品发布后可以方便地通过预留的通信口对产品中的固件程序进行更新升级。为了实现 IAP 功能,系统将分为 bootloader 和 app 两部分。bootloader 部分实现 app 升级功能和跳转,app 部分实现系统核心功能并能触发升级。

1.1 程序升级流程

  1. 上电后先运行IAP 代码,检查是否需要对APP 部分代码进行更新
  2. 如果需要更新则执行更新程序 / 如果不需要就转到步骤3
  3. 设置系统调度,跳转到用户应用程序运行

1.1.1 程序运行流程原理

  1. IAP、APP 成功烧录到单片机中;
  2. IAP、APP 代码配置正确;
  3. 单片机正常上电;
  4. 运行IAP 程序,检查EEPROM 中指定位置是否为指定标志数据;

如:EEPROM 指定地址为1000 的位置数据是否为0x1B

  1. 是则跳转到IAP 代码,开始烧录/升级APP 代码,代码烧录完成后,EEPROM 中指定位置数据恢复到默认跳转APP 代码的标志数据;
  2. 否则跳转到APP 代码运行;

另外,在运行APP 代码过程中,输入指定指令,可跳转到步骤4(IAP 代码)

1.2 单片机User Flash 代码布局

在这里插入图片描述

1.3 .hex 文件转.bin

在Keil 中下图位置添加代码fromelf.exe --bin -o "$L@L.bin" "#L",编译后,可在.hex 同文件夹下生成.bin 文件;
在这里插入图片描述

2. YModem 协议简介

【点击跳转百度百科】YModem 是⼀种⽂件传输的协议,由XModem协议演变⽽来的,每包数据可以达到1024字节,是⼀个⾮常⾼效的⽂件传输协议。

  • YModem 协议
    1. 起始帧:
      SOH + 00 + FF + filename + filesize + NULL + CRCH + CRCL
      起始帧是⽂件传输发送端发的第⼀条重要消息.
      filename表示传输⽂件的⽂件名.
      filesize表示需要传输⽂件的⼤⼩.
      CRCH + CRCL 表示整条帧(去掉前三个字节)的CRC16校验.
    2. 数据帧格式:
      STX/SOH + [编号] + 编号的反码 + data[0] + data[1] + data[2] + … + CRCH + CRCL
      SOH 表示有128个字节, 有的也只⽤SOH传输数据.
      STX 表示有1024个字节.
      CRCH + CRCL 表示整条帧(去掉前三个字节)的CRC16校验.如果传输最后⼀条字节不⾜128个字节, 则⽤1A填充
    3. 结束帧的数据格式:
      SOH + 00 + FF + NULL + NULL + … + NULL + CRCH + CRCL

使用Ymodem协议可以保证我们的传输数据安全,避免因为丢包等原因导致错误的bin(用户程序)烧录到FLASH,导致单片机运行异常跑飞等等

3. APP 应用程序

3.1 设置APP 的烧录/运行扇区

  1. 在APP 代码初始化前,添加以下代码:
NVIC_SetVectorTable(NVIC_VectTab_FLASH,(0x08003000));
  1. 在Target 设置中,设置对应的扇区位置:
    在这里插入图片描述
  2. 在Debug 设置中,选择擦除扇区:
    在这里插入图片描述

3.2 在APP 中添加跳转IAP 接口

除了3.1 步骤的操作外,在APP 中也需要添加一个跳转到IAP 到接口,以实现在APP 代码运行中进入IAP 代码升级APP 代码的功能;

  1. 在串口通讯函数中,添加跳转指令:
if(strcmp("UPLOAD FIRMWARE",ptr)==0){Get_TO_BootLoader();return;}
#define UPLOAD_FLAG_ADDR  1000
void Get_TO_BootLoader(void)
{
	IIC_24C256_Write_Byte(0XA0,UPLOAD_FLAG_ADDR,4,0X1B); // 在板载EEPROM 指定位置中改变标志数据,使得单片机重启后进入IAP 代码
	printf("0x%X\r\n",IIC_24C256_Read_Byte(0XA0,UPLOAD_FLAG_ADDR,4));	
	printf("MCU Into Upload firmware Pass\r\n@_@");
	soft_reset(); // 单片机重启
}

void soft_reset(void)
{
	//关闭所有中断
	__set_FAULTMASK(1);
	//单片机复位
	NVIC_SystemReset();
}

3.3 在IAP 中修改通讯串口

int main(void)
{
	int i;
	IAP_Init(); // <--- 进入
	IIC_Init(); 
	...
}
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);  // <--- 进入STM_EVAL_COMInit 的函数本体
  } 
void STM_EVAL_COMInit(COM_TypeDef COM, USART_InitTypeDef* USART_InitStruct)
{
	  GPIO_InitTypeDef GPIO_InitStructure;
	
	  /* Enable GPIO clock */
	  RCC_APB2PeriphClockCmd(COM_TX_PORT_CLK[COM] | COM_RX_PORT_CLK[COM] | RCC_APB2Periph_AFIO, ENABLE); 
	
	  /* Enable UART clock */
	  if (COM == COM1)
	  {
	    RCC_APB1PeriphClockCmd(COM_USART_CLK[COM], ENABLE); 
	  }
	  else
	  {
	    RCC_APB2PeriphClockCmd(COM_USART_CLK[COM], ENABLE);
	  }
	
	  /* Configure USART Tx as alternate function push-pull */
	  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	  GPIO_InitStructure.GPIO_Pin = COM_TX_PIN[COM];
	  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	  GPIO_Init(COM_TX_PORT[COM], &GPIO_InitStructure);
	
	  /* Configure USART Rx as input floating */
	  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	  GPIO_InitStructure.GPIO_Pin = COM_RX_PIN[COM];
	  GPIO_Init(COM_RX_PORT[COM], &GPIO_InitStructure);
	
	  /* USART configuration */
	  USART_Init(COM_USART[COM], USART_InitStruct); // <--- 选择COM_USART进入其定义
	    
	  /* Enable USART */
	  USART_Cmd(COM_USART[COM], ENABLE);
}
USART_TypeDef* COM_USART[COMn] = {EVAL_COM1, EVAL_COM2};  // <--- 选择EVAL_COM1进入其定义

GPIO_TypeDef* COM_TX_PORT[COMn] = {EVAL_COM1_TX_GPIO_PORT, EVAL_COM2_TX_GPIO_PORT};
 
GPIO_TypeDef* COM_RX_PORT[COMn] = {EVAL_COM1_RX_GPIO_PORT, EVAL_COM2_RX_GPIO_PORT};
 
const uint32_t COM_USART_CLK[COMn] = {EVAL_COM1_CLK, EVAL_COM2_CLK};

const uint32_t COM_TX_PORT_CLK[COMn] = {EVAL_COM1_TX_GPIO_CLK, EVAL_COM2_TX_GPIO_CLK};
 
const uint32_t COM_RX_PORT_CLK[COMn] = {EVAL_COM1_RX_GPIO_CLK, EVAL_COM2_RX_GPIO_CLK};

const uint16_t COM_TX_PIN[COMn] = {EVAL_COM1_TX_PIN, EVAL_COM2_TX_PIN};

const uint16_t COM_RX_PIN[COMn] = {EVAL_COM1_RX_PIN, EVAL_COM2_RX_PIN};
// 修改对应的串口和Pin 引脚,也可以多定义几组COM 口
#define EVAL_COM1                        USART2 // 如改为串口4,就把该项改为USART4,以下项同理
#define EVAL_COM1_CLK                    RCC_APB1Periph_USART2
#define EVAL_COM1_TX_PIN                 GPIO_Pin_2
#define EVAL_COM1_TX_GPIO_PORT           GPIOA
#define EVAL_COM1_TX_GPIO_CLK            RCC_APB2Periph_GPIOA
#define EVAL_COM1_RX_PIN                 GPIO_Pin_3
#define EVAL_COM1_RX_GPIO_PORT           GPIOA
#define EVAL_COM1_RX_GPIO_CLK            RCC_APB2Periph_GPIOA
#define EVAL_COM1_IRQn                   USART2_IRQn
  1. 最后编译下载到单片机调试;

4. python 脚本使用

  1. 待烧录的.bin文件根据“使用说明”,已特定前缀命名,放置到对应文件夹中;
  2. 打开mac 电脑“终端”,将python 脚本iap.py拖到终端窗口,敲回车;
    在这里插入图片描述
  3. 终端显示以下界面,表示.bin 文件已成功烧录到单片机;
    在这里插入图片描述
  • 4
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: STM32F103C8T6是一款性能强大的单片机芯片,具有丰富的功能和广泛的应用场景。在使用STM32F103C8T6芯片进行固件升级时,可以使用BootloaderIAP和OTA等技术。 Bootloader是一段预先编写的代码,它位于芯片的内部存储器中,用于引导系统启动。它可以通过外部介质(如串口,USB等)接收升级文件,并将其写入芯片的Flash存储器中。这样,在下次启动时,新的固件将被加载和运行,实现固件升级的目的。 IAP则是In-Application Programming的缩写,意为应用内编程。它提供了一种在运行状态下编程芯片的方法,而无需将芯片链接到外部编程工具。使用IAP技术,可以通过应用程序控制,将固件程序写入芯片的Flash存储器中,实现在线升级功能。 OTA是Over-The-Air的简称,指通过无线网络进行固件的远程升级。使用OTA技术,可以通过无线通信(如WiFi、蓝牙等)将新的固件文件传输到芯片中,实现在线固件升级,而无需将芯片与外部设备物理连接。 综上所述,STM32F103C8T6芯片可以通过BootloaderIAP和OTA等技术实现固件的升级。Bootloader适用于通过外部介质进行升级,IAP适用于在运行状态下应用内编程,而OTA则适用于通过无线网络进行远程升级。这些技术为STM32F103C8T6芯片的开发者提供了便利,使其能够灵活、高效地进行固件的升级。 ### 回答2: STM32F103C8T6是一款基于ARM Cortex-M3内核的微控制器,具有丰富的外设和强大的计算能力。在这个型号中,"bootloader"、"IAP"和"OTA"是三个与软件加载和更新相关的概念。 Bootloader是一段位于Flash内存中的程序代码,是系统启动时首先执行的部分。它提供了一些常用功能,如初始化硬件、检查Flash内存中是否存在可执行的固件代码等。同时,Bootloader还负责判断是否需要进行固件的更新,如果需要,它可以将新的固件程序加载到Flash中,然后跳转到更新后的程序。 IAP(In-Application Programming)是一种在应用程序运行时,通过软件的方式进行Flash存储器的编程,实现了固件的更新。相对于传统的烧录方式,它更加灵活方便,可以在不拆卸芯片的情况下对系统进行升级或修复。 OTA(Over-The-Air)则是通过无线网络将固件更新推送到设备中,无需物理连接即可实现远程升级。OTA主要用于各种智能设备,如手机、智能家居设备等。通过OTA,用户可以方便地更新和升级设备固件,提供了更好的用户体验。 综上所述,STM32F103C8T6可以利用Bootloader实现IAP,也可以通过OTA方式进行固件的远程升级。这些功能为开发者和用户提供了灵活、方便的固件加载和更新方式,使得系统的维护和升级变得更加便捷。 ### 回答3: STM32F103C8T6是STMicroelectronics公司推出的一款高性能ARM Cortex-M3内核的微控制器。它具有丰富的外设接口和强大的计算能力,在嵌入式系统领域得到广泛应用。 Bootloader是一种固件程序,用于启动设备并加载操作系统或其他应用程序。STM32F103C8T6微控制器上的Bootloader主要用于引导系统,可以从不同的存储介质(如闪存、外部Flash等)加载不同的固件程序。 IAP(In-Application Programming)是一种通过应用程序对设备进行编程的技术。在STM32F103C8T6微控制器中,IAP可以通过串口或其他通信接口进行固件更新,而无需通过外部编程器或者JTAG/SWD接口。 OTA(Over-The-Air)是一种通过无线网络进行固件更新的技术。在STM32F103C8T6微控制器中,OTA可以实现无线下载和安装固件更新,而无需将设备与计算机连接。这为设备的远程维护提供了方便和灵活性。 综上所述,STM32F103C8T6微控制器具有BootloaderIAP和OTA等功能。通过Bootloader可以引导系统并加载不同的固件程序,而IAP技术可以通过应用程序进行固件更新,OTA技术则实现了无线网络的固件更新。这些功能使得STM32F103C8T6微控制器在嵌入式系统领域具有更强大的应用和扩展能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Truffle7电子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值