原创 一次调试之殇(STM32)

2013-5-11 08:26 3722 19 14 分类: 消费电子

 

最近调试一段代码,发现一个很奇怪的现象,有一个函数放在一个位置,代码的执行结果是正确的。如果放在其他地方就会出现问题,同样的一个函数,为什么会出现这样的差距呢?
看到这里,或许很多人已经猜出问题的原因了。
但是,对于当时还在调试这段代码的人来说,或许是思维进入了一种惯性模式,看不到障眼法背后的实质原因。
一直以为是,函数的位置导致了程序执行结果的偏差。
甚至当时的心情,都有些向《代码大全》中提到的,“我的代码被狗吃了”。想怀疑是编译器出问题了,但是,《代码大全》让我知道,现在 的编译器出现问题的概率是极小的。如果我遇上了,几乎相当于买彩票中几百万的大奖。
还是要回到代码本身,代码出现问题,一般不是因为其他而导致的。程序是人写的,人在这个过程中,是最有可能出错的。也是出错概率最大的。平均,代码中30%左右的错误是因为输入拼写错误导致的。
但是,当自己找了很长时间,还是没有找到原因。因为找了很长时间,当时有些想放弃找到这个问题的真正原因了。然而,在分析其他代码的时候,突然想到如果有一个地方失误了,可能导致这个问题:即,变量使用的是一个随机值。
而造成随机值的原因,就是初始化问题。
 
想到这里,将出现问题的函数后重新check了一下,发现写入时,对于某些变量可能出现没有初始化的情况,这样将造成变量的值随机。
修正后,出问题的函数,不在出现了放置位置导致的执行效果,出错的问题。
对于此,想到几点:
  1. 代码完成后,休息一下,然后check几遍,check找到bug的效率是调试的几倍;
  2. 发现代码中的漏洞,很多时候,都是我们自己引起的;
  3. 关于这几天调试程序问题,有几方面原因:
    1. 开始时,一次调试需要很长时间,这里只在意尽快调试,没有把主要精力放在,代码check上;
    2. 调试时,过于集中于代码本身,而忽视了本质问题;
    3. 本次调试时,明显分析能力下降不少,只注重了表象,没有关心实质问题;
    4. 调试的心态不对,要注意;
  4. 还是没有做好这些东西;
  5. 学会放置代码,以后再进行检查,避免进入思维惯性;
  6. 不以物喜,不以己忧,尚要努力;
附注:
调试过程中的分析记录:
  1. cnt,记录下这个变量的值,使用这个值进行测试;
  2. 同时注释掉,删除下载文件的代码,使用这段代码进行升级下载测试;
  3. cnt = 0x103,下载文件结束偏移20400;
  4. 是什么原因,导致了升级时的APP_FAULT_ISR;
  5. 同时对于升级参数中,应该有一个判断是否升级成功的标识,这样避免的那个升级不成功的时候,恢复到原来版本时,擦出原来版本。
  6. 由断点调试发现,是重启后,没有跳转到升级后的FLash地址上运行,造成了还是在原版本上跳转,但是这里的问题是,为什么原有的程序也执行失败了?
  7. 怀疑是后边升级时写入Flash的问题。
  8. 升级部分的代码,确实很令人费解,一个函数的位置,竟然影响程序的生死,但是按照语言规则,不会有这么灵异的事情;
  9. 看到f_close和f_mount,怀疑是不是跟这两个函数有关系;
  10. 测试发现,这里跟f_close,f_mount没有关系,只跟判断到HEX文件的结束标志后,要立即复位,进行程序更新,否则就会出现问题。
  11. 造成了,程序的中断向量区,似乎没有进行更新,还是跑的以前的代码段,并跳转到了以前的main函数执行,但是经过了OSStart之后,程序发生了崩溃,回到了APP_FAULT_ISR的地方;这中间的问题,具体还没有想清楚;
  1. 首先先以(a方式)每次循环中都关闭的情况,来测试下看看;测试通过;
  2. 其次使用(b方式)先打开,在循环中读取并写入内部Flash,最后再关闭文件;测试不通过;现象:
    1. 程序启动后,跳转到原来版本的入口地址处;
    2. 之后程序能够正常初始化等,但是在OSStart函数之后,执行出现异常;
    3. 跳转到APP_FAULT_ISR;
    4. 重复以上步骤。
  3. 第三次,重复(1)的步骤,进行再次验证;测试通过;
  4. 由此说明(2)的方式在程序中通不过;
  5. 关于这个情况,描述下问题:
    1. 这里需要从外部Flash中读取一个文件,并将其写入到内部Flash中,然后完成程序复位,实现程序的升级;
    2. (a)中的方式是,每次读取一定的字节数时,先打开文件进行读取,读取结束后关闭文件,然后校验读取到的数据,校验成功,写入到内部Flash中,文件读取结束后,调用升级函数实现程序复位及升级;、
    3. (b)中的方式是,先打开外部Flash文件,读取一定的字节数据,然后校验读取到的数据,校验成功,写入内部Flash,文件读取结束后,关闭外部Flash文件,调用升级函数实现程序复位及升级;
  6. 关于两种方式,第一种会引起每次循环都有打开与关闭外部Flash文件的情况,第二种只有一次打开与关闭外部Flash文件的情况,理论上(b)的执行效率更高。但是实际测试发现,复位后(a)程序跳转正常,(b)程序跳转异常;这里边的原因,尚没有找到;
  7. 现猜测是由于Flash操作的问题;
  8. 先暂定使用(a)方式,如果以后需要效率问题,这里是个可以提升的地方,但是要详细测试;
  9. (a)方式,在将upgrade_program,放在发送回复之后,出现问题;
  10. 总之,这里得出一个结论,将程序写入内部Flash后,马上调用复位函数,进行程序升级;如果以后还需要对这里进行优化,可以详细测试下这里的原因,再行决定更合适的方案;
  11. (9)不是Flash操作的问题。
  12. 发现这里只跟何时调用upgrade_program函数有关系,检测到HEX文件的结束符,之后马上进行,程序复位,将不会引起错误;这个需要分析下原因在哪里;
  13. 发现,是在更新的时候,出现的错误;由于修改升级函数,但是没有及时将其bReadBkpDR,bWriteBkpDR函数没有配对使用;
PARTNER CONTENT

文章评论11条评论)

登录后参与讨论

1989tie_959541171 2013-11-17 17:51

还是对于lint了解的少,最近因为处于代码检查需要。发现pclint确实是可以检查写给单片机的代码,也谢谢以前的提醒。

用户1625273 2013-5-21 16:52

领教领教。

1989tie_959541171 2013-5-20 22:08

呵呵,确实是哈。凝词炼字非一朝之事,表辞达意非寸日之功。 言在此,而意在彼。 取舍之间,各自有道。

1989tie_959541171 2013-5-20 22:07

谢谢呵,虽然知道有些工具,但是具体的使用,还是没有在单片机的程序试过。

用户1684724 2013-5-20 21:14

C语言调试有时会遇到这样的问题

用户1602177 2013-5-20 11:26

@Big_Foot @FireKylin,两位同学说的也颇有道理~~哈哈,工程师们也都有颗严谨的文学之心~~

用户1610239 2013-5-20 09:57

深刻的教训啊。。。谢谢分享了

用户1043181 2013-5-20 09:23

代码为什么不做lint?这种错误,工具很容易就发现了。

用户1252881 2013-5-20 08:28

“殇”,夭折的意思

用户1033552 2013-5-20 08:01

人生经不起几次“殇”,这类标题不好。你愿代码与你终生为伴可以为之而“殇”,要不就不要用这类字。
相关推荐阅读
catch2000 2015-07-19 11:44
信号线小电阻的作用
在一块新的PCB上,测试系统能否正常运行的时候,发现系统上电后没有正常启动。  系统框图如下:   在上电的时刻,CPU A(GPIO电平2.6V)会向串口发送启动日志数据,CPU A启动后,...
catch2000 2015-07-05 17:04
协议设计中ACK机制的影响
在TCP/IP中,延时ACK和Nagle算法。  TCP为了同时处理成块数据(通常为512字节的用户数据)和交互数据(通常用户数据比较少,例如不大于10个字节),采用了延时ACK和Nagle算法...
catch2000 2015-05-23 15:48
话说物联网操作系统
最近好多家都宣布推出自己的物联网操作系统。   1. Google将要在Google I/O大会发布的Brillo; 2. 三星推出的Artik芯片搭载Mentor Graphics的...
catch2000 2015-03-31 23:52
不要采用异或来交换两个变量
在进行两个变量的时候,经常会看到有些书误人子弟的推荐使用异或的方式: 方式一 {   x = x ^ y;   y = x ^ y;   x = x ^ y; } 而不是...
catch2000 2014-10-09 07:28
为什么要测试先行
在产品的研发过程中,测试一项至关重要。不论是软件还是硬件。   软件的测试先行,在研发过程中,就做到质量的保证,因为在出现Bug的时候,容易定位Bug,而且即使是在客户端出现Bug,也能够...
catch2000 2014-10-09 07:26
C语言的面向对象编程(一)
一、前言 对于编程而言,重要的是解决问题的方式,而不是语言本身。面向对象与面向过程是解决问题和思考问题的方式。C语言常说是面向过程开发的语言,因为其缺少很多对于面向对象特性的支持。但,这并不影...
EE直播间
更多
我要评论
11
19
关闭 站长推荐上一条 /3 下一条