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

STM32 Flash详解

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

Flash存储器有以下特点

  • 最大1M字节的能力
  • 128位,也就是16字节宽度的数据读取
  • 字节,半字,字和双字写入
  • 扇区擦除和批量擦除

存储器的构成

主要存储区块包含4个16K字节扇区,1个64K字节扇区和7个128K字节扇区。

系统存储器是用于在系统boot模式启动设备的。这一块是预留给ST的。包括bootloader程序,boot程序用于通过以下接口对Flash进行编程。USART1、USART3、CAN2、USB OTG FS设备模式(DFU:设备固件升级)。boot程序由ST制造期间编写,用于保护防止错误写入和擦除操作。

512OTP(一次性编程)字节用于用户数据。OTP区域包含16个附加的字节,用于锁定响应的OTP数据。

选项字节,读写保护,BOR水平,软件/硬件看门狗和复位当设置处于待机和停机状态。


低功耗模式(参考参考手册的PWR部分)
1.png

对比参考手册的boot部分
2.png

当BOOT0为0是运行主存储区

当BOOT0为1,BOOT1为0时运行系统存储区

系统存储区运行的是ST出厂的bootloader代码,跳过过了用户的代码。如果在应用层代码锁定了JTAG管脚(将JTAG管脚用于普通GPIO),我们可以通过修改boot管脚状态,进入系统存储中,再进行debug。

02Flash操作
2.1、读取
内置的Flash是处于CortexM3的数据总线上的,所以可以在通用地址空间之间寻址,任何32位数据的读操作都能访问Flash上的数据。
  1. data32 = *(__IO uint32_t*)Address;
复制代码

将Address强制转化为32位整型指针,然后取该指针所指向的地址的值,就得到了Address地址上的32位数据。

2.2、擦除
Flash 擦除操作可针对扇区或整个Flash(批量擦除)执行。执行批量擦除时,不会影响OTP扇区或配置扇区。

扇区擦除步骤
  • 1、检查FLASH_SR 寄存器中的BSY 位,以确认当前未执行任何Flash 操作
  • 2、在FLASH_CR 寄存器中将SER 位置1 并选择要擦除的扇区(SNB)(主存储器块中的12个扇区之一)
  • 3、将FLASH_CR 寄存器中的STRT 位置1
  • 4、等待BSY 位清零


批量擦除步骤

  • 1、检查FLASH_SR 寄存器中的BSY 位,以确认当前未执行任何Flash 操作
  • 2、将FLASH_CR 寄存器中的MER 位置1
  • 3、将FLASH_CR 寄存器中的STRT 位置1
  • 4、等待BSY 位清零


ST提供相应的库函数接口

  1. FLASH_Status FLASH_EraseSector(uint32_t FLASH_Sector, uint8_tVoltageRange)
  2. FLASH_Status FLASH_EraseAllSectors(uint8_tVoltageRange)
复制代码


注意到,有个特殊的参数VoltageRange,这是因为

3.png

这里就不再翻译了,就是在不同电压下数据访问的位数不同,我们是3.3V,所以是32位数据,这也就是在读数据是为什么要读取32位的原因。

2.3、写入
写入之前必须擦除,这里和NorFlash操作是相同的

复位后,Flash控制器寄存器(FLASH_CR)不允许写入的,去保护Flash闪存因为电气原因出现的以外操作,以下是解锁的步骤

  • 1、在Flash 密钥寄存器(FLASH_KEYR) 中写入KEY1 = 0x45670123
  • 2、在Flash 密钥寄存器(FLASH_KEYR) 中写入KEY2 = 0xCDEF89AB

将FLASH_CR 寄存器中的LOCK 位置为1 后,可通过软件再次锁定FLASH_CR 寄存器

ST提供了库函数


  1. FLASH_Unlock();//解锁
  2. FLASH_Lock();//重新上锁
复制代码


备注:

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

这要求我们在写入前必须判断下FLASH_SR寄存器中的BSY位。

ST提供了对用的库函数

  1. FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR| FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR);
复制代码

写入步骤

  • 1、检查FLASH_SR 中的BSY 位,以确认当前未执行任何主要Flash 操作
  • 2、将FLASH_CR 寄存器中的PG 位置1。
  • 3、通过不同的位宽对指定地址写入
  • 4、等待BSY 位清零

对于写入接口,ST提供相应的库函数,提供了8位,16位,32位的操作,因为我们是3.3V电压,所以使用32位写入接口
  1. FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data)
复制代码

2.4、中断
如果对于写入要求较高,可以使能中断,对于写入完成,写入错误都会有响应的中断响应。我也没有详细研究,参看Flash编程手册的15.5章节

03Flash保护

3.1概述
Flash具有读写保护机制,主要是用过选项地址实现的。还有一次性编程保护

4.png
这讲述了选项字节的构成

5.png
用户修改选项字节

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:
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.

这个上面讲述的解锁Flash相同,就是要写入不能的数值

ST提供相应的库函数


  1. void FLASH_OB_Unlock(void)
  2. void FLASH_OB_Lock(void)
复制代码


修改用户字节的步骤

  • 1、检查FLASH_SR 寄存器中的BSY 位,以确认当前未执行任何Flash 操作
  • 2、在FLASH_OPTCR 寄存器中写入所需的选项值
  • 3、将FLASH_OPTCR 寄存器中的选项启动位(OPTSTRT) 置1
  • 4、等待BSY 位清零


3.2 读保护
从上面概述中得知,Flash读保护共分三个等级
1 等级0:没有保护
将0xAA 写入读保护选项字节(RDP) 时,读保护级别即设为0。此时,在所有自举配置(Flash用户自举、调试或从RAM 自举)中,均可执行与Flash 或备份SRAM 相关的所有读/写操作(如果未设置写保护)。

2 等级1:闪存读保护
这是擦除选项字节后的默认读保护级别。将任意值(分别用于设置级别0 和级别2 的0xAA和0xCC 除外)写入RDP 选项字节时,即激活读保护级别1。设置读保护级别1 后:

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

-激活级别1 后,如果将保护选项字节(RDP) 编程为级别0,则将对Flash 和备份SRAM执行批量擦除。因此,在取消读保护之前,用户代码区域会清零。批量擦除操作仅擦除用户代码区域。包括写保护在内的其它选项字节将保持与批量擦除操作前相同。OTP 区域不受批量擦除操作的影响,同样保持不变。

只有在已激活级别1 并请求级别0 时,才会执行批量擦除。当提高保护级别(0->1,1->2, 0->2) 时,不会执行批量擦除。.
3 等级2:禁止调试/芯片读保护
注意:

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

查询读保护状态库函数
  1. FlagStatus FLASH_OB_GetRDP(void)
复制代码

3.3 写保护
Flash 中的用户扇区(0到11)具备写保护功能,可防止因程序计数器(PC) 跑飞而发生意外的写操作。当扇区i 中的非写保护位(nWRPi, 0 ≤ i ≤ 11) 为低电平时,无法对扇区i 执行擦除或编程操作。因此,如果某个扇区处于写保护状态,则无法执行批量擦除。


如果尝试对Flash 中处于写保护状态的区域执行擦除/编程操作(由写保护位保护的扇区、锁定的OTP 区域或永远不能执行写操作的Flash 区域,例如ICP),则FLASH_SR 寄存器中的写保护错误标志位(WRPERR) 将置1。


写保护库函数

  1. void FLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState)
复制代码


查询写保护状态库函数

  1. uint16_t FLASH_OB_GetWRP(void)
复制代码
04一次性可编程字节
没有使用过,使用了芯片就废了吧,没有做过这个等级等保护,可以参看Flash编程手册的2.7章节

05 代码
关于读写保护代码如何调用的问题,在stm32f2xx_flash.c文件中有调用说明.


收藏 评论0 发布时间:2020-9-9 10:13

举报

0个回答

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

相似技术帖

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