记录一下最近调试单片机软件的问题
第一个bug
现象:在MDK中修改了优化等级0后,代码中的某一个全局变量莫名其妙的被修改了。将优化等级修改为3后,又正常了。
看到这个现象第一直觉就是代码操作了不属于自己的内存地址。由于是同事代码,我先让他自己调试,搞了一上午还是没有搞定,下午只好我上了。看了一下代码,似乎看到了多年前的自己,代码写的不够简洁,也不太规范。几次调试后,问题锁定了。问题就memset(pbuf,0,10);这行代码。pbuf是全局数组,长度只有8。看到这样的问题也很无语,其实这个问题,完全可以避免。要清除一个数组数据,通常情况下需要这样写memset(pbuf,0,sizeof(pbuf));而不是手动填写清除的长度。如果是动态分配内存,大小定义一个宏,代码中尽量不要出现具体的数字。特别是全局相关的。但是软件中也要尽量的避免使用全局表面,特别是RTOS中,能使用系统的同步方式的就用系统的信号量、消息队列、事件组。
第二个bug
现象记不太清楚了,大致是一个任务不正常工作,我看了一下这个任务的代码没发现的问题,我怀疑是任务栈不够了,把这个任务的栈加大了后还是存在这个问题。我问了他,他加入了哪些代码后出现的这个问题。问题估计就在新加入的代码。创建了一个新的任务:负责一种协议的处理(收发)。立马就去看了新加入的代码,封装了一个协议打包发送函数,看了一下代码,代码也没有问题。但是发现不合理的地方:由于协议要分多层打包,函数调用的层数有3层,每层中都定义一个打包数据缓存,大小是512字节的数组。我问了一下这个任务的栈你开了多大,回答:2K。这····,明显不够啊。我立马给他计算了一下你这个函数局部数组大约需要多大的内存,大概算出来1.8K的样子。修改任务栈大小后恢复正常。通过打印任务信息也证实了该任务的栈爆了。
其实在写这个函数的时候,就要考虑会被哪些任务调用,这些任务栈空间是否够。创建任务的时候也要考虑这个任务需要干什么,需要多大的栈空间。 这种函数需要较大内存缓存时,可以考虑动态内存分配。封装协议收发函数也要考虑这个协议一包数据最大是多少或者自己的业务最多一次需要发送多少数据,而不是直接开512大小的数组。
总结一下
年轻人还有很长的要走,加油!!!