shm32 写内部flash之怪现象!
本帖最后由 modu8888 于 2017-7-10 15:36 编辑我的产品用在工业上,需保存工作记录。选择使用STM32的内部flash储存——我使用的是较大容量产品STM32F105RBT6,已让记录存储区远离代码区和数据区。 考虑到STM32F105RBT6产品内部flash一页的大小为2k字节,加上我的一条记录规划为64字节,我选择在一页中保存32条记录,合计2048字节。
大体上,我预留30页循环存放记录,大致可存近960条。当记录超过后,则覆盖原来的。
现在的问题是,调用库函数写数据有问题。问题如下:
1 调用HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)ProgramData)库函数编程有问题——仅能写入首个半字数据,其他半字给我写为0,然而插入一个条件判断则又能正确写入了。反复调试确认了该问题,非常奇怪;
2 刚擦除一页后,写第一条记录,无论如何仅能正确写第一个半字,其他写为0.
具体请看下面代码和我用st Link Utility读出的数据截图。
i=Cycles%1200;
ShiftAddress=i*64;
ShiftAddress=ShiftAddress-64;
ProgramAddress=0x08011000+ShiftAddress;
FLASH_EraseInitTypeDef f;
f.TypeErase = FLASH_TYPEERASE_PAGES;
f.PageAddress = ProgramAddress;
f.NbPages = 1;
if((i-1)%32==0)
{
HAL_FLASH_Unlock();
uint32_t PageError = 0;
HAL_FLASHEx_Erase(&f, &PageError);
HAL_FLASH_Lock();
}
HAL_FLASH_Unlock();
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, Cycles);
ProgramAddress+=2;
if(Mb_Task!=0x0)
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)Mb_Task);
ProgramAddress+=2;
if(Minutes_Holding!=0x0)
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)Minutes_Holding);
ProgramAddress+=2;
if(Minutes_Dry!=0x0)
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)Minutes_Dry);
ProgramAddress+=2;
if(Seconds_of_Task!=0x0)
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)Seconds_of_Task);
ProgramAddress+=2;
if(StartTime!=0)
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)StartTime);
ProgramAddress+=2;
if(StartTime!=0)
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)StartTime);
ProgramAddress+=2;
if(StartTime!=0)
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)StartTime);
ProgramAddress+=2;
if(StartTime!=0)
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)StartTime);
ProgramAddress+=2;
if(StartTime!=0)
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)StartTime);
ProgramAddress+=2;
if(StartTime!=0)
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)StartTime);
ProgramAddress+=2;
if(SecondsVacuum!=0)
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)SecondsVacuum);
ProgramAddress+=2;
if(SecondsVacuum!=0)
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)SecondsVacuum);
ProgramAddress+=2;
if(SecondsVacuum!=0)
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)SecondsVacuum);
ProgramAddress+=2;
if(SecondsSteam!=0)
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)SecondsSteam);
ProgramAddress+=2;
if(SecondsSteam!=0)
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)SecondsSteam);
ProgramAddress+=2;
if(SecondsSteam!=0)
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)SecondsSteam);
ProgramAddress+=2;
if(TemptSteam!=0)
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)TemptSteam);
ProgramAddress+=2;
if(TemptSteam!=0)
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)TemptSteam);
ProgramAddress+=2;
if(TemptSteam!=0)
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)TemptSteam);
ProgramAddress+=2;
if(Tempture_Highest!=0)
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)Tempture_Highest);
ProgramAddress+=2;
if(Tempture_Lowest!=0)
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)Tempture_Lowest);
HAL_FLASH_Lock();
file:///C:\Users\Administrator\AppData\Roaming\Tencent\Users\119080844\QQ\WinTemp\RichOle\~SQU{KDDD7TAJ@]1D{TH3DL.png
上面这个图片,是按照希望保持的数据。
运行下面代码,则不是这样:
FLASH_EraseInitTypeDef f;
f.TypeErase = FLASH_TYPEERASE_PAGES;
f.PageAddress = ProgramAddress;
f.NbPages = 1;
if((i-1)%32==0)
{
HAL_FLASH_Unlock();
uint32_t PageError = 0;
HAL_FLASHEx_Erase(&f, &PageError);
HAL_FLASH_Lock();
}
HAL_FLASH_Unlock();
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, Cycles);
ProgramAddress+=2;
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)Mb_Task);
ProgramAddress+=2;
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)Minutes_Holding);
ProgramAddress+=2;
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)Minutes_Dry);
ProgramAddress+=2;
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)Seconds_of_Task);
ProgramAddress+=2;
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)StartTime);
ProgramAddress+=2;
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)StartTime);
ProgramAddress+=2;
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)StartTime);
ProgramAddress+=2;
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)StartTime);
ProgramAddress+=2;
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)StartTime);
ProgramAddress+=2;
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)StartTime);
ProgramAddress+=2;
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)SecondsVacuum);
ProgramAddress+=2;
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)SecondsVacuum);
ProgramAddress+=2;
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)SecondsVacuum);
ProgramAddress+=2;
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)SecondsSteam);
ProgramAddress+=2;
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)SecondsSteam);
ProgramAddress+=2;
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)SecondsSteam);
ProgramAddress+=2;
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)TemptSteam);
ProgramAddress+=2;
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)TemptSteam);
ProgramAddress+=2;
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)TemptSteam);
ProgramAddress+=2;
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)Tempture_Highest);
ProgramAddress+=2;
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ProgramAddress, (uint64_t)Tempture_Lowest);
HAL_FLASH_Lock();
:o 请问为什么? 我想应该是写flash的时序问题,也就是HAL库函数的问题。
请有经验的朋友指教哟~ :Q:Q:Q:Q:Q:Q 我用hal做过在线升级,编程十几k都没问题呢 海迹天涯 发表于 2017-7-11 08:36
我用hal做过在线升级,编程十几k都没问题呢
谢回复。
我平常写几个字节,都没问题。
结贴了。非HAL库问题! 郁闷,结贴了,也不说明问题的原因! shuolang126 发表于 2017-7-13 08:29
郁闷,结贴了,也不说明问题的原因!
是FreeRTOS的导致出错。系统复位后,创建的信号量的值都自动为1,也就使得我的任务自动执行一次!也就错误的写入一次~
:handshake
页:
[1]