stm32 HAL库 Flash操作简介

2023-11-20

目录

stm32的hal库确实提供有关flash的操作代码库,,但是我们在操作flash之前依旧需要对stm32的flash进行简单的介绍。
首先,stm32的flash读不限制次数,写大约100 0000次,也就是说一天对同一个地方写100次,你需要大约20年才能写坏,所以可以你可以放心大胆的写。
其次,对于flash的操作代码也储存在flash中,也就是说如果你的写块覆盖掉了你的原始代码,你的程序可能出现未知的错误。
最后,flash的读写操作在一定程度上的修正,可以有效的实现代码的边运行变更新,当然有人意识到这就是iap,但是我不这么认为,iap至少需要bootloaer启动不同的代码块,而采用这种操作可以在运行状态下修正部分常量。例如,如果你的某段控制代码或者运行代码的某些参数并非是最优的,需要在运行中调节,你就可以通过指定该常量的存储地址并且在之后的运行与自我修正中不停 的覆盖,就可以闪现代码的自我优化。
stm32HAL库提供的flash操作库

第一stm32,flash介绍

stm32的烧录后的程序起始地址是从 0x0800 0000开始的,但是起始地址是从0x0000 0000,根据芯片名字及明面规则计算可用flash的结束地址。
在这里插入图片描述
对照下图的内存映射表就可以看出内存的开始与结束位置
在这里插入图片描述

查看代码段,以判断代码长度

一个编译完成的程序在下方会提示你代码长度,其中

Code 表示代码占用的空间 
RO-data表示(Read Only) 只读常亮的大小,如const		  型、字符串常量;
RW-data表示(Read Wirte) 已初始化的读写数据,程序中定义并且初始化的全局变量和静态变量位于此处
ZI-data表示(Zero Initialize) 未初始化的读写数据,程序中定义了但没有初始化的全局变量和静态变量

烧写入Flash中所占用的空间为:Code + RO-data + RW-data
程序运行时,芯片所占用的RAM空间为:RW-data + ZI-data
在这里插入图片描述
然后通过实际可用地址开始位置为0x0800 0000+烧写入Flash中所占用的空间
当然这种方法还学要计算比较麻烦,还有一种更为简单的查找方式,打开工程所属的文件夹,在右上角搜索中找到 .map开头文件
在这里插入图片描述
找到内存映射,将这两个求和就行了。
在这里插入图片描述

flash的基本操作规则

flash的成型以块(block)和扇区(sector)存在

STM32的flash在写的时候不能读,读的时候不能写,也就是说stm32在操作flash的时候程序必然是中止的,所以既不能响应中断,也不能有运行程序

During a write operation to the Flash memory, any attempt to read the Flash memory willstall the bus. The read operation will proceed correctly once the write operation hascompleted. This means that code or data fetches cannot be made while a write/eraseoperation is ongoing.For write and erase operations on the Flash memory(write/erase), the internal RC oscillator (HSI) must be ON.
The Flash memory can be programmed and erased using in-circuit programming and in-application programming.
中文翻译第一段话:在Flash写入操作过程中,任何试图读取Flash的操作都会锁定住总线,在完成Flash写操作之后读取Flash操作会继续执行,这意味着写入Flash期间无法访问Flash中的代码和数据。

极端情况下,如果想写FLASH时响应中断,唯有cortex-m从RAM中取指令能行的通,即写FLASH前,将响应中断的代码从FLASH拷入RAM中运行并将中断向量表设置到RAM即可。
flash的读可以从读写可以从任何地方开始,但是一次必须以半字,字,或者双字的方式来,但是flash的写之前如果该扇区存在数据,必须擦除整个扇区,再重写。

对照下面的表格可以找出你所有的可操作的stm32的扇区,不是你的代码段,又恰好在可用的flash扇区。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

stm32 HAL库 Flash操作指南

stm32 有一个与flash相关的寄存器FLASH Option Control Registers该寄存器提供了flash的读写保护以及中断响应flag等标识。

stm32f1xx_hal_flash.c

该文件用于基本的flash操作,提供了以下的方法对flash进行写操作与上锁解锁操作。

写操作

/** @addtogroup FLASH_Exported_Functions_Group1
  * @{
  */
/* IO operation functions *****************************************************/
HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data); 
HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data);

/* FLASH IRQ handler function */
void       HAL_FLASH_IRQHandler(void);
/* Callbacks in non blocking modes */ 
void       HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue);
void       HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue);

上锁与解锁

/** @addtogroup FLASH_Exported_Functions_Group2
  * @{
  */
/* Peripheral Control functions ***********************************************/
HAL_StatusTypeDef HAL_FLASH_Unlock(void);
HAL_StatusTypeDef HAL_FLASH_Lock(void);
HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void);
HAL_StatusTypeDef HAL_FLASH_OB_Lock(void);
void HAL_FLASH_OB_Launch(void);
void FLASH_PageErase(uint32_t PageAddress); 

注意上面的最后一行代码,FLASH_PageErase该函数在擦除时没有检测并且置0忙标识位,使得该段flash一直状态忙,无法使用,所以在擦除页面时一定要使用下面文件中的HAL_FLASHEx_Erase函数

stm32f1xx_hal_flash_ex.c

flash擦除

/** @addtogroup FLASHEx_Exported_Functions_Group1
  * @{
  */
/* IO operation functions *****************************************************/
HAL_StatusTypeDef  HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError);
HAL_StatusTypeDef  HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit);

flash 寄存器操作

/** @addtogroup FLASHEx_Exported_Functions_Group2
  * @{
  */
/* Peripheral Control functions ***********************************************/
HAL_StatusTypeDef  HAL_FLASHEx_OBErase(void);
HAL_StatusTypeDef  HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit);
void               HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit);
uint32_t           HAL_FLASHEx_OBGetUserData(uint32_t DATAAdress);

代码实例

flash 读数据

uint16_t flash_read = *(__IO uint16_t*)( Flash_Add ); //读2字节
uint32_t flash_read = *(__IO uint32_t*)( Flash_Add );//读4字节

flash 擦除页

	uint32_t Flash_Add = 0x0800d000;
	FLASH_EraseInitTypeDef My_Flash;  //声明FLASH_EraseInitTypeDef 结构体为 My_Flash
	HAL_FLASH_Unlock();               //解锁Flash
            
   My_Flash.TypeErase = FLASH_TYPEERASE_PAGES;  //标明Flash执行页面只做擦除操作
   My_Flash.PageAddress = Flash_Add;  //声明要擦除的地址
   My_Flash.NbPages = 1;                        //说明要擦除的页数,此参数必须是Min_Data = 1和Max_Data =(最大页数-初始页的值)之间的值
            
   uint32_t PageError = 0;                    //设置PageError,如果出现错误这个变量会被设置为出错的FLASH地址
   HAL_FLASHEx_Erase(&My_Flash, &PageError);  //调用擦除函数擦除
   HAL_FLASH_Lock();

flash 写操作

	HAL_FLASH_Unlock();               //解锁Flash
   	uint16_t Write_Flash_Data = my_data;
   	HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, Flash_Add, Write_Flash_Data); //对Flash进行烧写,FLASH_TYPEPROGRAM_HALFWORD 声明操作的Flash地址的16位的,此外还有32位跟64位的操作,自行翻查HAL库的定义即可
   	HAL_FLASH_Lock(); //锁住Flash
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

stm32 HAL库 Flash操作简介 的相关文章

随机推荐

  • 学习java笔记:实现家庭记账

    第一步 采用 Utility工具类 import java util Scanner Utility工具类 将不同的功能封装为方法 就是可以直接通过调用方法使用它的功能 而无需考虑具体的功能的实现 public class Utility
  • centos7-docker安装mysql5.7

    目录 1 docker 拉取mysql5 7镜像 2 创建实例并启动 3 查看容器是否启动成功 4 使用navicat 连接mysql 5 配置mysql 配置文件 6 重启容器 7 进入容器 1 docker 拉取mysql5 7镜像 d
  • 分布式集群管理—认知

    分布式集群管理 认知 分布式系统都是大规模机器的应用 所以需要管理大量的集群与机器 特别是云计算领域 部署管理系统 支持在大规模 多集群上进行分布式系统的部署 冷升级和热升级 进程的配置通过一个专门的配置中心进行推送 集群的配置中心 用于管
  • centos8安装rabbitmq(rpm包)

    1 先下载好rpm包 https pkgs org 1 检索rabbitmq下载对应centos8的版本 rabbitmq server 3 9 14 1 el8 noarch rpm 2 检索erlang下载对应centos8的版本 在官
  • delphi 后台截图

    function PrintWindow SourceWindow hwnd Destination hdc nFlags cardinal bool stdcall external user32 dll name PrintWindow
  • Windows slmgr.vbs 命令详解

    系统软件授权管理工具主要是用来查看系统的激活状态 以及密钥许可证等信息 在现在不在是使用 接参数了 现在 接参数 详解可以在cmd窗口输入slmgr vbs了解 常用参数 使用方式 再次提醒是使用 而不是 ipk 配合密钥使用 安装密钥 替
  • 基于google升级版c++代码规范指南

    有些团队所有成员写的代码都一致 10个人写的代码像1个人写的 正因为有代码规范 使得代码可读性强 方便代码review 利于后期维护 这体现了代码规范的重要性 接下来 在参考google的代码规范基础上 详细列举代码规范细节 1 文件描述
  • matlab 怎么使用function,Matlab怎么调用函数 自定义函数使用方法

    Matlab作为一款专业性极强的商业数学软件 将诸多的算法开发 统计分析 数据可视化功能融入其中 用户可以方便地调用需要的函数 建立数学模型 为了满足你工作的需要 还可以自行设置自己需要的函数 下面就跟小编了解下吧 类别 理科工具 大小 1
  • Unix Network Programming Episode 77

    gethostbyaddr Function The function gethostbyaddr takes a binary IPv4 address and tries to find the hostname correspondi
  • time_wait的快速回收和重用

    问题现象 PC与工控机之间通信 工控机发送SYN PC一直回复FIN或者RST 问题解释 1 time wait产生的原因及作用 下面我们先来简单回顾一下TCP连接关闭动作 在Linux环境下我们可以如下的方式来统计TCP连接的情况 net
  • 高防服务器如何防止网站攻击,高防服务器怎么防御攻击的?

    高防服务器怎么防御攻击的 高防服务器 从字面上来理解就是具备防御性能的服务器 高防服务器相较于普通的服务器除了超高的防御性能以外 在配置上通常也是比较高的 所以在使用上 会更稳定一些 所以深受各类行业站长的喜爱 如今 很多企业在选择租用服务
  • C语言之冒泡排序法

    首先 还是老规矩先上代码 include
  • 数组双指针法汇总

    指针移动方向 相向夹逼 同向移动 维护的是一个区间还是只是关心指针指向的两个元素 同向移动的 维护一个区间的双指针法即滑动窗口法 2Sum 排序后两头往中间夹逼的双指针法 指针为什么可以不回退 即为什么可以i只 j只 当A i A j
  • jvm学习——7.运行时数据区之堆

    一个进程对应一个jvm实例 一个运行时数据区 又包含多个线程 这些线程共享了方法区和堆 每个线程包含了程序计数器 本地方法栈和虚拟机栈 66 核心概述 1 一个jvm实例只存在一个堆内存 堆也是java内存管理的核心区域 2 Java堆区在
  • kuboard获取token命令

    输入命令查看 echo kubectl n kube system get secret kubectl n kube system get secret grep kuboard user awk print 1 o go templat
  • u8系统怎么连接服务器,u8客户端连接服务器流程

    u8客户端连接服务器流程 内容精选 换一换 请点击下载 下载并安装桌面版客户端 您已经从企业的会议管理员那儿获取用户帐号了吗 快使用用户帐号登录客户端 开启会议之旅 桌面客户端定位基于电脑使用 在会议室中不支持接入鹅颈麦克风 音箱等外设使用
  • QT的QListWidget之单击双击增删改详解

    QListWidget是列表框控件 它是通过QListWidgetItem列表项来进行操作 我们的增删改操作也是围绕着它来开展 需要注意的是 删除操作 需要先断开QListWidget的信号和槽连接 否则会程序崩溃 void MainWin
  • opencv畸变校正的两种方法

    opencv中畸变校正有两种方法 1 undistort 直接进行畸变校正 void cv undistort InputArray src 原始图像 OutputArray dst 矫正图像 InputArray cameraMatrix
  • echarts中的地图展示所有省份以及悬浮上去展示具体的信息

  • stm32 HAL库 Flash操作简介

    stm32 HAL库 Flash操作简介 目录 第一stm32 flash介绍 查看代码段 以判断代码长度 flash的基本操作规则 stm32 HAL库 Flash操作指南 stm32f1xx hal flash c stm32f1xx