IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> stm32串口IAP例程解析 -> 正文阅读

[嵌入式]stm32串口IAP例程解析

访问个人博客也许可以获得无广告体验与更好的文章排版: https://codinglover.top/2022/03/07/stm32串口iap例程解析/

例程获取

可以通过访问官方网站www.st.com获取示例代码和应用笔记
示例代码:x-cube-iap-usart
应用笔记:an4657

同时本文涉及的所有资料可以从此下载:
链接:https://pan.baidu.com/s/19nKPc_oOyRZCTfaNKTNHbw
提取码:q0ge

工程文件结构

主要就两个文件夹:Drivers和Projects,前者是HAL库的驱动文件和示例开发板BSP包,后者是示例工程,有F1、L0、L4这三个系列单片机开发板的示例,可惜没有我手头的stm32g412dicovery开发板的例程,所以后面要手动移植。Bootloader主要使用到了USART和CRC外设,前者用于用户交互和文件传输,后者用于文件校验。Projects中包含两个文件夹:IAP_Main和IAP_Binary_Template,前者是bootloader的实现(主要研究对象),后者是用户app模板。
IAP_Main包含了bootloader的主要实现文件和适配IDE的工程,工程文件没什么好说的,主要需要分析的源代码文件如下:

  • main.c main.h : 主函数入口,进行外设和HAL库初始化,调用bootloader或跳转用户程序;
  • menu.c menu.h : 命令行菜单实现
  • ymodem.c ymodem.h : ymodem文件传输协议实现
  • flash_if.c flash_if.h : FLASH读写函数
  • common.c common.h : 一些通用的函数和宏定义,主要在menu.c和ymodem.c中调用

文件之间的调用关系大致如下:

在这里插入图片描述

移植到stm32g412discovery开发板

我是参考了STM32L476G_EVAL的例程进行移植,事实证明,还是使用同为F系列的另一份例程工程移植更省事点。

  1. 直接使用STM32CubeMX生成一份stm32f412zgt6的初始化工程,使用内部时钟。将前面提到的那些主要文件添加进工程
    在这里插入图片描述

  2. 使能stm32f4xx_hal_conf.c文件中的CRC和UART这两个模块,并将对应的.c文件加入工程;替换头文件,将stm32l4xx.h替换为stm32f4xx.h;

  3. COPY文件mian.c与main.h中的内容并修改适配开发板;重新实现main函数中的BSP_PB_Init和BSP_PB_GetState用于初始化按钮检测和获取按钮状态,这里我直接使用了官方提供的stm32412g开发板的BSP包改了改;根据情况修改IAP_Init函数,这个函数主要用于初始化串口和CRC外设,我这里根据开发板情况将串口初始化为了UART2以使用板载stlink的虚拟串口,同时由于stm32F4系列的CRC外设并不支持Ymodem协议使用的CRC16校验计算,这里可以去除相关的初始化代码,后面在校验时使用软件校验;

  4. 根据报错信息修改其他文件,我这边碰到的情况是common.c/.h文件有少量报错,flash_if.c/.h报错很多,毕竟型号不同,内部flash的分区方式有特别大的差异。下图左侧是stm32l4xx的FLASH分布,右侧是stm32f412的FLASH分布。
    在这里插入图片描述
    这里有个建议,建议修改flash_if.c中的接口时参考例程中的STM3210C_EVAL工程,一开始应该基于此工程做移植的,真是失算。
    在修改flash_if.c中的Option bytes读写函数时有一个让我很疑惑的地方,按照打印信息,在更新完Option bytes设置后系统应该reset,可是实际没有,而且demo中没有在修改Option bytes后重新读取更新(可能是demo编写人员认为系统会reset所以不需要进行更新?),导致显示的菜单和实际状况不符,在menu.c中执行完对应功能后添加更新语句解决这个问题,如下图。
    在这里插入图片描述
    还有一个地方需要注意,demo原本的FLASH写入函数FLASH_If_Write在写入FLASH时使用的是DOUBLEWORD模式,不知道为什么在F412上非常容易导致写入错误返回HAL_ERROR,将写入模式改为WORD模式后解决了这个问题,不过这也导致写入速度有所下降,修改对比的代码如下所示:
    在这里插入图片描述
    移植完成后,FLASH的内部控件分配为:
    Sector0~Sector1 : bootloader空间
    Sector2~Sector10 : 用户程序空间
    Sector11 : 空闲未使用(可以用于用户程序存储一些配置信息等)

  5. 最后还需要修改Ymodem.c文件中的ReceivePacket函数,将其使用硬件计算CRC的部分替换为软件计算,例程已经提供一个计算用函数Cal_CRC16,直接调用就行。
    在这里插入图片描述

使用方法

关于用户程序的编译需要注意两点:

  1. 根据flash_if.h中设置的用户程序起始地址来调整链接时的链接地址,使用IAR和Keil可以直接设置,使用GCC需要直接修改链接文件,方法就不说了,网上一大把;
  2. 修改中断向量表的偏移,否则中断跳转会有问题,如果使用的是HAL库,修改system_stmf4xx.c中的宏定义VECT_TAB_OFFSET。

关于命令交互:

  1. 官方应用笔记AN4657中推荐使用的终端工具为Tera Term,试了一下实在是太难用了,我自己测试时用的是SecureCRT,使用方法大同小异。参考应用笔记就是了。注意传输的文件为.bin结尾的二进制文件,传输.hex文件是不行的,一般IDE都有生成.bin文件的选项。

关键代码分析

用户程序跳转

在这里插入图片描述

以上是demo中的用户程序跳转代码,根据stm32程序的结构可知,程序起始地址存的是SP堆栈起始地址,由于stm32的堆栈位于以地址0x20000000为起始的SRAM中,对于SRAM大小为128K的STM32L476来说,SP起始地址可能的数值为0x20000000到0x2001FFFF,if中的比较语句即为比较程序起始地址存的SP堆栈起始地址是否在SRAM的地址范围内,从而判断用户程序是否存在。0x2FFE0000这个值为0x2FFFFFFF-0x2001FFFF所得,所以这个值也应该根据实际得SRAM内存大小而进行修改。

if里面的跳转就比较简单了,程序起始地址偏移4字节里存的是系统复位向量的地址,也就是第一条需要执行的指令的地址,在调用__set_MSP设置好MSP堆栈指针后,直接像调用函数一样跳转到第一条指令执行即可,实际是将PC指针指向了这里。

用户程序下载流程

用户在菜单中选择1来进行程序下载,当用户做出选择,程序内部的函数调用链如下:
在这里插入图片描述

最终实际进行程序数据包接收工作的是函数Ymodem_Receive,只要数据传输没有出现错误并且文件未接收完成,其会不断调用函数ReceivePacket接收Ymodem协议传输的数据包并进行解析,并根据处理结果进行回应。

用户程序下载过程中的总体Ymodem通讯流程如下所示,这里只给出正常时的流程,去除了校验错误、FLASH写入错误等异常处理流程。
在这里插入图片描述

给出一篇博客用于进一步了解Ymodem,当然如果有空闲想全面了解,读官方的文档更佳
博客:https://blog.csdn.net/huangdenan/article/details/103611081

用户程序上传流程

暂时用不到,不分析。目前移植后的上传功能是有问题的,简单读了下代码,此demo上传用户程序时会将用户区的所有内容全部上传,而不是上传实际的程序所占大小,感觉实用价值不大,就不折腾了,哪天我用上了再回来补这一章节。

结语

官方的这个demo怎么说呢,不能算写的很好,差强人意吧,我严重怀疑程是不是外包出去的。这个例程用来学习可以,程序传输、FLASH烧写、跳转,bootloader的基本功能有了,但是想真在工作中使用,还是自己写一套更靠谱,毕竟代码量也不大,写起来花不了多少时间。我还是决定花点时间自己写一个出来。
关于bootloader还有一些其他方面值得研究:

  • 通过串口外的其他接口(USB、CAN等)传输用户程序
  • 用户程序升级失败的处理(用户区分为AB区,保证时刻都有一个正常的用户程序可用)
  • bootloader自身的升级
  • 。。。。。。
  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-03-10 22:45:28  更:2022-03-10 22:46:36 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 7:34:00-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码