Flash的学习
1 概述
2 特性
STM32 的内部FLASH 包含主存储器、系统存储器以及选项字节区域。
2.1 主存储器
主存储器分为256 页,每页大小为2KB,共512KB。这个分页的概念,实质就是FLASH 存储器
的扇区,与其它FLASH 一样,在写入数据前,要先按页(扇区)擦除。
2.2 系统存储区
系统存储区是用户不能访问的区域,它在芯片出厂时已经固化了启动代码,它负责串口、USB以及 CAN 等 ISP 等烧录功能。
2.3 选项字节
选项字节用于配置 FLASH 的读写保护、待机、停机复位、软件/硬件看门狗等功能,这部分共 16 个字节。可以通过修改 FLASH 的选项控制寄存器修改。
3 Flash是如何工作的?
3.1 解锁
由于内部Flash空间主要存储的是应用程序,是非常关键的数据,为了防止误操作修改了这些内容,芯片复位后默认会给控制寄存器 FLASH_CR 上锁,这个时候不允许设置 Flash 的控制寄存器,从而不能修改 FLASH 中的内容。
所有对 Flash 写入数据前,需要先给它解锁。解锁的操作步骤如下:
- 往 FPEC 键寄存器 FLASH_KEYR 中写入 KEY1 = 0x45670123
- 再往 FPEC 键寄存器 FLASH_KEYR 中写入 KEY2 = 0xCDEF89AB
3.2 上锁
上锁的时候是对 FLASH_CR 寄存器的 FLASH_CR_LOCK 位置1。
3.3 页擦除
在写入新的数据前,需要先擦除存储区域, STM32 提供了页(扇区)擦除指令和整个 FLASH 擦除(批量擦除)的指令,批量擦除指令针对主存储区。
页擦除的过程如下:
- 检查 FLASH_SR 寄存器中的“忙碌寄存器位 BSY”,以确认当前未执行任何 Flash 操作;
- 在 FLASH_CR 寄存器中,将 “激活页擦除寄存器位 PER ”置1;
- 用 FLASH_AR 寄存器选择要擦除的页;
- 将 FLASH_CR 寄存器中的”开始擦除寄存器 STRT“置1,开始擦除;
- 等待 BSY 位被清零时,表示擦除完成。
3.4 写入数据
擦除完毕后即可写入数据,写入数据的过程并不仅仅使用指针向地址赋值,赋值前还需要配置一系列的寄存器,步骤如下:
- 检查 FLASH_SR 中的BSY位 ,以确认当前未执行任何其他的内部 Flash 操作;
- 将 FLASH_CR 寄存器中的”激活编程寄存器位 PG“置1;
- 向指定的Flash存储器地址执行数据写入操作,每次只能以 16 位的方式写入;
- 等待 BSY 位被清零时,表示写入完成。
4 FLASH擦写代码配置流程
- 调用 FLASH_Unlock() 解锁;
- 根据起始地址及结束地址计算要擦除多少页;
- 调用 FLASH_ClearFlag() 清除各种标志位;
- 使用循环调用 FLASH_ErasePage() 擦除页,每次擦除一页;
- 使用循环调用 FLASH_ProgramWord() 函数向起始地址至结束地址的存储区域写入变量 ”Data“ 存储的数值;
- 调用 FLASH_Lock 上锁;
- 使用指针读取写入的数据内容并校验
5 相关寄存器
5.1 解锁
- FLASH_KEYR FPEC键寄存器
作用:对FLASH写入数据前,需要先给它解锁,这些位用于输入 FPEC 的解锁键
5.2 擦除和写入
- FLASH_SR.BSY 忙碌寄存器位
作用:该位指示闪存操作正在进行,在闪存操作开始时,该位被设置为“1”;在操作结束或发生错误时该位被清除为“0”。 - FLASH_CR.PER 激活页擦除寄存器位
作用:激活页擦除 - FLASH_CR.STRT
作用:开始擦除 - FLASH_AR
作用:当进行编程时选择要编程的地址,当进行页擦除时选择要擦除的页。
note:当 FLASH_SR 中的 BSY 位为“1”时,不能写这个寄存器 - FLASH_CR.PG 激活编程寄存器位
作用:激活编程操作
5.3 上锁
- FLASH_CR.LOCK 锁寄存器位
作用:只能被写“1”。当该位为“1”时表示 FPEC和 FLASH_CR 被锁住。在检测到正确的解锁序列后,硬件清除此位为“0”。
note:在一次不成功的解锁操作后,下次系统复位前,该位不能被改变。
5.4 清除各种标志位
- FLASH_SR.EOP 操作结束寄存器位
作用:当闪存操作(编程/擦除)完成时,硬件设置这位为‘1’,写入‘1’可以清除这位状态。
note:每次成功的编程或擦除都会设置 EOP 状态 - FLASH_SR.WRPRTERR 写保护错误寄存器位
作用:试图对写保护的闪存地址编程时,硬件设置这位为‘1’,写入‘1’ 可以清除这位状态 - FLASH_SR.PGERR 编程错误寄存器位
作用:试图对内容不是‘0XFFFF’的地址编程时,硬件设置该位为‘1’,写入‘1’可以清除这位状态。
note:在进行编程操作之前,必须先清除 FLASH_CR 寄存器的STRT位
Note
- 擦除地址需要满足内存对齐,只能是扇区内存空间的整数倍。
- FlashDrive只能在调用的时候使用,其余情况下保障其不会被运行
- FlashDrive不能放在实际运行代码中,否则可能被串改数据
参考资料
STM32读写内部Flash(介绍+附代码)_Ch_champion的博客-CSDN博客