STM32单片机的FLASH编程详解

前面说到了单片机的ROM、RAM两块存储的位置和大小,以及简单的变量或函数的存储地址,这时候你应该对单片机的内存有了了解。

当你用仿真器下载程序的时候,前面提到的BIN文件的数据(也就是原始的ROM二进制数据,0101那种),会通过下载器0x0800 0000这块内存。之后根据你的下载选项可选自动运行,或者复位再运行。当然也有的同学和我这种穷*一样不舍得买几十块钱甚至更贵的下载器,那么就是使用串口进行下载(也就是ISP),这点和51一样,只不过不需要所谓的冷启动了。对应的引脚是PA9(TXD)、PA10(RXD)。

        你知道其中发生了什么吗?先以下载器为例,此时你的单片机和下载器最少只有3根线,首先是GND,也就是负极,你得共地才能确定0电平。然后是CLK(或者TCK)和DAT(或者叫TMS、DIO),也就是PA14和PA13这俩引脚,和IIC类似,数据和时钟,可读可写,那么你的单片机程序就是通过这个串行总线更新的。因此UP设计电路图一般会预留串口和仿真接口用于调试,像这样。 STM32单片机的FLASH编程详解_第1张图片

    那么你如果用的串口更新呢?首先你要保证boot0引脚拉低了再启动,也就是先拉低boot0再复位,这样启动的时候就是boot0为0了,也就是低电平。或者不复位而是按住boot0为低电平直接断电重新上电。然后你就可以用串口更新软件把hex文件发过来了,之后同样的复位重启,运行新程序。虽然过程有点复杂,但是有自动下载电路,可以用串口的DTR和RTS这俩信号协助你控制RST(复位)和boot0,这样就不用你管了。 

STM32单片机的FLASH编程详解_第2张图片

 

   有什么区别呢?仿真器快,对吧。还有就是串口只能下载,仿真器可以仿真,就是一步步运行程序,便于查看效果。我们先从下载方面分析,再说仿真方面。

        你写过stm32内置flash编程程序,你应该知道,就是那块0x0800 0000的存储器,你除了用来存储你的程序并运行外,你还可以用你的程序去读写它,只要没有碰到你自己的程序那块,不然那就是格式化C盘的效果,你的程序可能就挂了,并且可能再也运行不起来了。但是你也没那么容易直接碰它,因此你还需要解锁,然后才可以操作它。

        那么你下载程序的时候是谁在擦写你的ROM呢?是SWD接口吗?是串口吗?都不是,因为单片机不是24C02,也不是串口EEPROM,那么~~~

  没错,单片机里面还在运行着程序,这个程序在干嘛呢?串口更新的时候它在接收串口数据帧、校验数据,为你的串口更新上位机提供单片机ID查询,FLASH读写等服务。上位机通过串口信号(即DTR、RTS,注意不是数据)控制你的开发板的一键下载电路完成boot0的低电平启动(没有自动下载电路的话你就要手动完成这一步了),完成下载(也就是0x0800 0000那块FLASH写BIN文件数据)之后,上位机再次产生复位信号,开始运行新程序。可能你选择的是hex数据,这样不影响你更新新程序,因为他俩存储的数据都是一样的。就像瓜子和瓜子仁一样,瓜子可以解析出来瓜子仁。hex也能解析出来bin文件。所以bin文件更小,hex大一些。 

STM32单片机的FLASH编程详解_第3张图片

      那么这个程序存在哪?谁写的?怎么启动这个程序的?这个你应该知道,拉低boot0它就启动了,谁写的呢?肯定是单片机厂商了,用户修改不了它。这块区域存在的意义是什么呢?简单来说给我们提供低成本的固件更新方案,不需要昂贵的仿真器。其实这块程序还真不简单,串口其中只是一种方式,你还可以用CAN、USB等等。它在那个位置呢?下图说了,是在系统存储区。更具体的可以查看相关手册。

STM32单片机的FLASH编程详解_第4张图片

 在内存地图中你可以产看到系统存储区的地址和范围,然后你就可以算出来大小了,同样的你还可以看到FALSH和SRAM,也就是ROM和RAM的地址及范围,同样可以算出大小。当然这是以F4为例,其他不同的单片机,内存大小可能会不同。

STM32单片机的FLASH编程详解_第5张图片

  如果你想了解内置的bootloader怎么通过串口实现的,你可以登陆ST官网搜索an3155这个文档查看。 

STM32单片机的FLASH编程详解_第6张图片

  比如首先检测串口收到0x7F后,确认使用串口作为通信接口。

STM32单片机的FLASH编程详解_第7张图片

  或者bootloader的版本查询、单片机ID查询以及FLASH擦写等指令。

STM32单片机的FLASH编程详解_第8张图片

 单片机还有其它的启动方式,还有boot1引脚。不限于从这块内置的bootloader这里的内存启动。比如还可以从RAM里面启动。

        那么,仿真接口呢?仿真接口一般不会控制你的单片机从内置的boot loader那里启动,因为它没法准确控制你的boot0引脚,假如你掰断了呢,你也不一定用了串口。所以~~~

        没错用仿真器时跑的另一个程序,不然怎么会做到和内置bootloader一样的FLASH擦除功能?但是这个程序不在0x0800 0000这里,因为这里是要被擦写覆盖掉的,更不在内置的boot loader那块。所以你猜到了在哪里吗?

        没错,我们还有0x2000 0000这块RAM存储器,RAM也是可以运行程序的,怎么让RAM运行程序呢?要先给RAM写好程序吧,然后呢?从RAM启动即可,或者说执行RAM里面的指令。这里的程序就叫做下载算法。往RAM里面写这个下载算法的接口就是我们的仿真接口,占线最少的那种就是SWD接口。而SWD协议定义了SWD接口的通信规则。通过SWD接口和协议我们就可以往RAM里面写下载算法了。

        怎么写呢?你还需要个仿真器,仿真器可以通过单片机的SWD接口连接到单片机的调试单元,然后写下载算法等等。下载算法怎么来的呢?仿真器怎么知道的下载算法呢?仿真器不一定知道下载算法,但是MDK会告诉它,通过USB数据线,所以MDK有下载算法,路径可以通过添加算法,然后找到之前的算法来查看,就是最下面这里。 

STM32单片机的FLASH编程详解_第9张图片

       拷贝一下路径你就可以找到下载算法了。

STM32单片机的FLASH编程详解_第10张图片

   这个下载算法就在你安装的pack包里面,安装的时候就解压到这里了。下载选项你也可以知道下载算法存储的地址和大小。就是前面我们说的拷贝到RAM运行的地址。

STM32单片机的FLASH编程详解_第11张图片

 

整个过程就是pack包告诉MDK下载算法,MDK通过USB告诉仿真器,仿真器再通过SWD接口(也就是那总共三根线,当然你要保证单片机供电能跑)把下载算法下载到RAM。这时候RAM中的程序也就是下载算法就可以擦写你的FLASH了。还是一样的步骤,MDK把BIN文件通过USB告诉仿真器(当然并不一定要生成BIN文件,只是发送原始ROM数据),仿真器再通过SWD调用RAM中的下载算法把FLASH擦除,然后写MDK发来的BIN数据,最后按需(根据下载选项)复位运行。

        是不是比串口还复杂的过程,(不过这一切操作起来还是挺简单的,装好驱动,插好线,有没有一键下载电路都无所谓,MDK配置一下仿真器直接就可以使用了),既然这么复杂还这么贵,为什么还要仿真器,因为它除了下载程序还可以仿真,这是串口下载做不到的。

        仿真功能还是源于SWD接口,还是源于SWD协议,SWD协议除了写RAM数据外还有其他很多功能,比如我们之前运行时查看0x0800 0000地址处的BIN文件内容。这就是读FLASH,读FLASH本质上还是访问FLASH这里的寄存器,除此外你还可以访问外设的寄存器,帮助你调试程序,查看状态等等。

        你还可以自己设计下载算法,还是在那个下载算法路径。参考源工程的方式定义FLASH设备信息,编写FLASH编程函数等等。详细步骤可以参考安富莱的H7外部FLASH下载算法制作:https://www.cnblogs.com/armfly/p/13970387.html

STM32单片机的FLASH编程详解_第12张图片

   如果你知道了这个原理,你就可以自己做一个下载器了,把下载算法保存在下载器里面,控制要下载的单片机的SWD接口完成初始化FLASH,写下载算法,写FLASH,校验,复位运行等等。或者参考CMSIS的开源DAP程序(https://github.com/ARMmbed/DAPLink)做仿真器再或者参考安富莱的H7-TOOL(https://github.com/armfly/H7-TOOL_STM32H7_App),除了下载还可以仿真。  再次鸣谢CMSIS、安富莱 ~ ~ ~ 

【学习技术群:769843038】下方为一些实例教学,感兴趣的可以看一下。

stm32之SPI通信

SPI通信协议驱动norFlash

从零开始构建一个智能家居项目

天猫精灵蓝牙Mesh实战

stm32-点亮一盏led

学习物联网的那些坑

STM32单片机之GPIO开发

STM32-按键消抖

你可能感兴趣的:(嵌入式开发,stm32,智能家居,单片机,stm32,嵌入式硬件,arm,学习)