您好,欢迎访问三七文档
当前位置:首页 > 行业资料 > 其它行业文档 > 第4章 嵌入式系统软件开发概述
第4章嵌入式系统软件开发概述内容嵌入式软件开发环境嵌入式软件开发流程嵌入式系统调试典型的开发工具链Intel开发工具链开发例子4.1嵌入式软件开发环境交叉开发编程语言4.1.1交叉开发通用计算机的软件开发一般都是以本地(Native)编译方式进行的,嵌入式系统一般不支持本地环境开发,其软件开发通常采用交叉开发(CrossCompile)的方式。交叉开发环境建立在宿主机(Host)上,宿主机又称开发机,一般是一台通用计算机,如PC。对应嵌入式系统称为目标机。目标机指各式各样的嵌入式设备,例如手机、掌上电脑等;或者是嵌入式厂商提供的一套专用于开发的评估板(evaluationboard),所以又称开发板;甚至是基于软件的模拟器。开发时使用宿主机上的交叉编译、汇编和链接工具形成可在目标机上执行的二进制代码,然后把可执行文件下载到目标机上运行。此外嵌入式系统的调试也常采用交叉的方式。宿主机目标机目标代码4.1.1交叉开发为什么要交叉编译?目标机上往往无法进行有效的本地编译目标机硬件本身在开发过程中,还不能使用或还不够稳定目标机平台上缺乏完整的native编译工具、环境目标机系统本身性能不够,导致编译太慢嵌入式系统的软件编译,与windows开发不一样,不仅要编译应用程序,还要编译相应的依赖库、操作系统内核等。所以一次完整的编译非常费时比如编译一个Linux内核在奔4级别的PC上都需要十几分钟而从硬件角度,决定编译速度的主要因素是CPU速度、内存容量和文件系统IO速度。这些在嵌入式系统上往往都要比PC差很多所以在目标机系统上进行本地编译效率太低4.1.1交叉开发宿主机与目标机的区别体系结构的不同。宿主机和目标机通常是异构的。宿主机一般采用x86体系结构,但是目标机的体系结构则可能非x86的,如是ARM、MIPS、PowerPC等各式各样。对于某些系统这一点不一定成立。如Atom系统,宿主机和目标机一般都是x86系统,当然执行的指令集可能不一样,如宿主机(如Core2Duo)可能支持SSE4,而Atom支持到SSE3和SSSE3,因此编译时还是要考虑到目标机型号和指令集的选择。处理能力不同。通常宿主机的处理速度。存储容量等会远远大于目标机。运行的操作系统不同。宿主机一般运行通用操作系统,而目标机通常运行各种嵌入式操作系统。输入输出方式不同。相对宿主机,目标机的输入输出功能可能比较单一。交叉开发的主要工作有交叉编译(包括交叉链接)和交叉调试。4.1.2编程语言嵌入式系统比较常用编程语言有C/C++、ADA、Python和Modula-2等。级别常用的编程语言应用程序C/C++、Java、.NET、脚本、Python操作系统级别C/C++、汇编驱动程序级别C/C++、汇编启动代码,硬件抽象层(HAL)汇编、C/C++在底层方面又不得不用到汇编语言,虽然其使用量不大。复杂的嵌入式系统一般由多种语言混合编写而成。4.1.2编程语言通用计算机系统应用的编程语言很多从底层的汇编语言,到FORTRAN、C/C++、ADA、Module高级语言,再到与平台无关的Java、C#.NET等,数不甚数。从面向过程的PASCAL、C,发展到面向对象(Object-OrientedProgramming,OOP)的C++、Java、C#、到泛型编程(GenericProgramming,GP)的C++等。考察一门语言是否适用,需要从多个方面进行考虑。4.1.2编程语言选定一个高级语言之后,也未必在项目中使用其所有功能。例如对于C++语言而言,很多时候它的一些语言本身的功能在实际嵌入式开发中并不使用。例如对于模板,虽然对于泛型编程很重要,但如果编译器实现得不是很好,很容易增加最终代码的体积,这对于资源严重受限的嵌入式开发者来说,有时候难以容忍。还有异常处理,在一些嵌入式操作系统下,C++的异常处理会引起处理器执行状态的切换,导致系统效率的极大降低,这对实时性要求高的系统不适合。由于C/C++拥有便于底层编程等诸多优点,目前C/C++为大多数嵌入式系统开发的首选语言。4.2嵌入式软件开发流程一般地来说,嵌入式软件开发依次要经历编辑(代码准备)、编译、重定位(定址和打包)、烧写、下载、调试、优化等步骤,在某些嵌入式系统中可能还需要测试和验证等步骤。从流程上说,大致可分为编码阶段、构建阶段、部署阶段、调优和其他阶段。开始结束编写代码交叉编译、链接映像生成下载或烧写到目标机运行调试、优化使用汇编、C/C++编写源代码使用专用编译器、链接器生成目标代码使用打包工具生成可以执行的二进制映像使用烧写器或Loader把映像烧写到目标设备执行并查看代码的结果调试程序、优化性能典型的嵌入式软件开发流程图4.2嵌入式软件开发流程1.编码阶段编码阶段是软件开发的开始,其任务是编写软件的源代码代码,使用的工具是各种编辑器。2.构建阶段构建阶段的任务是把代码转化成可以在嵌入式硬件上可执行程序的过程。此阶段,包括截然不同的步骤,包括编译,链接、定址和打包。编译器目标文件链接器可重定位的程序定址器打包器源程序目标文件目标文件可执行文件可执行映像可执行文件可执行文件汇编语言源程序编译器C/C++源程序编译器构建阶段大致流程Build第一步第二步第三步构建的第一步是编译,即源代码文件翻译目标文件。编译工作是由编译器完成的,编译器的任务是将由某种程序设计语言编写的源代码翻译成特定处理器上等效的一系列操作码,这些操作码对应的文件称为目标文件。构建的第二步,就是将所有目标文件链接成一个目标文件,它称为可重定位程序(Re-locatableProgram)。链接工作由链接器完成的,链接器的主要工作是扫描所有输入的目标文件,然后将多个目标文件的段合并,并解决它们之间的依赖关系(这一过程称为符号解析),最终生成一个可执行文件。在许多开发工具中,将编译器和链接器的功能做在一起,可以直接将源代码文件转换成可执行文件,这一过程常称为生成(Build)。构建阶段可执行文件的可重定位和不可重定位一般来说嵌入式系统的可执行文件有可重定位(re-locatable)和不可重定位(non-relocatable)两种版本。可执行文件最后需要操作系统或加载程序将其加载到内存中才能执行。对于不可重定位版本的可执行文件,加载器只能把它加载到固定的地址运行;而对可重定位版本的可执行文件,可以加载到任何地址执行。源代码程序生成可执行文件时既可生成为可重定位版本的,也可生成不可重定位版本的,这在编译-链接时必须选择不同参数,不仅如此,相同源代码程序生成的两种版本的可执行文件的代码也不一样。对于简单的嵌入式系统软件,一般并不需要重定位功能,链接器直接生成只能在某个固定的内存地址运行的程序即可。构建阶段构建的第三步是定址和打包。定址和打包的目标是将可重定位执行文件整合为一个可以运行在嵌入式系统中的二进制映像的文件。对可重定位执行文件而言,在下载到目标机运行之前需要进行定址工作。定址又称重定位,其任务是解决程序中函数和变量的地址绑定问题。它的做法是对于编译器和链接器生成的每一条可能涉及内存地址的指令和数据(例如函数调用的跳转指令),都把指令中的内存地址存储为一个偏移量而不是绝对地址。这样当程序加载器(BootLoader或者嵌入式操作系统)把程序加载到机器内存时,可以根据实际的加载地址,把代码中的相对偏移量再加上实际加载基地址,就可以得到实际的内存地址。构建阶段定址和打包如果整个系统的软件只由一个可执行文件构成,只要通过定址,就可以生成能够再嵌入式系统中运行的映像了。但是很多时候,构成整个嵌入式软件的不只是一个可执行文件,而是多个。例如,对于一个车载终端,可能有一个可执行的文件负责从车身传感器获取行车数据,另一个可执行文件负责把数据显示在屏幕上,还有一个可执行文件负责播放视音频数据,这个时候需要把多个可执行文件进行打包,打包成一个映像,烧写到嵌入式系统的外存中。一般打包的有两种:压缩打包和非压缩打包,其区别在于是否对要打包的可执行文件进行压缩处理。压缩打包和非压缩打包各有优劣。压缩打包可以缩小映像的尺寸,从而可有效地利用外存空间,但缺点是程序执行之前还必须经过解压缩。而非压缩打包的代码运行不需要经过解压缩,缺点是需要比较大的外存空间。在一些嵌入式系统中还可以看到一种介于两种之间混合打包方法,即对要打包文件中的代码部分不进行压缩,而只对数据部分(图片、声音文件等)进行压缩,这样既可以缩小整个映像的体积,又可以是代码可以不经过压缩直接运行。构建阶段定址和打包打包操作通常由专门的打包工具完成,打包结束后得到的是一个二进制文件,它可以直接烧写到目标机的外存中。要说明的是,对于应用程序开发,上述第三步定址和打包并不是必需的。在某些嵌入式系统(如上网本),拥有功能比较强大、完善的操作系统(Moblin),可执行文件的定址由目标机操作系统自动完成,用户看不到这一独立的步骤。打包也不是必需的,例如在Moblin中用户可直接通过网络、串口等下载或复制独立的文件到本地运行,而不要求一定是打包的镜像。4.2嵌入式软件开发流程3.部署阶段软件开发的最后一个阶段是部署,即把可执行的运行时映像或可执行文件部署到嵌入式设备上,让嵌入式设备在系统上电后可以启动并加载开发者编写的代码。通过开发阶段得到的可执行文件映像,最终需要被部署到嵌入式设备上的非易失存储介质中。将数据写入到这些存储器中需要有一个专门的烧写过程。部署阶段部署(又称目标代码下载)机制如何把交叉编译好的目标代码转移到目标系统上,并且能够在其上运行关键是效率。因为开发过程中需要反复的修改代码并下载调试烧录(或称烧写)式–用某种机制将目标代码映像烧录到目标平台上的FlashROM中不方便一般用在开发过程晚期的系统集成测试阶段和最后发布时网络式–通过某种机制,让目标机直接通过网络加载所需的目标代码映像到内存十分方便,无需烧录FlashROM但需要bootloader和操作系统支持一般用在开发过程前、中期部署阶段Flash芯片的烧写,类似可编程器件的烧录,可分为脱线(Offline)方式需要将FlashROM芯片从目标板上取下一般目标板将FlashROM做成插座式安装,而非焊死使用专门的编程器和配套软件部署阶段烧录式目标代码下载,类似可编程器件的烧录,分为在线编程(In-system-programming)方式无需将FlashROM芯片从目标板上取下一般就是通过JTAG-ICE调试器将所需烧录的目标映像下载到目标板RAM中将执行烧录动作的程序下载到目标板RAM中告诉CPU去执行RAM中的烧录动作的程序,并给出目标映像所在地址方便,廉价,重用了JTAG-ICE的投资部署阶段网络式目标代码下载机制常见于基于Linux的嵌入式系统中。上网本应用软件目标代码下载是借助操作系统所提供的文件复制功能来完成的,这一过程为部署(deployment)。目标板(目标系统)FlashROM中的BootLoaderHostPCTFTP服务器NFS服务器目标板Linux内核映像目标板的根文件系统映像加载的LinuxKernel加载的根文件系统3.运行6.使用1.TFTP文件请求2.TFTP文件响应4.NFSMount请求5.NFSMount响应4.2嵌入式软件开发流程4.调优阶段(调试、优化阶段)此阶段主要是对软件进行调试和性能优化。熟练掌握调试技术对嵌入式软件开发至关重要。嵌入式软件调试的效率都比较低,因为即使改动一行代码,都可能需要把编译、链接、重定位、烧写、下载等步骤完整走一遍,这也是调优阶段最显著的特点。快速地定位到问题可以节省大量的时间。其次,如果将错误带到最终的嵌入式系统产品中,其后果可能是致命的。对于PC用户,用户或许可以忍受自己的机器每天死机一两次,但是想象在ATM上取款,在医疗系统上手术或在卫星发射时,软件发生异常,其带来的后果
本文标题:第4章 嵌入式系统软件开发概述
链接地址:https://www.777doc.com/doc-3402421 .html