完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
由于嵌入式系统是一个受资源限制的系统,故而直接在嵌入式系统硬件上进行编程显然是不合理的。在嵌入式系统的开发过程中,一般采取交叉平台的开发方法。即在通用PC上编程,然后通过交叉编译和链接,将源程序编成能够在目标平台上运行的二进制代码格式映像。最后将映像下裁到目标平台上的特定位置,由目标板上启动代码(Bootloader)执行这段二行制代码,从而运行起嵌入式系统。
|
|
相关推荐
3个回答
|
|
在嵌入系统的开发中,建立起交叉编译环境的机器称为主机(Host),需要运行嵌入式系统的机器环境称为目标板(Target)。如(图1)所示,嵌入式软件的开发和调试过程就通过多种连接方式在两者的互相合作之中完成。
s 图1 嵌入式系统开发环境 在主机端的开发软件主要包括交叉编译器(compiler)、链接器(linker)和源码级调试工具(debuger)。目标板上开发工具通常会包括动态装载器(loader)、监控诊断软件以及调试代理工具(debug agent)。各种连接方式用于从主机向目标板下载目标程序的映像文件以及调试器和目标板调试代理之间的调试信息。目标程序是由实时操作系统(RTOS)各部件、微内核和应用程序一同编择链接而成的可执行映像。一般,程序员在进行本机主应用开发时无须了解可执行程序是如何被装载入内存中运行又是如何将执行控制权交予此可执行程序的。而嵌入式系统的开发人员在做交叉平台的开发时,需要对目标平台有完全的认识和理解。他必须知道程序的映像文件是如何存储在目标嵌入式系统上的,当系统启动时是如何加载程序映像以及被加载到哪个位置,以及如何与目标系统交互进行调试开发。这些都将直接影响如何进行代码的编写、编译和链接的每个过程。 存在操作系统的情况下,嵌入式系统开发主要分如下几个步骤:建立交叉开发环境,交叉编译和连接,加载映像,联机调试。 |
|
|
|
1、建立开发环境
在准备开发之前,需要了解在嵌入式编程中使用的交叉开发环境(Cross-development Environment)。交叉开发环境的原理很简单,只是在主机和目标机器体系结构不同的情况下,在主机上开发那些将在目标机器上运行的程序。比如说在x86上开发ARM目标上运行的程序,就是在x86运行可以将程序编译、连接成ARM可运行代码的编译连接器,并以之编译在x86上编写的代码,就是一种交叉环境开发。 按照发布的形式,交叉开发环境主要分为开放和商用两种类型。开放式交叉开放环境实例主要有gcc,它可以支持多种交叉平台的编译器,由GNU负责维护,使用gcc作为交叉开发平台要遵守General Public License的规定。商用的交叉开发环境主要有Metrowerks CodeWarrior、ARM Software Development Toolkit、SDS Cross compiler、WindRiver Tomado等等。 按照使用方式,交叉开发工具主要分为使用Makefile和IDE开发环境两种类型。使用Makefile的开发环境需要编写Makefile来管理和控制项目的开发,可以自己手写,有时候也可以使用一些自动化的工具。这种开发工具是gcc、SDS Cross Compiler等等。新类型的开发环境一般有一个用户友好的IDE界面,方便管理和控制项目的开发,如Code Warrior抢救无效。有些开发环境既可以用Makefile管理项目,又可以使用IDE,如TomadoⅡ,给使用者很大的余地。 建立交叉开发环境是进行嵌入式系统软件开发的第一步。这里以gcc为例子,如果是在x86的Linux平台上建立一个面向ARM的开发平台,大概的步骤如下所不: ■从http://www.gnu.org/下载需要的文件包,包括binutils、gcc、gilbc、gdb等: ■按顺序对编译器、连接器和函数库进行编译和安装,在配置时需要使用-target=arm-linux选项指定开发环境的目标平台; 在安装结束之后应该有arm-linux-gcc,arm-linux-ar等程序,这些就是交叉开发平台的程序。 2、编译和连接 使用建立好的交叉开发环境完成编译和连接工作,将用户编写的源文件生成可在目标系统上执行的映像文件。程序员使用C/C++源文件和头文件记录程序源代码,部分与处理器相关的代码则会使用相应的汇编代码形式编写。用户编写Makefilr文件用于make工具以方便跟踪源文件的修改情况并在必要时对相应源文件重新编译连接。编译器(compiler) 和汇编器(assembler)将源文件生成包括二进制机器码和程序数据的目标文件。归档工具则将多个目标文件组合成一个库文件。连接器(linker)将目标文件作为输入文件生成可扫行映像或可与其它目标文件再次进行连接的目标文件。连接控制文件的作用就是指示连接器如何合并被连接的目标文件以及如何在目标系统上放置生成的二进制代码数据段。 编译和连接的主要目的就是生成一个大可重定位目标文件、一个可共享的目标文件或一个最终的可执行映像。比如ARM的gcc交叉开发环境中,arm-linux-gcc是编译器,arm-linux-ld是连接器。但并不是说对于一种休系结构只有一种编译连接器,比如说M68K休系结构的gcc编译器而言,就有多种不同的编译和连接器。如果使用COFF的可执行文件格式的话,那么在编译Linux内核时需要使用m68k-coff-gcc和m68k-coff-ld的编译连接器,在编译应用程序时需要使用m68k-coff-pic-gcc和m68k-coff-pic-ld编译连接器。这时因为应用程序代码需要编译成为可重定位代码。这样,虽然因为内核占用位置导致应用程序存放的位置不同,但仍可以使用相对地址运行应用程序。这方面需要注意的问题对各种嵌入式系统面言都是不同的。 在连接过程中,对于嵌入式系统的开发而言,都希望使用较小型的函数库,以使最后产生的可执行代码尽量小。因此在编译中使用的一般是经过特殊定制的函数库。比如使用C做嵌入式开发的人一般使用的几个嵌入式函数库有:uClibc/uClibm,uC-libc/uC-libm和 newlib等。 |
|
|
|
3、加载映像
生成了目标平台需要的image文件之后,需要从主机端将生成的可执行映像传送到目标系统上去,这个过程被称作加载映像(loading the image)。通常映像可以使用如下方式加载: ※将整个映像写入EEPROM或Flash存储器中。 ※通过串口(RS-232)或网络连接下载目标映像。这需要主机端和目标系统上有数据传送的工具。 ※使用硬件调试工具,通过JTAG或BDM接口下载映像。 嵌入式软件在最终产品中通常是存储在ROM或Flash存储器中的。整个可执行映像通过特殊的设备被写入到ROM或Flash之中,再插入或贴片到目标板对应的槽中。目标系统的处理器在上电时根据目标板上的跳线设置决定从ROM或Flash对应的首地址取指令从而执行目标映像。然而在系统开发调试阶段,嵌入式软件需要不断地增加、修改并加载到目标板上进行调试。显然每次因为调试需要和代码增加都使用重新擦写ROM或Flash是不实际的。使用串口、网络连接或者通过JTAG/BDM接口加载映像,将可执行映像直接下载到目标系统的RAM中,这是嵌入式系统开发阶段的最佳加载方法。 最为常用的方法是为目标板编写一个加载程序用于与主机端的下载工具通讯完成映像的下载,这个程序被称作bootloadet.Bootloader一般被放在目标板的ROM中,并在目标板上电时运行,此时主机端可以通过相应的工具与目标板上的bootloader程序进行通讯。可以使用bootloader提供的,或者通用的终端工具与目标板相连接。一般在目标板上使用串口,通过主机端工具和目标板通讯。Bootloader中提供下载等控制命令,完成在嵌入式系统正式在目标板上运行之前目标板的控制任务。Bootloader指定image文件下载的位置。在下载结束之后,使用bootloader提供的运行命令,从指定地址开始运行嵌入式系统软件。这样,一个完整的嵌入式软件开始运行了。 4、调试 嵌入式系统的调试有多种方法,也被分成不同层次。就调试方法而言,有软件调试和硬件调试两种方法,前者使用软件调试嵌入式系统软件,后者使用仿真调试协助调试过程。就操作系统调试的层次而言,有时需要调试嵌入式操作系统的内核,有时需要调试嵌入式操作系统的应用程序。由于嵌入式系统特殊的开发环境,不可避免的是调试时必然需要目标运行平台和调试器两方面的支持,基调试系统结构一般如(图2)所示。 s 图2 嵌入式系统调试结构图 使用硬件调试器,可以获得比软件功能强大得多的调试性能。硬件调试器的原理一般是通过仿真硬件的真正执行过程,让开发者在调试过程中可以时刻获得执行情况。硬件调试器主要有ICE(In-Circuit Emulator,在线仿真器)、ICD(In-Circuit Debugger)两种,前者主要完成仿真模拟的工能,后者使用硬件上的调试口完成调试任务。 (1)IC(In-Circuit Emulator) ICE是一种完全仿造调试目标CPU设计的仪器。该仿真器可以真正进运行所有的CPU动作,并且其使用的内存可以设置非常多的硬件中断点。在执行的过程中,可以按顺序单步向下执行,还可以倒退执行,同时可以实时查看所有需要的数据,从而给调试过程带来很多的便利。老式的ICE一般只有串口或者并口,新式的ICE还提供USB或者以太网接口。不过ICE的价格非常昂贵。 使用ICE和使用一般的目标硬件一样,只是在ICE完成调试之后,需要把调试好的程序重新下载到目标系统上而已。 (2)ICD(In-Circuit Debugger) 因为ICE的价格昂贵,而且每种CPU都需要一种与之对应的ICE,使得开发成本非常高。目前比较流行的做法是CPU将调试功能直接在其内部实现,通过在开发板上引出调试端口的方法,直接从端口获得CPU中提供的调试信息。在CPU中实现的主要是一些必要的调试功能: ※读/写寄存器 ※读/写内存 ※单步执行 ※硬件中断点 使用ICD和目标板的调试端口连接,发送调试命令和接收调试信息,就可以完成必要的调试功能。一般,Motorola公司提供的开发板上的调试口是BDM口顺ARM公司提供的开发板上使用JTAG口,开发板上的调试口在系统完成之后的产品上应当移除。 使用合适的工具可以利用这些调试口。比如说ARM开发板,可以使用JTAG调试器接在开发板的JTAG口中,通过JTAG口与ARM CPU进行通信。然后使用软件工具与JTAG调试器相连接,做到和ICE调试类似的调试效果。 参考文献 1、《Linux与嵌入式系统》 李善平等著 清华大学出版社 2002.12 2、王爽等.基于VxWorks嵌入式操作系统的SNMP应用.《微计算机信息》(中文核心期刊) 2005.5.P86-87 3、《Real-Time Concepts For Embedded Systems》 Qing Li CMP BOOK 2003 4、胡俐蕊.基于信号量通信的μC/OSⅡ应用程序设计方法. 《微计算机信息》(中文核心期刊) 2005.10-2.P40-42 |
|
|
|
只有小组成员才能发言,加入小组>>
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-18 09:47 , Processed in 0.839082 second(s), Total 83, Slave 64 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号