历史上的今天
今天是:2025年03月06日(星期四)
2019年03月06日 | STM32 Flash操作(擦写)过程中器件复位导致数据丢失问题
2019-03-06 来源:eefocus
1.问题描述
产品在运行过程中需要保存一些断电不丢失的数据,为此将数据保存在STM32内部的flash中。但是测试人员在测试的过程中,修改了数据参数,直接断电重启机器,并没有等待flash的操作时间,导致原有的数据丢失。
2. 原理分析
本产品硬件平台是基于STM32F429,采用HAL库开发。在操作内部flash这部分中,查看数据手册得知:
对于操作128KB的扇区擦写32位数据需要的时间,典型值是1S。最大值是2S。才能保证操作完成。
而在参考手册中提到:在Flash操作期间发生器件复位,则无法保证flash中的内容,
为此,我特地在擦写过程中,断电,然后看flash中的数据是什么,经过多次擦写,断电,然后用ST-Link查看扇区的数据发现,其数据如图所示:
数据为0xFFFFFFFF 或者0x00000000 不定。但是经过多次发现,基本上都是在这两个数据当中变化,无规则。
为此在判断的时候,可以采用这两个数据进行判断。
3. 解决方案:
采用一块Backup sector(备份扇区)用来存储修改参数前的数据,当第一块扇区数据丢失的时候,就读取备份扇区的内容。
具体看代码:
void flash_set_date(void)
{
static u8 update_flag=0;
uint8_t i=0;
//读取扇区内容,2块扇区内容同时为0xFFFFFFFF 表示没有参数,使用默认值
if((FLASH_ReadWord(MDATA_BASE+0)==0xffffffff)&&(FLASH_ReadWord(BACK_FLASH_BASE+0)==0xffffffff))
{
GD_BUF[INDEX_ID] = 0xff;//子控制板的ID默认设置为0xff
GD_BUF[INDEX_RED_CURRENT]=110; //红光电流默认值100mA
GD_BUF[INDEX_FORWORD_V]=38; //前向光默认值500
GD_BUF[INDEX_PD_BACK]=193; //回光默认值2500
GD_BUF[INDEX_5620_A2]=27;
GD_BUF[INDEX_5620_B2]=27;
GD_BUF[INDEX_BIAS_V]=154; //偏置电压默认值2000
GD_BUF[INDEX_OV_DTEMP]=40; //电水冷板温度报警默认值40
GD_BUF[INDEX_ADJ_POWER]=187; //满功率微调值默认186
GD_BUF[INDEX_OV_TEMP]=45; //泵源温度报警默认值45
GD_BUF[INDEX_OV_GTEMP]=35; //光水冷板温度报警默认值35
GD_BUF[INDEX_5620_A1]=27;
GD_BUF[INDEX_OVER_V]=131;//过压报警点
GD_BUF[INDEX_LOW_V]=100;//低压报警点
GD_BUF[INDEX_OVER_I]=181;//过流报警点
}
else//有参数,先读取扇区1
{
for(i=0;i { GD_BUF_FLASH[i] = FLASH_ReadWord(MDATA_BASE+i*4); } //意外擦除了 if((GD_BUF_FLASH[FLASH_RED_CURRENT]==0xffffffff)&&(GD_BUF_FLASH[FLASH_FORWORD_V]==0xffffffff)&&(GD_BUF_FLASH[FLASH_PD_BACK]==0xffffffff)\ &&(GD_BUF_FLASH[FLASH_BIAS_V]==0xffffffff))update_flag=1; //被意外清零了。 if((GD_BUF_FLASH[FLASH_RED_CURRENT]==0)&&(GD_BUF_FLASH[FLASH_FORWORD_V]==0)&&(GD_BUF_FLASH[FLASH_PD_BACK]==0)\ &&(GD_BUF_FLASH[FLASH_BIAS_V]==0))update_flag=1; } //不正确,读取扇区2的内容 if(update_flag>0) { for(i=0;i { GD_BUF[i] = FLASH_ReadWord(BACK_FLASH_BASE+i*4); } // flash_update();//写入扇区1 // pcset_5620_pro();//第一次上电设置5620输出。 TLC5620_Set1((u8)GD_BUF[INDEX_5620_A1],0); TLC5620_Set1((u8)GD_BUF[INDEX_RED_CURRENT],1); TLC5620_Set1((u8)GD_BUF[INDEX_FORWORD_V],2); TLC5620_Set1((u8)GD_BUF[INDEX_PD_BACK],3); TLC5620_Set2((u8)GD_BUF[INDEX_5620_A2],0); TLC5620_Set2((u8)GD_BUF[INDEX_5620_B2],1); TLC5620_Set2((u8)GD_BUF[INDEX_BIAS_V],2); } else//参数正确,比较扇区1 { if(Compare_Sector_Date(MDATA_BASE,BACK_FLASH_BASE,GD_LEN_FLASH)) { Update_Back_Flash(BACK_FLASH_BASE,GD_LEN_FLASH); } for(i=0;i { GD_BUF[i]=GD_BUF_FLASH[i]; } TLC5620_Set1((u8)GD_BUF[INDEX_5620_A1],0); TLC5620_Set1((u8)GD_BUF[INDEX_RED_CURRENT],1); TLC5620_Set1((u8)GD_BUF[INDEX_FORWORD_V],2); TLC5620_Set1((u8)GD_BUF[INDEX_PD_BACK],3); TLC5620_Set2((u8)GD_BUF[INDEX_5620_A2],0); TLC5620_Set2((u8)GD_BUF[INDEX_5620_B2],1); TLC5620_Set2((u8)GD_BUF[INDEX_BIAS_V],2); } } 具体流程: 1. 读取到两块扇区都为0xFFFFFFFF时,表示第一次烧写程序,采用默认值。 2. 有参数,则读取第一块扇区内容, 3. 判断第一块扇区内容是否正确,(可以采用校验的方式,或者采用在一个固定的位置写入固定的数据:写入0x55AA55AA)如果说扇区数据丢失,则写入的固定数据也将丢失,则说明第一块扇区内容不正确。 4. 不正确,读取第二块扇区内容,写入第一块扇区中。正确,比较两个扇区内容的差异,不同,则写入备份扇区。 对此,操作完成。flash扇区数据备份。
上一篇:STM32学习笔记:ADC理解
史海拾趣
|
被动安全系统方面 被动安全系统是指在交通事故发生后尽量减小损伤的安全系统,包括对乘客和行人的保护。 福特公司通过不断创新,推出先进的乘客约束系统和安全气囊技术,在乘员保护方面 ...… 查看全部问答> |
|
怎么一进中断I/O的状态就改变了,我在中断里面读取I/O的状态,怎么跟示波器显示的不一样? 怎么一进中断I/O的状态就改变了,我在中断里面读取I/O的状态,怎么跟示波器显示的不一样?… 查看全部问答> |
|
[转载] 簡易開核 輕鬆暢玩 ASUS M4A89GTD PRO/USB3 (存開箱) AMD 現今最夯的口號 我想還是 核心動力全開 小弟也藉由這次開核風氣 入手了M4A89GTD PRO/USB3 入手也一陣子了 就來發個開箱吧 本次的主角出現了 X2 555 與M4A89GTD PRO/USB3 這次華碩用的主機板的彩盒還滿亮眼的 在一張,把閃 ...… 查看全部问答> |
|
各位大哥大姐: 小弟求教! WinCE操作系统镜像生成以后,希望可以将其下载到Flash中,在以后系统复位或者重新上电以后,WinCE操作系统可以自动运行。可是,当我把镜像文件下载到Flash中后,却启动不起来,请问: &n ...… 查看全部问答> |
|
不知不觉已经wince驱动快一周年,写点学习经验,顺便散分,嘿嘿 刚洗完澡,头发未干,精神抖擞。想起自己快毕业一年了,特别来劲,情不自禁的在键盘上敲打起来。 我清楚的记得,我是2008.07.01被“轰出”校门的,然后申请了延迟离校,才可以在学校住宿,但是手里有几千块钱,于是就跑 ...… 查看全部问答> |
|
12岁的编程天才 田众和,1999年生,今年12岁,任时代网络软件工作室CEO兼CTO(技术总监)。小学4年级自学编程,创作第一个比较成熟的编程作品Othink系统,获得第一笔创业资金300元,招聘并领导11人团队,集资2000余元创建工作室,4个月盈利三万余 ...… 查看全部问答> |
|
本帖最后由 jameswangsynnex 于 2015-3-3 19:56 编辑 Canonical公司在职位的描述文字中写道“寻找业务拓展的精英来发展与行业伙伴的深度合作关系,来促进Ubuntu作为智能手机系统最终登陆手机”,以及“目标是创立一种围绕Ubuntu智能手机系统的良好 ...… 查看全部问答> |




