STM32的ISP升级详解
2018-08-22 来源:eefocus
最近在做一个给STM32用ISP升级的项目,接触到STM32厂家烧录的Bootloader工作流程,具体官方文档稍后上传供大家参考,也可去ST官网下载文档。接下来针对文档中部分内容分析其工作过程:
一、要进入该模式,需把STM32硬件上的BOOT0引脚拉高(置1),BOOT1拉低(置0),对此部分不明白的可以查阅STM32BOOT引脚的资料(网上一搜一大堆),不过多阐述。两个引脚配置好对STM32复位,其在4个时钟周期内会自动检测BOOT引脚相应的配置情况,进入相应模式(原厂Bootloader模式)下工作,此时已经到达此次旅行的起点——USART Bootloader 模式
此处要特别注意的是硬件上一定要用原厂规定的串口才能完成此功能!在项目我使用的是STM32F030X8,相应的是PA9、PA10或者PA14、PA15,具体用什么串口不同型号芯片有所差异,另一份官方文档我也会上传,它详细描述了不同型号芯片关于Bootloader的注意事项,两份文档结合即可
二、上图展示的即是整个模式下芯片内部的工作流程,我们只需遵照流程做事就OK
接下来的描述中以STM32作为从机,一切发送串口命令端为主机;从机对主机的正确应答为0X79(ACK),异常应答为0X1F(NACK),在文档中亦有描述:
所有命令中,如果收到为NACK则回到用户命令等待阶段
1.首先是第一步,主机在串口发送一个字节0X7F(十六进制),STM32会根据该字节主机传输时的波特率自动识别双方的通信速率(波特率)并初始化从机串口,完毕回复主机一个字节0X79(ACK)并且失能从机所有无用的外设,进入用户命令等待阶段
2.此时从机等待主机发送进一步的执行命令,所有命令及功能描述如下图:
可以注意到有些命令标注了右上角的小括号,这些注释也需要尤为关注,往往出现问题就是没有仔细查看注释内容!
此处要提及的就是有的芯片被RDP(读保护)激活,如果没有解除只有少部分命令可以使用;在擦除芯片命令(稍后介绍)的两个中,一个型号芯片只有一个命令会起作用哦(小弟就吃过亏啊~~),希望大家引起注意。还有的注释可以自行查看这里不介绍啦
在裸机开发(不使用VB编写上位机)我使用的只有从0X31(写内存命令)开始到0X92的7个命令,我就以此7个命令倒叙地(因为正常来说应该先做下面事情再往上做...)介绍一下我是如何做的。
①Readout Unprotect(0X92):解除芯片读保护
上图为解除读保护主机端流程图,很明确地首先发送两个字节0X92和0X6D的命令组合,等待芯片回应两个ACK,读保护就解除成功啦。
需要注意的是对读保护和写保护无论是解除还是激活,操作成功后都会触发芯片的复位而重新加载选项字配置并进入Bootloader模式,想进行下一步命令都要重新发0X7F让从机初始化串口进入等待用户命令模式哦,这里要强调强调再强调!
②Readout Protect(0X82):激活芯片读保护
上图为激活芯片读保护主机端的流程图,与解除读保护同理,不再描述啦
③Write Unprotect(0X73):解除芯片对所有扇区的写保护
上图为解除芯片所有扇区的写保护主机端流程图,与解除芯片读保护同理哦
④Write Protect(0X63):激活芯片部分扇区的写保护
细心的看官会发现,诶,部分扇区,什么情况呢?
上图为对激活芯片部分扇区写保护主机端的流程图,老规矩,发送两字节命令组合0X63+0X9C等待一个ACK,接着发送一个字节N表示长度值——要写保护的扇区数-1,发送扇区代码N+1个字节(说实话小弟也没有明白这里要发送的扇区代码指的是什么,如果有前辈可以解答的话,小弟在此感激不尽呐...在这里不影响我们可以烧程序进FLASH)发送完扇区代码,就是发送一个字节对长度值字节和代码区字节的异或校验值啦(这个校验值后面会详细说明滴),等待ACK应答,如果成功,芯片同样产生一个复位
⑤Extended Erase(0X44):用两个字节寻址模式擦除从一个到所有的闪存页
这个命令可以用户自由擦除闪存页
上图为主机端自由擦除闪存页的流程图,开始发送两字节组合命令0X44+0XBB,等到ACK后选择要擦除的方式,我使用的是全部擦除命令,也就是左边的0XFFFF来擦除所有闪存页的代码,接着是对上面这个两字节命令的校验字节,成功则回应ACK,其实特殊擦除命令中除了0XFFFF,下面的Bank1和Bank2...小弟不才,希望知道意思的前辈能指教指教呀~
至于右边的则是用户可以自定义要擦除哪些页的命令流程,首先以两个字节形式(MSB)把要擦除的总页数告诉BL程序,然后发送要擦除页的编号——如:要擦除第0页(Page 0)、第1页(Page 1),以两个字节形式(MSB)发送0X00,0X00;0X00,0X01;以此类推把要擦除的页码都发出去,最后对前面发送的总页数和各页码的异或校验字节...等待ACK即可
一页有多大呢?这个问题我也困惑过,不过在芯片的寄存器手册上有个表格已经写得很清楚啦,要仔细查阅FLASH相关章节哦
⑥Erase(0X43):擦除一个到所有闪存页
其实这个命令和上面一个类似,但是我前面说了一个型号芯片只支持一个命令有效
上图为擦除一个到所有闪存页主机端的流程图,和上一个命令类似地,这个倒是更简单点可以直接选择是否全部擦除的0XFF,选择的右边是使用页擦除的方式,每个型号芯片的一页大小有所不同,这里的流程表示先发送一个字节要擦除的页数量,接着是要擦除哪些页的编号,然后是校验值
⑦Write Memory(0X31):写闪存命令
最多可以写256字节到STM32RAM或FLASH闪存地址中,这个命令是整个烧录过程的重点
--上图为写内存命令在主机端的流程图,发送一个字节0X31接着0XCE(对0X31的检验值),如果从机的RDP没有被激活那么会等到从机给出一个ACK,否则从机将回复NACK,那么就需要去解除RDP,稍后会说;--等到ACK后发送一个四字节组成的内存地址,注意四个字节中MSB先发,四字节发完紧跟着发送一个字节异或校验值(对以上四字节的校验),等待从机校验正确给出ACK,如果从机接收到的异或校验值错误便回复NACK;--收到ACK后有三步:发送要传输的数据字节数量-1;发送数据字节;发送对字节数字节和数据字节一起的异或校验值,等待ACK; 此过程参考下图描述:
也许还有看官会疑惑,这都什么跟什么呀,一点都不清晰...没错!我的第一感觉也是这样[无奈],只能说此文档编写者描述不够详细,接下来小弟为大家的疑惑作些解答,见笑了...
首先一个问题就是校验值,这一点我挺奇怪的,明明就是异或校验嘛,写什么Checksum...还好看到了前面一个注解说明:
呐... 这里呢说的挺详细了,checksum表示异或的结果字节和每一个命令跟着他的异或值作为一个组合,有人会问了一个字节怎么异或?一个字节呢就和0XFF异或也就是取了个反,多个字节就互相之间取异或到最后一个字节啦
下一个问题是我在写内存流程图里圈出的,发送N+1个字节?什么鬼?莫着急,听我道来...
在收到地址四字节的ACK以后,主机就要发送表示长度值的字节和用户数据了嘛,这个长度值的字节就是N,用户数据却要发N+1个字节。 下面这个栗子会直观点:
发送的长度值是3(N),那么在用户数据区就要传输4个字节(N+1)数据,最后是对长度值字节和数据区字节的校验值,这里还要注意哦,用户数据区的字节数一定要为4的倍数哦(4/8/12/16/20...以此类推),否则将出现收不到ACK的情况
再一个问题就是,如果给STM32升级,那要往指定FLASH里放什么数据嘞? 有人说这不废话嘛,单片机FLASH里不放代码拿什么给它执行呢... 对,就是这个问题,你怎么获得代码?当工程里复制粘贴肯定是不行的,我们不是有.hex文件嘛,用串口ISP烧录工具不就是hex文件嘛!诶,这是不行的哦,.hex文件用文本查看出来也是有一定格式的,是为了上位机更好的识别要把什么内容放到什么地址去,所以会有一大堆对我们写入FLASH来说无用的格式呢...
那到底是什么文件才能直接用呢——bin文件,bin文件是什么这里不讲述,通过查看可以知道里面包含的就是hex中的数据区内容,也就是我们真正要的内容,把这些内容读出来写到对应FLASH地址就对啦!
以上命令如果要循环执行,比如写闪存命令,则需要再次发送0X31+0XCE来启动这个命令功能写下一包的数据,注意地址要偏移相应的数据区大小哦~
三、把第“一”步骤中的BOOT0引脚拉低(置0),对STM32复位来使新烧录的程序正常运行