STM32 Flash详解

2023-11-01

本文将根据ST官方Flashprogramming manual,文档编号:PM0059,讲解STM32F207内部Flash编程。

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部分)

对比参考手册的boot部分

当BOOT0为0是运行主存储区

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

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

02、Flash操作

2.1、读取

内置的Flash是处于CortexM3的数据总线上的,所以可以在通用地址空间之间寻址,任何32位数据的读操作都能访问Flash上的数据。

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提供相应的库函数接口

FLASH_Status FLASH_EraseSector(uint32_t FLASH_Sector, uint8_tVoltageRange)
FLASH_Status FLASH_EraseAllSectors(uint8_tVoltageRange)

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

这里就不再翻译了,就是在不同电压下数据访问的位数不同,我们是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提供了库函数

FLASH_Unlock();//解锁
FLASH_Lock();//重新上锁

备注:

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

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

ST提供了对用的库函数

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位写入接口

FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data)

2.4、中断

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

03、Flash保护

3.1概述

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

这讲述了选项字节的构成

用户修改选项字节

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提供相应的库函数

void FLASH_OB_Unlock(void)
void FLASH_OB_Lock(void)

修改用户字节的步骤

1、检查FLASH_SR 寄存器中的BSY 位,以确认当前未执行任何Flash 操作

2、在FLASH_OPTCR 寄存器中写入所需的选项值

3、将FLASH_OPTCR 寄存器中的选项启动位(OPTSTRT) 置1

4、等待BSY 位清零

3.2 读保护

从上面概述中得知,Flash读保护共分三个等级

等级0:没有保护

将0xAA 写入读保护选项字节(RDP) 时,读保护级别即设为0。此时,在所有自举配置(Flash用户自举、调试或从RAM 自举)中,均可执行与Flash 或备份SRAM 相关的所有读/写操作(如果未设置写保护)。

等级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) 时,不会执行批量擦除。

等级2:禁止调试/芯片读保护

注意:

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

读保护库函数

void FLASH_OB_RDPConfig(uint8_t OB_RDP)

查询读保护状态库函数

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。

写保护库函数

void FLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState)

查询写保护状态库函数

uint16_t FLASH_OB_GetWRP(void)

04、一次性可编程字节

没有使用过,使用了芯片就废了吧,没有做过这个等级等保护,可以参看Flash编程手册的2.7章节

05、代码

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

/** @defgroup FLASH_Group3 Option Bytes Programming functions
 *  @brief   Option Bytes Programming functions 
 *
@verbatim   
 ===============================================================================
                        Option Bytes Programming functions
 ===============================================================================  
 
   This group includes the following functions:
   - void FLASH_OB_Unlock(void)
   - void FLASH_OB_Lock(void)
   - void FLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState)
   - void FLASH_OB_RDPConfig(uint8_t OB_RDP)
   - void FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY)
   - void FLASH_OB_BORConfig(uint8_t OB_BOR)
   - FLASH_Status FLASH_ProgramOTP(uint32_t Address, uint32_t Data)              
   - FLASH_Status FLASH_OB_Launch(void)
   - uint32_t FLASH_OB_GetUser(void)            
   - uint8_t FLASH_OB_GetWRP(void)            
   - uint8_t FLASH_OB_GetRDP(void)              
   - uint8_t FLASH_OB_GetBOR(void)
   
   Any operation of erase or program should follow these steps:
   1. Call the FLASH_OB_Unlock() function to enable the FLASH option control register access

   2. Call one or several functions to program the desired Option Bytes:
      - void FLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState) => to Enable/Disable 
        the desired sector write protection
      - void FLASH_OB_RDPConfig(uint8_t OB_RDP) => to set the desired read Protection Level
      - void FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY) => to configure 
        the user Option Bytes.
      - void FLASH_OB_BORConfig(uint8_t OB_BOR) => to set the BOR Level

   3. Once all needed Option Bytes to be programmed are correctly written, call the
      FLASH_OB_Launch() function to launch the Option Bytes programming process.
     
     @note When changing the IWDG mode from HW to SW or from SW to HW, a system 
           reset is needed to make the change effective.

   4. Call the FLASH_OB_Lock() function to disable the FLASH option control register
      access (recommended to protect the Option Bytes against possible unwanted operations)
    
@endverbatim
  * @{
  */

编程Flash,写保护,读保护代码开源

开源地址:

https://github.com/strongercjd/STM32F207VCT6

点击查看本文所在的专辑,STM32F207教程

关注公众号,第一时间收到文章更新。评论区不能及时看到,需要交流可以到公众号沟通

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32 Flash详解 的相关文章

  • 让更多消费者接受刷脸支付养成刷脸习惯

    扫码支付能够取代现金和刷卡支付 就是基于其便捷的支付体验 消费者只要带上手机 用手机扫码就可以完成支付 免去了许多携带现金或卡的不便 降低了遗失风险 但是扫码支付也是过度依赖了手机这一媒介 在手机忘带和没电的时候 也是束手无策 基于此 刷脸
  • 慢SQL语句优化

    对慢SQL语句优化一般可以按下面几步思路 开启慢查询日志 设置超过几秒为慢SQL语句 抓取慢SQL语句 通过explain查看执行计划 对慢SQL语句分析 创建索引并调整语句 再查看执行计划 对比调优结果 参数 slow query log
  • git版本库创建三部曲(git权威指南笔记)

    1 全局配置 a 告诉git当前用户的姓名和邮箱 git config global user name heaiming git config global user email 576439313 qq com b 设置git命令别名

随机推荐

  • CSS改变layui时间控件不显示秒

    laydate time list gt li last child display none width 0 laydate time list gt li not last child width 50 layui laydate ma
  • Win7系统安装哪个版本的Chrome浏览器

    Win系统安装Chrome浏览器 Win7系统环境 安装Chrome应该尽量考虑2021年发布的浏览器版本 理由如下 Win7版Chrome 续命 到2022年 延长支持6个月 Win7版Chrome 续命 到2022年 90版本Chrom
  • starting switch Root:systemd [1]: Failed to execute /bin/sh, giving up : No such file or directory

    启动centos 卡在starting switch Root starting switch Root systemd 1 Failed to execute bin sh giving up No such file or direct
  • LeetCode第二章链表

    203 移除链表元素 题目链接 203 移除链表元素 给你一个链表的头节点 head 和一个整数 val 请你删除链表中所有满足 Node val val 的节点 并返回 新的头节点 示例 1 输入 head 1 2 6 3 4 5 6 v
  • C++初始化参数列表(类的组合)

    A 类的组合 定义 类的组合就是以另一个的对象为数据成员 注意 要优先使用组合而不是继承 组合表达式的含义一部分的关系 类的组合案例分析 1 类组合包含的类的对象 必须采用初始化参数列表方式调用各自类当中的构造函数去初始化 2 要通过包含的
  • 用户级线程和内核级线程

    用户级线程和内核级线程 根据在用户空间还是在核心实现多线程机制 线程又被分为用户级线程 User Level Thread 和内核级线程 Kernel Level Thread
  • 文件操作【上篇】

    文章目录 1 为什么使用文件 2 什么是文件 2 1 程序文件 2 2 数据文件 2 3 文件名 3 文件的打开和关闭 3 1 文件指针 3 2 文件的打开和关闭 4 文件的顺序读写 4 1 fputc 写文件 4 2 fgetc 读文件
  • 【再回首Python之美】【模块 math】math模块的基本使用

    学好数理化 走遍天下都不怕 所以一定要把Python的math模块学好 math简介 math提供两个数学常量和众多数学函数 这俩常量和众多数学函数都是哪些呢 通过dir math 一看便知 使用math模块之前 一定要把模块包括进来 告诉
  • 关于Jenkins插件无法更新的问题

    由于Jenkins默认的更新站点服务器在国外 所以国内使用时需要翻墙 下面整理了一些国内的镜像站点 可以将更新站点修改后 进行相关插件的更新 国内镜像站点 站点一 实测通过 http mirror xmission com jenkins
  • ipad连接电脑_躺在被窝玩电脑,利用ipone ipad远程控制局域网电脑

    时光荏苒 人生的旅途来到了2019年 小科祝愿大家在新的一年里 猪 事顺利 和和美美 冬天 一年中最寒冷的季节 作为一个南方人 对于寒冷是唯恐而不及了 既没有暖气 一天开着空调又太耗电 所以能在床上解决的事情就坚决不下床 今天小科来教大家如
  • python 声音合成,使用python进行声音生成/合成?

    Is it possible to get python to generate a simple sound like a sine wave Is there a module available for this If not how
  • 机械革命蛟龙16ubuntu双系统的移除与重装

    介绍一下本人重装的一个初衷 首先系统更新内核导致cuda无法运行 其次原本的70g空间捉襟见肘 因此想要重装分配更多一些空间 若没有扩容的需求可以去找找系统自带的重装方法 应该会比我下面的流程快很多 1 预备工作 1 1 查看电脑的引导方式
  • 怎么理解分布式、高并发、多线程?(含面试题和答案解析)

    看到分布式 高并发 多线程这三个词的时候 很多人是不是都认为分布式 高并发 多线程 当面试官问到高并发系统可以采用哪些手段来解决 或者被问到分布式系统如何解决一致性的问题 是不是一脸懵逼 确实 在一开始接触的时候 不少人都会分布式 高并发
  • 基于深度学习的道路交通标志数字识别

    基于MATLAB深度学习的交通标志识别 课题介绍 交通标志识别技术的研究最早开始于奔驰等14家大型汽车公 司组成的民间组织所资助的Prometheus Program for European Traffic with Highest Ef
  • 解决mac command 找不到mysql命令

    root DB 02 mysql u root bash mysql command not found 原因 这是由于系统默认会查找 usr bin下的命令 如果这个命令不在这个目录下 当然会找不到命令 我们需要做的就是映射一个链接到 u
  • js手写MVC模式

    效果图如下 代码如下 div class dataInputArea div span 请输入个 span div div
  • BugkuCTF-Web 前八题

    web2 打开题目发现全是越来越快的滑稽笑脸 并没有很明显的提示 所以打开F12看源码 用快捷键ctrl F来搜索Flag 在源码中轻松找到Flag 计算器 打开题目发现要求求两个二位数之和且和必然为三位数 但结果输出框只能输出一位数字 这
  • XGBoost参数调优完全指南(附Python代码)

    XGBoost参数调优完全指南 附Python代码 原文地址 Complete Guide to Parameter Tuning in XGBoost with codes in Python 译注 文内提供的代码和运行结果有一定差异 可
  • 什么是HTTP协议和HTTPS协议,以及两者的区别

    HTTP协议 超文本传输协议 Hyper Text Transfer Protocol 是一个简单的请求 响应协议 它通常运行在TCP之上 它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应 请求和响应消息的头以形式给出 而消息
  • STM32 Flash详解

    本文将根据ST官方Flashprogramming manual 文档编号 PM0059 讲解STM32F207内部Flash编程 01 概述 这里的flash是指STM32F207内部集成的Flash Flash存储器有以下特点 最大1M