嵌入式软件调试技术 读书笔记

第一章 软件调试概述

第二章 边界扫描测试技术 (JTAG)

第三章 学习使用GDB调试器

第四章 GDB远程调试技术

第五章 网络应用程序调试

第六章 多进程与多线程调试

第七章 静态库与动态库的调试

第八章 MPEG-4视频播放器的设计与调试

第九章 基于GPS的移动定位终端

参考文献

边界扫描测试技术

TIPS:

1. TRST为什么是可选信号呢?

因为通过TMS也可以复位测试逻辑

2. 为什么在TMS信号上加上拉电阻?

IEEE 1149.1规定,在TMS上没有输入信号驱动的情况下,测试逻辑工作应该和在TMS上送入高电平时是一样的,这样TAP控制器将会被强制进入Test-Logic-Reset状态。

3. TDI TMS在上升沿采样,TDO在下降沿采样?

为了避免在进行测试的时候存在竞争条件。

4. JTAG调试接口由TAP控制器、指令寄存器、数据寄存器组3部分构成,而TAP控制器就是控制测试逻辑对指令(数据)寄存器进行操作的。

5. 不管TAP控制器的原始状态是什么,只要TMS保持高电平至少5个TCK上升沿的时间以上,就将使得TAP控制器进入Test-Logic-Reset状态。只要TMS为高电平,就将使控制器保持在这一状态。

6. 每个支持JTAG调试的芯片必须至少包含一个指令寄存器。对于特定的某款芯片而言,芯片生产厂商一般都会在IEEE1149.1标准的基础山扩充一些私有的指令寄存器和数据寄存器,以方便在开发过程中进行功能测试和诊断调试。

7. JTAG标准允许不同的指令共享相同的二进制编码,通过TAP控制器的当前状态来区分指令的行为。他们是OPCODE相同的不同指令,如SAMPLE和PRELOAD

8. JTAG公共指令(public)以及私有指令(private)

通过自检对元件进行测试的能力

能依靠边界扫描寄存器对板级互联进行测试的能力

9. 必须包含的共有指令:

BYPASS

SAMPLE

PRELOAD

EXTEST

IDCODE(有设备ID寄存器的情况)

10. BYPASS:二进制编码所有位都为1

其指令的目的是将BYPASS寄存器链入该元件自身的TDI和TDO之间,这样就可以使测试数据能够快速地从扫描链中通过。

11. SAMPLE:

将边界扫描寄存器串行地链入TDI和TDO之间。

12. PRELOAD:和SAMPLE类似,但是数据流的方向是反的。S是将元件核心逻辑或外部引脚上的信号状态加载到边界扫描链中,而PRELOAD指令是将边界扫描链中的数据值送入核心逻辑或外部引脚。

13. EXTEST:用于板级互联性测试。

14. 设备ID寄存器包括3部分

厂商ID,11bits压缩码

零件编号16bits编码

版本号4bits

其核心就是Test Access Port Controller(测试访问端口控制器)的内部这个有限状态机见下图:

clip_image002

多进程与多线程调试

TIPS:

1. UNIX类系统中,进程的创建几乎都是通过fork()系统调用来完成

2. fork出的子进程会继承父进程的大部分内容,如程序段、数据段、堆栈段、用户ID、组ID、控制终端和环境变量等。

3. fork函数在被调用一次后会返回两次,一次在父进程中,返回值为子进程的ID,一次在子进程中返回值是0

4. fork完成后,父进程还是子进程先被调度,这个顺序不是确定的

5. Linux下,fork采用了copy-on-write的技术,fork出子进程后并不立即对父进程的资源进行复制,而是当子进程试图向这些空间中写入数据时,才由内核完成真正的复制工作。写到这里我想到实际遇到的一个问题(2.4.25的kernel),64Mbytes的系统内存,除去系统占用的10MB,主进程起来用了30MB的内存,当调用System的时候就会失败,erro no是内存申请失败。其原因是fork虽然采用了copy-on-write的技术,但是在创建进程的时候还是会检测剩下的内存是否够主进程的尺寸。因为他考虑到你可能会去修改,而实际上你并没有这样做。最后解决问题的办法是通过proc接口配置了内核的一个参数,在做内存申请判断的时候,当内存不足的情况下也返回成功。

6. GDB并没有为多进程程序提供太多的支持,通常情况下,fork出来的子进程将脱离GDB的控制。

7. follow-fork-mode [mode]

mode可以是parent和child。为P,fork后GDB调试父进程,为C则调试子进程

对应的命令:set follow-fork-mode [mode]; show follow-fork-mode;

8. detach-on-fork [mode] mode: on / off

为on(默认情况)不被GDB控制的进程(参考follow-fork-mode的配置)将脱离GDB而独立运行,为off,这不被GDB控制的进程将被挂起。

对应的命令:set detach-on-fork [mode]; show detach-on-fork

9. info forks,该命令将打印出出于GDB控制下的多有fork出的进程列表。

10. fork [fork-id],该命令将fork-id对应的进程设成当前进程

11. detach-fork [fork-id],使fork-id对应的进程脱离GDB的控制

12. delete fork [fork-id],将杀死fork-id对应的进程通过在info forks列表中将其删除

13. 线程可以看做轻量级的进程(以前课本上叫轻权进程),线程的优势在于所占用的资源少,执行效率高,上下文切换快,但缺点是难以对资源进行包含和管理。

14. Linux下的两套线程的API:LinuxThread,Pthreads(POSIX),前者我记得到了2.6才开始有了支持,2.4的环境下没有使用过。

15. GDB对多线程调试的支持:自动通知新线程的产生;在多个线程之间切换;查询当前线程的信息;将命令运用到一组线程上;特定于线程的断点

16. info threads 用来获得当前进程中所有线程的概要信息。

17. thread [threadno] 切换当前的线程为threadno所对应的线程。

18. thread apply [threadno | all] command,将在threadno所代表的线程上应用command命令。

19. break linespec thread threadno

break linespec thread threadno if cond

这两个命令可以设置特定于线程的断点

20. set scheduler-locking mode

该命令能够选择是否锁住内核线程调度。Mode可以是off、on和step

Off不会锁住内核线程调度,因此该线程能够在任何时刻被调度

On完全锁住内核线程调度,只有当前线程能够运行

Step单步指令不会引起其他线程运行,别的指令如C可以使其他线程运行。

静态库与动态库的调试

1. 目标文件的归档工具ar,和文件的归档工具tar相比,他会为被归档的目标文件中的符号表建立索引,还可以对归档文件执行追加、修改和删除等操作。

2. 通常我们使用的归档命令是:ar rcs libxxx.a obj1.o … objx.o

r: 将成员(objx.o)插入到archive中,如果archive有同名的成员,则替换已有的成员。默认情况下插入到archive中的成员会被添加到archive的末尾

c: 创建archive

s: 将目标文件的索引写入archive中

注: ar s 命令等同于归档文件使用的ranlib命令

v: 该参数显示详细信息

t: 显示archive中的成员

3. ar生成的文件是否经过压缩的呢?还是像tar不带j和z参数一样是不压缩的?

我觉得是不会压缩的(经过试验发现是不压缩的

4. 用交叉编译器上的ar和主机的ar工具对同样的目标文件归档,其输出的结果有什么不同?

我用ar和mips-linux-ar进行了对比,发现生成的文件除了时间戳不一样,剩下部分是一样的。

关于AR的文件头参考:http://en.wikipedia.org/wiki/Ar_(Unix)

Global header

The global header is a single field containing the magic ASCII string "! " followed by a single LF control character

File header

The common format is as follows.

Field Offset from

Field Offset to

Field Name

Field Format

0

15

File name

ASCII

16

27

File modification timestamp

Decimal

28

33

Owner ID

Decimal

34

39

Group ID

Decimal

40

47

File mode

Octal

48

57

File size in bytes

Decimal

58

59

File magic

0x60 0x0A

Due to the limitations of file name length and format, both the GNU and BSD variants devised different methods of storing long filenames.

5. nm是一个很有用的工具,通过他可以获得archive中obj文件里的符号信息

6. 对于静态库的GDB调试,只要保证生成库文件的目标文件是带调试信息的,即生成该文件时是含有-g参数的

7. 对于静态链接生成可执行文件时,连接器会将静态链接库复制一份到最终得到的可执行代码中去。那么对于库里没有使用到的函数是否也会复制一份呢?

通过实验证明即使不用到也是会复制的(gcc环境)

8. 动态库的优缺点

优点

a> 节省内存,如果多个应用程序使用到同一个动态链接库,内存是只会存在一个动态共享库的副本。

b> 节省硬盘,同样如果多个应用程序使用到同一个动态库,那么在存储介质上只会有一个副本。

c> 便于软件的修复和升级,因为动态库和应用程序是独立的文件,所以可以做到分开维护,这样可以减少编译和软件升级的时间。

d> 提高性能,当一个用到该动态库的应用程序已经在运行,那么启动另外个的时候不会再加载动态库,这可以节省些时间。

缺点

e> 复杂性。首先动态库的API接口不能轻易变动,其次动态库函数必须是可重入的,再次动态库复杂的依赖关系对于软件移植是不利的。

f> 兼容性,因为动态库和应用程序是分开发表的,就要保证好其版本的依赖性。

g> 调试困难,在嵌入式环境下调试动态库是不容易的(其实我觉得也没复杂多少)

9. 动态库的命令(soname = share object name),例如系统里可以找到一个libc.so.6的文件,实际上是指向libc-2.3.2.so的软连接,是谁来建立这个软连接呢?是ldconfig,其工作1是建立软连接2是更新共享库的cache /etc/ld.so.cache 那么他是如何工作的呢?首先在libc-2.3.2.so中包含了soname的信息,通过命令readelf –d libc-2.3.2.so可以看到:

0x0000000e (SONAME) Library soname : [libc.so.6]

在/etc/ld.so.conf文件中定义的所有动态库的搜索路径,这样ldconfig就可以通过搜索这些目录找到所有的动态库,生成符号链接,更新cache

10. 在连接可执行程序指定链接库的时候像 libc.so.6只要写成 –lc就可以了。

11. 除非在编译应用程序时明确地使用GCC的-static选项,否则GCC将使用动态共享库与应用程序链接。问题是:如果目录下同时存在共享库和动态库,那是优先共享库么?

通过实验证明,是优先共享库的如何指定使用静态库还不清楚

-static选项的确可以生成使用静态库的image,不过值得注意的是所有的库都会使用静态库,包括libc,所以生成的image会比较庞大。

通过,对于动态库也是将完整的库镜像加载到应用程序的虚拟内存上的,而不仅仅是那些应用程序用到的部分,这点是比较好理解的,毕竟动态库可能很多人用到,不可能一一处理。

12. 共享库是不需要ar来打包的,直接通过gcc就可以了。下面是要使用到的几个gcc的参数

-shared 告诉gcc生成共享目标文件,此选项必须和-fPIC等选项联合使用。(实际中我记得没有使用这个-fPIC的参数,好像也没什么问题)

-fPIC 生成位置无关代码(Position-Independent Code, PIC)

-Wl,-soname,xxx gcc会把-soname,xxx作为一个命令行选项传递给链接器ld,来生成类似0x0000000e (SONAME) Library soname : [libc.so.6]的信息,例如生成libc-2.3.2.so时的参数 –Wl,-soname,libc.so.6

-fomit-frame-pointer 编译后的程序中不使用指令来保存和恢复函数的栈帧寄存器,这样可以提高程序的执行效率,副作用是某些平台上调试器将不正常工作(例如bt可能不正常,个人理解)

13. 生成动态库的命令:gcc –shared –Wl,soname,xxx –o libname filelist liblist

14. 对于动态库进行GDB调试的时候一个主要的问题是动态库的不会像应用程序一样自动的加载,对于远程调试还有一个主要问题是要区别好local和target上的动态库。

15. 远程动态库,一般调试过程:

a> 启动gdbserver,client连接上后在动态库加载完成的地方设置断点(通常在main上)

b> 找到动态库在应用程序虚拟内存上的加载地址,例如:

cat /proc/758/maps

4001d000 – 4001e000 r-xp 00000000 1f:03 2921 /usr/local/lib/libfoobar.so.0.0

这里只要这个0x4001d000地址

c> 找到动态库文件中,text段在文件中的偏移地址,例如:

arm-linux-objdump –h libfoobar.so.0.0

idx Name Size VMA LMA File off Algn

9. text 000001bc 0000073c 0000073c 0000073c 2**2

这里需要的是0000073c这个地址

d> 在叠加出的地址上通过命令进行gdb的调试符号加载,例如:

(gdb) add-symbol-file libfoobar.so.0.0 0x4001d000+0x0000073c

16. add-symbol-file file addr [-s -s …]

从file中加载符号

17. set auto-solib-add mode

mode = on, 所有动态库中的符号都将自动被加载,自动加载的时刻:

a> 当被调试程序开始运行时

b> 当gdb连接到被调试程序是(attach)

c> 当操作系统的动态链接器通知gdb有新的动态库被加载时

默认下为off

18. show auto-solib-add

19. sharedlibrary regex

从正则表示式regex指定的动态库中加载符号

20. nosharedlibrary

将丢弃所有从动态库中加载的符号信息

21. info sharedlibrary

打印当前所有加载的动态库的文件名

22. set solib-absolute-prefix path

show solib-absolute-prefix

path将用作动态共享库觉得路径的前缀。这点是针对远程调试的,例如:

/opt/arm-linux/usr/lib

23. set solib-search-path path

path是一个以冒号分隔的目录列表,gdb将在这些目录列表里搜索动态共享库。该搜索操作会在solib-absolute-prefix搜索后进行

后面为AVI部分的介绍,主要是RIFF和相关的一些规范,后面是C的一个协议实现libavi,大量篇幅在数据结构的定义和代码实现上,真正和调试相关的只占了5页,这部分目前用不上,略读,跳过。

参考文献

1. Andrew S. Tanenbaum, Albert S. Woodhull. 操作系统:设计与实现. 第二版。 尤晋元,等译。 北京:电子工业出版社,2003

2. Bill Blunden。虚拟机的设计与实现------C/C++。杨涛,等译。北京:机械工业出版社,2003

3. 毛德操,胡希明。Liux内核源代码情景分析。上册。浙江:浙江大学出版社,2001.

4. 赵民栋。嵌入式软件集成开发环境中调试器的设计与实现。西安:西北工业大学硕士学位论文,2004

5. Norman Matloff,P.J. Salzmann. The Art of Debugging with GDB and DDD. No Starch Press, 2006

6. Richard Stallman, 等。Debugging with GDB. Free Software Foundation, 2006

7. Jonathan B. Rosenberg. How Debugger Work: Algorithms, Data Structures, and Architecture. John Wiley & Sons. Inc, 1996.

8. IA-32 Intel Architecture Software Developer’s Manual Volume 3B: System Programming Guide Part 2. Intel Co., 2006.

9. 毛德操,胡希明。嵌入式系统 --- 采用公开源代码和StrongARM/Xscale 处理器。浙江: 浙江大学出版社,2003.

10. 黄红燕。嵌入式系统调试技术的分析与设计。浙江:浙江大学硕士学位论文,2006.

11. Test Technology Standards Committee of the IEEE Computer Society. IEEE Standard Test Access Port and Boundary-Scan Architecture. 2001

12. John F. Wakerly. 数字设计----原理与实践。影印版。第三版。北京:高等教育出版社,2003

13. twentyone。 ARM JTAG调试原理。 http://twentyone,blogchina.com/index.html.

14. ARM7TDMI Technical Reference Manual. ARM Limited. 2001

15. W. Richard Stevens. UNIX 环境高级编程. 尤晋元,等译。 北京:机械工业出版社,2005

16. Jeffrey E.F.Friedl. 精通正则表达式。英文影印版。第二版。南京:东南大学出版社,2005

17. 严蔚敏,吴伟民。数据结构。C语言版。北京:清华大学出版社,2002

18. 雷航,王茜。现代微处理器及总线技术。北京:国防工业出版社,2006

19. Anany Levitin. 算法设计与分析基础。影印版。北京:清华大学出版社,2003.

20. Samuel P. Harbison, 等。 C语言参考手册。英文版。第五版。北京:人民邮电出版社,2003

21. Kurt Wall, 等。GNU/Linux 编程指南。张辉,译。北京:清华大学出版社,2005.

22. Geert Uytterhoeven. The Frame Buffer Device. 2001

23. Alex Buell. Framebuffer Howto. 2000

24. Linux 2.2 Framebuffer Device Programming Tutorial. www.linuxsir.org

25. [美]冈萨雷斯,等。数字图像处理。第二版。阮秋琦,等译。北京:电子工业出版社,2005

26. Thomas G. Lane. USING THE IJG JPGE LIBRARY. 1994-1998

27. Sitang-PXA255 Evaluation Platform User Guild. Intel Inc, 2003

28. Sitang-PXA255 Evaluation Platform Linux User Guild. Intel Inc, 2003

29. John Shapley Gray. UNIX进程同学。第二版。张宇,译。北京:电子工业出版社,2001

30. 赵炯。Linux Developing History. www.plinux.org

31. 林锐。高质量C++/C编程指南。上海:上海贝尔公司,2001

32. 汤凯。OSS---跨平台的音频接口简介。http://www-128ibm.com/developerworks/cn/linux/l-ossaip/

33. 肖文鹏。Linux音频编程指南。http://www-128ibm.com/developerworks/cn/linux/l-audio/

34. Open Sound System Programmer’s Guild. www.opensound.com

35. W. Richard Stevens. TCP/IP详解。范建华,等译。北京:机械工业出版社,2000

36. W. Richard Stevens. UNIX网络编程。第二版,施振川,等译。北京:清华大学出版社,2001

37. Marshall Kirk McKusick,等。4.4BSD操作系统设计与实现。英文影音版。北京:人民邮电出版社,2001

38. Michael R. Sweet. Serial Programming Guide for POSIX Operating System. 5th Edition. http://digilander.libero.it/robang/serial.htm#CONTENTS. 1994-1999

39. CDMA AT Commands Interface Specification v1.78. 2003

40. http://www.unicode.org

41. W. Richard Stevens. UNIX网络编程。第二版。杨继张,译。北京:北京科海电子出版社,2000

42. Bil Lewis, Daniel J. Berg. PThreads Primers: A Guide to Multithreaded Programming. Prentice Hall PTR, 1995

43. David R.Butenhof. POSIX 多线程程序设计。于磊,曾刚,译。北京:中国电力出版社,2003

44. Portable Applications Standards Committee of the IEEE Computer Society and The Open Group. Standard for Information Technology ---- Portable Operating System Interface (POSIX ) System Intefaces. 2004

45. 嵌入式Linux调试:用gdbserver调试共享库。http://blog.csdn.net/absurd/archive/2006/06/18/804810.aspx. 2006

46. AVI RIFF File Reference. http://msdn2.microsoft.com/en-us/library/ms779636.aspx

47. Matrox Electronic System Ltd.. OpenDML AVI File Format Extensions(version 1.02). 1997

48. Iain E. G. Richardson. H.264 and MPEG-4 Video Compression ---- Video Coding for Next-genertaion Multimedia. John Wiley & Sons Inc. , 2003

49. http://www.xvid.org

50. SDL Library Documentation. http://www.libsdl.org

51. http://www.nmea.org

52. GARMIN Inc.. GPS 15 Technical Specifications. 2002

53. 北京飞漫软件技术有限公司。MiniGUI编程指南 for MiniGUI Ver 1.3.x. 2003

54. 北京飞漫软件技术有限公司。MiniGUI用户手册for MiniGUI Ver 1.3.x. 2003

55. 北京飞漫软件技术有限公司。MiniGUI API Reference Documentation for MiniGUI Ver 1.3.x. 2003

56. 谭浩强。 C程序设计。第二版。北京:清华大学出版社,2005

57. http://www.tcpdump.org

58. 李天文。GPS原理及应用。北京:科学出版社,2004.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值