570 likes | 702 Views
嵌入式操作系统 Embedded Operating System. 第八课 开发环境和调试技术. 课程大纲 . 交叉开发环境模式概述 宿主机环境 目标板环境 交叉编译工具链 gdb 调试器 远程调试 其他 调试. 2. 2. 交叉开发环境模式概述. 什么是嵌入式系统 “ 以应用为中心、以计算机技术为基础、软件硬件可裁剪、适应应用系统对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统。 ” 硬件上的局限性 存储空间小 处理器频率低 缺少存储、输入输出设备. 宿主机—目标板交叉开发模式. 组成部分
E N D
嵌入式操作系统Embedded Operating System 第八课开发环境和调试技术
课程大纲 交叉开发环境模式概述 宿主机环境 目标板环境 交叉编译工具链 gdb调试器 远程调试 其他调试 2 2
交叉开发环境模式概述 • 什么是嵌入式系统 • “以应用为中心、以计算机技术为基础、软件硬件可裁剪、适应应用系统对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统。” • 硬件上的局限性 • 存储空间小 • 处理器频率低 • 缺少存储、输入输出设备
宿主机—目标板交叉开发模式 • 组成部分 • 宿主机:平时使用的桌面计算机 • 目标板:嵌入式开发板 • 介绍 • 利用宿主机上已有的成熟的开发工具,专门针对目标板定制一套系统,包括引导程序、内核和文件系统,然后下载到目标板上运行。
宿主机—目标板交叉开发模式 • 开发过程 • 在宿主机上编写代码,并通过交叉编译工具编译出能够在目标板上运行的程序,然后下载到目标板上测试执行,最后利用宿主机上的调试工具对目标板上运行的程序进行远程调试。 • 特点 • 使用和桌面开发一样的工具,降低学习成本。 • 充分利用宿主机的开发环境。
宿主机—目标板连接方式 • 串口 • 利用串口给目标板发送命令,同时也可以接受目标板返回的信息并显示。 • 宿主机可以通过串口往目标板传送文件; • 目标板可以把程序运行的结果返回并显示。 • 串口驱动程序的实现相对比较简单,缺点是传输速度慢,并不适用于传输大量数据的场合。 • 以太网 • 以太网是当今局域网采用的最通用的通信协议标准。 • 它使用简单,配置灵活,支持广泛,传输速率快,安全可靠,缺点是网络驱动的实现比较复杂。
宿主机—目标板连接方式 • USB • USB是Universal Serial Bus通用串行总线)的缩写,现已成为PC的标准,基于USB标准的设备被广泛使用。 • 一种快速、灵活的总线接口,与其它通信接口相比,USB接口的特点是易于使用。 • 支持热插拔,无需用户自己配置,系统会自动搜索驱动并安装。 • USB是典型的主从结构,两端分别需要不同的驱动程序。 • JTAG • JTAG是一种国际标准测试协议,主要用于芯片内部测试及对系统进行仿真、调试。 • 在嵌入式系统领域,几乎所有的处理器都支持JTAG,调试器的单步调试和断点都需要和JTAG交涉。 • 可以使用JTAG将程序烧写到目标板上。
课程大纲 交叉开发环境模式概述 宿主机环境 目标板环境 交叉编译工具链 gdb调试器 远程调试 其他调试 8 8
宿主机环境 串口终端 BOOTP协议 TFTP协议 交叉编译 Make工具
串口终端 • 串口的用途 • 作为终端执行命令,管理嵌入式系统。 • 使用zmodem协议等传送小文件。 • 串口终端 • 超级终端 (Windows XP) • Minicom (Linux)
BOOTP协议 • 什么是BOOTP协议 • 引导协议(Bootstrap Protocol,BOOTP)是一种基于TCP/IP的协议,它最初在RFC951中定义,如今在通用计算机上广泛使用的DHCP协议就是从BOOTP协议扩展而来。BOOTP协议使用TCP/IP网络协议中的UDP 67/68两个通讯端口。 • BOOTP协议用途 • 用于无盘客户机从服务器得到自己的IP地址、服务器的IP地址、启动映象文件名、网关信息等等
BOOTP处理过程 第一步,在主机平台运行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服务器下载启动映象文件。
TFTP协议 • 什么是BOOTP协议 • TFTP的全称是Trivial File Transfer Protocol,即“简单文件传输协议”,它是TCP/IP协议族中的一个在客户端和服务端之间进行简单文件传输的协议,提供不复杂、开销不大的文件传输服务。 • TFTP特点 • 不提供用户名和口令 • TFTP 协议传输由客户端发起
交叉编译 • 背景 • 目标文件在不同架构间由于采用的CPU指令集不同等原因不能通用。 • 定义 • 交叉编译就是在一个架构的机器下编译另一个架构的目标文件。 • 需要安装交叉编译工具链
make工具 • GNU Make是一种常用的编译工具,通过它,程序员可以很方便地管理软件编译的内容、方式和时机,从而使程序员能够把主要精力集中在代码的编写上。Make自动判断源码中哪些部分有更新,重新编译这些文件并重新链接。对于那些由许多源文件组成的大型软件项目来说,采用这种项目管理方法则可以极大地提高工作效率,让原本复杂繁琐的开发工作变得简单。 • make 工具通过一个称为makefile的文件来完成并自动维护编译工作。makefile需要按照某种语法进行编写,其中说明了如何编译各个源文件并连接生成可执行文件,并定义了源文件之间的依赖关系。当修改了其中某个源文件时,如果其他源文件依赖于该文件,则也要重新编译所有依赖该文件的源文件。
基本规则 :目标、依赖关系、指令 target : dependency …… command …… 目标(target):需要由make工具创建的项目,是指令(command)执行的结果文件(目标文件或执行文件),也可以是一个标签(Lable),如make clean、make all等。 依赖(dependency):要创建的项目依赖于哪些文件或目标。依赖条件顶格书写。指令(command):创建每个项目时make需要运行的命令(任意的Shell命令) 。指令必须使用一个TAB符(制表位)开始进行书写。 在指令部分定义的指令会在依赖文件的内容有所变更或找不到目标文件时被执行。
如果一个工程有三个源文件write.c,read.c,main.c生成可执行程序test 。 用于生成test的Makefile文件如下: -c:对源程序进行预处理、编译,产生目标文件,但不进行连接。 -o <文件名>:定义输出的执行文件名为<文件名>。
clean不是一个文件,它只不过是一个动作名字,有点像C语言中的lable一样,其冒号后什么也没有,那么,make就不会自动去找文件的依赖性,也就不会自动执行其后所定义的命令。要执行其后的命令,就要在make命令后明显得指出这个lable的名字。 • 例如,使用名为clean标签来进行清除,可以没有依赖关系部分,即执行命令 以此来清除所有的目标文件,以便重新编译。 相当于执行了: [root@XSBase test]# make clean [root@XSBase test]# rm test main.o read.o write.o
使用vi编译器创建Makefile后,进行make,则生成执行文件test。Make将按照 Makefile中指定的依赖关系来依次执行。 [root@XSBase test]# make Makefile依赖关系
宏和标签 • 为了makefile的易维护,在makefile中我们可以使用变量。makefile的变量也就是一个字符串,理解成C语言中的宏可能会更好。 比如,我们声明一个能够表示obj文件的宏,宏名可为objects,OBJECTS,objs,OBJS,obj或 OBJ等。 • 可使用宏(Macro)功能和标签(Label)功能使Makefile的创建更为灵活。宏起到以替换指定的内容使程序简单化的作用。宏必须要在$(..)里面使用。
例:利用宏来创建Makefile。在这里宏是OBJECTS,将main.o、read.o、write.o替换为OBJECTS来使用。
预定义的宏(Pre-defined Macro) 执行make -p可看到Make中事先指定好的各个值(宏,环境参数等)。
扩展名规则 • 扩展名规则(Suffix Rule)是根据文件的扩展名来进行适当的运算操作。例如,.c一般指C源文件,.o文件是目标文件。.c文件编译后应成为.o文件。 • 在这里出现名为.SUFFIXES的宏,这个宏自动处理Makefile中需要慎重处理的文件的扩展名。 .SUFFIXES = .c .o 上面的例子对带有.c和.o扩展名的文件按照扩展名规则来处理,自动操作使.c文件编译后生成.o文件。
内部宏定义(Internal Macro) 用于简化Makefile的写法
内部宏的用法 例子一: main.o : main.c io.h gcc -c $*.c 说明:$*是没有扩展名的当前目标文件,所以$*.c扩展为main.c。 例子二: test : main.c gcc -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就会被$<自动重新编译。
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)
make工作过程 • 编写Makefile • Makefile由一系列规则组成,每条规则说明要生成哪些目标文件、生成目标文件所依赖的其它文件以及生成目标文件所需要的命令。 • 编译过程 • 通过查看时间戳来确认依赖文件是否比目标文件更新,如果是则重新执行这条规则的命令,并进一步地执行依赖这些中间目标文件的规则,层层推进,最后生成新的结果文件。
需要重新编译的情况 所有的依赖文件都没有被编译过,则对每个源文件进行编译并进行链接,生成最后的可执行程序 。 源文件在上次编译之后被修改过,则在本次执行make的时候将会被重新编译。 头文件在上次编译之后被修改过,则所有包含此头文件的源文件在本次执行make的时候将将会被重新编译。
课程大纲 交叉开发环境模式概述 宿主机环境 目标板环境 交叉编译工具链 gdb调试器 远程调试 其他调试 29 29
目标板环境 • JTAG接口 • Boot Loader
JTAG接口简介 • 作为硬件测试手段,JTAG的功能与CPU状态无关,可驱动设备的所有外部引脚并读入数据,而且在设备内部夺取外部的连接点(与通往外部的各个pin脚一一连接)。 • 各个cell为了形成 Serial Shift Register而相连。整体的接口由5个pin脚来控制(TDI,TMS,TCK,nTRST,TDO)。 • 其功能包括:测试线路连线和端子的连接状态;测试设备间的连接状态;进行Flash memory 烧写等。
Boot Loader简介 • Boot Loader是系统加电后运行的第一段代码。 • 完成初始化硬件设备、创建内核需要的信息等工作,最后调用操作系统内核。 • 对硬件的依赖非常强,不同的体系结构、不同的嵌入式板级设备配置都会对Boot Loader有不同的需求。
课程大纲 交叉开发环境模式概述 宿主机环境 目标板环境 交叉编译工具链 gdb调试器 远程调试 其他调试 33 33
交叉编译工具链 • 交叉编译工具链是一个由编译器、链接器和解释器组成的集成开发环境。和本地编译类似,交叉编译的过程也是由编译、链接等阶段组成,源程序通过交叉编译器编译成目标模块,并由交叉链接器加载库最后链接成可在目标平台上执行的程序代码。
交叉编译的构建 • 从头编译 • 编译难度大,不适合初学者。 • 脚本编译 • 需要选择合适的脚本工具,例如crosstool • 下载使用 • 下载指定平台编译好的二进制包。
相关工具 • 交叉编译工具链主要包括: • 标准库:glibc • 编译器:gcc • 链接器:ld • 汇编器:as • 调试器:gdb
标准库:glibc • 最初是自由软件基金会为其GNU操作系统所写,但目前最主要的应用是配合Linux内核,成为GNU/Linux操作系统一个重要的组成部分。 • 是Linux系统中最底层的API,几乎其它任何运行库都会直接或间接地依赖于glibc。 • 除了封装系统调用之外,还提供一些基本的功能,例如open、malloc、printf、exit等等。
编译器: gcc • 支持不同的编程语言,它被目前许多Unix/Linux系统作为默认的标准编译器。 • 支持多种处理器架构上,并且在商业、专利和开源软件开发环境中广泛使用。 • 支持嵌入式系统平台。
binutils • 是一组开发工具包,包括连接器、汇编器和其他用于目标文件和档案的工具。其中包括:addr2line、ar 、as、ld、nm、objdump 、ranlib、readelf
调试器:gdb • 是一款功能非常强大的调试器,既支持多种硬件平台,也支持多种编程语言,目前gdb支持的调试语言有C/C++、Java、Fortran、Modula-2等多种语言。 • 不仅用于本地调试,还可以用于远程调试,非常适合嵌入式系统开发使用。
课程大纲 交叉开发环境模式概述 宿主机环境 目标板环境 交叉编译工具链 gdb调试器 远程调试 其他调试 42 42
gdb调试 • 使用gdb可以完成下面这些任务: • 运行程序,可以给程序加上所需的任何调试条件; • 在给定的条件下让程序停止; • 检查程序停止时的运行状态; • 通过改变一些数据,可以更快地改正程序的错误。
课程大纲 交叉开发环境模式概述 宿主机环境 目标板环境 交叉编译工具链 gdb调试器 远程调试 其他调试 44 44
远程调试 • 以调试器和被调试程序是否在同一台机器区分 • 本地调试 • 远程调试 • 嵌入式系统大多使用远程调试方式 • 远程调试解决方案—插桩方案 • 需要在目标操作系统和宿主机调试器内分别添加一些功能模块,然后二者互通信息调试,这种方案称为插桩(stub)
远程调试原理 运行在目标板上的被调试程序,一经初始化,在入口点会调用设置断点的函数,主动触发异常然后由异常处理程序控制,异常处理程序将会调用调试端口通信模块,监听宿主机调试器发送的调试信息。双方通信一旦建立,就可以根据远程调试协议进行调试。
远程调试方法 • 使用ROM Monitor调试目标机目标板程序 • 使用kgdb调试系统内核 • 使用gdbserver调试用户空间应用程序
gdb远程调试功能 • 由宿主机gdb和目标板调试stub共同构成。 • 两者通过串口或TCP连接,采用gdb远程串行协议(Remote Serial Protocol, RSP)连接。 • RSP定义了宿主机gdb和被调试的目标板程序进行通信时数据包的格式。它是一种基于消息的ASCII码协议,包含了内存读写、寄存器查询、程序运行等命令。