当前位置: 首页 > news >正文

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

 

相关文章:

  • 基于深度学习的工业OCR数字识别系统架构解析
  • Linux的文件查找与压缩
  • BGP实验练习2
  • spring中的@Async注解详解
  • 2025年PMP 学习十 -第8章 项目质量管理(8.1,8.2)
  • 内存泄漏与OOM崩溃根治方案:JVM与原生内存池差异化排查手册
  • 【登录认证】JWT令牌
  • D-Pointer(Pimpl)设计模式(指向实现的指针)
  • 【氮化镓】电子辐照下温度对GaN位移阈能的影响
  • 青少年编程与数学 02-019 Rust 编程基础 09课题、流程控制
  • 【js中数据类型及区别】
  • 20250513_问题:由于全局Pytorch导致的错误
  • 十天学会嵌入式技术之51单片机—day-9
  • 深入理解 NumPy:Python 科学计算的基石
  • 【Bootstrap V4系列】学习入门教程之 组件-导航(Navs)高级用法
  • Nacos源码—9.Nacos升级gRPC分析八
  • 物理:从人出生和死亡的角度来讨论基本粒子的创生和湮灭以及是否守恒?
  • Spark 缓存(Caching)
  • 配置Nginx启用Https
  • C++中void*知识详解和注意事项
  • 北京航空航天大学首个海外创新研究院落户巴西
  • 回望乡土:对媒介化社会的反思
  • 高波︱忆陈昊:在中年之前离去
  • 【社论】人工智能将为教育带来什么
  • 上海交大计算机学院成立,设多个拔尖人才特色班
  • 中方发布会:中美经贸高层会谈氛围是坦诚的、深入的、具有建设性的