《第五章基于ARM的嵌入式程序设计ok.ppt》由会员分享,可在线阅读,更多相关《第五章基于ARM的嵌入式程序设计ok.ppt(79页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第五章基于ARM的嵌入式程序设计ok5.1ARM汇编语言的伪操作、宏指令与伪指令汇编语言的伪操作、宏指令与伪指令5.1.1两种常见的ARM编译开发环境5.1.2ADS编译环境下的伪操作和宏指令5.1.3GNU编译环境下的伪操作和宏指令5.1.4ARM汇编语言的伪指令 两种常见的ARM编译开发环境ADS/SDT IDE开发环境:它由ARM公司开发,使用了CodeWarrior公司的编译器;集成了GNU开发工具的IDE开发环境:它由GNU的汇编器as、交叉编译器gcc、和链接器ld等组成。编译环境下的伪操作和宏指令ADS编译环境下的伪操作可分为以下几类:符号定义(SymbolDefinition)
2、伪操作数据定义(DataDefinition)伪操作汇编控制(AssemblyControl)伪操作信息报告(Reporting)伪操作其他(Miscellaneous)伪操作 符号定义伪操作伪操作语法格式作用GBLAGBLAVariable声明一个全局的算术变量,并将其初始化成0。GBLLGBLLVariable声明一个全局的逻辑变量,并将其初始化成FALSE。GBLSGBLSVariable声明一个全局的字符串变量,并将其初始化成空串“”。LCLALCLAVariable声明一个局部的算术变量,并将其初始化成0。LCLLLCLLVariable声明一个局部的逻辑变量,并将其初始化成FALS
3、E。LCLSLCLSVariable声明一个局部的串变量,并将其初始化成空串“”。SETASETAVariableexpr给一个全局或局部算术变量赋值。SETLSETLVariableexpr给一个全局或局部逻辑变量赋值。SETSSETSVariableexpr给一个全局或局部字符串变量赋值。RLISTname LIST list of registers为一个通用寄存器列表定义名称。CNnameCNexpr为一个协处理器的寄存器定义名称。CPnameCPexpr为一个协处理器定义名称。DN/SNnameDN/SNexprDN/SN为一个双精度/单精度的VFP寄存器定义名称。FNnameFNe
4、xpr为一个FPA浮点寄存器定义名称。数据定义伪操作伪操作语法格式作用LTORGLTORG声明一个数据缓冲池(也称为文字池)的开始。MAPMAPexpr,base-register定义一个结构化的内存表(StorageMap)的首地址。FIELDlabelFIELDexpr定义一个结构化内存表中的数据域。SPACElabelSPACEexpr分配一块连续内存单元,并用0初始化。DCBlabel DCB expr,expr分配一段字节内存单元,并用expr初始化。DCD/DCDUlabel DCD expr,expr分配一段字内存单元。DCDOlabelDCDOexpr,expr分配一段字对齐的
5、字内存单元。DCFD/DCFDUlabelDCFDUfpliteral,fpliteral为双精度的浮点数分配字对齐的内存单元。DCFS/DCFSUlabel DCFS U fpliteral,fpliteral为单精度的浮点数分配字对齐的内存单元。DCIlabel DCI expr,expr在ARM代码中分配一段字对齐的内存单元;在Thumb代码中,分配一段半字对齐的半字内存单元。DCQ/DCQUlabelDCQUliteral,literal分配一段以双字(8个字节)为单位的内存DCW/DCWUlabelDCW U expr,exprDCW用于分配一段半字对齐的半字内存单元。汇编控制伪操作
6、 伪操作语法格式作用IF,ELSE及ENDIFIFlogicalexpressionELSEENDIF能够根据条件把一段源代码包括在汇编语言程序内或者将其排除在程序之外。WHILE及WENDWHILElogicalexpressionWEND能够根据条件重复汇编相同的一段源代码。MACRO、MEND及MEXITMACRO$labelmacroname$parameter,$parameter;宏 代码MENDMACRO标识宏定义的开始,MEND标识宏定义的结束。MERIT用于从宏中跳转出去。用MACRO和MEND定义的一段代码,称为宏定义体。通过宏名称来调用宏。信息报告伪操作伪操作语法格式作用
7、ASSERTASSERTlogicalexpression对汇编程序的第二遍扫描中,如果其中ASSERT中条件不成立,ASSERT伪操作将报告该错误信息。INFOINFO numeric-expression,string-expression在汇编处理过程的第一遍扫描或者第二遍扫描时INFO伪操作报告诊断信息。OPTOPTn通过OPT伪操作可以在源程序中设置列表选项。TTLTTLtitle在列表文件的每一页的开头插入一个标题。SUBTSUBTsubtitle在列表文件的每一页的开头插入一个子标题。其他伪操作伪操作语法格式作用CODE16CODE16告诉汇编编译器后面的指令序列为16位的Thu
8、mb指令CODE32CODE32告诉汇编编译器后面的指令序列为32位的ARM指令。EQUname EQU expr,type为数字常量、基于寄存器的值和程序中的标号(基于PC的值)定义一个字符名称。AREAAREA sectionname,attr,attr定义一个代码段或者数据段。ENTRYENTRY指定程序的入口点。ENDEND告诉编译器已经到了源程序结尾。ALIGNALIGNexpr,offset 通过添加补丁字节使当前位置满足一定的对齐方式。EXPORT/GLOBALEXPORTsymbolWEAK声明一个符号可以被其他文件引用,相当于声明了一个全局变量。IMPORTIMPORTsym
9、bolWEAK告诉编译器当前的符号不是在本源文件中定义的,而是在其他源文件中定义的,在本源文件中可能引用该符号。EXTERNEXTERN symbol WEAK告诉编译器当前的符号不是在本源文件中定义的,而是在其他源文件中定义的,在本源文件中可能引用该符号。GET/INCLUDEGET将一个源文件包含到当前源文件中,并将被包含的文件在其当前位置进行汇编处理。INCBININCBIN将一个文件包含到当前源文件中,被包含的文件不进行汇编处理。KEEPKEEPsymbol告诉编译器将局部符号包含在目标文件的符号表中。NOFPNOFP禁止源程序中包含浮点运算指令。REQUIREREQUIRElable
10、指定段之间的相互依赖关系。RNnameRNexpr为一个特定的寄存器定义名称。ROUTnameROUT定义局部变量的有效范围。5.1.3GNU编译环境下的伪操作和宏指令GNU编译环境下的伪操作可分为以下几类:常量编译控制伪操作汇编程序代码控制伪操作宏及条件编译控制伪操作其他伪操作常量编译控制伪操作伪操作伪操作语法格式语法格式作作用用.byte.byteexpr,expr分配一段字节内存单元,并用分配一段字节内存单元,并用expr初始化。初始化。.hword/.short.hwordexpr,expr分配一段半字内存单元,并用分配一段半字内存单元,并用expr初始化。初始化。.ascii.asc
11、iiexpr,expr定义字符串定义字符串expr(非零结束符)。(非零结束符)。.asciz/.string.ascizexpr,expr定义字符串定义字符串expr(以(以/0为结束符)。为结束符)。.float/.single.floatexpr,expr定义一个定义一个32bitIEEE浮点数浮点数expr。.double.doubleexpr,expr定义定义64bitIEEE浮点数浮点数expr。word/.long/.int.wordexpr,expr分配一段字内存单元,并用分配一段字内存单元,并用expr初始化。初始化。.fill.fill repeat,size,value分
12、分配配一一段段字字节节内内存存单单元元,用用size长长度度value填填充充repeat次。次。.zero.zerosize分配一段字节内存单元,并用分配一段字节内存单元,并用0填充内存。填充内存。.space/.skip.spacesize,value分配一段内存单元,用分配一段内存单元,用value将内存单元初始化。将内存单元初始化。字符编译控制字符编译控制.equ.equiv操作符操作符.set.global.globl说说明明将将symbol 定义为定义为expr作用同作用同.equ定义定义symbol为为expr,若,若symbol已定义则出错已定义则出错将将symbol 定义为全
13、局标号定义为全局标号使用同使用同.global语语法法.equsymbol,expr.setsymbol,expr.equivsymbol,expr.globalsymbol.globlsymbol例例子子.equVersion,0.1.setCo,EMBEST.equivVersion,0.2.globalMyAsmFunc.globlMyAsmFunc汇编程序代码控制伪操作 伪操作伪操作语法格式语法格式作作用用.section.sectionexpr定义域中包含的段。定义域中包含的段。.text.textsubsection将操作符开始的代码编译到代码段或代码段子段。将操作符开始的代码编译
14、到代码段或代码段子段。.data.datasubsection将操作符开始的数据编译到数据段或数据段子段。将操作符开始的数据编译到数据段或数据段子段。.bss.bsssubsection将变量存放到将变量存放到.bss段或段或.bss段的子段。段的子段。.code16/.thumb.code16.thumb表明当前汇编指令的指令集选择表明当前汇编指令的指令集选择Thumb指令集。指令集。.code32/.arm.code32.arm表明当前汇编指令的指令集选择表明当前汇编指令的指令集选择ARM指令集。指令集。.end.end标记汇编文件的结束行,即标号后的代码不作处理。标记汇编文件的结束行,即
15、标号后的代码不作处理。.include.include“”将一个源文件包含到当前源文件中。将一个源文件包含到当前源文件中。.align/.balign.align alignment ,fill,max通过添加填充字节使当前位置满足一定的对齐方式。通过添加填充字节使当前位置满足一定的对齐方式。宏及条件编译控制伪操作伪操作伪操作语法格式语法格式作作用用.macro、.exitm及及.endm.macroacroname parameter,parameter.endm.macro伪伪操操作作标标识识宏宏定定义义的的开开始始,.endm标标识识宏宏定定义义的的结结束束。用用.macro及及.end
16、m定定义义一一段段代代码码,称称为为宏定义体。宏定义体。.exitm伪操作用于提前退出宏。伪操作用于提前退出宏。.ifdef,.else及及.endif.ifdefcondition.else.endif当当满满足足某某条条件件时时对对一一组组语语句句进进行行编编译译,而而当当条条件件不不满足时则编译另一组语句。其中满足时则编译另一组语句。其中else可以缺省。可以缺省。其他伪操作 伪操作伪操作语法格式语法格式作作用用.eject.eject在汇编符号列表文件中插入一分页符。在汇编符号列表文件中插入一分页符。.list.list产生汇编列表(从产生汇编列表(从.list到到.nolist)。)
17、。.nolist.nolist表示汇编列表结束处。表示汇编列表结束处。.title.title“heading”使用使用“heading”作为标题。作为标题。.sbttl.sbttl“heading”使用使用“heading”作为子标题。作为子标题。.ltorg.ltorg在当前段的当前地址(字对齐)产生一个文字池。在当前段的当前地址(字对齐)产生一个文字池。.req.reqname,expr为一个特定的寄存器定义名称。为一个特定的寄存器定义名称。.err.err使编译时产生错误报告。使编译时产生错误报告。.print.printstring打印信息到标准输出。打印信息到标准输出。.fail.
18、failexpr编译汇编文件时产生警告。编译汇编文件时产生警告。5.1.4ARM汇编语言的伪指令 伪指令伪指令语法格式语法格式作作用用ADRADRcondregister,expr将将基基于于PC或或基基于于寄寄存存器器的的地地址址值值读读取取到到寄寄存存器器中中。小范围的地址读取。小范围的地址读取。ADRLADRLcondregister,expr将将基基于于PC或或基基于于寄寄存存器器的的地地址址值值读读取取到到寄寄存存器器中中。中等范围的地址读取。中等范围的地址读取。LDRLDRcondregister,=expr|label-expr将将一一个个32位位的的立立即即数数或或者者一一个个
19、地地址址值值读读取取到到寄寄存存器器中。大范围的地址读取。中。大范围的地址读取。NOPNOP在汇编时将被替换成在汇编时将被替换成ARM中的空操作。中的空操作。5.2ARM汇编语言程序设计汇编语言程序设计5.2.1ARM汇编中的文件格式5.2.2ARM汇编语言语句格式5.2.3ARM汇编语言编程的重点5.2.4ARM汇编程序实例汇编中的文件格式ARM源程序文件(可简称为源文件)可以由任意一种文本编辑器来编写程序代码,它一般为文本格式。在ARM程序设计中,常用的源文件可简单分为以下几种:源程序文件源程序文件文件名文件名说说明明汇编程序文件汇编程序文件*.S用用 ARM汇汇 编编 语语 言言 编编
20、写写 的的 ARM程程 序序 或或Thumb程序。程序。C程序文件程序文件*.C用用C语言编写的程序代码。语言编写的程序代码。头文件头文件*.H为为了了简简化化源源程程序序,把把程程序序中中常常用用到到的的常常量量命命名名、宏宏定定义义、数数据据结结构构定定义义等等等等单单独独放放在一个文件中,一般称为头文件。在一个文件中,一般称为头文件。汇编语言语句格式ARM汇编语言语句格式如下所示:symbolinstruction|directive|pseudo-instruction;comment其中:instruction为指令。directive为伪操作。pseudo-instruction为
21、伪指令。symbol为符号。comment为语句的注释。ARM汇编语言程序格式ARM汇编语言是以段(section)为单位来组织源文件的。段是相对独立的、具有特定名称的、不可分割的指令或者数据序列。段又可以分为代码段和数据段,代码段存放执行代码,数据段存放代码运行时需要用到的数据。一个ARM源程序至少需要一个代码段,大的程序可以包含多个代码段和数据段。举例说明举例说明ARM汇编汇编语言源程语言源程序的基本序的基本结构结构.equx,45/*x=45*/.equy,64/*y=64*/.equstack_top,0 x1000/*definethetopaddressforstacks*/.gl
22、obal_start.text_start:/*codestart*/movsp,#stack_topmovr0,#x/*putxvalueintoR0*/strr0,sp/*savethevalueofR0intostacks*/movr0,#y/*putyvalueintoR0*/ldrr1,sp/*readthedatafromstack,andputitintoR1*/ADDr0,r0,r1STRr0,spstop:bstop/*endthecode,cycling*/.end5.2.3ARM汇编语言编程的重点ARM数据处理操作设置条件码汇编语言子程序调用及返回跳转表思想ARM与Thu
23、mb之间的状态转换及函数的相调用ARM数据处理操作ARM中数据的处理有以下三种形式:简单的寄存器操作立即数操作寄存器移位操作其中32位立即数在32位指令中的编码以及ARM特有的寄存器移位操作是数据处理方面的难点。设置条件码ARM的任何数据处理指令都能通过增加“S”操作码来设置条件码(N,Z,C和V)。条件执行条件执行ARM指令集不同寻常的特征是每条指令(除了某些v5T指令)都可以是条件执行的。条件转移条件转移在程序中可以通过条件码的使用让微处理器决定是否进行转移,还可用来控制循环的退出。汇编语言子程序调用及返回 子程序的调用在ARM汇编语言中,子程序调用是通过BL指令来完成的。BL指令的语法格
24、式如下:BLsubname其中,subname是被调用的子程序的名称。子程序的返回在返回调用子程序时,转移链接指令保存到LR寄存器(r14)中的值需要拷贝回程序寄存器PC(r15)。跳转表思想在程序设计中,有时为使程序完成一定的功能,需要调用一系列子程序中的一个,而决定究竟调用哪一个由程序的计算值确定。跳转表是解决该问题的有效方案。跳转表是利用程序计数器PC在通用寄存器文件中的可见性来实现的,如下例所示:ARM与Thumb间的状态转换及函数的相调用 状态切换的实现ARM/Thumb之间的状态切换是通过一条专用的转移交换指令BX来实现的。BX利用Rn寄存器中目的地址值的最后一位来判断跳转后的状态
25、。当最后一位为0时,表示转移到ARM状态;当最后一位为1时,表示转移到Thumb状态,如下图所示。ARM与Thumb间的状态转换及函数的相调用ARM/Thumb之间的函数调用在同一状态下的子程序调用,通常只需要一条指令实现调用:BLfunction实现返回也只需要从LR恢复PC即可:MOVPC,LR 在不同状态下的子程序调用中,就需要进行状态之间的切换,需要考虑到以下几点:需要由BX来切换状态,因为BL不能完成状态切换。需要在BX之前先保存好LR,BX不能自动保存返回地址到LR。需要用“BXLR”来返回,不能使用“MOVPC,LR”,返回时要仔细考虑保存在LR中最低位的内容是否正确。汇编程序实
26、例1.简单的ARM指令程序2.数据块复制 3.利用跳转表实现程序跳转4.ADS编译环境下的汇编代码与GNU编译环境下有较多不同点,主要是符号及伪操作的不同。5.3 5.3 嵌入式嵌入式C语言程序设计基础语言程序设计基础5.3.1C语言“预处理伪指令”在嵌入式程序设计中的应用5.3.2嵌入式程序设计中的函数及函数库5.3.3嵌入式程序设计中常用的C语言语句5.3.4嵌入式程序设计中C语言的变量、数组、结构、联合5.3.1C语言“预处理伪指令”在嵌入式程序设计中的应用“预处理命令”可以改进程序设计的环境,提高编程效率,一般以#号打头,可分为以下三种:文件包含宏定义条件编译文件包含文件包含伪指令可将
27、头文件包含到程序中,头文件中定义的内容包括符号常量、复合变量原型、用户定义的变量类型原型和函数的原型说明等。编译器编译预处理时用文件包含的正文内容替换到实际程序中。文件包含伪指令的格式#include;标准头文件#include“头文件名.h”;自定义头文件#include宏标识符文件包含举例#defineMYINCLUDE“d:EmbestIDEdef.h”#include“44blib.h”#include“44b.h”#includeMYINCLUDE#include“./LCD_Test/bmp.h”宏定义宏定义宏定义伪指令分为:简单宏、参数宏、条件宏、预定义宏及宏释放。宏定义伪指令分
28、为:简单宏、参数宏、条件宏、预定义宏及宏释放。简单宏简单宏:#define宏标识符宏标识符宏体宏体参数宏:参数宏:#define宏标识符(宏标识符(形式参数表)形式参数表)宏体宏体条件宏定义:条件宏定义:#ifdef宏标识符宏标识符#ifndef宏标识符宏标识符#undef宏标识符宏标识符#define宏标识符宏标识符宏体宏体#define宏标识符宏标识符宏体宏体#else#else#undef宏标识符宏标识符#define宏标识符宏标识符宏体宏体#define宏标识符宏标识符宏体宏体#endif#endif宏定义举例简单宏简单宏#definerSYSCFG(*(volatileunsigne
29、d*)0 x1c00000)参数宏参数宏#defineSQR(x,y)sqrt(x)*(y)+(y)*(y)#definemin(x1,x2)(x1x2)?x1:x2)条件宏定义条件宏定义#ifndef BLOCK-SIZE#ifndef BLOCK-SIZE#define BLOCK-SIZE 128#define BLOCK-SIZE 128#else#else#undef BLOCK-SIZE#undef BLOCK-SIZE#define BLOCK-SIZE 128#define BLOCK-SIZE 128#endif#endif条件编译条件编译伪指令是写给编译器的,指示编译器在满
30、足某一条件时仅编译源文件中与之相应的部分。其格式如右框中所示:#if(条件表达式1)#elif(条件表达式2)#elif(条件表达式n)#else#endif嵌入式程序设计中的函数及函数库函数是C语言程序设计的核心。一个较大的C语言程序一般是由一个主函数和若干个子函数组成,每个函数完成一个特定的功能。函数之间也可以相互调用。函数的格式函数的格式:定义性说明格式:存储类说明符存储类说明符 类型说明符类型说明符 修饰符修饰符 标识符标识符 (参数表)(参数表)函数体函数体 原型说明格式:extern extern 类型说明符类型说明符 修饰符修饰符 标识符(参数表)函数体标识符(参数表)函数体 存
31、储类说明符存储类说明符:static:static、externextern类型说明符类型说明符:char:char、unsigned charunsigned char int int、unsignedunsigned long long、unsigned longunsigned long float float、doubledouble、long doublelong double struct struct、unionunion、voidvoid修饰符修饰符:interrupt:interrupt、nearnear、farfar、hugehuge标识符标识符:函数名、函数名、*函数名等
32、函数名等嵌入式程序设计中的函数及函数库函数库是为了减少编程工作量,将一些常用的功能的函数放在函数库中供公共使用.它包括C的标准库函数,也包括一些用户自己编写非标准库。例如,44blib.h是根据基于S3C44B0X处理器的开发板及其功能模块编写的一个C语言函数库。它不属于C语言的标准库。44blib.c结构如下:结构如下:用户定义头文件:用户定义头文件:44blib.h:库函数原型定义库函数原型定义44b.h:44B0X片上各模块寄存器宏定义片上各模块寄存器宏定义def.h:数据类型重新宏定义,常用常量宏定义数据类型重新宏定义,常用常量宏定义Option.h:44B0X片上可选项宏定义片上可选
33、项宏定义标准头文件:标准头文件:Stdarg.h:定义读函数参数表宏定义读函数参数表宏String.h:串操作和内存操作函数串操作和内存操作函数Stdio.h:标准标准I/O预定义函数预定义函数Ctype.h:字符分类及转换信息字符分类及转换信息voiddelay(inttime);/延时函数延时函数voidport_init(void);/I/O端口初始化函数端口初始化函数voidcache_flush(void);/清空清空cachevoiduart_init(intnMainClk,intnBaud);voiduart_select(intnChannel);voiduart_txemp
34、ty(intnChannel);charuart_getch(void);charuart_getkey(void);voiduart_sendbyte(intnData);voiduart_sendstring(char*pString);voiduart_printf(char*fmt,.);voidtimer_start(intnDivider);/WatchdogTimerisused.inttimer_stop(void);/WatchdogTimerisused.voidsys_init();/Interrupt,PortandUARTintget_uartID();嵌入式程序设计
35、中常用的C语言语句C语言语句格式为:标号:语句;C语言语句很多,常用到的有以下几种:条件语句swith语句循环语句嵌入式程序设计中嵌入式程序设计中C语言的变量、数组、结构、联合语言的变量、数组、结构、联合 变量变量 存储类型存储类型 类型说明符类型说明符 修饰符修饰符 标识符标识符 初值初值 ,标识符,标识符 初值初值;存储类说明符存储类说明符:autoauto、registerregister、externextern、staticstatic类型说明符类型说明符:charchar、unsigned charunsigned char int int、unsignedunsigned lon
36、g long、unsigned longunsigned long float float、doubledouble、long doublelong double struct struct、unionunion、voidvoid修饰符修饰符:constconst、volatilevolatile const const int int a;volatile unsigned char*a;a;volatile unsigned char*a;标识符标识符:变量名、变量名、*变量名等变量名等数组数组 一维数组:一维数组:类型说明符类型说明符标识符标识符常量表达式常量表达式初值,初值,初值,初值
37、,;char char 标识符标识符 =“=“字符串字符串”;二维数组:二维数组:类型说明符类型说明符 标识符标识符 mn mn 初值表初值表,初值表初值表;指针数组和数组指针指针数组和数组指针类型说明符类型说明符*标志符标志符常量表达式常量表达式=地址,地址,地址,地址,;类型说明符类型说明符 (*标志符)标志符)=数组标识符数组标识符;嵌入式程序设计中C语言的变量、数组、结构、联合结构说明结构说明存储类说明符struct结构原型名类型说明标识符,标识符;类型说明标识符,标识符;标识符=初值表,标识符=初值表;嵌入式程序设计中C语言的变量、数组、结构、联合联合说明联合说明存储类说明符unio
38、n联合原型名类型说明符标识符,标识符;类型说明符标识符,标识符;标识符=初值表,标识符初值表;5.4 5.4 嵌入式嵌入式C语言程序设计实例语言程序设计实例5.4.1S3VCE40开发板测试程序实例5.4.2嵌入式C语言程序编写的简单构架5.4.3Flash测试代码介绍 S3VCE40开发板的测试程序实例我们以S3VCE40开发板上的各个功能模块的整个测试程序为例,介绍如何运用C语言进行基于ARM的嵌入式程序设计。该程序完成的功能如下所示:1.实验板加电时数码管八段全亮;LED1、LED2轮流闪烁(频率近1Hz);使用PC键盘操作;串口终端输出信息如图:2.然后使用开发板上的PC键盘选择各部分
39、功能测试操作,如下图:程序源代码介绍整个测试程序主文件main.c的代码构成图如下图所示,由BootLoader启动程序进入C语言主函数main()入口。5.4.2嵌入式C语言程序编写的简单构架#include预编译指令个C语言代码,一般要用#include编译指令将所需要的头文件加到该程序中,这是很有必要的,尤其是对编写较大的程序代码时。随后是定义一些外部变量,并对程序中的函数进行声明。主函数main()的编写;在每一个C语言代码中,一定要有一个main()函数,在该函数中完成该程序文件所要完成的各个功能,一般是通过调用各个子函数来完成。当然,它也可以调用其他文件中的函数。完成相应功能的各个
40、功能函数的编写。各个函数之间可以相互调用。5.4.3Flash测试代码介绍下面给出功能测试程序中Flash测试程序的代码结构图:5.5嵌入式嵌入式C语言程序设计技巧语言程序设计技巧5.5.1变量定义5.5.2参数传递5.5.3循环条件变量定义 在变量声明的时候,最好把所有相同类型的变量放在一起定义,这样可以优化存储器布局。由下例可以看出:对于局部变量类型的定义,使用short或char来定义变量并不是总能节省存储空间。有时使用32位int或unsinged int局部变量更有效率一些,如下图所示:变量定义中,为了精简程序,程序员总是竭力避免使用冗余变量。但有时使用冗余变量可以减少存储器访问的次
41、数这可以提高系统性能。errs为全局变量voidtest1(void)errs+=f();errs+=g();Voidtest2(void)intlocal=errs;local+=f();local+=g();errs=local;5.5.2参数传递 为了使单独编译的C语言程序和汇编程序能够互相调用,定义了统一的函数过程调用标准ATPCS。ATPCS定义了寄存器组中的R0R3作为参数传递和结果返回寄存器,如果参数数目超过四个,则使用堆栈进行传递。内部寄存器的访问速度是远远大于存储器的,所以要尽量使参数传递在寄存器里面进行,即应尽量把函数的参数控制在四个以下。循环条件计数循环是程序中十分常用的
42、流程控制结构,一般有以下两种形式:for for(loop=1loop=1;loop=limitloop New Workspace,系统弹出工程创建对话框。在Project name编辑框中输入新建工程名led_int,Location编辑框中输入保存该工程的目录路径C:EmbestIDEEV4510led_int。选择OK按钮,创建新工程led_int,集成环境将创建与工程同名的workplace和project。在工作区窗中选择右键菜单创建源文件夹并添加相关源文件。工程的建立和配置 工程配置工程创建完成后,需要对工程进行配置,EmbestIDE才能正确的编译、链接和调试等。选择Proje
43、ctSettings菜单项,弹出工程配置对话框,如下图所示。工程配置包括处理器的选择、仿真器配置、调试配置、目录配置、编译配置、汇编配置、链接配置,工程配置是整个软件开发过程中非常关键的一步。在RAM中调试软件 软件的调试既可以在ROM区也可以在RAM区完成,由于RAM区可以很方便地读写,访问速度高,因此软件开发过程中的调试只要硬件条件许可,都应该在RAM区完成。软件调试前需要完成以下几步:一编译链接工程一连接仿真器、评估板一程序下载软件的固化 在RAM中调试通过的程序与最终固化到电路板的Flash中的程序有所区别,需要做以下改动:在汇编器的预定义选项中设置ROM=1,或者直接在init.s文
44、件中增加“.equROM”。在链接器的链接文件中选择ldscript.flash。重新编译程序。然后使用ElftoBin工具将led_int.elf文件转换成二进制指令格式文件led_int.bin。最后使用EmbestFlashProgrammer将led_int.bin下载到电路板的Flash中,如图所示。程序在Flash中调试 程序在Flash中与在RAM中调试工程配置不同:一调试选项中不需要执行脚本文件,该工作在启动文件中完成,需要将连接后行为(Actionafterconnected)选项改为无(None);调试过程也有所不同:一连接仿真器后,无需再执行下载(Download)程序操作;一如果要从启动程序的入口开始调试程序,先必须执行复位(reset)命令,此时程序将停在零地址处;一程序在Flash中调试时最多可以设置两个硬件断点。