STM32HAL库-内部Flash在指定页读写保护示例
概述
本篇文章介绍如何使用STM32HAL库,内部Flash在特定页读写保护示例。
硬件:STM32F103CBU6最小系统板
软件:Keil 5.29 + STM32CubeMX5.6.1
一、使用方法
通过参阅《STM32中文参考手册》得知,不同型号的芯片对应FLASH大小不一样,如下所示:
在《STM32中文参考手册》pdf文档中找到,第2.3.3小节:嵌入式闪存,对应的页数30。
这里我使用的是STM32F103CBU6的FLASH是128k,通过手册得知是属于中容量,所以只需看下面FLASH地址分配图与每一页对应的大小(字节)即可。
想更详细的了解,请阅读《STM32中文参考手册》,网上大把可以下载,这里就给出此文档的下载链接了。
二、STM32CubeMx配置
三、Examples
打开STM32CubeMx生成的keil工程,新建bsp文件夹,同时分别新建bsp_readWriteProtect.c与bsp_readWriteProtect.h文件,并把这两个文件,添加keil工程中来即可。
添加头文件路径
1、bsp_readWriteProtect.h文件
#ifndef __BSP_READWRITEPROTECT_H
#define __BSP_READWRITEPROTECT_H
#ifdef __cplusplusextern "C" {
#endif#define WRITE_PROTECTION_DISABLE 1
#define WRITE_PROTECTION_ENABLE 1#define PASSED 1
#define FAILED 0
#define TestStatus int//写入的起始地址与结束地址
#define FLASH_USER_START_ADDR ((uint32_t)0x08008000)
#define FLASH_USER_END_ADDR ((uint32_t)0x0800C000)#define FLASH_PAGE_TO_BE_PROTECTED (OB_WRP_PAGES0TO3 | OB_WRP_PAGES4TO7 | OB_WRP_PAGES8TO11 | OB_WRP_PAGES12TO15 | \OB_WRP_PAGES16TO19 | OB_WRP_PAGES20TO23 | OB_WRP_PAGES24TO27 | OB_WRP_PAGES28TO31 | \OB_WRP_PAGES32TO35 | OB_WRP_PAGES36TO39 | OB_WRP_PAGES40TO43 | OB_WRP_PAGES44TO47 | \OB_WRP_PAGES48TO51 | OB_WRP_PAGES52TO55 | OB_WRP_PAGES56TO59 | OB_WRP_PAGES60TO63 )/* ALL PAGES */
//#define FLASH_PAGE_TO_BE_PROTECTED (OB_WRP_PAGES0TO3 | OB_WRP_PAGES4TO7 | OB_WRP_PAGES8TO11 | OB_WRP_PAGES12TO15 | \
// OB_WRP_PAGES16TO19 | OB_WRP_PAGES20TO23 | OB_WRP_PAGES24TO27 | OB_WRP_PAGES28TO31 | \
// OB_WRP_PAGES32TO35 | OB_WRP_PAGES36TO39 | OB_WRP_PAGES40TO43 | OB_WRP_PAGES44TO47 | \
// OB_WRP_PAGES48TO51 | OB_WRP_PAGES52TO55 | OB_WRP_PAGES56TO59 | OB_WRP_PAGES60TO63 | \
// OB_WRP_PAGES64TO67 | OB_WRP_PAGES68TO71 | OB_WRP_PAGES72TO75 | OB_WRP_PAGES76TO79 | \
// OB_WRP_PAGES80TO83 | OB_WRP_PAGES84TO87 | OB_WRP_PAGES88TO91 | OB_WRP_PAGES92TO95 | \
// OB_WRP_PAGES96TO99 | OB_WRP_PAGES100TO103 | OB_WRP_PAGES104TO107 | OB_WRP_PAGES108TO111 | \
// OB_WRP_PAGES112TO115 | OB_WRP_PAGES116TO119 | OB_WRP_PAGES120TO123 | OB_WRP_PAGES124TO127 )void FLASH_Test(void);#endif
2、bsp_readWriteProtect.c文件
#include "bsp_readWriteProtect.h"
#include "stdio.h"
#include "stm32f1xx_hal.h"FLASH_OBProgramInitTypeDef OptionsBytesStruct;
FLASH_EraseInitTypeDef EraseInitStruct;uint32_t Address = 0x00; //记录写入的地址
uint32_t DATA_32 = 0x3210ABCD; //记录写入的数据
uint32_t PageError = 0;void FLASH_Test(void)
{printf("Beginning of the test\r\n");/* 初始化测试状态 */ TestStatus MemoryProgramStatus = PASSED;/* 解锁 Flash 以启用闪存控制寄存器访问*/HAL_FLASH_Unlock();/* 解锁选项字节*/HAL_FLASH_OB_Unlock();/* 获取页面写保护状态*/HAL_FLASHEx_OBGetConfig(&OptionsBytesStruct);#if WRITE_PROTECTION_DISABLE #if 0 /* 检查所需页面是否已被写保护*/if ((OptionsBytesStruct.WRPPage & OB_WRP_ALLPAGES) != OB_WRP_ALLPAGES) {/*恢复写保护页面 */OptionsBytesStruct.OptionType = OPTIONBYTE_WRP;OptionsBytesStruct.WRPState = OB_WRPSTATE_DISABLE;OptionsBytesStruct.WRPPage = OB_WRP_ALLPAGES;if (HAL_FLASHEx_OBProgram(&OptionsBytesStruct) != HAL_OK) {while (1) {//printf("Run failed\r\n");}}/* 生成系统重置以加载新选项字节值*/HAL_FLASH_OB_Launch();}#else/* 检查所需页面是否已被写保护*/if ((OptionsBytesStruct.WRPPage & FLASH_PAGE_TO_BE_PROTECTED) != FLASH_PAGE_TO_BE_PROTECTED) {/*恢复写保护页面 */OptionsBytesStruct.OptionType = OPTIONBYTE_WRP;OptionsBytesStruct.WRPState = OB_WRPSTATE_DISABLE;OptionsBytesStruct.WRPPage = FLASH_PAGE_TO_BE_PROTECTED;if (HAL_FLASHEx_OBProgram(&OptionsBytesStruct) != HAL_OK) {while (1) {//printf("Run failed\r\n");}}/* 生成系统重置以加载新选项字节值*/HAL_FLASH_OB_Launch();}#endif
#elif defined WRITE_PROTECTION_ENABLE /* 检查所需页面是否尚未写保护*/if (((~OptionsBytesStruct.WRPPage) & FLASH_PAGE_TO_BE_PROTECTED ) != FLASH_PAGE_TO_BE_PROTECTED) {/* 启用页面写保护*/OptionsBytesStruct.OptionType = OPTIONBYTE_WRP;OptionsBytesStruct.WRPState = OB_WRPSTATE_ENABLE;OptionsBytesStruct.WRPPage = FLASH_PAGE_TO_BE_PROTECTED; if (HAL_FLASHEx_OBProgram(&OptionsBytesStruct) != HAL_OK) {while (1) {//LED1_ONprintf("Run failed\r\n");}}/* 生成系统重置以加载新选项字节值*/HAL_FLASH_OB_Launch();}
#endif /* WRITE_PROTECTION_DISABLE *//*锁定选项字节*/printf("Lock option byte\r\n");HAL_FLASH_OB_Lock();/* 所选页面未被写保护*/if ((OptionsBytesStruct.WRPPage & FLASH_PAGE_TO_BE_PROTECTED) != FLASH_PAGE_TO_BE_PROTECTED) {/*填写 EraseInit 结构*/EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;EraseInitStruct.PageAddress = FLASH_USER_START_ADDR;EraseInitStruct.NbPages = (FLASH_USER_END_ADDR - FLASH_USER_START_ADDR) / FLASH_PAGE_SIZE;if (HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK){/*页面擦除时发生错误。用户可以在这里添加一些代码来处理这个错误PageError 将包含有问题的页面,然后知道此页面上的代码错误,用户可以调用函数'HAL_FLASH_GetError() '*/while (1) {printf("Run failed\r\n");}}/*由 FLASH_USER_START_ADDR 和 FLASH_USER_END_ADDR 定义的地址处的 DATA_32 FLASH 字程序 */Address = FLASH_USER_START_ADDR;while (Address < FLASH_USER_END_ADDR) {if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Address, DATA_32) == HAL_OK) {Address = Address + 4;} else {while (1) {printf("Run failed\r\n");}}}/*检查书面数据的正确性*/ Address = FLASH_USER_START_ADDR; while (Address < FLASH_USER_END_ADDR) {if ((*(__IO uint32_t*) Address) != DATA_32) {MemoryProgramStatus = FAILED;}Address += 4;}} else {/*所需页面受写保护 *//* 检查是否允许在此页面中写入 */Address = FLASH_USER_START_ADDR;if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Address, DATA_32)!= HAL_OK) {/* 编程期间返回错误。 *//* 检查 WRPERR 标志是否设置良好 */if (HAL_FLASH_GetError() == HAL_FLASH_ERROR_WRP) {MemoryProgramStatus = FAILED;} else {while (1) {printf("Run failed\r\n");}}} else {while (1) {printf("Run failed\r\n");}}}HAL_FLASH_Lock();/*检查程序数据是否存在问题*/if (MemoryProgramStatus == PASSED) {//printf("Run successful\r\n");} else {while (1) {printf("Run failed\r\n");}}while (1) {}
}
3、mian.c文件
/* USER CODE BEGIN Header */
/********************************************************************************* @file : main.c* @brief : Main program body******************************************************************************* @attention** <h2><center>© Copyright (c) 2020 STMicroelectronics.* All rights reserved.</center></h2>** This software component is licensed by ST under BSD 3-Clause license,* the "License"; You may not use this file except in compliance with the* License. You may obtain a copy of the License at:* opensource.org/licenses/BSD-3-Clause********************************************************************************/
/* USER CODE END Header *//* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usart.h"
#include "gpio.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "bsp_readWriteProtect.h"
#include "stdio.h"
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 *//* USER CODE END 0 *//*** @brief The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 */FLASH_Test();/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Initializes the CPU, AHB and APB busses clocks */RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB busses clocks */RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK){Error_Handler();}
}/* USER CODE BEGIN 4 *//* USER CODE END 4 *//*** @brief This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state *//* USER CODE END Error_Handler_Debug */
}#ifdef USE_FULL_ASSERT
/*** @brief Reports the name of the source file and the source line number* where the assert_param error has occurred.* @param file: pointer to the source file name* @param line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{ /* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT *//************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
四、运行结果
指定页写保护
修改:bsp_readWriteProtect.h文件
下载代码运行:
编译,下载程序如下所示:
解除无法下载问题,使用ST-Link Utility工具
擦除失败
解除擦除问题:
再次擦除芯片,可以成功擦除。
传送门->代码
(注:提供的代码,与文章给出的有些地方需要做修改,按照文章给出代码即可)
五、总结
STM32HAL库-内部Flash在指定页读写保护示例相关推荐
- HAL库内部flash及IAP(boot)升级
1.内部flash的用法 1.闪存模块存储器组织(STM32F407) STM32的闪存模块由:主存储器.系统存储器.OPT区域和选项字节等4部分组成.如下图所示: 1.主储存器(flash):有11 ...
- stm32hal库应用笔记之 硬件I2C读写ZD24C64
话不多说 直接上资料 这是ZD24C64 数据手册里面的读写操作时序. 数据手册网上有很多相信大家也能随便就找到. 如下图所示: 这是使用iic按字节写操作 器件地址:我的是0xA0 来不及解释了赶快 ...
- stm32hal库应用笔记之硬件IIC读写SHTC31000温湿度传感器
话不多说上图: 完成的数据手册百度吧 嘻嘻 这是SHTC31000芯片的时序图: 这个怎么看我就不多解释了哈 SHTC3.h #ifndef SHTC3_SHTC3_H_ #define SHTC3_ ...
- stm32内部Flash读写
文章目录 1.stm32内部flash介绍 2.读写驱动编写 3.源码 上篇文章讲到了STM32来驱动外部flah的操作,flash真是好东西啊,内存大,能存的东西多,这样我们就可以用它来做一些大点的 ...
- map文件分析 stm32_使用STM32内部Flash额外的空间来存储数据
本次分享关于STM32内部FLASH的笔记. STM32 芯片内部的 FLASH 存储器,主要用于存储我们代码.如果内部FLASH存储完我们的代码还有剩余的空间,那么这些剩余的空间我们就可以利用起来, ...
- STM32内部flash详解(1)
STM32 内部FLAsh概述 今天说一下STM32中的内部flash. 当我们把写好的代码下载MCU中,这个代码时存放在flash中的.当芯片重启复位上电后,会通过内核对flash进行代码的加载运行 ...
- APM32F103VCT6 写内部Flash失败解决方案(亲试可用)
文章目录 1 前言 2 APM32F103xCxDxE 与 Sxx32F103xCxDxE 差异 3 两种解决方案 3.1 解决方案1 - 换芯片型号 3.2 解决方案2 - 改代码 4. 想说的话 ...
- STM32HAL库-针对芯片内部FLASH读保护实现防篡改、破解功能(详解)
目录 概述 一.使用方法 二.STM32CubeMx配置 三.Examples 四.运行结果 五.总结 概述 本篇文章介绍如何使用STM32HAL库,针对芯片读写保护实现防篡改.破解功能(详解),本 ...
- STM32HAL库-F4-针对芯片内部FLASH读保护实现防篡改、破解功能(详解)
概述 本篇文章介绍如何使用STM32HAL库,针对芯片读写保护实现防篡改.破解功能(详解),本案例还包含内部FLASH读写数据,本质就是操作Flash. 硬件:STM32F401CEU6最小系统板(内 ...
最新文章
- lvs+iptables持久连接
- sqlserver linkserver
- NSArray打印汉字的方法
- 从基础到高级讲解Kafka
- JEECG - 基于代码生成器的J2EE智能开发框架 杂记:【演示视频和源码】
- 【Kubernetes】mac 安装minikube
- web\app可视化图表设计模板,UI设计师临摹学习的帮手
- ADO.NET与ORM的比较(4):EntityFramework实现CRUD
- html audio无法播放,audio 无法播放的问题
- 机顶盒ttl无法输入_一个作业,多个TTL——Flink SQL 细粒度TTL配置的实现(二)
- android:textStyle 设置加粗并倾斜
- m126a linux驱动下载,hpm126a驱动下载
- CATIA怎么约束快捷键_Catia快捷键怎么设置?CATIA小技巧-设置快捷键方法
- 为什么我的QQ会被冻结?
- 谁是史上最强-用爬虫分析IMDB TOP250电影数据
- 云计算领域常见的一些专业术语、专有名词总结(一)
- 输入一个四位数将其加密后输出c语言,从键盘输入一个四位数-按如下规则加密后输出...
- 2015年度个人总结(公司版)
- 选购硬盘HDD、SSD、SSHD、IDE、SATA、SCSI、SAS、PCIe、M.2、USB
- 你想知道,Microsoft Edge这种巨型项目是如何进行版本管理的吗?
热门文章
- VLC for Android源码下载和编译
- 【万物物联】Siri+快捷指令+onenet控制掌控板
- 计算机考试的知识要记忆背,2017计算机等级考试(NCRE)备考小技巧
- 老人与海好词100英文带翻译_老人与海优美段落英文,英文的优美句子,带翻译,越多越好,谢谢...
- 从年轻大学教师待遇说到大学教学质量
- 大数据时代,IT行业的热门岗位有哪些?9大前景分析
- APP测试的主要内容
- 重庆科技学院计算机考研资料汇总
- html 转换 hta,HTA (HTML Application) 簡介
- invoke调用成员方法(无参和有参):