IAP升级:基于STM32F4系列标准库+Ymodem+RS485/RS232

文章概要

本文是基于STM32F4系列标准库的一个IAP在线升级程序,详细讲解了IAP程序从第一步到最终完成程序跳转的各过程。在正式开始之前,需要先去了解以下前置基础知识,以及获取对应资料。

预先说明一下结论:Boot程序是基于标准库写的,App程序是基于HAL库写的这种情况不会影响从Boot程序跳转到APP,也不影响从App跳回Boot,并且App程序是可以执行的,标准库、HAL库的本质还是寄存器的操作。

在从Boot跳转至App程序的时候大多用的是函数指针的方式,但是当实际App程序过大的时候不推荐仍旧使用函数指针的方式跳回Boot程序,因为会由于App程序过大而导致栈没有及时清空,在第二次从Boot跳回App的时候导致无法正常跳转,程序卡死。

本文是基于正点原子开发板STM32F407ZGT6来学习IAP程序。

通讯的物理层是基于RS232和RS485两个实验

仅使用到开发板上一个外设:UART。

Flash大小1M,RAM大小192KByte

我的源码最后会打包成一个Zip,提供一个连接供大家下载,但是目前还没有把例程和源码都整理好,等我整理好了之后我会在摘要当中提供我的源码连接(网盘方式)。

由于本人第一次做IAP升级程序,如有不足之处,希望大家能够在评论区中给出意见,感谢大家。

前置知识和资料获取

1.正点原子讲解基于UART的IAP升级实验和片上Flash操作实验

传送门:

Flash的学习:

第67讲 FLASH闪存编程原理与步骤-M4_哔哩哔哩_bilibili

第68讲 FLASH模拟EEPROM实验-M4_哔哩哔哩_bilibili

串口IAP的学习:

第92讲 IAP在应用编程原理_哔哩哔哩_bilibili

第93讲 串口IAP实验讲解_哔哩哔哩_bilibili

2.有关Ymodem和IAP的基础知识

Ymodem知识传送门:

https://blog.csdn.net/huangdenan/article/details/103611081
https://blog.csdn.net/qq_33475105/article/details/116866436

STM32 IAP在线升级嵌入式_哔哩哔哩_bilibili

STM32F4 IAP BOOTLOADER YMODEM_stm32f4 iap ymodem-CSDN博客

IAP知识传送门:

单片机三种烧录方式ICP、IAP和ISP详解_icp iap-CSDN博客

STM32在线升级 (IAP)-CSDN博客

3.在完成了上述步骤后,需要一个基于标准库的IAP官方例程

基于STM32官方IAP在线升级例程传送门:

STM32 IAP 升级官方资料汇总_stm32 官网 iap-CSDN博客

F4系列选则:AN3965

如果是其他系列的,比如F1系列的就去找F1对应的例程,如果是HAL方式的就去找HAL库的,我这边只提供标准库的官方例程,需要官方例程的原因是因为官方例程中提供了非常重要的函数,就是Ymodem.c这个文件中的接收函数,其他的暂时都用不到,当然了,在文章的后面会详细的介绍官方例程的源码和使用以及Ymodem接收函数。

4.需要一款终端软件来模拟上位机通过Ymodem协议发送数据包。

终端软件 SecureCRT 获取传送门:
https://pan.baidu.com/s/1WkbYMe_Mj0muLdWy4sHgDw 
提取码:1234 

SecureCRT安装教程传送门:

https://zhuanlan.zhihu.com/p/163089404

再分享一些写的比较好的帖子:

分享我的项目必需品:IAP+YMODEM+CRC16+AES256+PC端软件+hex合并-OpenEdv-开源电子网

正点原子【STM32-F407探索者】第五十五章 串口 IAP 实验 - 知乎

让我们开始吧

IAP和启动模式简介:

1.首先还是简单介绍一下IAP、ISP、ICP和启动模式。

ISP:    In System Programing       

 英文直译在系统编程,这种方式是使用预先存入系统存储器区域中的Bootloader程序进行引导,再利用外围设备,如USART、SPI进行数据包的传输下载到Flash中。

而系统存储器中的Bootloader是官方预先存入其中的,如下图所示,系统存储器区从地址0x1FFFF0000开始,这段区域放的就是厂家预先设置的Bootloader启动程序。

(后期ISP编程配 一个实际图片助于理解)

ICP:    In Circuit Programing         

英文直译:在电路编程,通俗点就是平时大家用的J-Link仿真器或者ST-Link仿真器把程序下载到指定Flash中的这种方式。

(后期配一个图片有助于理解)

IAP: In Application Programing

英文直译:在应用编程,IAP这种在应用编程的方式是将Flash分成了两个部分,第一个部分为Bootloader引导程序,其实跟ISP中官方写的Boot引导程序的作用具有相同的功能的,第二部分就是我们要使用的程序,叫做App程序(应用程序),比如说你想要实现跑马灯、串口输出、或者通讯又或者显示屏这种功能程序。

Bootloadr程序的作用:

通过某种方式接收到新的App程序,并将新App程序下载至芯片指定Flash中

能够实现从Bootloader程序跳转至App程序。

那么为什么会有IAP这种烧录程序方式的出现呢,原因是因为IAP程序相比较于ISP和ICP烧录程序,IAP能够做到不需要接线就将App程序下载到指定的Flash中去。可以方便产品再发布的后续升级。

2.STM32的启动模式有三种模式,根据Boot1 和 Boot0 引脚电平的组合来选择程序从哪里开始启动。

如图所示:

本质上,不同的启动模式反映了保存MSP指针值和PC指针值的映射地址的不同。

默认情况下,地址0x00000000的值是MSP的值,地址0x00000004的值是PC指针变量的值。

从代码上来表示就是:

 *(__IO uint32_t*)0x00000000 和 *(__IO uint32_t*)0x00000004

而不同的启动模式本质上是将MSP指针和PC指针的值映射到不同的地址中去,比如上表第一种启动模式则是将地址0x00000000映射为0x08000000,将地址0x00000004映射为0x08000004,

显然是ST芯片中Flash的地址,注意这一点很重要,在后面进行跳转校验的时候需要用到。

ST官方允许把默认地址映射到不同的地址位置,一般而言我们用的都是上图第一种的启动模式。

也就是将原MSP值和PC值由最初存入地址0x00000000 0x00000004中,更换为存入

地址0x08000000和0x08000004中。

上电后的启动过程之一就是初始化MSP的值和初始化PC的值,所谓初始化其实就是从地址

0x0800000和0x0800004(这里假设启动模式是从Flash启动)位置获取栈顶地址和复位中断函数地址。

因此,如果选择了从Flash启动,那么你会发现Flash中这两处地址中的值分别是MSP的值和PC值

地址0x08000000:中保存的值是 initial_sp(栈顶地址,反映了当前程序占用RAM的大小)

地址0x08000004:中保存的值是 复位中断服务函数地址(就是某个函数的地址)

PS:(这里记得配一个图,有助于理解)

第二种启动模式就是我们之前提到的ISP,在正点原子的教学中会有一个软件是用HEX文件进行烧录的,这种方式就是通过ISP方式将程序下载到板子上。

第三种启动模式是从SRAM中启动,其实就是把地址0x00000000 和0x00000004映射到了内存上

应该是0x20000000和0x20000004。

总之芯片厂商可以把0x0000000 0x0000004地址映射到其他的地址。根据Boot1 Boot2的不同引脚配置将上述地址映射到不同的地址,从而可以选择不同的启动模式。

UART+RS232+Ymodem实验

实验介绍:该实验是基于Ymodem传输协议进行在线升级的一类实验,使用终端软件SecureCRT模拟上位机进行App更新包的发送,物理层通信方式采用RS232的连接方式,使用到的外设为:UART。

一、原理图及接线

RS232接线

二、Boot程序解析

一、移植官方文件到Boot程序中

在Boot程序中,我们首先需要移植ST官方提供的8个文件:

源文件:ymodem.c + memu.c + flash_it.c + common.c

头文件:ymodem.h + memu.h + flash_it.h + common.h

上述最重要的文件是ymodem文件及其头文件,其他文件为次要文件,次要文件中的函数和内容我们可以自己实现,但是核心的文件是ymodem.c文件中的数据包接收函数。

在我的例程中,我将common.c文件中的内容复制移植到了rs232.c文件中进行了对比,发现common.c文件中的内容涉及到了串口数据的发送和接收和"字符串-整数"互相转换的函数。

因此我的例程中没有common.c的文件,其内容被移植到了rs232.c文件中。

二、Boot程序内容解析

1.主程序:

Boot主程序需要做的如上图所示,我们首先要保证的是能够进行App更新包的接收,在此基础上再进行跳转,因此上述图片中最重要的事情是第34行到38行。

2.有关Boot程序移植部分注意事项和讲解:

我们要注意的一点是,在官方的common.c文件中,有关UART发送数据的函数是需要进行修改的

如下图:

这个函数是利用UART发送一个字符给上位机,ST官方中使用的发送函数 串口可能会跟我们使用的芯片不同,因此要进行一下修改,还有其他修改部分大家可以根据我提供的源码和官方的例程进行对比。

(注意:此函数是整个IAP升级中最重要的函数)

在函数int32_t Ymodem_Receive (uint8_t *buf)当中,ST官方例程中在进行Flash扇区擦除前和写数据前是没有对Flash进行解锁操作的,在我的例程中添加了解锁上锁操作。

此处还需要补充,如果大家不想用ST官方的写入和擦除函数可以自己写好自己的函数后将其替换掉,我的例程中则是直接使用的ST官方的扇区擦除和数据写入操作,这两个函数我大概看了一下,他的扇区擦除函数的用法是:你给他一个App起始地址后,他会从起始地址所在扇区开始将起始地址所在扇区包括芯片后面所有的扇区全部擦除掉。

3.int32_t Ymodem_Receive (uint8_t *buf)函数解析:

此函数是最重要的函数,可以说,在main函数中直接调用这个函数都能够进行数据包的接收,因为就是这个函数起到了数据包的接收作用。

而这个函数里面又包括了另一个重要的函数:

static int32_t Receive_Packet (uint8_t *data, int32_t *length, uint32_t timeout)

我们先从Receive_Packet 函数开始,注意:你看到这里的时候一定是对ymodem协议有了一定的了解了,最起码整个发送数据的流程和格式,帧格式、数据包格式是什么样 应该是明白了的,否则无法看明白下面对于两个函数的解析。

对两Receive_Packet()进行解析,另外一个函数解析见例程。


static int32_t Receive_Packet (uint8_t *data, int32_t *length, uint32_t timeout)
{
  uint16_t i, packet_size;
  uint8_t c;
  *length = 0;
    
    //如果没有接收到数据,则函数返回-1,接收到数据则返回0
  if(Receive_Byte(&c, timeout) != 0)               return -1;    
  
    //如果收到了数据,进行判断。
  switch (c)
  {
    case SOH:            //收到0x01.则packet_size赋值为128,跳出switch
      packet_size = PACKET_SIZE;
      break;
    case STX:            //收到0x02.则packet_size赋值为1024,跳出switch
      packet_size = PACKET_1K_SIZE;
      break;
    case EOT            //收到0x04.函数返回0
      return 0;
    case CA:             //收到0x18,则进行判断,如果在下面if中再一次收到CA,则函数返回0
      if((Receive_Byte(&c, timeout) == 0) && (c == CA))
      {
        *length = -1;
        return 0;
      }
      else
      {
        return -1;
      }
            
    case ABORT1:
    case ABORT2:
      return 1;
    default:
      return -1;
  }
    
  *data = c;                                                                        //一个包中的首字节存入*data中
  for (i = 1; i < (packet_size + PACKET_OVERHEAD); i++) //在1029或133次循环中进行判断
  {
    if(Receive_Byte(data + i, timeout) != 0)                        //如果没有连续1029次或者133次收到数据则函数返回-1
    {
      return -1;
    }
  }
    
    //如果序号不等于序号的取反值,则函数返回-1
  if (data[PACKET_SEQNO_INDEX] != ((data[PACKET_SEQNO_COMP_INDEX] ^ 0xff) & 0xff))
  {
    return -1;
  }
  *length = packet_size;      //将数据包的大小存入*length中,也就是函数Ymodem_Receive的变量packet_length中
  return 0;                               //数据包接收正常,返回0
}

基于RS232+485+Ymodem的IAP升级程序使用步骤:

1.打开模拟上位机的超级终端SecureCRT:点击File->Connect->选择连接方式为Serial连接,配置波特率等参数。

2.建立起上位机和MCU的通讯后,上位机软件会显示一直在受到来自MCU的"C",符号。如图:

这个时候仅仅只是表明你们之间建立起了通讯,还没有开始进行文件的发送和接收。

3.点击Transfer->SendYmodem

如果成功后会做出如下提示,且App程序已经被运行:

处于Boot程序时开发板仅亮红灯,处于App程序后,开发板红灯绿灯常亮。

Boot程序显示:

App程序显示:

UART+R485+Ymodem实验

实验介绍:该实验是基于Ymodem传输协议进行在线升级的一类实验,使用终端软件SecureCRT模拟上位机进行App更新包的发送,物理层通信方式采用RS485的连接方式,使用到的外设为:UART2。

程序代码和RS232实验一样,只是将物理层从RS232换成了RS485,而RS485进行数据传输的时候是半双工(一次只能进行发送数据或者接收数据,不能同时进行数据收发),因此在我们进行数据接收和发送的时候需要将相应的485使能位置进行接收和发送设置,有关Boot代码部分内容是一样的,区别仅仅在于485的配置方面,具体的可以参照文章末尾给出的例程。下面贴出连接方式和原理图。

485实验和RS232的不同在于接线,因为485是根据差分信号来进行电压的判断,特别是在工业领域需要要求能够具有良好的抗干扰性和远距离传输,因此工业控制相关中485通讯用的是比较多的。那么此处用到的是正点原子的485转USB芯片,通过两根杜邦线连接AB输出口再连接到485转USB转换芯片,这样就能够发数据在上位机上了,否则无法实现通讯。

有关485原理图参照下面,在MCU开发板上是有一个485转换TTL电平的芯片的,我们是将串口的Tx和Rx引脚连接到TPT8485芯片的Rx和Tx再有此芯片输出到AB端口从而连接到外部差分信号线,具体原理需要去学习一下RS485的知识,总之485是一主多从机控制,也是不通电终端连接到同一个485总线上(485_Hig 或者 485_Low 又或者叫A或者B,根据总线上电压差值来区分高低数字电平)

最终实验操作方式和RS232实验一样,此处我就不再贴出类似的过程了。

如下图是用485和上位机进行通讯,

最后用到的例程是跟RS232一样的,贴一下结果,可以看到,下载从成功后 Flash中是可以在指定地址中看到你的Bin文件数据的,并且开发板上的灯也在进行闪烁。

此时如果想要回到Boot中可以按复位按钮,或者你自己写一个软件复位程序跳回Boot即可,

一般项目中都是用软件复位跳回Boot的,关于软件复位跳回Boot程序的注意事项在文章开头已经给出了,无非是注意栈溢出和跳转的逻辑,这些需要大家自己去实现,最后,如果大家在文章中发现存在的错误的话,欢迎在评论区指出,文章末尾我会给出相关的例程文件和配套Bin文件。

  • 21
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: STM32F429串口IAP(Ymodem)升级是一种在STM32F429上通过串口进行最小系统升级的方法。其中,IAP全称为In-Application Programming,可以实现对单片机程序在应用程序的控制下进行在线升级的功能;而Ymodem则是一种通用的串行数据传输协议,可以保证数据的可靠性。 该方法的使用过程如下: 1.使用对应的工具(如ST-LINK Utility)将应用程序和BOOTLOADER程序分别烧录至单片机的Flash中。其中,BOOTLOADER程序一定要占用Flash的起始位置,并且大小应该尽量小。 2.编写在应用程序中调用的IAP程序,该程序通过解析Ymodem数据包的方式将更新数据升级到Flash中。同时,IAP程序需要包含一些自我保护措施以避免出现卡死等问题。 3.通过串口将更新数据以Ymodem协议的方式发送给单片机。在发送数据之前,需要保证串口配置正确(比如波特率、数据位等)。 4.单片机收到数据后,进行解析并将数据写入Flash中。在写入数据时需要判断支持Flash的型号和大小,以及使用哪个扇区。 该方法的优点在于可以实现在线升级,并且对于不同的Flash型号和大小都有较好的兼容性。同时,采用Ymodem协议可以保证了数据的可靠性,避免了出现数据出错、丢失等问题。缺点则在于需要编写一定的IAP程序,并且在升级时存在一定的安全风险。 ### 回答2: STM32F429作为一款高性能的微控制器,具有多种升级方式。其中比较常用的方式为串口IAP和Ymodem升级。 串口IAP(In-Application Programming)是通过串口通信升级系统的一种简单可行的方法。在程序中添加IAP函数库,修改引脚配置,通过串口连接PC,将升级文件发送至微控制器,程序将自动更新Flash存储器中的程序。 而Ymodem升级则是通过调用UART外设与上位机之间通信,采用基于CRC-16校验的Ymodem-M协议完成数据传输的无需Bootloader的升级方式。该方法优点是可以通过任何终端软件直接实现,缺点是升级速度可能会受到波特率和数据带宽限制,传输时间可能长。 综合来看,根据具体需求和情况选择合适的升级方式,既能提高升级效率,又能确保升级的稳定性和可靠性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值