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
繁體地址,請注明出處:http://hk.pswp.cn/web/80414.shtml
英文地址,請注明出處:http://en.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 …