> 技术文档 > stm32程序升级第一站:stm32程序远程升级介绍_stm32远程升级

stm32程序升级第一站:stm32程序远程升级介绍_stm32远程升级


STM32程序升级

stm32程序升级第一站:stm32程序升级介绍
stm32程序升级第二站: boot程序介绍
stm32程序升级第三站: 升级文件的传输与存储

文章目录

  • STM32程序升级
  • 前言
  • 一、STM32内存介绍
  • 二、程序运行顺序
  • 三、内存划分
  • 总结

前言

做嵌入式行业这么多年发现在很多产品上都有用到远程升级功能,虽然这个功能不常用,但是我们给产品留出一个后门用来解决使用过程中发现的bug还是很方便的。
这里我们用stm32为例介绍一下远程升级的原理和代码设计,实现程序升级功能。
是的stm32芯片也可以像手机APP一样远程升级,如何在资源有限的32芯片上完成远程升级?这篇文章带你了解stm32远程升级的原理。

一、STM32内存介绍

首先看一下STM公司给出的Stm32芯片内存地址映射图(后面所介绍的地址均按照图中映射地址)
stm32程序升级第一站:stm32程序远程升级介绍_stm32远程升级
这是单片机的参数介绍

stm32程序升级第一站:stm32程序远程升级介绍_stm32远程升级
flash 256KB 也就是说我们能操作的flash地址范围是0x80000000-0x80040000.
RAM 48K 就是运行内存从地址映射图可以得知运行内存的范围是0x20000000-0x2000C000我们烧录到芯片中的程序就是放在了地址0x80000000这个地址中。

二、程序运行顺序

问:明明是M3的内核为什么不是从0x00000000开始的呢?
答:映射地址就是0x80000000,M3内核复位后确实是从0x00000000开始运行,但是意法半导体公司封装芯片是将片内flash的开始地址映射到0x80000000,程序也就在这个位置开始存储。
问:M3内核在初始化的时候要读取中断向量表,如果程序在0x80000000开始,怎么读取中断向量表?
你应当记得单片机上有两个特殊引脚BOOT0和BOOT1,他们的作用如下:
stm32程序升级第一站:stm32程序远程升级介绍_stm32远程升级
我这里就按照stm32f103RCT6这个型号的单片机为例,我们的程序在系统复位后通过BOOT引脚判断运行区代码地址,这两个引脚我们在设计电路的时候一般都将Boot0接个下拉电阻,所以单片机启动模式是片上闪存。
注意上面的介绍系统在复位之后内核会从0x08000000中获取栈顶指针,在0x08000004地址中指示的地址中执行代码,什么意思呢,给个图就明白了,用j-flash随便打开一个Hex文件:
stm32程序升级第一站:stm32程序远程升级介绍_stm32远程升级

栈顶指针0x200044F0,程序将从0x0800020D开始执行,这里的0x0800020D地址其实就是复位中断的入口地址,main函数会在复位中断中被调用,仿真一下看下复位后PC指针和栈顶指针:
stm32程序升级第一站:stm32程序远程升级介绍_stm32远程升级
为什么PC指的不是0x800020D呢?
其实这里涉及到指令集的问题,ARM cortexM3执行的是Thumb-2指令集,同时兼容16位的ARM指令和32位的Thumb的指令,为了区分两个指令集,规定指令最低位为1就是Thumb指令,为0就是ARM指令,但在Cortex-M3中,ARM指令集并不被支持,地址最低位通常总是1,Keil的调试器在显示PC值时,会自动将PC的Thumb位(最低位)清零,以显示逻辑地址。这会导致PC显示的值比Hex文件中记录的地址小1。例如,实际PC为0x0800_0001(Thumb模式),但Keil可能显示为0x0800_0000。在仿真中可以看到中断向量表里的中断入口地址都与实际hex中的地址少1

(中断向量地址表也是很重要的知识点,它是内核执行中断任务的关键部分,第二站将会单独介绍。)
stm32程序升级第一站:stm32程序远程升级介绍_stm32远程升级

三、内存划分

好了前面重点介绍了单片机内存和程序启动运行逻辑,怎么来规划远程升级,如何分配内存?我这里使用的是stm32f103rct6单片机256Kb flash+48KbRAM
内存的划分主要分为以下几个部分
1.boot区(0x8000000-0x8008000)
我们知道单片机复位后是固定从0x8000000开始的(启动方式为主闪存,Boot0=0)这里要有一个固定的代码用来告诉内核应该怎么去运行用户代码,这部分程序我们就称作boot程序。
可能你还没有理解,我来做个比较,就拿电脑来说,电脑有个芯片叫做bios,里面存储有系统启动程序,和自检程序,电脑开机先运行BIOS程序,检查硬件状态读取windows系统程序信息,然后执行Windows系统。
所以我们的这个boot程序也是如此,他的工作就是用户代码启动前的预处理程序,这个程序比较小通常只分配32k的flash空间就可以了(0x8000000-0x8007FFF)
2.用户数据区(这部分可要可不要,如果你的代码运行参数是存在外置flash或者eeprom中可以不用规划此区)一般放在boot区之后大小自定,以我的项目来讲4K足够使用(0x8008000-0x8008FFFF)
3.用户代码区或者叫业务代码区,就是你真正要实现产品功能的代码。(剩余200多Kb全用在这里)

如果你用的单片机内存很小可以通过删减boot区和用户数据区空间,优化代码等方法实现,如果优化完,用户代码区还是不够用就考虑换单片机啦

总结

工作之余时间有限,本节到此为止,下一节介绍远程升级的boot代码,以及升级两种方式