57
1 嵌嵌嵌嵌嵌嵌Embedded Operating System 嵌嵌嵌 嵌嵌嵌嵌嵌嵌嵌嵌嵌

嵌入式操作系统 Embedded Operating System

Embed Size (px)

DESCRIPTION

嵌入式操作系统 Embedded Operating System. 第八课 开发环境和调试技术. 课程大纲 .  交叉开发环境模式概述  宿主机环境  目标板环境  交叉编译工具链  gdb 调试器  远程调试  其他 调试. 2. 2. 交叉开发环境模式概述. 什么是嵌入式系统 “ 以应用为中心、以计算机技术为基础、软件硬件可裁剪、适应应用系统对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统。 ” 硬件上的局限性 存储空间小 处理器频率低 缺少存储、输入输出设备. 宿主机—目标板交叉开发模式. 组成部分 - PowerPoint PPT Presentation

Citation preview

Page 1: 嵌入式操作系统 Embedded Operating System

1

嵌入式操作系统Embedded Operating

System

第八课 开发环境和调试技术

Page 2: 嵌入式操作系统 Embedded Operating System

22

课程大纲 

2

交叉开发环境模式概述 宿主机环境 目标板环境 交叉编译工具链 gdb调试器 远程调试 其他调试

Page 3: 嵌入式操作系统 Embedded Operating System

3

交叉开发环境模式概述什么是嵌入式系统 “以应用为中心、以计算机技术为基础、软件硬件可裁剪、适应应用系统对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统。”

硬件上的局限性 存储空间小 处理器频率低 缺少存储、输入输出设备

Page 4: 嵌入式操作系统 Embedded Operating System

4

宿主机—目标板交叉开发模式组成部分 宿主机:平时使用的桌面计算机 目标板:嵌入式开发板

介绍 利用宿主机上已有的成熟的开发工具,专门针对目标板定制一套系统,包括引导程序、内核和文件系统,然后下载到目标板上运行。

Page 5: 嵌入式操作系统 Embedded Operating System

5

宿主机—目标板交叉开发模式开发过程 在宿主机上编写代码,并通过交叉编译工具编译出能够在目标板上运行的程序,然后下载到目标板上测试执行,最后利用宿主机上的调试工具对目标板上运行的程序进行远程调试。

特点 使用和桌面开发一样的工具,降低学习成本。 充分利用宿主机的开发环境。

Page 6: 嵌入式操作系统 Embedded Operating System

6

宿主机—目标板连接方式串口 利用串口给目标板发送命令,同时也可以接受目标板返回的信息并显示。

宿主机可以通过串口往目标板传送文件; 目标板可以把程序运行的结果返回并显示。 串口驱动程序的实现相对比较简单,缺点是传输速度慢,并不适用于传输大量数据的场合。

以太网 以太网是当今局域网采用的最通用的通信协议标准。 它使用简单,配置灵活,支持广泛,传输速率快,安全可靠,缺点是网络驱动的实现比较复杂。

Page 7: 嵌入式操作系统 Embedded Operating System

7

宿主机—目标板连接方式USB USB是 Universal Serial Bus通用串行总线)的缩写,现已成为 PC的标准,基于 USB标准的设备被广泛使用。

一种快速、灵活的总线接口,与其它通信接口相比, USB接口的特点是易于使用。

支持热插拔,无需用户自己配置,系统会自动搜索驱动并安装。 USB是典型的主从结构,两端分别需要不同的驱动程序。

JTAG JTAG是一种国际标准测试协议,主要用于芯片内部测试及对系统进行仿真、调试。

在嵌入式系统领域,几乎所有的处理器都支持 JTAG,调试器的单步调试和断点都需要和 JTAG交涉。

可以使用 JTAG 将程序烧写到目标板上。

Page 8: 嵌入式操作系统 Embedded Operating System

88

课程大纲 

8

交叉开发环境模式概述 宿主机环境 目标板环境 交叉编译工具链 gdb调试器 远程调试 其他调试

Page 9: 嵌入式操作系统 Embedded Operating System

9

宿主机环境串口终端BOOTP协议TFTP协议交叉编译Make工具

Page 10: 嵌入式操作系统 Embedded Operating System

10

串口终端串口终端串口的用途 作为终端执行命令,管理嵌入式系统。 使用 zmodem协议等传送小文件。

串口终端 超级终端 (Windows XP) Minicom (Linux)

Page 11: 嵌入式操作系统 Embedded Operating System

11

BOOTP协议什么是 BOOTP协议 引导协议( Bootstrap Protocol, BOOTP)是一种基于 TCP/IP的协议,它最初在 RFC951中定义,如今在通用计算机上广泛使用的DHCP协议就是从 BOOTP协议扩展而来。 BOOTP协议使用TCP/IP网络协议中的 UDP 67/68两个通讯端口。

BOOTP协议用途 用于无盘客户机从服务器得到自己的 IP 地址、服务器的 IP 地址、

启动映象文件名、网关信息等等

Page 12: 嵌入式操作系统 Embedded Operating System

12

BOOTPBOOTP 处理过程处理过程

第一步,在主机平台运行 BOOTP 服务的情况下,目标板由 Boot Loader 启动 BOOTP,此时目标板还没有 IP 地址,它就用广播形式以IP 地址 0.0.0.0 向网络中发出 IP 地址查询的请求,这个请求帧中包含了客户机的网卡 MAC 地址。

第二步,主机平台上的 BOOTP 服务器接收到的这个请求帧,根据这帧中的MAC 地址在 Bootptab 启动数据库中查找这个 MAC的记录,如果没有此 MAC的记录则不响应这个请求;如果有就将 FOUND 帧发送回目标板。 FOUND 帧中包含的主要信息有目标板的 IP 地址、服务器的 IP 地址、硬件类型、网关 IP 地址、目标板MAC 地址和启动映象文件名。

第三步,目标板就根据 FOUND 帧中的信息通过 TFTP 服务器下载启动映象文件。

Page 13: 嵌入式操作系统 Embedded Operating System

13

TFTP协议什么是 BOOTP协议 TFTP的全称是 Trivial File Transfer Protocol,即“简单文件传输协议”,它是 TCP/IP协议族中的一个在客户端和服务端之间进行简单文件传输的协议,提供不复杂、开销不大的文件传输服务。

TFTP特点 不提供用户名和口令 TFTP 协议传输由客户端发起

Page 14: 嵌入式操作系统 Embedded Operating System

14

交叉编译背景 目标文件在不同架构间由于采用的 CPU 指令集不同等原

因不能通用。

定义 交叉编译就是在一个架构的机器下编译另一个架构的目标文件。

需要安装交叉编译工具链

Page 15: 嵌入式操作系统 Embedded Operating System

15

make工具GNU Make是一种常用的编译工具,通过它,程序员可以很方便地管理软件编译的内容、方式和时机,从而使程序员能够把主要精力集中在代码的编写上。 Make自动判断源码中哪些部分有更新,重新编译这些文件并重新链接。对于那些由许多源文件组成的大型软件项目来说,采用这种项目管理方法则可以极大地提高工作效率,让原本复杂繁琐的开发工作变得简单。make 工具通过一个称为 makefile的文件来完成并自动维护编译工作。 makefile需要按照某种语法进行编写,其中说明了如何编译各个源文件并连接生成可执行文件,并定义了源文件之间的依赖关系。当修改了其中某个源文件时,如果其他源文件依赖于该文件,则也要重新编译所有依赖该文件的源文件。

Page 16: 嵌入式操作系统 Embedded Operating System

16

基本规则 :目标、依赖关系、指令

target : dependency …… command ……

目标( target):需要由 make工具创建的项目,是指令( command)执行的结果文件(目标文件或执行文件),也可以是一个标签( Lable),如 make clean、make all 等。依赖( dependency):要创建的项目依赖于哪些文件或目标。依赖条件顶格书写。 指令( command):创建每个项目时make需要运行的命令(任意的Shell命令) 。指令必须使用一个 TAB 符(制表位)开始进行书写。在指令部分定义的指令会在依赖文件的内容有所变更或找不到目标文件时被执行。

Page 17: 嵌入式操作系统 Embedded Operating System

17

如果一个工程有三个源文件 write.c, read.c,main.c 生成可执行程序 test 。 用于生成 test的Makefile文件如下:

test: main.o read.o write.o gcc –o test main.o read.o write.o

main.o : io.h main.c gcc –c main.cread.o : io.h read.c gcc –c read.cwrite.o : io.h write.c gcc –c write.cclean: rm test main.o read.o write.o

-c:对源程序进行预处理、编译,产生目标文件,但不进行连接。-o <文件名 >:定义输出的执行文件名为 <文件名 >。

Page 18: 嵌入式操作系统 Embedded Operating System

18

clean不是一个文件,它只不过是一个动作名字,有点像 C语言中的 lable一样,其冒号后什么也没有,那么,make就不会自动去找文件的依赖性,也就不会自动执行其后所定义的命令。要执行其后的命令,就要在make命令后明显得指出这个 lable的名字。

例如,使用名为 clean标签来进行清除,可以没有依赖关系部分,即执行命令

以此来清除所有的目标文件,以便重新编译。相当于执行了:

[root@XSBase test]# make clean

[root@XSBase test]# rm test main.o read.o write.o

Page 19: 嵌入式操作系统 Embedded Operating System

19

Makefile 依赖关系

使用 vi编译器创建 Makefile后,进行make,则生成执行文件 test。Make 将按照 Makefile中指定的依赖关系来依次执行。

[root@XSBase test]# make

Page 20: 嵌入式操作系统 Embedded Operating System

20

宏和标签 为了 makefile的易维护,在makefile中我们可以使用变量。makefile的变量也就是一个字符串,理解成 C 语言中的宏可能会更好。 比如,我们声明一个能够表示 obj文件的宏,宏名可为objects, OBJECTS, objs, OBJS, obj 或 OBJ 等。

可使用宏 ( Macro )功能和标签 ( Label )功能使Makefile的创建更为灵活。宏起到以替换指定的内容使程序简单化的作用。宏必须要在 $(..) 里面使用。

Page 21: 嵌入式操作系统 Embedded Operating System

21

例:利用宏来创建 Makefile。在这里宏是 OBJECTS,将main.o、 read.o、 write.o 替换为 OBJECTS 来使用。

OBJECTS = main.o read.o write.otest: $(OBJECTS) #使用名为 OBJECTS 的宏来创建 Makefile.

gcc –o test $(OBJECTS)main.o: io.h main.c gcc –c main.cread.o: io.h read.c gcc –c read.cwrite.o: io.h write.c gcc –c write.cclean: rm test $(OBJECTS)

Page 22: 嵌入式操作系统 Embedded Operating System

22

预定义的宏 (Pre-defined Macro) 执行make -p可看到Make中事先指定好的各个值(宏,环境参数等)。

宏的定义 涵义AS = as 指定汇编器,默认值为 as

ASFLAGS = 汇编程序( AS 指令)的选项设置CC = cc 或 CC = gcc 指定编译器( C),默认值为 cc

CFLAGS = C编译器( gcc 指令)的选项设置CXX = g++ 指定 C++编译器,默认值为 g++

CPPFLAGS = C++编译器( g++ 指令)的选项设置LD = ld 指定链接器LDFLAGS = ld 的选项设置

Page 23: 嵌入式操作系统 Embedded Operating System

23

扩展名规则

扩展名规则( Suffix Rule)是根据文件的扩展名来进行适当的运算操作。例如, .c一般指 C 源文件, .o文件是目标文件。 .c文件编译后应成为 .o文件。

在这里出现名为 .SUFFIXES的宏,这个宏自动处理Makefile中需要慎重处理的文件的扩展名。 .SUFFIXES = .c .o

上面的例子对带有 .c和 .o 扩展名的文件按照扩展名规则来处理,自动操作使 .c文件编译后生成 .o文件。

Page 24: 嵌入式操作系统 Embedded Operating System

24

宏名 涵义$* 没有扩展名的当前目标文件

$@ 当前目标文件的完整名称

$< 第一个依赖文件的名称,即比当前目标文件更新的第一个文件名

$?所有的依赖文件,以空格分开,这些依赖文件修改日期比目标的创建日期晚。比当前目标文件更新的所有文件名

$^ 所有的依赖文件,以空格分开,重复出现的名字只保留一个

$+所有的依赖文件,以空格分开,并以出现的先后为序,保持重复出现的名字不变

内部宏定义( Internal Macro)用于简化 Makefile的写法

Page 25: 嵌入式操作系统 Embedded Operating System

25

内部宏的用法例子一:

main.o : main.c io.h gcc -c $*.c

说明: $*是没有扩展名的当前目标文件,所以 $*.c 扩展为main.c。 例子二:

test : main.cgcc -o $@ -c main.c

说明: $@是当前目标文件,相当于 test。 例子三:

.c.o : gcc -c $<

test: main.o gcc -o $@ main.o

说明:如果源文件 .c比目标文件 .o 更新,则 .c文件会自动编译。即在main.o 生成之后更新了 main.c的话,那么main.c 就会被 $<自动重新编译。

Page 26: 嵌入式操作系统 Embedded Operating System

26

myprog:main.o display.o input.o

gcc main.o display.o input.o -o myprog

main.o:main.c common.h

gcc -c main.c

display.o:display.c display.h common.h

gcc -c display.c

input.o:input.c input.h common.h

gcc -c input.c

clean:

rm -f myprog main.o display.o input.o

CC=gcc

OBJS=main.o display.o input.o

myprog:$(OBJS)

$(CC) $(OBJS) -o $@

main.o:main.c commom.h

$(CC) -c $<

display.o:display.c display.h common.h

$(CC) -c $<

input.o:input.c input.h common.h

$(CC) -c $<

clean:

rm -f myprog $(OBJS)

Page 27: 嵌入式操作系统 Embedded Operating System

27

make工作过程编写Makefile Makefile 由一系列规则组成,每条规则说明要生成哪些目标文件、

生成目标文件所依赖的其它文件以及生成目标文件所需要的命令。

编译过程 通过查看时间戳来确认依赖文件是否比目标文件更新,如果是则重

新执行这条规则的命令,并进一步地执行依赖这些中间目标文件的规则,层层推进,最后生成新的结果文件。

Page 28: 嵌入式操作系统 Embedded Operating System

28

需要重新编译的情况需要重新编译的情况所有的依赖文件都没有被编译过,则对每个源文件进行编译并进行链接,生成最后的可执行程序 。源文件在上次编译之后被修改过,则在本次执行make的时候将会被重新编译。头文件在上次编译之后被修改过,则所有包含此头文件的源文件在本次执行make的时候将将会被重新编译。

Page 29: 嵌入式操作系统 Embedded Operating System

2929

课程大纲 

29

交叉开发环境模式概述 宿主机环境 目标板环境 交叉编译工具链 gdb调试器 远程调试 其他调试

Page 30: 嵌入式操作系统 Embedded Operating System

30

目标板环境

JTAG接口Boot Loader

Page 31: 嵌入式操作系统 Embedded Operating System

31

JTAG接口简介作为硬件测试手段, JTAG的功能与 CPU 状态无关,可驱动设备的所有外部引脚并读入数据,而且在设备内部夺取外部的连接点(与通往外部的各个pin 脚一一连接)。各个 cell为了形成 Serial Shift Register 而相连。整体的接口由 5个 pin 脚来控制( TDI, TMS, TCK, nTRST, TDO)。其功能包括:测试线路连线和端子的连接状态;测试设备间的连接状态;进行 Flash memory 烧写等。

Page 32: 嵌入式操作系统 Embedded Operating System

32

Boot Loader简介Boot Loader是系统加电后运行的第一段代码。完成初始化硬件设备、创建内核需要的信息等工作,最后调用操作系统内核。对硬件的依赖非常强,不同的体系结构、不同的嵌入式板级设备配置都会对 Boot Loader有不同的需求。

Page 33: 嵌入式操作系统 Embedded Operating System

3333

课程大纲 

33

交叉开发环境模式概述 宿主机环境 目标板环境 交叉编译工具链 gdb调试器 远程调试 其他调试

Page 34: 嵌入式操作系统 Embedded Operating System

34

交叉编译工具链交叉编译工具链是一个由编译器、链接器和解释器组成的集成开发环境。和本地编译类似,交叉编译的过程也是由编译、链接等阶段组成,源程序通过交叉编译器编译成目标模块,并由交叉链接器加载库最后链接成可在目标平台上执行的程序代码。

Page 35: 嵌入式操作系统 Embedded Operating System

35

交叉编译过程交叉编译过程

源程序

编辑器

目标文件

交叉编译器

可执行程序

交叉链接器

库文件

Page 36: 嵌入式操作系统 Embedded Operating System

36

交叉编译的构建从头编译 编译难度大,不适合初学者。脚本编译 需要选择合适的脚本工具,例如 crosstool

下载使用 下载指定平台编译好的二进制包。

Page 37: 嵌入式操作系统 Embedded Operating System

37

相关工具

交叉编译工具链主要包括:标准库: glibc编译器: gcc链接器: ld 汇编器: as调试器: gdb

Page 38: 嵌入式操作系统 Embedded Operating System

38

标准库:标准库: glibc

最初是自由软件基金会为其 GNU 操作系统所写,但目前最主要的应用是配合 Linux内核,成为 GNU/Linux 操作系统一个重要的组成部分。

是 Linux系统中最底层的 API,几乎其它任何运行库都会直接或间接地依赖于 glibc。

除了封装系统调用之外,还提供一些基本的功能,例如 open、malloc、 printf、 exit 等等。

Page 39: 嵌入式操作系统 Embedded Operating System

39

编译器:编译器: gcc

支持不同的编程语言,它被目前许多 Unix/Linux系统作为默认的标准编译器。支持多种处理器架构上,并且在商业、专利和开源软件开发环境中广泛使用。支持嵌入式系统平台。

Page 40: 嵌入式操作系统 Embedded Operating System

40

binutils

是一组开发工具包,包括连接器、汇编器和其他用于目标文件和档案的工具。其中包括:addr2line、 ar 、 as、 ld、 nm、 objdump 、 ranlib、 readelf

Page 41: 嵌入式操作系统 Embedded Operating System

41

调试器:调试器: gdbgdb

是一款功能非常强大的调试器,既支持多种硬件平台,也支持多种编程语言,目前 gdb支持的调试语言有 C/C++、 Java、 Fortran、Modula-2 等多种语言。

不仅用于本地调试,还可以用于远程调试,非常适合嵌入式系统开发使用。

Page 42: 嵌入式操作系统 Embedded Operating System

4242

课程大纲 

42

交叉开发环境模式概述 宿主机环境 目标板环境 交叉编译工具链 gdb调试器 远程调试 其他调试

Page 43: 嵌入式操作系统 Embedded Operating System

43

gdbgdb 调试调试

使用 gdb可以完成下面这些任务:运行程序,可以给程序加上所需的任何调试条件;在给定的条件下让程序停止; 检查程序停止时的运行状态;通过改变一些数据,可以更快地改正程序的错误。

Page 44: 嵌入式操作系统 Embedded Operating System

4444

课程大纲 

44

交叉开发环境模式概述 宿主机环境 目标板环境 交叉编译工具链 gdb调试器 远程调试 其他调试

Page 45: 嵌入式操作系统 Embedded Operating System

45

远程调试以调试器和被调试程序是否在同一台机器区分 本地调试 远程调试

嵌入式系统大多使用远程调试方式远程调试解决方案—插桩方案 需要在目标操作系统和宿主机调试器内分别添加一些功能模块,然后二者互通信息调试,这种方案称为插桩( stub)

Page 46: 嵌入式操作系统 Embedded Operating System

46

远程调试原理远程调试原理

被调试程序入口点运行调试器

指定通信端口向目标系统发送调试信息

触发异常调用异常处理程序转入调试端口通信

宿主机 目标机

Page 47: 嵌入式操作系统 Embedded Operating System

47

远程调试原理远程调试原理 运行在目标板上的被调试程序,一经初始化,在入口点会调用设置断点的函数,主动触发异常然后由异常处理程序控制,异常处理程序将会调用调试端口通信模块,监听宿主机调试器发送的调试信息。双方通信一旦建立,就可以根据远程调试协议进行调试。

Page 48: 嵌入式操作系统 Embedded Operating System

48

远程调试方法远程调试方法使用 ROM Monitor调试目标机目标板程序使用 kgdb调试系统内核使用 gdbserver调试用户空间应用程序

Page 49: 嵌入式操作系统 Embedded Operating System

49

gdb远程调试功能由宿主机 gdb和目标板调试 stub共同构成。两者通过串口或 TCP连接,采用 gdb远程串行协议( Remote Serial Protocol, RSP)连接。RSP定义了宿主机 gdb和被调试的目标板程序进行通信时数据包的格式。它是一种基于消息的ASCII码协议,包含了内存读写、寄存器查询、程序运行等命令。

Page 50: 嵌入式操作系统 Embedded Operating System

50

gdbserver远程调试

Linux内核嵌入式

Linux内核

gdb

被调试程序及源代码

gdbserver

被调试程序

stub

串口 或 网络连接

调试通信

宿主机 目标机

Page 51: 嵌入式操作系统 Embedded Operating System

5151

课程大纲 

51

交叉开发环境模式概述 宿主机环境 目标板环境 交叉编译工具链 gdb调试器 远程调试 其他调试

Page 52: 嵌入式操作系统 Embedded Operating System

52

内核调试Linux内核的规模之庞大,单靠阅读代码查找BUG已经非常困难。而 Linux内核的开发人员出于保证内核代码正确性的考虑,不愿意在 Linux内核源代码中添加调试器。所以对 Linux内核进行调试一直是项艰苦的工作。

内核调试技术内核打印函数 printk内核源代码调试 kgdb

Page 53: 嵌入式操作系统 Embedded Operating System

53

内核打印函数内核打印函数printk 函数具有良好的健壮性,不受内核运行条件的限制,在系统运行的任何阶段都可以使用。

和 C标准库中的 printf 函数不同的是, printk 函数可以指定一个日志级别。内核根据这个级别来判断是否在终端上打印消息。

在头文件 <linux/kernel.h>中定义了可用的日志级别

Page 54: 嵌入式操作系统 Embedded Operating System

54

kgdb内核调试kgdb是一种插桩式( stub)的内核调试机制,它提供Linux内核源代码级别的调试手段,通过配合使用远程 gdb来调试 Linux内核。

可以像调试用户空间的应用程序那样,在内核中设置断点、单步跟踪运行内核和观察变量。

Page 55: 嵌入式操作系统 Embedded Operating System

55

kgdb调试模型

Linux内核

gdb

内核符号表及内核源码

kgdb

stub串口或网络连接

宿主机 目标机

被调试的Linux内核

Page 56: 嵌入式操作系统 Embedded Operating System

56

网络调试在传统的网络分析和调试技术中,嗅探器

( sniffer)是最常见也是最重要的一种技术。嗅探器工具是专门为网络管理员和网络程序员进行网络分析而设计的。使用嗅探器可以随时掌握当前的网络状况,在网络性能下降或者出现故障时,可以通过嗅探器工具来分析原因,找出网络故障的来源。

Page 57: 嵌入式操作系统 Embedded Operating System

57

谢谢!