STMCU小助手
发布时间:2022-4-18 10:41
本文将根据ST官方Flashprogramming manual,文档编号:PM0059,讲解STM32F207内部Flash编程。
01、概述$ i, M, k, u1 }" j2 h8 P& i g 这里的flash是指STM32F207内部集成的Flash & j5 T. [% `& T" {9 \( O0 w0 ` Flash存储器有以下特点 最大1M字节的能力 128位,也就是16字节宽度的数据读取 字节,半字,字和双字写入 扇区擦除和批量擦除 存储器的构成 / J5 H+ v; W/ v1 }6 g4 s( f0 R 主要存储区块包含4个16K字节扇区,1个64K字节扇区和7个128K字节扇区。 ! V6 p4 x1 \5 ]( g 系统存储器是用于在系统boot模式启动设备的。这一块是预留给ST的。包括bootloader程序,boot程序用于通过以下接口对Flash进行编程。USART1、USART3、CAN2、USB OTG FS设备模式(DFU:设备固件升级)。boot程序由ST制造期间编写,用于保护防止错误写入和擦除操作。 p) F+ z9 G! m' A 4 T9 u- `: O& a5 z# [7 @0 T 512OTP(一次性编程)字节用于用户数据。OTP区域包含16个附加的字节,用于锁定响应的OTP数据。2 @. }7 s8 T' D K6 B 选项字节,读写保护,BOR水平,软件/硬件看门狗和复位当设置处于待机和停机状态。 2 ]. m/ `4 m5 d' C# B( L1 t* @/ } 低功耗模式(参考参考手册的PWR部分) " r1 P" G% a, P# ]* o1 [
对比参考手册的boot部分 , u5 G; \( S6 l6 B. a5 w; S
当BOOT0为0是运行主存储区 当BOOT0为1,BOOT1为0时运行系统存储区 % U4 h5 o6 ^& ~+ T 系统存储区运行的是ST出厂的bootloader代码,跳过过了用户的代码。如果在应用层代码锁定了JTAG管脚(将JTAG管脚用于普通GPIO),我们可以通过修改boot管脚状态,进入系统存储中,再进行debug。 02、Flash操作* X3 l- X% a1 e/ `3 e+ ?7 n9 w 2.1、读取 内置的Flash是处于CortexM3的数据总线上的,所以可以在通用地址空间之间寻址,任何32位数据的读操作都能访问Flash上的数据。 data32 = *(__IO uint32_t*)Address;& R6 u6 d" y# ~; O 将Address强制转化为32位整型指针,然后取该指针所指向的地址的值,就得到了Address地址上的32位数据。 6 F/ p% m' @2 [2 k0 X+ E! J 2.2、擦除 Flash 擦除操作可针对扇区或整个Flash(批量擦除)执行。执行批量擦除时,不会影响OTP扇区或配置扇区。 扇区擦除步骤 1、检查FLASH_SR 寄存器中的BSY 位,以确认当前未执行任何Flash 操作+ G- D. m2 C' H+ Y2 V 2、在FLASH_CR 寄存器中将SER 位置1 并选择要擦除的扇区(SNB)(主存储器块中的12个扇区之一)' F" r+ L$ N7 E: ^+ E7 d" e 3、将FLASH_CR 寄存器中的STRT 位置1 4、等待BSY 位清零 * Y! \8 v; c6 n5 k1 z' d 批量擦除步骤; v+ z& h/ a7 |/ e+ N- `7 Q, t0 t4 W . Q* _! V6 S* A: k* @7 G 1、检查FLASH_SR 寄存器中的BSY 位,以确认当前未执行任何Flash 操作 2、将FLASH_CR 寄存器中的MER 位置1 ! r7 p6 ?7 N% R# S. x+ k j" \, z2 ~0 x 3、将FLASH_CR 寄存器中的STRT 位置1 9 [% r" w U6 d7 `4 w- f. z, Z 4、等待BSY 位清零 - G' d0 `9 @9 `8 D: e- D/ D- | ST提供相应的库函数接口
注意到,有个特殊的参数VoltageRange,这是因为) r1 s3 A/ {4 c9 V r( H/ ` Y
这里就不再翻译了,就是在不同电压下数据访问的位数不同,我们是3.3V,所以是32位数据,这也就是在读数据是为什么要读取32位的原因。' k, T* q! p0 G' q7 R" c 2.3、写入 写入之前必须擦除,这里和NorFlash操作是相同的' ~3 u; p$ ^4 y$ a% v" p . Q5 i/ j1 x& m- y 复位后,Flash控制器寄存器(FLASH_CR)不允许写入的,去保护Flash闪存因为电气原因出现的以外操作,以下是解锁的步骤 1、在Flash 密钥寄存器(FLASH_KEYR) 中写入KEY1 = 0x456701234 J2 y. w2 [8 w % L+ x m0 i# Q3 h( F. }. j 2、在Flash 密钥寄存器(FLASH_KEYR) 中写入KEY2 = 0xCDEF89AB: F7 V3 m2 C% J3 t( K 将FLASH_CR 寄存器中的LOCK 位置为1 后,可通过软件再次锁定FLASH_CR 寄存器 ST提供了库函数 " }: X* q& Q9 T2 }
备注: - c, O& N" a- e9 D5 w2 F 当FLASH_SR 寄存器中的BSY 位置为1 后,将不能在写模式下访问FLASH_CR 寄存器。BSY 位置为1 后,对该寄存器的任何写操作尝试都会导致AHB 总线阻塞,直到BSY位清零/ s/ M d9 H$ W 4 ?; ^4 D6 z8 u" ]' X 这要求我们在写入前必须判断下FLASH_SR寄存器中的BSY位。 : h1 P& O' F% w$ I' ?( b) E' w ST提供了对用的库函数 W9 H Z1 k+ m1 ?: X; D X 5 Z9 s- N# I$ W7 E& p
写入步骤 . K9 p& c( n6 z3 C* v9 _ 1、检查FLASH_SR 中的BSY 位,以确认当前未执行任何主要Flash 操作 - a( I5 o. I6 S2 k5 s; P1 N 2、将FLASH_CR 寄存器中的PG 位置1。 ' |- ]' L# k9 s- N0 F- g* M O 3、通过不同的位宽对指定地址写入5 w9 o; h, N+ i- y. | . c! ~5 y! |; ]( n 4、等待BSY 位清零 0 g3 d% _3 m" x& B( P; q 对于写入接口,ST提供相应的库函数,提供了8位,16位,32位的操作,因为我们是3.3V电压,所以使用32位写入接口% C' D: W D% h5 X
2.4、中断 如果对于写入要求较高,可以使能中断,对于写入完成,写入错误都会有响应的中断响应。我也没有详细研究,参看Flash编程手册的15.5章节" ?5 Y5 l) I% m0 _ & [# s& c: c3 c 03、Flash保护- y* x" R. N: i( X2 u. z; N 3.1概述 Flash具有读写保护机制,主要是用过选项地址实现的。还有一次性编程保护! a, j+ W" F# y7 a
1 K1 h/ T" \4 X% ^( K% r 这讲述了选项字节的构成. r) w; j% R; y c" q3 p8 e" N& z" G
" J g' J. ~$ Q 用户修改选项字节, i$ ?/ ~3 f& K To run any operation on this sector, the option lock bit (OPTLOCK) inthe Flash option control register (FLASH_OPTCR) must be cleared. Tobe allowed to clear this bit, you have to perform the followingsequence: . r9 @( l1 H0 n) ]. Y 1. Write OPTKEY1 = 0x0819 2A3B in the Flash option key register(FLASH_OPTKEYR) 8 `8 Q# t2 E* I6 ~" c& b. q' }' _ 2. Write OPTKEY2 = 0x4C5D 6E7F in the Flash option key register(FLASH_OPTKEYR)/ p/ ^* _. w6 P9 m" p6 v+ V& j! y8 { The user option bytes can be protected against unwanted erase/programoperations by setting the OPTLOCK bit by software.6 g& [4 k4 r& r5 M7 Y 这个上面讲述的解锁Flash相同,就是要写入不能的数值 ' x% k s" j( _$ \6 E: }6 K ST提供相应的库函数1 q% A, `+ @( E# q1 N2 B% j
修改用户字节的步骤 1、检查FLASH_SR 寄存器中的BSY 位,以确认当前未执行任何Flash 操作" O* X# o( [+ s , D0 c$ d' t3 X& F 2、在FLASH_OPTCR 寄存器中写入所需的选项值8 L l) G# P/ g4 }9 ?, } ; x' R3 H& |) j e 3、将FLASH_OPTCR 寄存器中的选项启动位(OPTSTRT) 置1 . G2 x: S: h2 v7 t R 4、等待BSY 位清零 ( t5 f6 w' P% x! t 3.2 读保护$ }0 ]! i: @- c* I& g! U# R 从上面概述中得知,Flash读保护共分三个等级 5 d7 S% ]% R/ O* O* E 等级0:没有保护1 G/ J u! e: E, a ! R7 e: Z# a, f! ~ 将0xAA 写入读保护选项字节(RDP) 时,读保护级别即设为0。此时,在所有自举配置(Flash用户自举、调试或从RAM 自举)中,均可执行与Flash 或备份SRAM 相关的所有读/写操作(如果未设置写保护)。4 F, g: ?$ V. J0 c , c' y# l1 v* _( `' L3 y 等级1:闪存读保护/ J2 ?3 L* p' l 这是擦除选项字节后的默认读保护级别。将任意值(分别用于设置级别0 和级别2 的0xAA和0xCC 除外)写入RDP 选项字节时,即激活读保护级别1。设置读保护级别1 后:* h" }. B. J- R% H -在连接调试功能或从RAM 进行自举时,将不执行任何Flash 访问(读取、擦除和编程)。Flash 读请求将导致总线错误。而在使用Flash 用户自举功能或在系统存储器自举模式下操作时,则可执行所有操作 -激活级别1 后,如果将保护选项字节(RDP) 编程为级别0,则将对Flash 和备份SRAM执行批量擦除。因此,在取消读保护之前,用户代码区域会清零。批量擦除操作仅擦除用户代码区域。包括写保护在内的其它选项字节将保持与批量擦除操作前相同。OTP 区域不受批量擦除操作的影响,同样保持不变。4 I/ `+ W0 x# [0 D/ Y 只有在已激活级别1 并请求级别0 时,才会执行批量擦除。当提高保护级别(0->1,1->2, 0->2) 时,不会执行批量擦除。) \$ U. ~) f- e. V3 Z 9 r, f& u# L. J, z( Q" E- ]1 { 等级2:禁止调试/芯片读保护 5 n. }/ u. Z$ T0 r1 @0 y% w 注意:+ a+ V% o% g4 s3 n+ D 5 H9 |4 ?6 G, V) ] 在注意中写道,如果使能了等级2的读保护,永久禁止JTAG端口(相当于JTAG熔丝)ST也无法进行分析,说白了就是没办法再debug了,目前我没有使用到这个水平的读保护 读保护库函数3 Y: G( F# y9 ~, V ?/ J6 \3 K5 c! ^7 L0 K
查询读保护状态库函数
3.3 写保护) I9 @( E `6 | e, D- G Flash 中的用户扇区(0到11)具备写保护功能,可防止因程序计数器(PC) 跑飞而发生意外的写操作。当扇区i 中的非写保护位(nWRPi, 0 ≤ i ≤ 11) 为低电平时,无法对扇区i 执行擦除或编程操作。因此,如果某个扇区处于写保护状态,则无法执行批量擦除。7 o7 u7 P+ [7 r4 F& D% I 如果尝试对Flash 中处于写保护状态的区域执行擦除/编程操作(由写保护位保护的扇区、锁定的OTP 区域或永远不能执行写操作的Flash 区域,例如ICP),则FLASH_SR 寄存器中的写保护错误标志位(WRPERR) 将置1。 写保护库函数1 b2 i" ^; p5 b$ M% c
查询写保护状态库函数
04、一次性可编程字节; J9 y4 u, M9 B, B: K6 n 没有使用过,使用了芯片就废了吧,没有做过这个等级等保护,可以参看Flash编程手册的2.7章节* v; Z# a$ w4 I. m 05、代码 关于读写保护代码如何调用的问题,在stm32f2xx_flash.c文件中有调用说明.。
1 L: V* V7 K( j. x! D 7 ]$ D. e9 ~8 _, f/ o |
【经验分享】STM32语音识别的智能蓝牙音箱(源程序+原理图+PCB+设计说明书+PPT)
想找个ST芯片
[GPIO] 使用新型抽象开始C++嵌入式编程,从GPIO开始
技术手册stm32f1xx中的一个小问题
【经验分享】STM32 HAL库移植FreeModbus详细步骤
【逢7发帖赢大礼】STM32开发之IC门禁卡UID读取方法!
实战经验 | Keil工程使用NEAI库的异常问题
经验分享 | FDCAN数据段波特率增加后发送失败的问题分析
STM32几种流行开发环境的优缺点
好用软件推荐-TouchGFX Designer
微信公众号
手机版