完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
描述:
通常在做IOT产品或者项目需要参数保存时,通常我们的逻辑是首先判断flash中是否有参数的痕迹,有则读出直接使用,否则认为参数不合法,或者没有参数则要进行参数的初始化。 typedef struct { uint16 Start_Init_Flag; uint8 iFlashHardwareUniqueID[4]; //DEVICE ID uint8 iFlashFactoryAESKey[16]; //出厂加密KEY uint8 iFlashHardwareUniqueIDCipher[8]; //Cipher ID uint16 End_Init_Flag; }T_FLASH_FACTORY,*PT_FLASH_FACTORY; 如图在结构体中,有Start_Init_Flag、 End_Init_Flag两个参数,在参数保存时赋值一个值如,0X5A5A,则在读取参数时则判断此值是否为人为赋的正常值0X5A5A来判定参数区域是否合法。 此通过头尾变量的方式来做,是可以达到效果,但是不完善存在BUG,问题如下:
typedef struct { uint16 Start_Init_Flag; //参数存在标志 uint8 Allocation_Net_SSID[MAX_NET_SSID_LEN]; //连接网 络名称 uint8 Allocation_Net_PWD[MAX_NET_PWD_LEN]; //连接网络密码 uint8 iFlashNewIPAddress[MAX_SERVECE_IPADDRESS]; //新的入网IP uint8 iFlashNewIPPort[MAX_SERVECE_IPPORT]; //新的入网端口号 uint8 iFlashGatewayUseIp; //使用域名或者IP标志 uint8 iFlashNewDomainName[MAX_SERVECE_DOMAINNAME]; //域名 uint16 iFlashMaxMessageID; //message ID最大值 T_SLEEP_MODE_PARAMETER Sleep_Parameter; uint8 iFlashWifi_APMAC[20]; //WIFI MAC地址 uint16 Cat_Out_Scab_Time; //猫砂结痂时间 uint8 Device_WorkPattern; //设备工作模式 uint16 End_Init_Flag; //参数存在标志 uint8 Parameter_Crc; }__attribute__ ((packed))T_FLASH_PROGRAM,*PT_FLASH_PROGRAM; //保存flash参数 如次结构:在结构体中除了头尾标志,增加 uint8 Parameter_Crc字段,在保存时加入crc。并且结构体采用单字节对齐方式,保证增加减少参数一定会改变结构长度,不会出现增加参数导致长度不变,导致对齐问题出现异常赋值问题。 如下为读取参数,保存机制: void Device_FlashConfig_Parameter_Save(void) { uint8 Parameter_Crc; Device_flashParam.Start_Init_Flag = FLASH_PARAMETER_INTACT_FLAG; //标志置位 Device_flashParam.End_Init_Flag = FLASH_PARAMETER_INTACT_FLAG; //标志置位 Parameter_Crc = Check_CRC((uint8 *)&Device_flashParam,sizeof(Device_flashParam)-sizeof(Device_flashParam.Parameter_Crc)); Device_flashParam.Parameter_Crc = Parameter_Crc; STM32_Flash_ErasePage(DEVICE_CONFIG_PARAMETER_ADDR); STM32_Flash_Write_NBytes(DEVICE_CONFIG_PARAMETER_ADDR,(uint8 *)&Device_flashParam,sizeof(Device_flashParam)); } uint8 Device_FlashConfig_ParameterCheck(void) { uint8 Parameter_Crc; STM32_Flash_Read_NBytes(DEVICE_CONFIG_PARAMETER_ADDR, (uint8 *)&Device_flashParam, sizeof(Device_flashParam)); //读出falsh参数 Parameter_Crc = Check_CRC((uint8 *)&Device_flashParam,sizeof(Device_flashParam)-sizeof(Device_flashParam.Parameter_Crc)); if((Device_flashParam.Start_Init_Flag != FLASH_PARAMETER_INTACT_FLAG) || (Device_flashParam.End_Init_Flag != FLASH_PARAMETER_INTACT_FLAG) || (Parameter_Crc != Device_flashParam.Parameter_Crc)) { #if Debug_Parameter printf("*rn======FlashConfig_ParameterCheckInit=======*Parameter_Crc=0X%X,Device_flashParam.Parameter_Crc =0X%Xrn",Parameter_Crc,Device_flashParam.Parameter_Crc); #endif Device_FlashConfig_ParameterInit(); Device_FlashConfig_Parameter_Save(); return 1; } #if Debug_Parameter PCTxString("*======FlashConfig_Parameter Read successd=======*rn"); #endif return 0; } 注意: 尽管结构中增加头尾标志变量、crc校验、单字节对齐。但也应对不了一种情况,那就是结构体空间未出现大小变化,仅是将结构体成员进行位置调换,在这种情况下,读取数据后,crc校验正常,但是参数会错位,所以需要极其注意,最好是对每个参数都进行范围检测,判断是否非法!保证程序不会出现较大的隐患。 |
|
|
|
只有小组成员才能发言,加入小组>>
3316 浏览 9 评论
2995 浏览 16 评论
3494 浏览 1 评论
9060 浏览 16 评论
4088 浏览 18 评论
1180浏览 3评论
605浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
599浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2335浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1896浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-24 03:15 , Processed in 1.546998 second(s), Total 80, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号