完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
先描述一下问题吧,调试单片机程序,用的是华大的一款国产单片机:HDSCl130,专门用于做低功耗的单片机,只开启rtc定时唤醒的话,功耗在0.5uA左右,功耗已经算是很低了,这就不多说了,还是说重点吧。
今天在调试设备的时候,用的NB模块联网,联网成功后我把设备断电了,然后重新上电。按理说应该会有一个重新联网的过程,但是我看jlink打印信息,竟然没有执行重新联网。正常情况下设备重新上电,单片机复位,将所有的变量重新恢复到初始值,只要恢复到初始值,NB模块就会重新联网,我debug调试之后发现在参数确实每次初始化为原始值了,但是在某个地方执行之后,初始值全部变掉了,如下图: #define SAVE_SYS_INFO_LEN 512 device_t smoke_fog_detector = { .state = DEVICE_STATE_STANDBY, .frozen_data_nums = 0, .alarm_data_nums = 0, .alarm_data_break_nums = 0, .alarm_data_grand_total = 0, .alarm_data_test_grand_total = 0, .alarm_data_break_grand_total = 0, .frozen_cycle_type = TYPE_DAY, .smog_threshold = 2400, .vdd_shreshold = 2400, .beyond_smog_delay = 0x02, .noise_reduct_dely_time = 0x0f, .frozen_cycle_time = 24, .wake_up_check_cricle = 8, .selfcheck_dely_time = 0x0f, .system_type = 0x80, .system_addr = 0, .device_type = 0x15, .device_addr = {0x00}, .device_mark = {0x00}, .factory_code = {0x00}, .date = {0x00}, .soft_version = {0x00}, .hard_version = {0x00}, .comm_protocol = {0x00}, .comm_protocol_version = {0x00} }; 当时定义了一个大的结构体,需要将结构体内部分参数保存在flash中,如果将整个结构体都保存flash的话就好办了,直接sizeof求结构体的长度,然后根据长度写入flash。但实际不是,只是保存结构体中部分参数。于是我就加了一个宏定义来定义长度。因为结构体中的参数是一点一点加的,这就导致每次修改结构体,都要修改宏定义SAVE_SYS_INFO_LEN的值。索性我就直接先定义长度为512.接下来就悲剧了。先看下边一个函数: /*************************************************************************** * @fn save_sys_info * * @brief * * @data * * @param void * * @return void *************************************************************************** */ void save_sys_info(void) { uint8_t save_info[SAVE_SYS_INFO_LEN]; static device_t smoke_fog_detector_pre; if(memcmp(&smoke_fog_detector_pre,&smoke_fog_detector,SAVE_SYS_INFO_LEN) == 0) return; memcpy(&smoke_fog_detector_pre,&smoke_fog_detector,SAVE_SYS_INFO_LEN); memcpy(save_info,&smoke_fog_detector,SAVE_SYS_INFO_LEN); Flash_SectorErase(SMOG_DETECTOR_SYS_INFO_PTR); Flash_WriteByte(SMOG_DETECTOR_SYS_INFO_PTR,(uint8_t *)save_info,SAVE_SYS_INFO_LEN); } 该函数是保存结构体中的参数到flash的操作,其写入flash的长度是SAVE_SYS_INFO_LEN,正是上方我定义的512的长度。当时没注意这个地方,起始写入flash是没什么问题的,关键是读,看下方函数: /*************************************************************************** * @fn restore_sys_info * * @brief * * @data * * @param void * * @return void *************************************************************************** */ void restore_sys_info(void) { uint32_t flash_empty_flag = *(uint32_t *)SMOG_DETECTOR_SYS_INFO_PTR; if(flash_empty_flag != 0xFFFFFFFF) { memcpy((uint8_t *)&smoke_fog_detector, (uint8_t *)SMOG_DETECTOR_SYS_INFO_PTR, SAVE_SYS_INFO_LEN); } } 从flash中将读取到的数据赋值给该结构体,但是现在有一个问题,该结构体的长度也就100多个字节,可我读取的长度是多少?SAVE_SYS_INFO_LEN这么长,512个字节。也就是说剩下的300多字节放到哪?结构体放不下了啊,上边代码中我只提供了一个结构体的首地址,从该首地址将读到的数据依次赋值。这种情况就会造成内存溢出,把剩下的300多字节也依照结构体首地址的偏移依次赋值下去,这就和一开始我说的NB模块重新上电之后无法重新联网的问题对应上了。因为每次上电之后都会从flash中将保存的数据重新赋值给结构体,但是结构体只能接收100多个字节,其他字节理所应当就给了ram中其他全局变量,这也就造成了设备重新上电之后某些全局变量被重新赋值导致程序运行异常。 |
|
|
|
只有小组成员才能发言,加入小组>>
imx6ull 和 lan8742 工作起来不正常, ping 老是丢包
1739 浏览 0 评论
3339 浏览 9 评论
3017 浏览 16 评论
3508 浏览 1 评论
9106 浏览 16 评论
1224浏览 3评论
633浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
621浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2363浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1928浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-1-15 00:37 , Processed in 1.085143 second(s), Total 79, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (威廉希尔官方网站 图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号