(第2版)
主讲内容 第1章 嵌入式系统概述 第2章 ARM微处理器概述与编程模型 第3章 ARM9指令系统 第4章 嵌入式程序设计基础 第1章 嵌入式系统概述 第2章 ARM微处理器概述与编程模型 第3章 ARM9指令系统 第4章 嵌入式程序设计基础 第5章 嵌入式内部可编程模块 第6章 嵌入式接口技术应用 第7章 软件开发环境
ADS1.2集成开发环境 7.1 嵌入式Linux的软件开发环境 7.2
7.1 ADS1.2集成开发环境 CodeWarrior 集成开发环境(IDE)为管理和开发项目提供了简单多样化的图形用户界面。 用户可以使用ADS 的CodeWarrior IDE 为ARM 和Thumb 处理器开发用C,C++,或ARM汇编语言的程序代码。通过提供下面的功能,CodeWarrior IDE 缩短了用户开发项目代码的周期。
7.1.1 使用ADS创建工程 在CodeWarrior 中新建一个工程的方法有两种,可以在工具栏中单击“New ”按钮,也可以在“File”菜单中选择“New… ”菜单。这样就会打开一个如图7.1 所示的对话框。
ARM Executabl Image:用于由ARM 指令的代码生成一个ELF 格式的可执行映像文件; ARM Object Library:用于由ARM 指令的代码生成一个armar 格式的目标文件库; Empty Project :用于创建一个不包含任何库或源文件的工程; Makefile Importer Wizard :用于将Visual C 的nmake 或 GNU make 文件转入到CodeWarrior IDE 工程文件; Thumb ARM Executable Image:用于由ARM 指令和Thumb 指令的混和代码生成一个可执行的ELF 格式的映像文件; Thumb Executable image:用于由Thumb 指令创建一个可执行的ELF 格式的映像文件; Thumb Object Library :用于由Thumb 指令的代码生成一个armar 格式的目标文件库。
在这里选择ARM Executable Image,在“Project name:”中输入工程文件名,本例为“ledcircle”,点击“Location:”文本框的“Set…”按钮,浏览选择想要将该工程保存的路径,将这些设置好后,点击“确定”,即可建立一个新的名为ledcircle 的工程。 这个时候会出现ledcircle.mcp 的窗口,如图7-2 所示,有三个标签页,分别为files,link order,target 默认的是显示第一个标签页 files。通过在该标签页点击鼠标右键,选中“Add Files…”可以把要用到的源程序添加到工程中。
在建立好一个工程时,默认的target 是DebugRel, 还有另外两个可用的target,分别为Realse 和Debug,这三个target 的含义分别为: DebugRel :使用该目标,在生成目标的时候,会为每一个源文件生成调试信息; Debug :使用该目标为每一个源文件生成最完全的调试信息; Release:使用该目标不会生成任何调试信息。
点击Edit 菜单,选择“DebugRel Settings…”, 出现如图7-2 所示的对话框。 主要包括: 1. target 设置选项 2.Language Settings 3. Linker 设置
点击CodeWarrior IDE 的菜单Project 下的make 菜单,就可以对工程进行编译和链接了。
7.1.2 用AXD进行代码调试 1. 在AXD中打开调试文件 在菜单File 中选择“Load image…”选项,打开Load Image 对话框,找到要装载的.axf 映像文件,点击“打开”按钮,就把映像文件装载到目标内存中了。
2. 查看存储器内容 Processor Views 菜单中选择“Memory ”选项 3. 设置断点 4. 查看变量值
7.2 嵌入式Linux的软件开发环境 linux下的交叉编译环境主要包括以下几个部分: 针对目标系统的编译器gcc; 针对目标系统的二进制工具binutils; 目标系统的标准c库 目标系统的linux内核头文件。
7.2.1安装交叉编译环境 1、准备工作
binutils-2.15.tar.bz2:这个压缩包包含有ld,ar,as等一些产生或者处理二进制文件的工具。其主要目的是为GNU系统提供汇编和连接工具等。 gcc-3.4.5.tar.bz2:这个压缩包主要是为GNU系统提供C 编译器。现在支持多种语言,这其中包括C/C++、Fortran、Java、Objective-C、Ada等。 glibc-2.2.5.tar.gz:Libc是很多用户层应用都要用到的库,用于定义系统调用和其它一些基本的函数调用。 glibc-linuxthreads-2.2.5.tar.gz:这是Libc用于支持Posix线程而单独发布的一个压缩包。 linux-2.6.8.tar.bz2:这个压缩包就是Linux的内核,在编译glibc时,要用到Linux内核中的include目录的内核头文件。
交叉编译环境建立过程如下: (1)创建编译环境。 (2)建立内核头文件, (3)创建binutils。 (4)创建一个交叉编译版本的gcc(称为bootstrap gcc) (5)创建一个交叉编译版本的glibc。 (6)重新创建gcc(称为full gcc)。
7.2.2嵌入式Linux程序开发工程管理 1 嵌入式系统开发概述 由嵌入式系统本身的特性所影响, 嵌入式系统开发与通用系统的开发有很大的区别。嵌入式系统的开发主要分为系统总体开发、嵌入式硬件开发和嵌入式软件开发3大部分,其总体流程图如图7-21 所示。
嵌入式系统的软件开发与通用软件开发的区别主要在于软件实现部分,其中又可以分为编译和调试两部分。 1.交叉编译 所谓交叉编译就是在一个平台上生可以在另一个平台上执行的代码。嵌入式系统交叉编译环境如图 所示。
嵌入式系统的交叉调试有多种方法,主要可分为软件方式和硬件方式两种。 它们一般都具有如下一些典型特点: 2.交叉调试 嵌入式系统的交叉调试有多种方法,主要可分为软件方式和硬件方式两种。 它们一般都具有如下一些典型特点: 调试器和被调试进程运行在不同的机器上,调试器运行在PC 机 (宿主机),而被调试的进程则运行在各种专业调 板上 (目标板)。 调试器通过某种通信方式(串口、网络、JTAG 等)控制被调试进程 在目标机上一般会具备某种形式的调试代理,它负责与调试器共同配合完对目标机上运行着的进程的调试。这种调试代理可能是某些支持调试功能的硬件设备,也可能是某些专门的调试软件(如gdbserver)。 目标机可能是某种形式的系统仿真器,通过在宿主机上运行目标机的仿真软件,整个调试过程可以在一台计算机上运行。此时物理上虽然只有一台计算机,但逻辑上仍然存在着宿主机和目标机的区别。
7.2.3 程序调试 1 .内核调试方法 对于庞大的Linux 内核软件工程,单靠阅读代码查找问题已经非常困难,需要借助调试技术解决BUG 。通过合理的调试手段,可以有效地查找和判断BUG 的位置和原因。 内核调试方法很多,主要有以下4 类。 通过打印函数 获取内核信息 处理出错信息 内核源码调试
2.内核打印函数 嵌入式系统一般都可以通过串口与用户交互。大多数 Bootloader 可以向串口打印信息,并且接收命令。内核同样可以向串口打印信息。但是在内核启动过程中,不同阶段的打印函数不同。分析这些打印函数的实现,可以更好地调试内核。 (1) 内核映像解压前的串口输出函数 (2) 内核错误报告子程序 (3) 内核打印函数
3.获取内核信息 Linux 内核提供了一些与用户空间通信的机制,大部分驱动程序与用户空间的接口都可以作为获取内核信息的手段。另外内核也有专门的调试机制。 (1) 系统请求键 (2) 通过/proc 接口 (3) 通过/sys 接口 (4) 通过ioctl 方法
4. 处理出错信息 当系统出现错误时,内核有两个基本的错误处理机制:oops 和panic。 (1) oops 信息 ●oops 消息包含系统错误的详细信息 ●使用ksymoops 转换oops 信息 ●内核kallsyms 选项支持符号信息 (2) panic 当系统发生严重错误的时候,将调用panic()函数。
5.内核源码调试 因为Linux 内核程序是GNU GCC 编译的,所以对应地使用GNU GDB 调试器。Linux 应用程序需要gdbserver 辅助交叉调试。 (1) KGDB 调试内核源代码 ●配置编译Linux 内核映像 ●在目标板上启动内核 ●启动gdb,建立连接 ●使用gdb 的调试命令设置断点,跟踪调试 (2) BDI2000 调试内核源代码 ●主机/ 目标机设置 ●准备要调试的内核 ●通过BDI2000 控制硬件开发板 ●设置BDI2000 断点 ●下载内核 ●gdb 连接BDI2000 ●设置gdb 断点 ●重新控制调试过程 ●调试内核模块