STM32 HAL驱动程序 内部Flash

hal_flash.c

#include "hal_flash.h"volatile uint32_t flashWriteOffset = SYS_APP_BAK_SAVE_ADDR_BASE;
volatile uint32_t flashReadOffset = SYS_APP_BAK_SAVE_ADDR_BASE;/* MCU OTA */
/*擦除指定的Flash页*/
void flash_erase_page(uint8_t flashPage , uint32_t addr_base)
{HAL_FLASH_Unlock();FLASH_EraseInitTypeDef f;f.TypeErase = FLASH_TYPEERASE_PAGES;f.PageAddress = addr_base+flashPage*FLASH_PAGE_SIZE;f.NbPages = 1;uint32_t PageError = 0;HAL_FLASHEx_Erase(&f, &PageError);HAL_FLASH_Lock();
}
void flash_erase(uint32_t size , uint32_t addr_base)
{uint32_t flashPageSum;uint32_t i;/*如果小于1024做处理*/if(size < FLASH_PAGE_SIZE)size = FLASH_PAGE_SIZE;												///* 计算需要擦写的Flash页 */if((size % FLASH_PAGE_SIZE) == 0){flashPageSum = size / FLASH_PAGE_SIZE;				//小于一页擦除一页}else{flashPageSum = (size / FLASH_PAGE_SIZE) + 1;	//大于一页擦除n+1页}for(i = 0;i<flashPageSum;i++){flash_erase_page(i,addr_base);								//基址累加擦除flash}
}void writeFlash(uint16_t * buf_to_save , uint16_t len , uint32_t wFlashAddr)
{uint16_t count=0;if(wFlashAddr >= 0x08010000){
#ifdef DEBUGprintf("Waring:Flash Write Addr Error\r\n");
#endifflashWriteOffset = SYS_APP_BAK_SAVE_ADDR_BASE;return;}HAL_FLASH_Unlock();while(count < len){HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,(wFlashAddr + count*2),buf_to_save[count]); //вflashһٶַ֘дɫѫؖè16λé	count ++;     }HAL_FLASH_Lock();
}void readFlash(uint16_t * buf_to_get,uint16_t len , uint32_t readFlashAddr)
{uint16_t count=0;while(count<len){buf_to_get[count]=*(uint16_t *)(readFlashAddr + count*2);count++;}
}
/*写Flash,控制写长度,Flash地址偏移*/
void wFlashData(uint8_t * buf_to_save , uint16_t len , uint32_t wFlashAddr)
{uint8_t WriteFlashTempBuf[PIECE_MAX_LEN];//写Flash临时缓冲区uint16_t WriteFlashTempLen = 0;//写Flash长度memset(WriteFlashTempBuf,0xEE,sizeof(WriteFlashTempBuf));//写Flash临时缓冲区首先全部填充0xEEmemcpy(WriteFlashTempBuf,buf_to_save,len);//临时缓冲区WriteFlashTempLen = len;if(len%2 != 0)WriteFlashTempLen += 1;//因为Flash只能写半字writeFlash((uint16_t *)&WriteFlashTempBuf ,  WriteFlashTempLen/2 , wFlashAddr);
}
void rFlashData(uint8_t * buf_to_get , uint16_t len , uint32_t rFlashAddr)
{uint8_t ReadFlashTempBuf[PIECE_MAX_LEN];//读Flash临时缓冲区uint16_t ReadFlashTempLen = 0;//读Flash长度if(len%2 == 0){ReadFlashTempLen = len;readFlash((uint16_t *)&ReadFlashTempBuf,ReadFlashTempLen/2 , rFlashAddr);memcpy(buf_to_get,ReadFlashTempBuf,len);}else{ReadFlashTempLen = len + 1;//因为Flash只能读半字readFlash((uint16_t *)&ReadFlashTempBuf,ReadFlashTempLen/2 , rFlashAddr);memcpy(buf_to_get,ReadFlashTempBuf,len);}
}
/****IAP*****/
typedef  void (*iapfun)(void);				//֨ӥһٶگ˽`эքӎ˽.
iapfun jump2app; 
u16 iapbuf[1024];   #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) 
#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr)) 
#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum)) //设置栈顶指针
__asm void MSR_MSP(u32 addr) 
{MSR MSP, r0 			//set Main Stack valueBX r14
}
void iap_load_app(u32 appxaddr)
{if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000)	//ݬөջַ֥֘ˇرۏר.{ printf("Stack Success!\r\n");jump2app=(iapfun)*(vu32*)(appxaddr+4);		//ԃۧպëȸ֚׾ٶؖΪԌѲߪʼַ֘(شλַ֘)		MSR_MSP(*(vu32*)appxaddr);					//ԵʼۯAPPבջָ֫(ԃۧպëȸք֚һٶؖԃԚզ؅ջַ֥֘)jump2app();									//͸תսAPP.}else{printf("Stack Failed!\r\n");}
}

 hal_flash.h

#ifndef _FLASH_
#define _FLASH_#include "stm32f1xx.h"typedef uint32_t  u32;
typedef uint16_t u16;
typedef uint8_t  u8;typedef __IO uint32_t  vu32;
typedef __IO uint16_t vu16;
typedef __IO uint8_t  vu8;//#include "stm32f10x.h"
/* BootLoader Flash首地址 */
#define SYS_Bootloader_SAVE_ADDR_BASE       0x08000000//Bootloader首地址
/* 升级参数存储 */
#define UPDATE_PARAM_SAVE_ADDR_BASE         0x08002C00
#define UPDATE_PARAM_MAX_SIZE               (1*1024)//支持参数大小1KB
/* APP Flash首地址 */
#define SYS_APP_SAVE_ADDR_BASE              0x08003000
#define APP_DATA_MAX_SIZE                   (26*1024)//支持APP大小26KB
/* APP BAK Flash首地址 */
#define SYS_APP_BAK_SAVE_ADDR_BASE          0x08009800
#define APP_BAK_DATA_MAX_SIZE               (26*1024)//支持APP_BAK大小26KB/* FLASH页大小 */
//#define FLASH_PAGE_SIZE           0x400U   //1KB#define NEED_UPDATA_PARAM 0xA5A5//10100101 10100101
#define DONT_UPDATA_PARAM 0x5A5A//01011010 01011010void save_param_to_flash(uint16_t * buf_to_save,uint16_t len );
void read_param_from_flash(uint16_t * buf_to_get,uint16_t len);
void set_flash_flag_to_updata(uint16_t crc_code);
void flash_erase(uint32_t size , uint32_t addr_base);
void EraseFlash(uint32_t size);
void rFlashData(uint8_t * buf_to_get , uint16_t len , uint32_t rFlashAddr);
void wFlashData(uint8_t * buf_to_save , uint16_t len , uint32_t wFlashAddr);
void iap_load_app(u32 appxaddr);
#endif

 

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

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

相关文章

电子电路:什么是电流离散性特征?

关于电荷的量子化,即电荷的最小单位是电子的电荷量e。在宏观电路中,由于电子数量极大,电流看起来是连续的。但在微观层面,比如纳米器件或单电子晶体管中,单个电子的移动就会引起可观测的离散电流。 还要提到散粒噪声,这是电流离散性的表现之一。当电流非常小时,例如在二…

AI agent与lang chain的学习笔记 (1)

文章目录 智能体的4大要素一些上手的例子与思考。创建简单的AI agent.从本地读取文件&#xff0c;然后让AI智能体总结。 也可以自己定义一些工具 来完成一些特定的任务。我们可以使用智能体总结一个视频。用户可以随意问关于视频的问题。 智能体的4大要素 AI 智能体有以下几个…

react+html2canvas+jspdf将页面导出pdf

主要使用html2canvasjspdf 1.将前端页面导出为pdf 2.处理导出后图表的截断问题 export default function AIReport() {const handleExport async () > {try {// 需要导出的内容idconst element document.querySelector(#AI-REPORT-CONTAINER);if (!element) {message.err…

FFmpeg:多媒体处理的终极利器

FFmpeg详细介绍 1. 定义与基本概述 FFmpeg是一套开源的跨平台多媒体处理工具集,最初由法国程序员Fabrice Bellard于2000年开发,其名称源自“Fast Forward MPEG”,体现了其高效处理MPEG格式的能力。它不仅是命令行工具,还包含多个库和开发套件,支持视频转码、剪辑、合并、…

【应用开发十】pwm

1 应用层操作PWM 与LED设备一样&#xff0c;操作PWD也是通过sysfs方式 1&#xff09; 所在目录&#xff1a;/sys/class/pwm&#xff0c;该目录下的文件为pwmchipX&#xff0c;为PWM控器&#xff0c;I.MX6ULL有八个pwm控制器 1.1 pwm 控制器 PWM控制器里内容&#xff08;即pw…

LeetCode算 法 实 战 - - - 双 指 针 与 移 除 元 素、快 慢 指 针 与 删 除 有 序 数 组 中 的 重 复 项

LeetCode算 法 实 战 - - - 双 指 针 与 移 除 元 素、快 慢 指 针 与 删 除 有 序 数 组 中 的 重 复 项 第 一 题 - - - 移 除 元 素方 法 一 - - - 双 重 循 环方 法 二 - - - 双 指 针方 法 三 - - - 相 向 双 指 针&#xff08;面 对 面 移 动&#xff09; 第 二 题 - - -…

设计模式系列(03):设计原则(二):DIP、ISP、LoD

本文为设计模式系列第3篇,聚焦依赖倒置、接口隔离、迪米特法则三大设计原则,系统梳理定义、实际业务场景、优缺点、最佳实践与常见误区,适合系统学习与团队协作。 目录 1. 引言2. 依赖倒置原则(DIP)3. 接口隔离原则(ISP)4. 迪米特法则(LoD)5. 常见误区与反例6. 最佳实…

计算机图形学中MVP变换的理论推导

计算机图形学中MVP变换的理论推导 课程地址&#xff1a;Computing the Pixel Coordinates of a 3D Point 知识铺垫&#xff1a;矩阵的真实内涵 矩阵的每一列/行&#xff08;左乘和右乘的区别&#xff09;代表了新坐标系的基向量在原基向量构成的坐标系中的坐标&#xff0c;这…

先说爱的人为什么先离开

2025年5月19日&#xff0c;15~23℃&#xff0c;贼好的一天&#xff0c;无事发生 待办&#xff1a; 2024年税务申报 《高等数学2》取消考试资格学生名单 《物理[2]》取消考试资格名单 5月24日、25日监考报名 《高等数学2》备课 《物理[2]》备课 职称申报材料 教学技能大赛PPT 遇…

面试中的线程题

原文链接&#xff1a;线程题大全 Java 并发库同步辅助类 CountDownLatch 工作机制&#xff1a;初始化一个计数器&#xff0c;此计数器的值表示需要等待的事件数量。 提供了两个主要方法&#xff1a; await()&#xff1a;当一个线程调用此方法时&#xff0c;它将阻塞&#…

Linux梦开始的地方

1.概率 经过C语言&#xff0c;数据结构&#xff0c;C的学习我们现在要开始学习Linux的学习了。我们学习Linux是从四部分来进行的&#xff1a; 1.Linux初识&#xff0c;Linux环境&#xff0c;Linux指令&#xff0c;Linux开发环境。 2.Linux系统。 3.Linux网络 4.MySQL Lin…

“二维前缀和”算法原理及模板

在学习本篇内容前建议先学习一下“一维前缀和” 一维前缀和 算法https://blog.csdn.net/czt230610/article/details/148012923?fromshareblogdetail&sharetypeblogdetail&sharerId148012923&sharereferPC&sharesourceczt230610&sharefromfrom_link接下来…

软件设计师CISC与RISC考点分析——求三连

一、考点分值占比与趋势分析&#xff08;CISC与RISC&#xff09; 综合知识分值统计表 年份考题数量分值分值占比考察重点2018111.33%指令特征对比2019111.33%控制器实现方式2020222.67%寄存器数量/流水线技术2021111.33%寻址方式对比2022222.67%指令复杂度/译码方式2023111.3…

顺 序 表:数 据 存 储 的 “ 有 序 阵 地 ”

顺 序 表&#xff1a;数 据 存 储 的 “ 有 序 阵 地 ” 线 性 表顺 序 表 - - - 顺 序 存 储 结 构顺 序 表 的 操 作 实 现代 码 全 貌 与 功 能 介 绍顺 序 表 的 功 能 说 明代 码 效 果 展 示代 码 详 解SeqList.hSeqList.ctest.c 总 结 &#x1f4bb;作 者 简 介&#xf…

网络安全深度解析:21种常见网站漏洞及防御指南

一、高危漏洞TOP 10 1. SQL注入(SQLi) 原理:通过构造恶意SQL语句突破系统过滤机制 典型场景: - 联合查询注入: union select 1,version(),3--+ - 布尔盲注:and (select substr(user(),1,1)=r) - 时间盲注:;if(now()=sysdate(),sleep(5),0)/ 防御方案: - 严格参数化查…

代码上传gitte仓库

把代码push上去就行

创建型:单例模式

目录 1、核心思想 2、实现方式 2.1 饿汉式 2.2 懒汉式 2.3 枚举&#xff08;Enum&#xff09; 3、关键注意事项 3.1 线程安全 3.2 反射攻击 3.3 序列化与反序列化 3.4 克隆保护 4、适用场景 1、核心思想 目的&#xff1a;确保一个类仅有一个实例 功能&#xff1a;…

副业小程序YUERGS,从开发到变现

文章目录 我为什么写这个小程序网站转小程序有什么坑有什么推广渠道个人开发者如何变现简单介绍YUERGS小程序给独立开发者一点小建议 我为什么写这个小程序 关注我的粉丝应该知道&#xff0c;我在硕士阶段就已经掌握了小程序开发技能&#xff0c;并写了一个名为“约球online”…

React路由(React学习笔记_09)

React路由 1,路由基础 现代的前端应用大多都是SPA(单页应用程序)&#xff0c;也就是只有一个HTML页面的应用程序。因为它的用户体验更好、对服务器的压力更小&#xff0c;所以更受欢迎。为了有效的使用单个页面来管理原来多个页面的功能&#xff0c;前端路由应运而生。 1, 安装…

2009-2025计算机408统考真题及解析

整理2009-2025 年计算机408统考真题及解析PDF 目录树&#xff1a; └── 2025考研计算机408统考真题及答案&#xff08;回忆版&#xff09;.pdf ├── 2009-2024计算机408真题解析 │ ├── 2009年计算机408统考真题解析.pdf │ ├── 2010年计算机408统考真题解析.pdf …