八、嵌入式程序设计与分析.ppt
- 文档编号:18796160
- 上传时间:2023-11-19
- 格式:PPT
- 页数:56
- 大小:428.50KB
八、嵌入式程序设计与分析.ppt
《八、嵌入式程序设计与分析.ppt》由会员分享,可在线阅读,更多相关《八、嵌入式程序设计与分析.ppt(56页珍藏版)》请在冰点文库上搜索。
嵌入式系统设计与实例开发ARM与C/OS-第八讲程序设计与分析北京航空航天大学嵌入式机电控制研究室,本节提要,1,3,2,程序编译技术,程序优化技术,Linux初步,嵌入式软件的要求,功能性要求:
满足系统所要求的功能。
时限性要求:
满足系统的实时性要求。
存储器要求:
适应系统内存总量要求。
功耗要求:
满足系统能耗的要求。
嵌入式编程语言的选择,高级语言:
C、C+、JAVA、Ada等。
汇编语言:
硬件体系结构相关。
程序的编译执行过程,嵌入式C编译环境,嵌入式C交叉编译环境一般都包括汇编器、链接器和定位器。
汇编器的任务是将符号级的汇编语言翻译成称为目标代码的指令位级表示。
链接器是用来将不同的模块(编译或汇编过的文件)链接成目标文件。
定位器则允许将代码和数据放置在目标处理器的指定内存空间。
汇编程序,汇编完成汇编语言到二进制代码的转换。
标记处理方法:
第一次扫描代码以决定每个标记的地址。
第二次用第一次中的标记值汇编指令,产生二进制代码。
符号表,ADDr0,r1,r2Label1ADDr3,r4,r5CMPr0,r3Label2SUBr5,r6,r7assemblycode,Label10x8Label20x10symboltable,编译过程,ARM开发环境包含的C/C+编译器,编译=翻译+优化,编译结合了翻译和优化两个环节翻译是将高级语言翻译为低级指令形式(或汇编语言形式)。
优化一方面产生更好的指令顺序,另一方面从整体上考虑程序效率。
编译过程中,高级语言被拆分成语句和表达式。
编译技术语句翻译,a*b+5*(c-d),expression,DFG,*,-,*,+,a,b,c,d,5,2,3,4,1,算术表达式的代码翻译,ADRr4,aMOVr1,r4ADRr4,bMOVr2,r4MULr3,r1,r2,DFG,*,-,*,+,a,b,c,d,5,ADRr4,cMOVr1,r4ADRr4,dMOVr5,r4SUBr6,r4,r5,MULr7,r6,#5,ADDr8,r7,r3,code,控制代码的产生,if(a+b0)x=5;elsex=7;,a+b0,x=5,x=7,3,2,1,控制代码的翻译,ADRr5,aLDRr1,r5ADRr5,bLDRr2,bADDr3,r1,r2BLElabel3,a+b0,x=5,x=7,LDRr3,#5ADRr5,xSTRr3,r5Bstmtent,label3LDRr3,#7ADRr5,xSTRr3,r5stmtent.,过程链接,过程一般指不返回值的结构。
要求代码:
调用并返回。
传递参数和结果。
参数和结果是在堆栈中传递的。
带有几个参数的过程可以使用寄存器。
过程堆栈,proc1,growth,proc1(inta)proc2(5);,proc2,SPstackpointer,FPframepointer,编译技术ARM过程调用标准(APCS),APCS,ARM过程调用标准(ARMProcedureCallStandard),提供了紧凑的编写例程的一种机制,定义的例程可以与其他例程交织在一起。
最显著的一点是对这些例程来自哪里没有明确的限制。
它们可以编译自C、Pascal,也可以是用汇编语言写成的。
APCS定义了:
r0-r3passparametersintoprocedure.Extraparametersareputonstackframe.r0holdsreturnvalue.r4-r7holdregistervalues.r11isframepointer,r13isstackpointer.,编译技术数据结构,编译程序必须对相关数据结构的引用翻译成对原始存储器的引用,通常需要在运行时进行地址计算。
一维数组二维数组结构体,编译技术表达式简化,1.A*B+A*CA*(B+C)2.for(i=0;i8+1;i+)for(i=0;i9;i+),编译技术死代码清除,死代码是指永远不会被执行的代码,在编译时要能够识别这些代码,并将其从程序中清除掉。
死代码大都是一些调试信息。
编译技术循环变换,循环是重要的程序结构,经常占用大量的CPU的计算时间,在编程时需要优化;循环展开:
循环合并:
循环折叠:
for(i=0;iN;i+)ai=bi*5;for(j=0;jN;j+)wj=cj*dj;for(i=0;iN;i+)ai=bi*5;wi=ci*di;,for(i=0;i4;i+)ai=bi*ci;for(i=0;i2;i+)ai*2=bi*2*ci*2;ai*2+1=bi*2+1*ci*2+1;,编译技术寄存器分配,寄存器分配选择寄存器变量的分配以使所需的寄存器总数最少;,w=a+b;x=c+w;y=c+d;ar0br1cr2dr0wr3xr0yr3,time,a,b,c,d,w,x,y,1,2,3,t=1,t=2,t=3,本节提要,1,3,2,程序编译技术,程序优化技术,Linux初步,程序优化,Optimizingforexecutiontime.Optimizingforenergy/power.Optimizingforprogramsize.,影响程序运行时间的主要因素,源代码:
编写高效优化的高级语言源代码可以缩短程序运行的时间。
编译器:
编译器负责把高级语言代码转换成机器代码程序,不同的编译器会导致代码效率的不同。
硬件的体系结构:
硬件的体系结构对程序的运行时间有较大的影响,如CPU内部寄存器的数量、高速缓存的大小和组织、系统的内存大小等。
操作系统:
操作系统决定了任务调度与内存管理等对程序执行时间有重要影响,结合硬件的体系结构,决定了系统的中断响应时间。
程序优化的基本策略,1.高级程序设计:
选择适当的算法与数据结构,避免使用可能会渐进产生较差性能的算法与编码技术。
2.基本编码原则:
避免采用限制编译器优化的因素,从而令编译器产生高效的代码;消除连续的函数调用:
如将计算移动循环外。
消除不必要的存储器引用:
引入临时变量来保存中间结果,只有当最后的值计算出来时,才将结果存放到数组或全局变量中。
3.低级优化:
尝试各种与数组代码相对的指针形式。
通过展开循环降低循环开销。
通过迭代分割的技术,找到使用流水线优化的功能单元的方法。
程序剖析(Profiling),1.程序剖析用来分析程序的各个部分需要多少CPU时间,程序剖析一边可以在现实的基准数据上运行实际的程序,一边进行剖析。
2.GPROFUNIX提供的剖析程序:
确定程序中每个函数花费了多少CPU时间。
计算每个函数被调用的次数,以调用函数来分类。
Amdahl定律,Amdahl定律主要用于描述提高系统某一部分性能对整个系统性能的影响;例:
设一个系统执行某个应用程序需要时间Told,而系统的某个部分运行所需要时间的百分比为a,如果性能提高了k倍,则这个部分原来需要时间aTold,而现在需要时间(aTold)/K。
因此,整个程序执行时间为:
Tnew=(1-a)Told+(aTold)/k=Told(1-a)+a/k所以程序加速比为:
S=Told/Tnew=1/(1-a)+a/k即:
如果以前占系统60%时间的部分性能提高了3倍(k=3),则程序加速比为1.67。
所以要想提高整个系统的速度,光大幅度提高某一部分的速度是不够的。
影响程序性能的要素,程序的执行时间=程序路径+指令耗时路径是被程序(或者说它等价于程序的高级语言表示)执行的指令序列。
指令耗时基于被程序路径跟踪的指令序列,它考虑数据相关性、流水线行为和高速缓存。
本节提要,1,3,2,程序编译技术,程序优化技术,Linux初步,嵌入式Linux分类,第一类是在利用Linux强大功能的前提下,使它尽可能得小,以满足许多嵌入式系统对体积的要求,如CLinux(http:
/www.uclinux.org)。
第二类是将Linux开发成实时系统尤其是硬(firm)实时系统,应用于一些关键的控制场合,如Fsmlabs公司(http:
/www.rtlinux.org)的RTLinux、MontaVista(http:
/)的HardHatLinux等。
第三类的产品就是将实时性和嵌入式方案结合起来的方案,很多公司都这么做,并且提供集成化的开发方案,如Lineo、TimeSys等。
全球每年生产的CPU的数量在二十亿颗左右,超过80%应用于专用性很强的各类嵌入式系统。
其中,又有相当一部分面向低端市场。
为降低硬件成本及运行功耗,有一类CPU在设计中取消了内存管理单元(MemoryManagementUnit,简称MMU)功能模块。
如Motorola公司的M68328、M68EN322、MC68360、DragonBall系列如68EZ328、68VZ328,ColdFire系列的如5272、5307,ARM7TDMI和MC68EN302、ETRAX、Inteli960、PRISMA、Atari68k等。
标准Linux针对有MMU的处理器设计。
在这种处理器上,虚拟地址被送到MMU,把虚拟地址映射为物理地址。
通过赋予每个任务不同的虚拟地址/物理地址转换映射,可支持不同任务之间的保护。
为什么要使用CLinux,最初,运行于这类没有MMU的CPU之上的都是一些很简单的单任务操作系统,或者更简单的控制程序,甚至根本就没有操作系统而直接运行应用程序。
在这种情况下,系统无法运行复杂的应用程序,或者效率很低,而且,所有的应用程序需要重写,并要求程序员十分了解硬件特性。
这些都阻碍了应用于这类CPU之上的嵌入式产品开发的速度。
然而,随着CLinux的诞生,这一切都改变了。
CLinux是一个完全符合GNU/GPL公约的项目,完全开放代码,现由Lineo公司支持维护。
英文单词中u表示Micro,小的意思,C表示Control,控制的意思,所以CLinux就是Micro-Control-Linux,字面上的理解就是“微控制领域中的Linux系统”。
它专门针对没有MMU的CPU,并专为嵌入式系统做了许多小型化的工作,已支持前面提到的多款CPU。
官方主页在http:
/www.uclinux.org。
EmbeddedLinux/MicrocontrollerProject,CLinux内核简介,CLinux是Linux2.0核心的分支,是针对没有MMU管理单元的微控制器设计的。
继承了Linux的大多数特性。
多数的Linux下应用程序和驱动程序都可以在CLinux下运行。
内核精简。
Kernel512KB。
Kernel+root900KB。
并入Linux2.6内核中。
CLinux与Linux的区别
(1),内存管理CLinux运行于没有MMU的处理器上。
使用平坦式(flat)内存管理模式,虚拟内存到物理内存是一对一的映射关系。
对于应用程序,使用固定的栈空间。
加载应用程序的时候需要重新定位。
可用内存空间的大小受到物理内存的限制。
CLinux与Linux的区别
(2),fork与vforkCLinux的多进程管理通过vfork来实现,CLinux只能支持vfork。
vfork使父进程锁定直到子进程exec()或exit()。
注:
CLinux的应用程序的多线程可以依赖于标准C库来实现(CLibc)。
CLinux与C/OS-II
(1),CLinux源于Linux,是一个很完整的系统,包括:
多任务调度;内存管理;文件系统(及接口);设备驱动程序;完整的TCP/IP的支持.源码开放,支持广泛(GUI、FS、驱动程序等等)。
CLinux与C/OS-II
(2),C/OS-II源码开放,内核简单,易于学习和移植。
占先式内核,实时性好。
只有多任务调度的简单内核。
内存管理过于简单,几乎没有动态内存管理功能。
文件系统和图形界面需要外挂。
对于设备驱动程序没有专门统一的接口。
CLinux的实时性问题,CLinux内核不关心实时性问题。
可以和RTLinux配合来实现实时。
RTLinux处理实时任务,非实时任务由Linux完成。
RTLinux是为Linux提供实时性的方法,同样也适用于CLinux。
通过RTLinux的patch,可以满足CLinux对实时性的需求。
CLinux的移植版本,MotorolaDragonBall、68KMotorolaColdfireARM7TDMI、ARM9TDMI(ARM940T)AlteraNios,CLinux的内核组成,初始化程序段(init)32KB左右数据段(data)50100KB左右未初始化数据段(bss)100150KB左右代码段(text)300KB左右(init、data、bss和text的地址是由编译链接时的定位文件vmlinux.lds决定的)文件系统(romfs)80KB左右,移植CLinux的主要工作,选择处理器对应的交叉编译器。
选择并修改Bootloader。
修改链接文件(vmlinux-armv.lds.in),定位各个数据段。
定义系统定时器、控制台(Console)。
编写中断的控制函数。
定义根文件系统。
编写其他系统设备驱动,编译器的选择,CLinux内核在ARM上的编译交叉编译器arm-elf-gcc、arm-linux-gcc标准C库应用程序C-libc、CLibc,(C)Linux的bootloader,系统配置、中断接管、引导。
装载内核、根文件系统、参数传递、内核调试、内核和根文件系统的下载等。
常见的CLinux(Linux)的Bootloader:
RedbootBlobViviUbootarmBoot,CLinux发行版的目录结构,uCLinux-dist,/NetSilicon,/Samsung,/Arcturus,Romfs的相关工具,根文件系统,新版的标准C库uClibc,应用程序,各制造商的配置文件,forNET+40,forS3C4510,foruCdimmanduCsimm,config,Documentation,vendors,lib,linux-2.0.x,linux-2.4.x,tools,uClibc,user,romfs,uClinux-2.4内核,uClinux-2.0内核,旧版的标准C库uC-libc,配置脚本,相关的文档,uClinux的内核目录结构,Linux2.4.x,/arch,/drivers,/fs,/include,/init,/ipc,/kernel,/lib,/mm,/mmnommu,/net,/scripts,/armnommu,/i196,/m68knommu,/boot,/mach-s3c44b0,/kernel,/lib,/mm,/asm-armnommu,/linux,/net,/arch-netarm,/proc-netarm,uClinux内核结构,读懂CLinux内核源码,(C)Linux内核庞大,结构复杂。
对CLinux内核的统计:
接近1万个文件,4百万行代码。
内核编程习惯(技巧)不同于应用程序。
(C)Linux内核的C代码,Linux内核的主体使用GNUC,在ANSIC上进行了扩充。
Linux内核必须由gcc编译。
gcc和Linux内核版本并行发展,对于版本的依赖性强。
内核代码中使用的一些编程技巧,在通常的应用程序中很少遇到。
建立嵌入式Linux开发环境
(1),建立开发环境,操作系统REDHATLinux(7或9),安装GCC交叉编译器进行安装(比如arm-linux-gcc、arm-uclibc-gcc。
配置开发主机,配置MINICOM(与windows系统类似),作为调试嵌入式开发板的信息输出的监视器和键盘输入的工具;配置网络,主要是配置NFS网络文件系统,需要关闭防火墙,简化嵌入式网络调试环境设置过程。
建立引导装载程序BOOTLOADER,在一些公开源代码的BOOTLOADER,如U-BOOT、BLOB、VIVI、LILO、ARM-BOOT、RED-BOOT等上根据自己具体芯片进行移植修改有些芯片没有内置引导装载程序,比如三星的ARM7、ARM9系列芯片,这样就需要编写烧写开发板上Flash的烧写程序,对开发自己的应用的人来说可以极大提高开发速度。
建立嵌入式Linux开发环境
(2),建立Linux操作系统,下载专门针对你所使用的CPU移植好的Linux操作系统,进行修改。
完善自己的特定硬件的驱动程序,进行调试修改。
建立根文件系统,从下载使用BUSYBOX软件进行功能裁减,产生一个最基本的根文件系统,再根据自己的应用需要添加其他的程序。
根文件系统在嵌入式系统中一般设为只读,需要使用mkcramfs,genromfs等工具产生烧写映像文件下载专门针对你所使用的CPU移植好的Linux操作系统,进行修改。
建立应用程序的Flash磁盘分区,建立应用程序的Flash磁盘分区,一般使用JFFS2或YAFFS文件系统,这需要在内核中提供这些文件系统的驱动。
有的系统使用一个线性Flash(NOR型)512K32M,有的系统使用非线性Flash(NAND型)8512M,有的两个同时使用,需要根据应用规划Flash的分区方案。
开发应用程序,应用程序可以放入根文件系统中,也可以放入YAFFS、JFFS2文件系统中,有的应用不使用根文件系统,直接将应用程序和内核设计在一起,这有点类似于C/OS-II的方式。
烧写内核、根文件系统、应用程序。
发布产品,建立嵌入式Linux开发环境(3),嵌入式Linux开发环境建立方案,基于PC机WINDOWS操作系统下的CYGWIN。
在WINDOWS下安装虚拟机后,再在虚拟机中安装Linux操作系统。
直接安装Linux操作系统。
谢谢!
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 嵌入式 程序设计 分析