
01概述 这里的flash是指STM32F207内部集成的Flash Flash存储器有以下特点 / X; N6 s* k* w! o2 N8 f9 |
7 G. b# ?- t M3 ?* W0 ]# t 存储器的构成 主要存储区块包含4个16K字节扇区,1个64K字节扇区和7个128K字节扇区。 系统存储器是用于在系统boot模式启动设备的。这一块是预留给ST的。包括bootloader程序,boot程序用于通过以下接口对Flash进行编程。USART1、USART3、CAN2、USB OTG FS设备模式(DFU:设备固件升级)。boot程序由ST制造期间编写,用于保护防止错误写入和擦除操作。 ) m8 I D! t+ k* T- m, x- | 512OTP(一次性编程)字节用于用户数据。OTP区域包含16个附加的字节,用于锁定响应的OTP数据。 ' ^# b h! m3 o' k( b: ~) y) | 选项字节,读写保护,BOR水平,软件/硬件看门狗和复位当设置处于待机和停机状态。 ) {, O- I! q1 @ 低功耗模式(参考参考手册的PWR部分) ![]() 对比参考手册的boot部分 ![]() 当BOOT0为0是运行主存储区 ! F% p" t: ]* b 当BOOT0为1,BOOT1为0时运行系统存储区 系统存储区运行的是ST出厂的bootloader代码,跳过过了用户的代码。如果在应用层代码锁定了JTAG管脚(将JTAG管脚用于普通GPIO),我们可以通过修改boot管脚状态,进入系统存储中,再进行debug。 & ?9 ]4 n: g7 Y4 d' J 02Flash操作6 Q% }# F+ G* I' `7 l9 l8 Y L2.1、读取 内置的Flash是处于CortexM3的数据总线上的,所以可以在通用地址空间之间寻址,任何32位数据的读操作都能访问Flash上的数据。
将Address强制转化为32位整型指针,然后取该指针所指向的地址的值,就得到了Address地址上的32位数据。 2.2、擦除 Flash 擦除操作可针对扇区或整个Flash(批量擦除)执行。执行批量擦除时,不会影响OTP扇区或配置扇区。 0 l e) U$ l* V- w! {扇区擦除步骤
0 @, A0 S8 P+ G/ k/ S p: B # |: z4 C, R& }. v7 t 批量擦除步骤 ! u8 p$ F% t$ @1 h4 {$ ^" p7 L
ST提供相应的库函数接口
注意到,有个特殊的参数VoltageRange,这是因为 S- ?: T! F! B& E/ A* T ![]() 这里就不再翻译了,就是在不同电压下数据访问的位数不同,我们是3.3V,所以是32位数据,这也就是在读数据是为什么要读取32位的原因。 3 w& U4 ]2 B! y 2.3、写入 写入之前必须擦除,这里和NorFlash操作是相同的 复位后,Flash控制器寄存器(FLASH_CR)不允许写入的,去保护Flash闪存因为电气原因出现的以外操作,以下是解锁的步骤
3 c; @+ F* P3 w 将FLASH_CR 寄存器中的LOCK 位置为1 后,可通过软件再次锁定FLASH_CR 寄存器 ST提供了库函数 r8 b, U. r' W, ]
6 w' n- m2 Y0 |0 E. a# s 备注: 当FLASH_SR 寄存器中的BSY 位置为1 后,将不能在写模式下访问FLASH_CR 寄存器。BSY 位置为1 后,对该寄存器的任何写操作尝试都会导致AHB 总线阻塞,直到BSY位清零 这要求我们在写入前必须判断下FLASH_SR寄存器中的BSY位。 ST提供了对用的库函数
写入步骤
, }) \4 _+ T) p, g5 F9 Q. D& F$ U 对于写入接口,ST提供相应的库函数,提供了8位,16位,32位的操作,因为我们是3.3V电压,所以使用32位写入接口
2.4、中断 如果对于写入要求较高,可以使能中断,对于写入完成,写入错误都会有响应的中断响应。我也没有详细研究,参看Flash编程手册的15.5章节 1 e, ?3 n% I& V" j3 o2 k03Flash保护 3.1概述 Flash具有读写保护机制,主要是用过选项地址实现的。还有一次性编程保护 $ V5 W7 ~' t. F" B ![]() 这讲述了选项字节的构成 ) H8 N$ V4 N: @ r9 n ![]() 用户修改选项字节
这个上面讲述的解锁Flash相同,就是要写入不能的数值 ) b0 ~% {1 ^ u/ Y. y. l ST提供相应的库函数 2 \( m1 u$ f) z
修改用户字节的步骤
( U5 s b* A& n% [* ` 1 ?! l }' {% @ 3.2 读保护 从上面概述中得知,Flash读保护共分三个等级 1 等级0:没有保护; k6 t% @+ [( J b/ k& a将0xAA 写入读保护选项字节(RDP) 时,读保护级别即设为0。此时,在所有自举配置(Flash用户自举、调试或从RAM 自举)中,均可执行与Flash 或备份SRAM 相关的所有读/写操作(如果未设置写保护)。 这是擦除选项字节后的默认读保护级别。将任意值(分别用于设置级别0 和级别2 的0xAA和0xCC 除外)写入RDP 选项字节时,即激活读保护级别1。设置读保护级别1 后: -在连接调试功能或从RAM 进行自举时,将不执行任何Flash 访问(读取、擦除和编程)。Flash 读请求将导致总线错误。而在使用Flash 用户自举功能或在系统存储器自举模式下操作时,则可执行所有操作 -激活级别1 后,如果将保护选项字节(RDP) 编程为级别0,则将对Flash 和备份SRAM执行批量擦除。因此,在取消读保护之前,用户代码区域会清零。批量擦除操作仅擦除用户代码区域。包括写保护在内的其它选项字节将保持与批量擦除操作前相同。OTP 区域不受批量擦除操作的影响,同样保持不变。 5 C& b9 |! U4 J只有在已激活级别1 并请求级别0 时,才会执行批量擦除。当提高保护级别(0->1,1->2, 0->2) 时,不会执行批量擦除。. 3 等级2:禁止调试/芯片读保护 u; X/ l* A8 r+ X2 B注意: 在注意中写道,如果使能了等级2的读保护,永久禁止JTAG端口(相当于JTAG熔丝)ST也无法进行分析,说白了就是没办法再debug了,目前我没有使用到这个水平的读保护 读保护库函数
查询读保护状态库函数
3.3 写保护 Flash 中的用户扇区(0到11)具备写保护功能,可防止因程序计数器(PC) 跑飞而发生意外的写操作。当扇区i 中的非写保护位(nWRPi, 0 ≤ i ≤ 11) 为低电平时,无法对扇区i 执行擦除或编程操作。因此,如果某个扇区处于写保护状态,则无法执行批量擦除。# I2 p' l$ ]8 @: ~; q: B& a$ a+ n如果尝试对Flash 中处于写保护状态的区域执行擦除/编程操作(由写保护位保护的扇区、锁定的OTP 区域或永远不能执行写操作的Flash 区域,例如ICP),则FLASH_SR 寄存器中的写保护错误标志位(WRPERR) 将置1。) [- \, e; ^" O 写保护库函数
查询写保护状态库函数 3 Y5 d! }' [; l7 H8 M5 N! A4 z9 D
没有使用过,使用了芯片就废了吧,没有做过这个等级等保护,可以参看Flash编程手册的2.7章节 关于读写保护代码如何调用的问题,在stm32f2xx_flash.c文件中有调用说明. 8 I' W9 J5 S' f1 E- |2 W* { w |