STM32 ——bootloader IAP

这篇具有很好参考价值的文章主要介绍了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 代码布局

STM32 ——bootloader IAP

1.3 .hex 文件转.bin

在Keil 中下图位置添加代码fromelf.exe --bin -o "$L@L.bin" "#L",编译后,可在.hex 同文件夹下生成.bin 文件;
STM32 ——bootloader IAP

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 设置中,设置对应的扇区位置:
    STM32 ——bootloader IAP
  2. 在Debug 设置中,选择擦除扇区:
    STM32 ——bootloader IAP

3.2 在APP 中添加跳转IAP 接口

除了3.1 步骤的操作外,在APP 中也需要添加一个跳转到IAP 到接口,以实现在APP 代码运行中进入IAP 代码升级APP 代码的功能;文章来源地址https://www.toymoban.com/news/detail-408576.html

  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); // <--- 选择COM_TX_PORT_CLK进入其定义
	
	  /* 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);
	    
	  /* 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 引脚
#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拖到终端窗口,敲回车;
    STM32 ——bootloader IAP
  3. 终端显示以下界面,表示.bin 文件已成功烧录到单片机;
    STM32 ——bootloader IAP

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

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

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

相关文章

  • GD32单片机和STM32单片机的对比分析

    GD32单片机和STM32单片机都是基于Arm Cortex-M3/M4内核的32位通用微控制器,广泛应用于各种嵌入式系统和物联网领域。两者之间有很多相似之处,但也有一些不同之处,本文将从以下几个方面对比分析两者的特点、优势和开发成本。 GD32单片机采用的是二代的M3/M4内核,而STM32单片

    2024年02月16日
    浏览(57)
  • J-LINK J-FLASH 下载STM32单片机程序使用教程

    J-LINK J-FLASH 下载程序使用教程 -V1.0 2023.05.09 Introduction 本教程用于演示如何使用JLINK V9配套J-FLASH软件烧写更新MCU程序的教程 安装提供的 JLINK驱动程序。JLink_Windows_V722a.rar。全程默认安装,只能安装在C盘,不可安装于其它盘。 安装驱动完成后,将JLINK V9仿真器上USB口插上电脑,

    2024年02月11日
    浏览(44)
  • STM32单片机(一)STM32简介

    ❤️ 专栏简介:本专栏记录了从零学习单片机的过程,其中包括51单片机和STM32单片机两部分;建议先学习51单片机,其是STM32等高级单片机的基础;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 :适用于想要从零基础开始学习入门单片机,且有一定C语言基础的的童鞋

    2024年02月10日
    浏览(57)
  • STM32单片机(二)STM32环境搭建

    ❤️ 专栏简介:本专栏记录了从零学习单片机的过程,其中包括51单片机和STM32单片机两部分;建议先学习51单片机,其是STM32等高级单片机的基础;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 :适用于想要从零基础开始学习入门单片机,且有一定C语言基础的的童鞋

    2024年02月10日
    浏览(59)
  • STM32单片机开发-01 STM32介绍

    通过野火开发板学习单片机 从内核上分有Cortex-M0、M3、M4 和M7 F1 代表了基础型,基于Cortex-M3 内核,主频为72MHZ F4 代表了高性能,基于Cortex-M4 内核,主频180M。 数据手册:用于芯片选型和设计原理图 参考手册:用于编程时查阅 Icode总线 – 该总线讲M3内核的指令总线与闪存指令

    2024年01月21日
    浏览(57)
  • 【单片机】STM32单片机的各个定时器的定时中断程序,标准库,STM32F103

    高级定时器和普通定时器的区别(https://zhuanlan.zhihu.com/p/557896041): TIM1是高级定时器,使用的时钟总线是RCC_APB2Periph_TIM1,和普通定时器不一样。 timer.c timer.h 调用 timer.c timer.h 调用 timer.c timer.h 调用 timer.c timer.h 调用 timer.c timer.h 调用

    2024年02月07日
    浏览(55)
  • STM32单片机学习3--STM32控制键盘

    单片机型号:STM32F103C8T6 开发环境:Keil5 4种输入模式 上拉输入模式:在默认状态下(GPIO引脚无输入),读取得的GPIO引脚数据为1,高电平(与Vdd相连的为上拉电阻); 下拉输入模式:在默认状态下(GPIO引脚无输入),读取得的GPIO引脚数据为0,低电平(与Vss相连的为下拉电

    2024年02月10日
    浏览(55)
  • 【STM32】STM32单片机结构及部件原理

    STM32是目前比较常见并且多功能的单片机,要想学习STM32,首先要去了解它的基本构成部分以及各部分的原理。 单片机型号:正点原子STM32F103ZET6 目录 STM32内部结构总览图: 2.内部结构解析         1.内核 :STM32F103ZET6采用的是 ARM Cortex-M3 处理器,内核可以理解为单片机 处

    2023年04月08日
    浏览(46)
  • 【单片机】STM32单片机,定时器的输入捕获,基于捕获的频率计,STM32F103

    下面的定时器都具有输入捕获能力: 查看另一篇文章:https://qq742971636.blog.csdn.net/article/details/131471539 外部计数频率计的缺点:需要两个定时器配合,最高能测量的频率是否有限制我没具体尝试。 基于捕获的频率计的缺点:最高能测量的频率有限制。 TIM3_CH1 PWM PA6 10KHZ。 输入

    2024年02月14日
    浏览(52)
  • 单片机stm32智能鱼缸

    随着我国经济的快速发展而给人们带来了富足的生活,也有越来越多的人们开始养鱼,通过养各种鱼类来美化居住环境和缓解压力。但是在鱼类饲养过程中,常常由于鱼类对水质、水位及光照强度有着很高的要求,而人们也由于工作的方面而无法贴心的照料,因此经常因为水

    2024年02月22日
    浏览(42)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包