建立网站免费,一个人做网站设计兼职,政务网站开发协议,宝安公司网站建设FLASH简介
Flash是常用的用于存储数据的半导体器件#xff0c;它具有容量大#xff0c;可重复擦写#xff0c;按“扇区/块”擦除、掉电后数据可继续保存的特性。
常见的FLASH主要有NOR FLASH和NAND FLASH两种类型。NOR和NAND是两种数字门电路#xff0c;可以简单地认为FL…FLASH简介
Flash是常用的用于存储数据的半导体器件它具有容量大可重复擦写按“扇区/块”擦除、掉电后数据可继续保存的特性。
常见的FLASH主要有NOR FLASH和NAND FLASH两种类型。NOR和NAND是两种数字门电路可以简单地认为FLASH内部存储单元使用哪种门作存储单元就是哪种类型的FLASH。
U盘SSDeMMC等为NAND型而NOR FLASH则根据设计需要灵活应用于各类PCB上如BIOS手机等。 NOR与NAND在数据写入前都需要有擦除操作。 但实际上NOR FLASH的一个bit可以从1变成0而要从0变1就要擦除后再写入NAND这两种情况都需要擦除。 擦除操作的最小单位为“扇区/块”这意味着有时候即使只写一字节的数据这个扇区/块上之前的数据都可能会被擦除。
NOR的地址线和数据线分开它可以按“字节”读写数据符合CPU的指令译码执行要求所以假如NOR上存储了代码指令CPU给NOR一个地址NOR就能向CPU返回一个数据让CPU执行中间不需要额外的处理操作其中依靠XIPeXcutable In Place。因此可以用NOR FLASH直接作为嵌入式MCU的程序存储空间。
NAND的数据和地址线共用只能按块来读写数据假如NAND上存储了代码指令CPU给NAND地址后它无法直接返回该地址的数据所以不符合指令译码要求。
若代码存储在 NAND 上可以把它先加载到 RAM 存储器上再有 CPU 执行。所以在功能上可以认为 NOR 是一种断电后数据不丢失的 RAM但它的擦除单位与 RAM 有区别且读写速度比 RAM 要慢得多。
FLASH 也有对应的缺点我们在使用过程中需要尽量去规避这些问题一是 FLASH 的使用率另一个是可能的位反转。
使用寿命体现在读写上FLASH的擦除次数都是有限的NOR FLASH普遍是10万次左右当它的使用接近寿命的时候可能会出现写操作失败。由于NAND通常是整块擦写块内有一位失效整个块就会失败这称为坏块。使用NAND FLASH最好通过算法扫描介质找出坏块并标记为不可用因为坏块上的数据是不准确的。
位反转是数据位写入时为1但经过一定时间的环境变化后可能实际变为0的情况反之亦然。位反转的原因很多可能是器件特性也可能由于环境干扰。由于位反转的问题可能存在所以FLASH存储器需要“探测/错误更正”算法来确保数据的正确性。
FLASH 芯片有很多种芯片型号在我们的 norflash.h 头文件中有定义芯片 ID 的宏定义对应的就是不同型号的 NOR FLASH 芯片比如有W25Q64、BY25Q64、NM25Q64它们是来自不同的厂商的同种规格的 NOR FLASH 芯片内存空间都是 64M 字即 8M 字节。它们的很多参数、操作都是一样的所以我们的实验都是兼容它们的。
由于这么多的芯片我们就不一一进行介绍了就拿其中一款型号进行介绍即可其他的型号都是类似的。 下面我们以华邦的 W25Q64 为例认识一下具体的 NOR FLASH 的特性。 FLASH模拟EEPROM
EEPROM是一种掉电后数据不丢失的存储器常用来存储一些配置信息在系统重新上电时就可以加载。
STM32本身没有自带EEPROM但是STM32具有IAP在应用编程功能所以我们可以把FLASH当成EEPROM来使用。 STM32内部FLASH简介
在STM32芯片内部有一个FLASH存储器主要用于存储代码。 根据内存容量划分为几个密度等级 不同密度等级的FLASH其组织结构也不一样。 内部FLASH构成
内部FLASH主要由三部分组成主存储器、信息块、闪存存储器接口寄存器。
主存储器用来存放代码和数据常量如const类型的数据信息块分为两个部分系统存储启动程序代码、选项字节用户选项字节闪存存储器接口寄存器用于控制闪存读写等是整个闪存模块的控制结构
主存储器该部分用来存放代码和数据常数如 const 类型的数据。对于大容量产品其被划分为 256 页每一页 2K 字节。注意小容量和中容量产品则每页只有 1K 字节。从上图可以看出主存储器的起始地址就是 0x08000000B0、B1 都接 GND 的时候就是从0x08000000 开始运行代码的。
信息块该部分分为2个小部分其中启动程序代码用来存储ST自带的启动程序用来串口下载代码。当 B0 接 3V3B1 接 GND 的时候运行的就是这部分代码。用户选中字节则一般用于配置写保护、读保护等功能。
闪存存储器接口寄存器该部分用于控制闪存读写等是整个闪存模块的控制结构。
对主存储器和信息块的写入由内嵌的闪存编程/擦除控制器FPEC管理编程与擦除的高电压由内部产生。
在执行闪存写操作时任何对闪存的读操作都会锁住总线在写操作完成后读操作才能正确地进行。既在进行写或擦除操作时不能进行代码或数据的读取操作。
FLASH读写过程 对FLASH的核心操作就是读和写。 FLASH的物理特性只能写0不能写1写1靠擦除。
闪存的读取
直接在通用地址空间直接寻址任何32位数据的读操作都能访问闪存模块的内容并得到相对应的数据。 CPU通过ICode指令总线访问FLASH指令通过DCode数据总线访问FLASH数据。
CPU运行速度比FLASH快得多STM32F103的FLASH最快访问速度≤24MHzCPU超过这个速度得加入等待时间否则读写FLASH可能出错导致死机等情况。
正确设置好等待周期后利用指针读取数据。 从地址addr读取数据字节为8位半字为16位字为32位
data *(volatile uint8_t *)addr; /* 读取一个字节数据 */
data *(volatile uint16_t *)addr; /* 读取一个半字数据 */
data *(volatile uint32_t *)addr; /* 读取一个字的数据 */将addr强制转换为uintx_t指针然后取该指针所指向地址的值即可获得addr地址的数据。
在这个代码片段中‘volatile’关键字用于告诉编译器所涉及的内存位置可能会在程序的执行过程中被意外地更改而不是由程序代码直接引起的。
通常来说编译器会对代码进行优化例如缓存变量的值假设在执行流程中它们不会在未被程序代码显示修改的情况下改变。这种优化可能会导致对某些变量的读取操作不会实时地从内存中获取值而是使用已经缓存的值。在一些特殊情况下这种优化可能会导致问题特别是在与硬件相关的代码中其中寄存器的值可能会由硬件异步地发生变化。
通过使用’volatile’告诉编译器不要对这个变量进行优化而是始终从内存中读取起当前值。这对于需要实时地反映硬件状态变化的情况非常重要因此在嵌入式系统、驱动程序等场景中经常会看到 volatile 的使用。
闪存的写入
闪存编程是由FPEC闪存编程和擦除控制器模块处理的。 这个模块包含 7 个 32位寄存器它们分别是 ⚫ FPEC 键寄存器FLASH_KEYR ⚫ 选择字节键寄存器FLASH_OPTKEYR ⚫ 闪存控制寄存器FLASH_CR ⚫ 闪存状态寄存器FLASH_SR ⚫ 闪存地址寄存器FLASH_AR ⚫ 选择字节寄存器FLASH_WRPR 其中 FPEC 键寄存器总共有 3 个键值 RDPRT 键 0X0000 00A5 KEY1 0X4567 0123 KEY2 0XCDEF 89AB 写操作有四步
解锁擦除写数据上锁
STM32复位后FPEC模块是被保护的不能写入FLASH_CR通过写入特定的序列到 FLASH_KEYR 寄存器可以打开 FPEC 模块即写入 KEY1 和 KEY2只有在写保护被解除后我们才能操作相关寄存器。