近日,有位STM32用户在使用STM32芯片内置的BOOTLOADER对芯片进行MCU芯片的信息读取及编程。他发现通过UART接口使用相关BOOTLAODER指令对STM32F1系列芯片的各项功能进行读写时都正常。当改到STM32F4系列时发现有些命令运行就不正常,比如通过READ MEMORY指令获取UID或FLASH SIZE时就会出错。
从STM32F4参考手册中可以得知:Flash size Base address: 0x1FFF 7A22; 读取FLASH SIZE操作步骤及现象如下: 1、启动读内存指令 11 EE 反馈79 2、读内存地址 1F FF 7A 22 B8 反馈79 1F 3、读内存字节数 01 FE 反馈 79 31 00 00 79 上面的现象除了第一步,另外两步都不是用户所期待的数据或反馈。其中第三步的01 FE正好跟获取自举程序版本和读保护状态的命令相同,用户怀疑是否发生了命令冲突。
在谈这个问题之前,我们有必要大致了解一些背景知识。 STM32芯片的片上FLASH往往由几部分组成。以STM32F40X/STM32F41X为例,主要由以下几部分组成:【main memory/system memory/OTP/option bytes】 
其中SYSTEM MEMORY[系统存储区]用来存放系统启动程序和部分其它芯片特征信息,当芯片配置为从SYSTEM MEMORY启动时,芯片复位后就会从这里开始执行程序。 当MCU进入系统启动模式后,用户可以通过多种串行接口与MCU通信。自然,这里就定义了一些相关协议的操作命令。

上表是针对UART接口的BOOTLOADER命令集及说明,比方GO/Get ID/Read Memory/Write memory等。其实不管你用哪种接口,这些BOOTLOADER协议命令都是一样的。
当主机【比如PC】给MCU发正确命令包时 BOOTLOADER会反馈一个ACK, 即0X79。 当主机给MCU发出错误指令或指令运行异常时它会反馈NACK,即0X1F。

尽管说不论哪种接口或芯片的BOOTLOADER的协议命令是一样的,但这些命令所操作的对象或参数可能会因芯片型号或bootloader版本的的不同而呈现差异。

也就是说,不同STM32系列的PID数据、bootloader命令可访问的RAM和system memory的存储空间范围可能不同。
好,该回到开篇客户反映的问题了。客户想通过READ MEMORY指令读取片内FLASH SIZE.
我们查看STM32F1参考手册得知有关FLASH SIZE寄存器的地址是:0x1fff f7e0; 查看STM32F4参考手册得知有关FLASH SIZE寄存器的地址是:0x1fff 7a22; 现在现象是命令一样,接口一样,唯一差别就是二者地址不一样。结合前面的介绍,难道是二者SYSTEM MEMORY地址空间不一样导致?我们可以查看二者的参考手册或者ST官方的应用笔记AN2606查看二者的信息。
我们可以得知STM32F1的SYSTEM MEMORY地址空间为0x1ffff 000--0x1fff f7ff或0x1fff b000--0x1fff f7ff。STM32F4的SYSTEM MEMORY地址空间为0x1ffff000--0x1fff77ff。【在本文的第一个表格里就可看到】

到此,不难看出F4的flash size寄存器地址没有落在自身的SYSTEM MEMORY区,而F1的就落在它自身的SYSTEM MEMORY之内。也就是说,在用READMEMORY命令对STM32F4芯片发送的那个地址是非法的,从而导致错误。当然对于读STM32F4的UID也有同样的问题。所以在应用中我们要注意这些诸如Read /Write/Go命令是有地址范围访问限制的。

下面对客户反馈过来的结果做个简单解读: 从STM32F4参考手册中可以得知:Flash size Base address: 0x1FFF 7A22; 读取FLASH SIZE操作步骤及现象如下: 1、读内存指令启动 11 EE 反馈79 2、读内存地址 1F FF 7A22 B8 反馈79 1F 3、读内存字节数 01 FE 反馈 79 31 00 00 79
第一步,主机发出read memory 指令,MCU反馈ACK,即0X79,这步正确的。 紧跟第二步,主机发出地址及地址数据的异或码【蓝色数据】。命令本身是没问题的,MCU反馈ACK,0X79,但地址数据非法,随即反馈NACK即0X1F;此次命令以失败而结束。 当进行到第三步时,01 FE被重新识别为获取自举程序版本和读保护状态的命令。命令正确并给予ACK确认,并给出版本号3.1及相关选项数据,最后以ACK 0x79结束。 经过三步下来,最后并没有出现客户所期待的结果。原因很简单,命令地址非法。
关于使用systembootloader的调试编程,ST官方有篇应用笔记AN2606首先需要阅读,再就是结合你的通信接口选择下面罗列出的相应笔记进行阅读。 
相关话题链接【点击即可阅读】
1.一个关于STM32 FLASH编程应用相关的话题 2.STM32F0的BOOT配置及相关话题 3.聊聊STM32芯片的DFU编程及相关话题
|