news 2026/4/21 3:06:18

SeanLib系列函数库-MyFlash

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SeanLib系列函数库-MyFlash


查看其它库函数说明,请点击此处跳转到SeanLib主页

1. 本篇内容

本篇提供了一个适用于STM32F429的片内Flash操作库,支持读(一般不使用)、扇区擦除、写(按字节形式)三个方法,相比于HAL库中的函数,本函数库操作更简单方便。
本库不依赖HAL库等其它库文件。
其它的单片机型号暂不支持,但F4系列可能都支持,如果有更新,会更新此篇文章。

2. 使用说明

本库包含 MyFlash.lib 和 MyFlash.h 两个文件,头文件内容如下:

#include"SeanLib.h"/******************************************************************************* *本库适用于 STM32F429 ,其它型号未经测试 扇区划分如下: | Secotor Size | BANK1 | ADDRESS | BANK2 | ADDRESS | | 16K | 0 | 0x08000000 | 12 | 0x08100000 | | 16K | 1 | 0x08004000 | 13 | 0x08104000 | | 16K | 2 | 0x08008000 | 14 | 0x08108000 | | 16K | 3 | 0x0800C000 | 15 | 0x0810C000 | | 64K | 4 | 0x08010000 | 16 | 0x08110000 | | 128K | 5 | 0x08020000 | 17 | 0x08120000 | | 128K | 6 | 0x08040000 | 18 | 0x08140000 | | 128K | 7 | 0x08060000 | 19 | 0x08160000 | | 128K | 8 | 0x08080000 | 20 | 0x08180000 | | 128K | 9 | 0x080A0000 | 21 | 0x081A0000 | | 128K | 10 | 0x080C0000 | 22 | 0x081C0000 | | 128K | 11 | 0x080E0000 | 23 | 0x081E0000 | *******************************************************************************/typedefstruct{/*************************************************************************** 功能:读字节函数(一般用不上读Flash的函数) ***************************************************************************/void(*Read)(unsignedintAddr,unsignedchar*Data,unsignedintLength);/*************************************************************************** 功能:擦除指定编号的扇区,如0、1、2...23 ***************************************************************************/Sean_Result_t(*Erase)(unsignedcharSector);/*************************************************************************** 功能:写入一组字节数据 参数: Addr:Flash地址,必须是4字节对齐地址 Data:要写入的数据指针 Length:要写入的数据长度,允许不是4的倍数 返回值:操作完成状态或错误代码 ***************************************************************************/Sean_Result_t(*Write)(unsignedintAddr,unsignedchar*Data,unsignedintLength);}MyFlash_t;//系统已经创建一个Flash对象,应用程序中不需要再定义,可以直接使用MyFlash,其中封装了一些支持的方法externMyFlash_t MyFlash;

使用Write方法写入可以确保写入成功,因为该方法在写入后会回读校验。

2.1 扇区擦除

Flash在写之前需要先擦除,因为Flash的存储单元仅允许由1写为0,若要由0改写为1,仅能通过擦除操作完成。而Flash的寿命与擦除次数有关,一般为10000次,因此项目中应谨慎擦除,采用合理的Flash存储策略,比如存储log,应先擦除1个扇区,之后开始逐条存储,在此扇区存满之前都不需要再擦除。
擦除是以扇区为单位的,单片机的扇区大小并不都是相同的,具体请看头文件开头部分的表格,列出了每个扇区的大小。

2.2 实例代码

以下是从SD卡读文件写入到Flash的代码:

//根据固件大小,计算需要擦除的扇区数量unsignedcharCalc_Erase_Count(unsignedintSize){constunsignedintSector_Size[16]={131072,// 0: 128KB262144,// 1: 256KB393216,// 2: 384KB524288,// 3: 512KB540672,// 4: 528KB557056,// 5: 544KB573440,// 6: 560KB589824,// 7: 576KB655360,// 8: 640KB786432,// 9: 768KB917504,// 10: 896KB1048576,// 11: 1MB1179648,// 12: 1.125MB1310720,// 13: 1.25MB1441792,// 14: 1.375MB1572864};// 15: 1.5MBunsignedcharcount;for(count=0;count<16;count++){if(Size<=Sector_Size[count]){returncount+1;}}return0;}//从指定的起始扇区号开始擦除指定数量的扇区Sean_Result_tFlash_Erase_Sectors(unsignedcharSector_Start,unsignedcharCount){unsignedchari;Sean_Result_t ret;for(i=0;i<Count;i++){ret=MyFlash.Erase(Sector_Start+i);if(ret!=Sean_PASS){returnSean_FAIL;}}returnSean_PASS;}unsignedcharbuf[1024]__attribute__((aligned(4)));//打开指定的固件文件,返回文件大小,若文件存在,则保持文件开启unsignedintOpen_File(constchar*Path){FRESULT ret;unsignedintFW_Size;ret=f_open(&File,Path,FA_OPEN_EXISTING|FA_READ);//打开文件if(ret==FR_OK)//打开成功时,返回文件大小{FW_Size=f_size(&File);//读取固件大小if(FW_Size==0)//若固件文件异常,则删除该文件{printf("Size of file is 0, delete file\r\n");f_close(&File);f_unlink(Path);return0;}returnFW_Size;}printf("Failed to open file %s:%s\r\n",Path,File_Err[ret]);return0;}//更新MCU的固件Sean_Result_tUpdate_MCU(constchar*FW_Path){FRESULT ret;unsignedintFW_Size;unsignedintRem_Count,Finish_Count;floatProcess;FW_Size=Open_File(FW_Path);//打开文件并读取固件大小if(FW_Size==0){returnSean_FAIL;}unsignedcharErase_Count;Erase_Count=Calc_Erase_Count(FW_Size);//计算要擦除的Flash扇区数量if(Flash_Erase_Sectors(8,Erase_Count)!=Sean_PASS)//从第8个扇区开始擦除需要擦除的所有扇区{printf("Failed to erase sector:%hhu\r\n",8+Erase_Count);f_close(&File);returnSean_FAIL;}unsignedintWrite_Addr=0x08080000;//固件起始地址unsignedintReadLen;unsignedshortPackage;Rem_Count=FW_Size;Finish_Count=0;while(Rem_Count>0)//读取固件写入Flash{Package=Rem_Count>1024?1024:Rem_Count;//每包大小1024字节ret=f_read(&File,buf,Package,&ReadLen);//从文件中读一包数据if(ret!=FR_OK||Package!=ReadLen)//读取失败,关闭文件{printf("Read file error: %s\r\n",File_Err[ret]);f_close(&File);returnSean_FAIL;}if(MyFlash.Write(Write_Addr,buf,Package)!=Sean_PASS){printf("Failed to write flash\r\n");f_close(&File);returnSean_FAIL;}Rem_Count-=Package;Finish_Count+=Package;Process=(float)Finish_Count;Process*=100.0f;Process/=(float)FW_Size;printf("Download process: %.1f%%\r\n",Process);if(Rem_Count==0)//更新完成,关闭文件{f_close(&File);returnSean_PASS;}Write_Addr+=Package;}returnSean_FAIL;}

这里演示了擦除、写入的完整过程,Calc_Erase_Count函数用于计算要擦除的扇区数量,因为擦除操作耗时较长,扇区越大耗时越长,所以要采用最少化擦除原则。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/21 3:03:09

C#合并首尾相连多段线实战

问题解构 用户需要在C#中实现合并所有首尾相连的多段线。核心需求包括&#xff1a; 识别连接性&#xff1a;判断多段线是否首尾相连&#xff08;端点重合&#xff09;合并算法&#xff1a;将相连的多段线合并为单一多段线CAD环境&#xff1a;通常在AutoCAD等CAD二次开发环境中…

作者头像 李华
网站建设 2026/4/21 3:01:22

基于TMS320F28035的汇川变频器源码:MD290、MD380、MD500三种型号及新的...

变频器汇川的三种变频器源码&#xff0c;包括MD290,MD380,MD500变频器源码,基于TMS320F28035 新的SVC3算法&#xff0c;高速速度波动小&#xff0c;新的转子电阻&#xff0c;漏感辩识算法.系统概述 本文基于汇川技术股份有限公司开发的MD290、MD380、MD500系列变频器的嵌入式软…

作者头像 李华
网站建设 2026/4/21 3:00:25

旷世之作,云南第一书画史诗《白族创世纪》诞生,中国艺术的经典

由艺术大师范笑歌创作的云南第一书画史诗《白族创世纪》终于完成&#xff0c;作为云南艺术史册上的顶尖之作&#xff0c;从诗歌的编写到书法、绘画的精工&#xff0c;都是范先生独自完成。为何称此作品为云南第一书画史诗&#xff0c;主要因为这是书法与绘画的完美合璧&#xf…

作者头像 李华
网站建设 2026/4/21 2:59:55

【MATLAB源码-第422期】基于MATLAB的5G NR LDPC码的误码率复杂度仿真,对比BP,LBP,NMS。

操作环境&#xff1a;MATLAB 2024a1、算法描述摘要低密度奇偶校验码因其接近香农极限的纠错能力、良好的并行处理特性以及较强的速率兼容能力&#xff0c;已经成为新一代移动通信系统中共享信道的重要编码方案。5G NR标准围绕LDPC码给出了基图选择、提升因子构造、穿孔与速率匹…

作者头像 李华