打印
[匠人手记]

程序调试(除错)过程中的一些雕虫小技(更新:2010-04-09)

[复制链接]
59072|185
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
程序匠人|  楼主 | 2009-8-13 23:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
一、前言

调试程序,是软件开发过程中的一个必不可少的环节。这篇帖子,匠人试着来整理一下一些调试的技巧。

说到“技巧”,这个词自从被所长批臭之后,匠人就吓得不敢再提,生怕一不小心就暴露了思想的浅薄和眼光的局限,呵呵。所以咱们不叫“技巧”,干脆低调点,就叫“雕虫小技”吧。

这里所讨论的“调试”技巧,有些是必须结合开发工具本身的功能来实现,而有些可以通过烧录芯片来验证。

各种开发工具,提供的功能多少强弱也不尽相同,这些方法也未必都能套用。仅供参考吧。

最后说明一下,这是没有草稿的帖子,匠人仍然以不定期连载的方式,边写边发边改。可能结构会比较混乱。欢迎大家一起参与讨论。
评分
参与人数 13威望 +24 收起 理由
dzbsgoldlg + 1 很好很强大,写出了我一直知道却没发写出来 ...
lovebaby8848 + 1 受益匪浅
chinacn1989 + 1
manle789 + 1
forget121 + 1

查看全部评分

相关帖子

沙发
程序匠人|  楼主 | 2009-8-13 23:29 | 只看该作者
二、磨刀不误砍柴功

在调试之前,需要掌握以下一些基本功:

1、熟悉当前的开发(调试)环境,比如:设置断点、单步运行、全速运行、终止运行,查看RAM、查看堆栈、查看IO口状态……总之,要熟练掌握基本操作的方法,并深刻了解其中意义。

2、了解芯片本身的资源和特性。

3、了解一点汇编语言的知识。(本来匠人是准备写“精通”的,但考虑到现状,还是“放低”这方面的要求罢了)。

4、掌握基本的电路知识和排错能力。(软件调试有时也会牵涉到硬件原因。总不能连三极管的好坏都不能识别吧?)

5、万用表、示波器、信号发生器……这些工具总该会用吧?

6、搜索、鉴别资料的能力。(内事问百度、外事问古狗、有事没事上21ic网)

7、与人沟通,描述问题的能力。(调试36计的最后一计——就是向他人讨教。当然,你得把话说明白才行)

差不多了,如果上述7把砍柴刀磨好了,就可以开始调试了。接下来,请调入你的程序……

——什么?你说你程序还没写?
——匠人倒塌……

(连载未完,敬请期待)

使用特权

评论回复
板凳
cauhorse| | 2009-8-13 23:48 | 只看该作者
我还真打算明天再去写呢。。;P

使用特权

评论回复
地板
欧阳青云| | 2009-8-13 23:59 | 只看该作者
早点写完分享哈。

使用特权

评论回复
5
程序匠人|  楼主 | 2009-8-14 00:09 | 只看该作者
三、优先调试人机界面

面对程序中的一大堆模块,无从下手是吗?好吧,匠人告诉你,先调显示模块,然后是键盘。

为什么要先调显示模块?道理很简单,我们说“眼睛是心灵的窗户”,同样,“显示是程序的窗户”。一旦把显示模块调试好了,就可以通过这个窗口,偷 窥 (天呐,这两个居然是敏感字!) 程序内部的数据和状态了。

然后紧接着,就是调试键盘模块。有了这个按键,我们就可以人工干预程序的运行了。

——什么,你的程序没有显示和按键?
——这位童鞋,你真不幸,请去检查一下自己的人品和星座运程先。谢谢。

实在是没显示?再看看系统有蜂鸣器吗?如果侥幸有的话,也能凑合着发发提示声音吧?

或者,有串口吗?可以考虑借助PC 端的串口调试软件来收发数据,这也是一个间接的人机交流方法。

总而言之,要尽快建立人机交流界面。

(未完待续)

使用特权

评论回复
6
程序匠人|  楼主 | 2009-8-14 00:14 | 只看该作者
觉觉去啦。。。。

使用特权

评论回复
7
飞跃无线| | 2009-8-14 08:07 | 只看该作者
顶一个呗

使用特权

评论回复
8
jerkoh| | 2009-8-14 08:13 | 只看该作者
我顶,等下集

使用特权

评论回复
9
mytempid| | 2009-8-14 08:37 | 只看该作者
不错

使用特权

评论回复
10
hongjunzgt| | 2009-8-14 09:36 | 只看该作者
不错,经验!

使用特权

评论回复
11
snow88| | 2009-8-14 09:53 | 只看该作者
匠人,继续呀!  我没有仿真器,也是通过串口和LED点阵来调试的

使用特权

评论回复
12
thanksgiving| | 2009-8-14 10:55 | 只看该作者
顶顶更健康

使用特权

评论回复
13
blitzero| | 2009-8-14 11:07 | 只看该作者
顶一个,等着匠人继续

使用特权

评论回复
14
leaoking| | 2009-8-14 11:39 | 只看该作者
看了,可是怎么建立人机交流呢?初学唉,现在什么都不懂呢!!寒自己一个,目前为止只学过C语言,电路基础没学,数电模电没学,现在是自学单片机。之前的时候只调试过用keil自带的软件调试,简单的输出型程序会调试,比如流水灯,我能够在keil上P0口的打钩与不打钩看出是哪个灯亮,但是复杂一点儿的调试,比如用锁存器控制的数码管我就不会调试了,虽然也是输出。键盘之类的输入的程序更不会调了。。。。。
有一块单片机开发板,一个仿真芯片,软件有keil,stc等软件,这些可以吗?

使用特权

评论回复
15
程序匠人|  楼主 | 2009-8-14 21:54 | 只看该作者
14楼的初学者不要急。功到自然成。“技术源于积累,成功源于执着!”
你提到的“怎么建立人机交流呢?”,那匠人就顺着这个思路来讲。

四、慢镜头的威力

2009年春晚捧红了魔术师刘谦(这位老兄名“谦”,其实一点都不谦虚——长的帅不是错,出来拽就是罪过了!),也勾起了大家对魔术的浓厚兴趣,如何识破那些快速的眼花缭乱的魔术手法呢?很简单,用慢镜头回放即可。据说刘谦那个橡皮筋魔术的手法就是被人如此识破的。

回到我们单片机上来。我们知道,单片机的运行速度,一般都是在几M到几十M(当然,也有为了节能而采用几十K的低速)。不管怎么样,这个速度都远远超出了我们人眼能够分辨的速度。眼睛一眨,也许几M条指令已经执行过去了。

比如说数码管显示(假设有4位数码管)。平时我们看到数码管同时点亮着,但是实际上,这4个数码管是逐个扫描的。在任意一个时刻,只有一位数码管被点亮。在微观上,我们可以进一步把每位数码管的扫描动作细分为以下几个步骤:
1、关闭上一位数码管的位选信号;
2、输出当前位数码管的段选信号;
3、开启当前位数码管的位选信号;
4、启动1ms延时;
5、延时结束后,指针移动到下一位数码管,并重复上述4个步骤,如此周而复始。

你看,这样是不是就像用一个慢镜头在分解显示扫描的动作了?

那么如何实现这个慢镜头呢?方法很多:
1、单步运行(需要仿真器支持);
2、在每一步分动作之后设立断点(需要仿真器支持);
3、在每一步分动作之后插入足够的延时,让我们肉眼可以看清楚这些分动作(不需要仿真器,适合烧片测试);

通过慢镜头的反复回放,我们就可以发现,到底是哪一个分动作出现了问题。

这个技巧,不仅仅适用于调试显示程序,也适用于按键扫描或其它模块。只要一个功能可以被细分为若干的动作,那么这一招“慢镜头分解法”都是可以使用的。

(未完待续,喜欢就顶)

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
jy1984 + 1 不错,相当不错
16
new1988| | 2009-8-16 08:47 | 只看该作者
占个沙发听课

使用特权

评论回复
17
程序匠人|  楼主 | 2009-8-17 23:47 | 只看该作者
五、给程序安装个黑匣子

某年某月的某一天,一架飞机以优美的抛物线形状,一头栽到海里去了……几天后,人们找到了飞机的黑匣子,里面记录了飞行员的最后一句话:“天呐,我看到火星人了!……”

以上空难情节我们经常会通过新闻看到吧(当然,最后一句是匠人版的科幻情节)。看看,飞机的黑匣子可以记录并再现现场,多么神奇!欧耶!

我们在调试程序时,也可以借鉴这个方法,给程序按装一个黑匣子。程序中的黑匣子其实就是一个在内存中开辟的队列。队列的原理我们很清楚,先进先出,后进后出(与飞机黑匣子的特性相同)。

比如说吧,假设我们的系统在工作中,某个输入量的采样值经常受到不明原因的扰动。我们要摸清这种扰动的规律,以便对症下药。但是这种扰动稍纵即逝。

我们的困扰是:程序正常运行时看不出规律,单步走又难以捕捉扰动。怎么办?

有没有办法,把扰动记录下来?

当然可以。

我们可以利用系统里剩余的RAM,开辟一块单元,做成队列。并写段测试程序,定时把新采样值压入队列。

然后我们让程序运行,在需要的(任意)时刻,让程序停下来。这时,队列里记录的就是最新一批采样数据。

只要队列的深度足够大,我们就可以找出扰动的规律来。

——什么,你问我什么叫队列?
——匠人曰“天呐,我看到火星人了!……”

(未完待续……)

PS:如果您喜欢此贴,请用实际行动支持:
  支持方法1、可以点击作者的帖子边上的“评分”按钮,给作者加分。(放心,给作者加分的同时,您的分数不会减少。)
  支持方法2、跟贴是美德。

使用特权

评论回复
评分
参与人数 23威望 +24 收起 理由
578896817fyt + 2
924684929 + 1 很给力!
abbccc308 + 1 很给力!
dldxhzmt + 1 我是火星人……&
lifeinjoy + 1

查看全部评分

18
cauhorse| | 2009-8-18 09:57 | 只看该作者
那么请问匠人:
如果俺用的芯片片内RAM太少,也不支持IAP啥的,然后呢,那个扰动又不一定啥时候出现,出现时又没法自动触发某个中断,全靠手动停下观察,是不是有点难。。:)

使用特权

评论回复
19
程序匠人|  楼主 | 2009-8-18 10:14 | 只看该作者
那么请问匠人:
如果俺用的芯片片内RAM太少,也不支持IAP啥的,然后呢,那个扰动又不一定啥时候出现,出现时又没法自动触发某个中断,全靠手动停下观察,是不是有点难。。:) ...
cauhorse 发表于 2009-8-18 09:57


方法总是有的。
方法1:临时关闭其他不相关的功能模块,释放内存用作黑匣子队列。
方法2:用其它方式捕捉扰动。

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
mfy0501 + 1
20
mjei| | 2009-8-18 10:17 | 只看该作者
有触动,不过汇编的功底还是扎实点好啊
1# 程序匠人

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名: 《匠人手记》第二版已经上市,各大网络书店和实体书店有售! 匠人手机——手机中的颤抖机!欧耶! 匠人手记——手记中的战斗记!欧耶!

734

主题

11156

帖子

676

粉丝