stm32 HAL库 Flash操作简介

目录

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
  • 18
    点赞
  • 110
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值