你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32 Flash详解

[复制链接]
STMCU-管管 发布时间:2020-9-9 10:13
01概述
这里的flash是指STM32F207内部集成的Flash

# F% P% U; ?& G: H+ A9 v
Flash存储器有以下特点
/ X; N6 s* k* w! o2 N8 f9 |
  • 最大1M字节的能力
  • 128位,也就是16字节宽度的数据读取
  • 字节,半字,字和双字写入
  • 扇区擦除和批量擦除8 N3 w% c, |4 o2 Q% |
7 G. b# ?- t  M3 ?* W0 ]# t
存储器的构成

0 O. s8 f6 P* B
主要存储区块包含4个16K字节扇区,1个64K字节扇区和7个128K字节扇区。

. g. i# O2 \1 `; z
系统存储器是用于在系统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 @

, i* ]& c/ o2 U! k
低功耗模式(参考参考手册的PWR部分)
1.png

9 V8 G: ]0 Q* E4 R5 K
对比参考手册的boot部分
2.png
: \( ]: w% r/ @) B- a
当BOOT0为0是运行主存储区
! F% p" t: ]* b
当BOOT0为1,BOOT1为0时运行系统存储区

0 G$ J9 n- ?! c) \
系统存储区运行的是ST出厂的bootloader代码,跳过过了用户的代码。如果在应用层代码锁定了JTAG管脚(将JTAG管脚用于普通GPIO),我们可以通过修改boot管脚状态,进入系统存储中,再进行debug。
& ?9 ]4 n: g7 Y4 d' J
02Flash操作6 Q% }# F+ G* I' `7 l9 l8 Y  L
2.1、读取
内置的Flash是处于CortexM3的数据总线上的,所以可以在通用地址空间之间寻址,任何32位数据的读操作都能访问Flash上的数据。
  1. data32 = *(__IO uint32_t*)Address;
复制代码
0 H4 e" @3 a$ O: X
将Address强制转化为32位整型指针,然后取该指针所指向的地址的值,就得到了Address地址上的32位数据。
% B$ p3 y/ e% E0 V; h

! }& Q0 y' K- V8 x/ i
2.2、擦除
Flash 擦除操作可针对扇区或整个Flash(批量擦除)执行。执行批量擦除时,不会影响OTP扇区或配置扇区。
0 l  e) U$ l* V- w! {
扇区擦除步骤
  • 1、检查FLASH_SR 寄存器中的BSY 位,以确认当前未执行任何Flash 操作
  • 2、在FLASH_CR 寄存器中将SER 位置1 并选择要擦除的扇区(SNB)(主存储器块中的12个扇区之一)
  • 3、将FLASH_CR 寄存器中的STRT 位置1
  • 4、等待BSY 位清零
    5 B8 e$ Z4 u/ W2 y7 Q) g: z
0 @, A0 S8 P+ G/ k/ S  p: B
# |: z4 C, R& }. v7 t
批量擦除步骤
! u8 p$ F% t$ @1 h4 {$ ^" p7 L
  • 1、检查FLASH_SR 寄存器中的BSY 位,以确认当前未执行任何Flash 操作
  • 2、将FLASH_CR 寄存器中的MER 位置1
  • 3、将FLASH_CR 寄存器中的STRT 位置1
  • 4、等待BSY 位清零
    / M- z8 k! I! f5 ?4 ^# {

  l2 d. ]& _: p" u8 n7 J- q

) X; t+ ?: B5 K2 e. d0 b
ST提供相应的库函数接口
  1. 4 Y/ a5 B" o2 |' v, m, b- S
  2. FLASH_Status FLASH_EraseSector(uint32_t FLASH_Sector, uint8_tVoltageRange)
    7 j. d7 s. w; d  Y/ D
  3. FLASH_Status FLASH_EraseAllSectors(uint8_tVoltageRange)
复制代码

9 N" A/ `$ L6 Y' T1 ]$ z  M

$ F, j+ Q6 C5 L& W4 N2 [6 x
注意到,有个特殊的参数VoltageRange,这是因为
  S- ?: T! F! B& E/ A* T
3.png

( V& v8 m% [8 Q
这里就不再翻译了,就是在不同电压下数据访问的位数不同,我们是3.3V,所以是32位数据,这也就是在读数据是为什么要读取32位的原因。
3 w& U4 ]2 B! y
2.3、写入
写入之前必须擦除,这里和NorFlash操作是相同的

: {6 n& D3 M; A- Z/ o+ O2 }6 o
复位后,Flash控制器寄存器(FLASH_CR)不允许写入的,去保护Flash闪存因为电气原因出现的以外操作,以下是解锁的步骤

# r. d1 ^" e" M9 G
  • 1、在Flash 密钥寄存器(FLASH_KEYR) 中写入KEY1 = 0x45670123
  • 2、在Flash 密钥寄存器(FLASH_KEYR) 中写入KEY2 = 0xCDEF89AB
    9 W7 M7 J/ a* o2 h8 A
3 c; @+ F* P3 w
将FLASH_CR 寄存器中的LOCK 位置为1 后,可通过软件再次锁定FLASH_CR 寄存器

9 ]7 G( _! s/ u6 f5 {% z9 q5 H/ W% l
ST提供了库函数
  r8 b, U. r' W, ]

  1. 8 ]( B8 \# R' {5 k. M
  2. FLASH_Unlock();//解锁
    ! e0 I8 @# |" u4 {  K2 k
  3. FLASH_Lock();//重新上锁
复制代码
5 M7 N, ~" K6 E$ I/ q! n
6 w' n- m2 Y0 |0 E. a# s
备注:

: v0 x- S9 _. _8 i4 ]
当FLASH_SR 寄存器中的BSY 位置为1 后,将不能在写模式下访问FLASH_CR 寄存器。BSY 位置为1 后,对该寄存器的任何写操作尝试都会导致AHB 总线阻塞,直到BSY位清零

* i. ?7 n9 E# b6 x
这要求我们在写入前必须判断下FLASH_SR寄存器中的BSY位。

: t3 B4 d& e7 U* \/ I
ST提供了对用的库函数

  1. 9 q; f: K" O& x$ p2 U9 E. M  T4 U  K
  2. FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR| FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR);
复制代码
; s1 _* U2 i# x2 f/ u9 `( _
写入步骤

4 E' }: ]/ X9 S) U
  • 1、检查FLASH_SR 中的BSY 位,以确认当前未执行任何主要Flash 操作
  • 2、将FLASH_CR 寄存器中的PG 位置1。
  • 3、通过不同的位宽对指定地址写入
  • 4、等待BSY 位清零4 D7 c1 N* ?% T* c+ c/ c1 P( D
, }) \4 _+ T) p, g5 F9 Q. D& F$ U
对于写入接口,ST提供相应的库函数,提供了8位,16位,32位的操作,因为我们是3.3V电压,所以使用32位写入接口
  1. FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data)% g0 K  s8 J+ w8 o
复制代码
( p/ }! `2 S( [+ z% n% k
2.4、中断
如果对于写入要求较高,可以使能中断,对于写入完成,写入错误都会有响应的中断响应。我也没有详细研究,参看Flash编程手册的15.5章节
1 e, ?3 n% I& V" j3 o2 k
03Flash保护

4 t7 a2 h1 y: T
3.1概述
Flash具有读写保护机制,主要是用过选项地址实现的。还有一次性编程保护
$ V5 W7 ~' t. F" B
4.png
这讲述了选项字节的构成
) H8 N$ V4 N: @  r9 n
5.png
用户修改选项字节

. l% O3 z9 P, x. @
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:
* y" h& @( P! D- S: s! g1 T. [
1. Write OPTKEY1 = 0x0819 2A3B in the Flash option key register(FLASH_OPTKEYR)
2. Write OPTKEY2 = 0x4C5D 6E7F in the Flash option key register(FLASH_OPTKEYR)
The user option bytes can be protected against unwanted erase/programoperations by setting the OPTLOCK bit by software.

" V6 t6 _  q9 M& N8 R3 z/ F
这个上面讲述的解锁Flash相同,就是要写入不能的数值
) b0 ~% {1 ^  u/ Y. y. l
ST提供相应的库函数
2 \( m1 u$ f) z

  1. . `9 g' t# J5 J) Z3 j  ?' G; B
  2. void FLASH_OB_Unlock(void), O- _- v! }# r
  3. void FLASH_OB_Lock(void)
复制代码
) t3 Y) ^  g: P5 k# W

# z2 o# {, k- d' Z& B: _
修改用户字节的步骤

* w. e0 y& ?" e2 D0 D
  • 1、检查FLASH_SR 寄存器中的BSY 位,以确认当前未执行任何Flash 操作
  • 2、在FLASH_OPTCR 寄存器中写入所需的选项值
  • 3、将FLASH_OPTCR 寄存器中的选项启动位(OPTSTRT) 置1
  • 4、等待BSY 位清零
    % p+ Z% t$ b1 m
( 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 相关的所有读/写操作(如果未设置写保护)。

6 E  g, n7 Z' u4 S; `. p
2 等级1:闪存读保护. P# b. Q- U& a& ~" i
这是擦除选项字节后的默认读保护级别。将任意值(分别用于设置级别0 和级别2 的0xAA和0xCC 除外)写入RDP 选项字节时,即激活读保护级别1。设置读保护级别1 后:

) r7 N8 M6 Z! b
-在连接调试功能或从RAM 进行自举时,将不执行任何Flash 访问(读取、擦除和编程)。Flash 读请求将导致总线错误。而在使用Flash 用户自举功能或在系统存储器自举模式下操作时,则可执行所有操作

- Y8 z) s4 ?+ {! G$ y* Z$ e
-激活级别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
注意:

; a4 ^; V& p5 |0 h+ R
在注意中写道,如果使能了等级2的读保护,永久禁止JTAG端口(相当于JTAG熔丝)ST也无法进行分析,说白了就是没办法再debug了,目前我没有使用到这个水平的读保护
读保护库函数
  1. void FLASH_OB_RDPConfig(uint8_t OB_RDP)
复制代码

3 a2 k1 ]; h5 m
查询读保护状态库函数
  1. FlagStatus FLASH_OB_GetRDP(void)
复制代码

. h7 A6 ^+ O; b* r
3.3 写保护
Flash 中的用户扇区(0到11)具备写保护功能,可防止因程序计数器(PC) 跑飞而发生意外的写操作。当扇区i 中的非写保护位(nWRPi, 0 ≤ i ≤ 11) 为低电平时,无法对扇区i 执行擦除或编程操作。因此,如果某个扇区处于写保护状态,则无法执行批量擦除。# I2 p' l$ ]8 @: ~; q: B& a$ a+ n

, O6 y! F8 E# w& E" u. G

9 c$ B1 j5 ~* s1 C5 g如果尝试对Flash 中处于写保护状态的区域执行擦除/编程操作(由写保护位保护的扇区、锁定的OTP 区域或永远不能执行写操作的Flash 区域,例如ICP),则FLASH_SR 寄存器中的写保护错误标志位(WRPERR) 将置1。) [- \, e; ^" O

( f6 i6 i5 Q+ u1 \7 j

) Q  w. s) O( G. I
写保护库函数

  1. . e1 p" F/ B7 G% X
  2. void FLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState)
复制代码
3 i) a( J/ s1 Q

8 G! E3 |* \7 l: R2 x
查询写保护状态库函数
3 Y5 d! }' [; l7 H8 M5 N! A4 z9 D
  1. uint16_t FLASH_OB_GetWRP(void)
复制代码
04一次性可编程字节
3 D( X  f( a6 {, r" M) S( g- A: X
没有使用过,使用了芯片就废了吧,没有做过这个等级等保护,可以参看Flash编程手册的2.7章节

* q! [. q# |0 @- S& R* i4 n
05 代码
( I! m' _7 k: `9 C0 x# c0 _4 I% C6 j
关于读写保护代码如何调用的问题,在stm32f2xx_flash.c文件中有调用说明.

+ d& D9 b8 V# \6 N' R8 Q3 D' O3 m8 I' W9 J5 S' f1 E- |2 W* {  w
收藏 评论0 发布时间:2020-9-9 10:13

举报

0个回答

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版