STM32 Flash

FLASH简介

Flash是常用的用于存储数据的半导体器件,它具有容量大,可重复擦写,按“扇区/块”擦除掉电后数据可继续保存的特性

常见的FLASH主要有NOR FLASH和NAND FLASH两种类型。NOR和NAND是两种数字门电路,可以简单地认为FLASH内部存储单元使用哪种门作存储单元就是哪种类型的FLASH。

U盘,SSD,eMMC等为NAND型,而NOR FLASH则根据设计需要灵活应用于各类PCB上,如BIOS,手机等。
在这里插入图片描述
NOR与NAND在数据写入前都需要有擦除操作。
但实际上NOR FLASH的一个bit可以从1变成0,而要从0变1就要擦除后再写入,NAND这两种情况都需要擦除。
擦除操作的最小单位为“扇区/块”,这意味着有时候即使只写一字节的数据,这个扇区/块上之前的数据都可能会被擦除。

NOR的地址线和数据线分开,它可以按“字节”读写数据,符合CPU的指令译码执行要求,所以假如NOR上存储了代码指令,CPU给NOR一个地址,NOR就能向CPU返回一个数据让CPU执行,中间不需要额外的处理操作,其中依靠XIP(eXcutable 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 字节。从上图可以看出主存储器的起始地址就是 0x08000000,B0、B1 都接 GND 的时候,就是从0x08000000 开始运行代码的。

信息块,该部分分为2个小部分,其中启动程序代码,用来存储ST自带的启动程序,用来串口下载代码。当 B0 接 3V3,B1 接 GND 的时候,运行的就是这部分代码。用户选中字节,则一般用于配置写保护、读保护等功能。

闪存存储器接口寄存器,该部分用于控制闪存读写等,是整个闪存模块的控制结构。

对主存储器和信息块的写入由内嵌的闪存编程/擦除控制器(FPEC)管理;编程与擦除的高电压由内部产生。

在执行闪存写操作时,任何对闪存的读操作都会锁住总线,在写操作完成后读操作才能正确地进行。既在进行写或擦除操作时,不能进行代码或数据的读取操作。

FLASH读写过程
对FLASH的核心操作就是读和写。
FLASH的物理特性:只能写0,不能写1,写1靠擦除。

闪存的读取

直接在通用地址空间直接寻址,任何32位数据的读操作都能访问闪存模块的内容并得到相对应的数据。
在这里插入图片描述
CPU通过ICode指令总线访问FLASH指令,通过DCode数据总线访问FLASH数据。

CPU运行速度比FLASH快得多,STM32F103的FLASH最快访问速度≤24MHz,CPU超过这个速度,得加入等待时间,否则读写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
写操作有四步:

  1. 解锁
  2. 擦除
  3. 写数据
  4. 上锁

STM32复位后,FPEC模块是被保护的,不能写入FLASH_CR;通过写入特定的序列到 FLASH_KEYR 寄存器可以打开 FPEC 模块(即写入 KEY1 和 KEY2),只有在写保护被解除后,我们才能操作相关寄存器。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/200656.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

多线程的概念

点击链接返回标题-> 什么是进程? 进程(Process),是程序的基本执行实体。 在早期面向进程设计的计算机结构中,进程是程序的基本执行实体; 在当代面向线程设计的计算机结构中,进程是线程的容器…

【阿里云】图像识别 摄像模块 语音模块

USB 摄像头模块测试及配置 一、首先将 USB 摄像头插入到 Orange Pi 开发板的 USB 接口中二、然后通过 lsmod 命令可以看到内核自动加载了下面的模块三、通过 v4l2-ctl 命令可以看到 USB 摄像头的设备节点信息为 /dev/video0四、使用 fswebcam 测试 USB 摄像头五、使用 motion …

opencv-简单图像处理

图像像素存储形式  对于只有黑白颜色的灰度图,为单通道,一个像素块对应矩阵中一个数字,数值为0到255, 其中0表示最暗(黑色) ,255表示最亮(白色) 对于采用RGB模式的彩色图片&#…

人工智能基础_机器学习046_OVR模型多分类器的使用_逻辑回归OVR建模与概率预测---人工智能工作笔记0086

首先我们来看一下什么是OVR分类.我们知道sigmoid函数可以用来进行二分类,那么多分类怎么实现呢?其中一个方法就是使用OVR进行把多分类转换成二分类进行计算. OVR,全称One-vs-Rest,是一种将多分类问题转化为多个二分类子问题的策略。在这种策略中,多分类问题被分解为若干个二…

Startdrive中上传参数设置的具体方法和注意事项

Startdrive中上传参数设置的具体方法和注意事项 适用于配 SINAMICS S120、G130、G150、S150和MV(基于CU3x0-2的驱动器)和所有启动驱动器版本INAMICS G115D/G120/G120D/G120C/G120P/G110M(基于CU2x0-2的驱动器) 根据SINAMICS类型的不同,Startdrive中的Upload参数有所不同。…

js ::after简单实战

::after的作用是在元素后面再加个XXX样式 工作中遇到了一个表格,鼠标指到单元格要有个整行编辑态的效果,下面写个简单的demo 有人可能会说了,直接修改某个单元格的hover样式不就行了嘛,问题是如果鼠标指到单元格和单元格直接的…

第4章 向量、SIMD和GPU体系结构中的数据级并行

4.1 引言 有多少应用程序拥有大量的数据级并行DLP?SIMD分类Flyn被提出后5年。答案不仅包括科学运算中的矩阵运算,还包括面向多媒体的图像和声音处理以及机器学习算法。 由于SIMD可以执行多个数据操作,能效比MIMD要高,使得SIMD对…

CFCA证书——基于SM2/3算法的安全信任

在中国金融认证中心(CFCA)发行的证书中,采用了最新的国密SM2/3算法来提供更高的安全保障。这一创新举措进一步增强了我国网络安全能力,并为用户提供了一种更可靠、更安全的选择。 SM2/3算法是中国自主研发的非对称加密算法&#…

vue中原生H5拖拽排序_拖拽图片也是同样的道理

原文地址【vue中原生H5拖拽排序_拖拽图片也是同样的道理】 H5有基于拖拽的事件机制&#xff0c;如果你还不熟悉&#xff0c;请看我之前的文章【拖拽上传】中有介绍。 原生拖拽API实现 由于比较简单直接上代码了&#xff1a; <!DOCTYPE html> <html lang"en&qu…

QT专栏2 -Qt for Android

#2023年11月18日 # Qt version 6.6 JDK17 JDK 安装 Java Downloads | Oracle 设置环境变量 鼠标右键我的电脑&#xff0c;出现如下界面 Qt配置 改用JDK18&#xff0c;没有乱码&#xff0c;由于不影响APK产生。 做了好多尝试&#xff0c;更换JDK版本(11,18,19,21)&…

动手学深度学习(三)---Softmax回归

文章目录 一、理论知识图像分类数据集 softmax回归 一、理论知识 回归估计一个连续值分类预测一个离散类别 回归单连续数值输出自然区间R跟真实值的区别作为损失 分类通常多个输出输出i是预测为第i类的置信度 一般我们使用交叉熵用来衡量两个概率的区别 将它作为损失 其梯…

负载均衡Ribbon和Feign的使用与区别

Ribbon 的介绍 Spring Cloud Ribbon 是基于Netflix Ribbon 实现的一套客户端负载均衡的工具。主要功能是提供客户端的软件负载均衡和服务调用。Ribbon 客户端组件提供一系列完善的配置项如连接超时&#xff0c;重试等。简单的说&#xff0c;就是在配置文件中列出Load Balancer…

redis的高可用

1.redis的高可用 在集群当中有一个非常重要的指标&#xff0c;提供正常服务的时间的百分比&#xff08;365天&#xff09;99% redis的高可用含义更宽泛&#xff0c;正常服务是指标之一&#xff0c;数据容量的扩展&#xff0c;数据的安全性。 在redis中实现高可用技术&#x…

Oracle实时同步技术

Oracle数据库的价值 Oracle数据库是一种高度可靠、安全和强大的关系型数据库管理系统&#xff0c;它具有以下几个方面的价值&#xff1a; 可靠性和稳定性&#xff1a;Oracle数据库以其高度可靠性、稳定性和数据完整性而闻名于世。 安全性&#xff1a;Oracle数据库提供了一系列…

JVM的垃圾收集算法

1.算法的分类 1.1标记清除算法 第一步&#xff1a;标记&#xff08;找出内存中需要回收的对象&#xff0c;并且把它们标记出来&#xff09; 根据可达性算法&#xff0c;标记的是存活的对象&#xff0c;然后将其他的空间进行回收 第二步&#xff1a;清除&#xff08;清除掉被…

阿里云oss存储文件上传功能实现(保姆级教程)

先登录&#xff1a; 点击进入控制台 点击左上角导航栏按钮 搜索oss&#xff0c;点击进入 进入之后点击立即开通oss按钮&#xff0c;开通之后点击下图立即创建&#xff0c;弹出创建Bucket 填上Bucket名称&#xff0c;读写权限改为公共读。其他不变点击确定创建&#xff0c;完成…

LVS+keepalived——高可用集群

lvskeepalived&#xff1a;高可用集群 keepalived为lvs应运而生的高可用服务。lvs的调度器无法做高可用&#xff0c;于是keepalived这个软件。实现的是调度器的高可用。但是&#xff1a;keepalived不是专门为lvs集群服务的&#xff0c;也可以做其他代理服务器的高可用。 lvs的…

Spring Boot要如何学习?【云驻共创】

Spring Boot 是由 Pivotal 团队提供的全新框架&#xff0c;其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置&#xff0c;从而使开发人员不再需要定义样板化的配置。我这里会分享一些学习Spring Boot的方法和干货&#xff0c;包括…

Python如何实现模板方法设计模式?什么是模板方法设计模式?Python 模板方法设计模式示例代码

什么是模板方法&#xff08;Template Method&#xff09;设计模式&#xff1f; 模板方法&#xff08;Template Method&#xff09;是一种行为型设计模式&#xff0c;它定义了一个算法的骨架&#xff0c;将一些步骤延迟到子类中实现。这种模式允许子类为一个算法的特定步骤提供…

【Flink】Process Function

目录 1、ProcessFunction解析 1.1 抽象方法.processElement() 1.2 非抽象方法.onTimer() 2、Flink中8个不同的处理函数 2.1 ProcessFunction 2.2 KeyedProcessFunction 2.3 ProcessWindowFunction 2.4 ProcessAllWindowFunction 2.5 CoProcessFunction 2.6 ProcessJo…