收藏 分享(赏)

嵌入式系统及应用——第8章 嵌入式软件编程.ppt

上传人:dreamzhangning 文档编号:3330675 上传时间:2018-10-14 格式:PPT 页数:94 大小:2.82MB
下载 相关 举报
嵌入式系统及应用——第8章 嵌入式软件编程.ppt_第1页
第1页 / 共94页
嵌入式系统及应用——第8章 嵌入式软件编程.ppt_第2页
第2页 / 共94页
嵌入式系统及应用——第8章 嵌入式软件编程.ppt_第3页
第3页 / 共94页
嵌入式系统及应用——第8章 嵌入式软件编程.ppt_第4页
第4页 / 共94页
嵌入式系统及应用——第8章 嵌入式软件编程.ppt_第5页
第5页 / 共94页
点击查看更多>>
资源描述

1、第八章,嵌入式软件编程,核心内容,嵌入式程序设计语言 汇编语言 C语言 C与汇编混合编程 嵌入式Java 编程规范,8.1 嵌入式程序设计语言,一种程序设计语言可以看成是控制某种设备,特别是一种计算机的人为语言。同自然语言一样,它也使用语法和语义规则分别定义其语句结构和涵义 程序设计语言的作用在于表述算法,以便更方便地组织和操作信息。,程序设计语言的定义中应该包括以下内容,功能 目标 结构 表达能力 程序设计语言需要较高的精确度和完整性.,8.2 汇编语言,GAS的基本风格与AT&T的差异,一、GAS的基本风格,1、程序的构成从整体结构上看,一个完整的GAS汇编语言程序需要包括 程序名(.ti

2、tle,也称为头信息)、全局定义(.global)、外部引用(.include,.extern)、数据段(.data)、文本段(.text)、主程序(main)、注释(#)等部分。其中,文本段是必不可少的。,2、注释以“#”开头的程序行是注释行。 3、标识符标识符是由字母和数字组成的一个字符串。定义标识符时,后面必须紧跟一个冒号“:”,表示标识符所在内存单元的地址计数值。,标识符作为变量名,被外部调用,则需要用 .global processname的方式 来申明该过程,在其他的汇编语言和C语言程序中 可以使用外部引用方式调用该过程,4、常数的表示在GAS中,数值表示如下: 1)二进制数:由0

3、b或者0B开头,如:0b1010101、0B1011110; 2)十六进制数:以0x或者0X开头,如:0x4e7、0X1f9; 3)八进制数:由0开头,如:0625、0450; 4) 十进制数:以非零数开头,如:365、13180; 5)字符串:由引号括起,如:”string”。,5、常用的汇编指示符 1).rept count:表示重复count次; 2).macro、.endm:定义宏; 3).include “filename:用于将一个程序文件插入到另外一个程序文件中; 4).global name:将name申明为全局符号; 5).set name, value:申明一个符号常量,程

4、序中使用时要在前面加一个“$”符号; 6).balign abs_expr,pad_value:表示将地址对齐; 7).p2align abs_expr,pad_value:表示将地址按2的次方对齐; 8).title “heading“:用于在生成符号列表时作为头信息。,二、与AT&T的差异,1、寄存器名的表达不同在GAS的80386汇编语言中,寄存器的名字前都要加上百分号“%”,而Intel的则没有:1)32位的寄存器:%eax,%ebx,%ecx,%edx,%edi,%esi,%ebp,%esp2)16位的寄存器:%ax,%bx,%cx,%dx,%di,%si,%bp,%sp3)8位的寄

5、存器:%ah,%al,%bh,%bl,%ch,%cl,%dh,%dl4)段寄存器:%cs,%ds,%ss,%es,%fs,%gs5)控制寄存器:%cr0,%cr2,%cr3,2、数据传送的方向不同GAS汇编语言中,数据的传送方向与Intel宏汇编的方向刚好相反,Intel宏汇编命令 将ax的内容送到cx中,在GAS汇编语言中 将cx的内容送到ax中,3、操作数位数的表达不同在GAS汇编语言中,操作数的位数由指令的后缀表示,其中后缀为“l”表示32位,“w”表示16位,“b”表示8位。 Intel宏汇编则用操作数前缀表示法,需要使用dword、wor、byte等关键字,在GAS汇编语言中,Int

6、el宏汇编,4、立即数的表达不同在GAS的汇编语言中,立即数前要加前缀“$”符号,Intel宏汇编语句,GAS汇编语句,表示将以地址0x16开始的 4个字节的内容送 到寄存器eax中,5、内存引用不同,6、长跳转指令不同,GAS汇编语言中,Intel宏汇编,GAS汇编语言,Intel宏汇编,8.3 C语言,gcc扩展 C51扩展 浮点运算支持,一、 gcc扩展gcc是为Linux配套的C语言编译器,在支持多个版本的ANSI C标准基础上,进行了一些扩展,主要集中在增强C语言的表达能力和语言功能,可通过使用-ansi、-traditional等编译参数来控制扩展功能是否启用。GNU的gcc编译器

7、在嵌入式领域使用的非常广泛,它支持众多的高档嵌入式处理器,如Intel386、Intel960、68000、ADM29K等。,这看上去多此一举,而且不符合通用的编程规范,但在替代不安全的宏定义时,显得特别有用,如:要计算两次a和b,有可能带来副作用,如如定义为则可消除该不安全因素。,1、表达式内可以包含变量声明、赋值、分支、循环等语句,2、局部标识符,主要用于限制标识符的作用域,避免名字冲突。其声明必须在语句块的开始,形式如下:,当宏定义中有循环判断时,使用比较方便,如:,3、内嵌函数,gcc的语法中支持函数内定义新函数,该函数的名字在该语句块内有效,也可通过指针传递到该语句块之外,这种新函数

8、称为内嵌函数。内嵌函数可以访问所在语句块的所有变量。,4、类型引用,在gcc语法中可以利用typeof获取表达式的类型,这主要用于定义与某一表达式或类型相同的变量,这在编写支持多种数据类型的通用函数时特别有用,典型用法如下:,5、条件语句可以省略操作数,这是指“?:”语句的中间操作数可以省略,如:等同于这种使用主要用于消除宏定义中两次使用宏变量的不安全隐患。,6、64位整数 gcc添加了64位类型:long long int。该类型的常数使用LL或LLU后缀。 7、复数 gcc添加了复数类型,声明时使用_complex_关键字。如:,8、零长数组,gcc支持零长度的数组,它在定义变长对象的头部

9、非常有效,不用像ANSI C数组长度必须大于零,既浪费空间,又不方便数组长度处理,典型用法如:,9、变长数组,gcc在声明数组时,长度可以是一变量。它的好处不言而喻,如:,10、数组和结构的构造器,gcc数组和结构的构造器可以采用灵活多样的形式,如此,编写代码省事,而且明了,例如:,11、Case语句的标识符,gcc支持如下的case语句标识符描述:和,12、内联函数,gcc支持内联函数。它使用inline描述符,主要用于提高软件性能,与宏定义相当,但增加了类型检测的安全性。如:需要注意的是,内联函数使用不当可能适得其反。如果函数体内的代码比较长,使用内联将导致内存消耗代价较高,不易使用。如果

10、函数体内出现循环,那么执行函数体内代码的时间要比函数调用的开销大,使用效果不明显。,13、行内汇编语句,gcc支持行内汇编语句,使用asm关键字,如:和关于这部分内容将在8.5节中详细讲解。,14、函数名字符串,gcc预定义了两字符串变量:_FUNCTION_和_PRETTY_FUNCTION_,用于获得当前函数的名字。这给调试带来很大方便,如:结果输出为:但注意,它们是字符串变量,而不是宏。,15、数据对齐特性查询,gcc支持使用关键字_alignof_查询某数据类型的对齐特性,这在编写多平台系统时特别有用,如:,二、 C51扩展ANSI C最主要是用于32位等高端处理器,使用到8位低端处理

11、器上必须进行许多相应限制和扩展,其中最主要的是关于内存存储模式、内存寻址等方面的扩展和限制。这些主要扩展有:1)存储类型2)数据类型3)指针4)函数属性,1、存储类型1)程序存储区2)内部数据存储区3)外部数据存储区4)扩展存储区5)特殊功能寄存器(SFR)存储区,Cx51所用存储标识符,2、数据类型 Cx51 编译器中独有的数据类型,1)BIT 类型bit 变量和bit 声明有如下限制:A)禁止中断的函数(#pragma disable)和用一个明确的寄存器组using n 声明的函数不能返回一个位值。B)一个位不能被声明为一个指针,例如:C)不能用一个bit类型的数组,例如:,bit类型例

12、子:,2)sfrSFR和别的C变量一样声明,唯一的不同点是,数据类型是sfr,而不是char 或int。例如:,3)sfr16许多新的8051派生系列,用两个连续地址的SFR来指定16位值,为此Cx51编译器提供sfr16数据类型,访问一个16位SFR,只能低字节跟着高字节,低字节用做sfr16 声明的地址,例如:,4)sbitCx51编译器用sbit 数据类型使这变为可能,它可访问可位寻址的SFR 和别的位可寻址的目标,例如:声明定义中,地址前5位为以字节为内存单元的绝对地址,后3位为该字节的位地址。因此,不是所有的SFR 都是可位寻址,只有地址可被8 整除的SFR 才可位寻址。,3、指针类

13、型Cx51 编译器用*字符支持变量指针的声明,Cx51编译器提供两个类型的指针:通用指针和指定存储区指针。 1)通用指针第一个字节是存储类型,第二个是偏移的高字节,第三是偏移的低字节,通用指针可访问8051 存储空间内的任何变量。,2)指定存储区的指针在指针的声明中,经常包含一个存储标识符,指向一个确定的存储区因为存储类型在编译时是确定的,通用指针所需的存储类型字节在指定存储区的指针是不需要的,idata、data、bdata和pdata存储区指针只用一个字节,code和xdata指针只用两字节。,指针的类型转化,4、函数属性Cx51 编译器扩展了标准C 函数,这些扩展有:可指定一个函数作为一

14、个中断函数可选择所用的寄存器组可选择存储模式可指定重入Cx51 函数声明标准格式:,1)函数参数寄存器与参数的对应关系,下面例子说明如何选择传递参数的寄存器: A)func1(int a):唯一一个参数a在寄存器R6和R7传递; B)func2(int b,int c,int*d):第一个参数b在寄存器R6和R7传递,第二个参数c在寄存器R4和R5传递,第三个参数d在寄存器R1、R2和R3传递; C)func3(long e,long f):第一个参数e在寄存器R4、R5、R6和R7传递,第二个参数f 不能用寄存器,因为long类型可用的寄存器已被第一个参数所用,这个参数用固定存储区传递; D

15、)func4(float g,char h):第一个参数g在寄存器R4、R5、R6和R7中传递,第二个参数h不能用寄存器传递,用固定存储区传递。,2)函数返回值 函数返回值通常用CPU寄存器传递函数的返回值类型及其对应的寄存器,3)指定函数的存储模式函数的参数和局部变量保存在由存储模式指定的缺省存储空间中,对单个函数可以在函数声明中用small、compact或large声明来指定存储模式。 4)可重入函数每个可重入函数,对应一个模拟的堆栈区,实现函数重入,其堆栈的存储位置由存储模式决定:A) SMALL 模式可重入函数在idata 存储区模拟可重入堆栈;B) COMPACT 模式可重入函数在

16、pdata 存储区模拟可重入栈;C) LARGE 模式可重入函数在xdata 存储区模拟可重入堆栈。用reentrant 属性声明的可重入函数还有限制规则,5)中断函数Cx51 编译器支持32 个中断函数,使用interrupt 函数属性声明,interrupt函数属性的参数为0到31的整常数值。,6)指定一个函数的寄存器组Cx51编译器扩展关键字using,专门用来选择805l单片机中不同的工作寄存器组。缺省的Cx51 编译器用绝对地址访问寄存器R0R7,这可得到最高性能,绝对寄存器访问由AREGS 和NOAREGS 控制命令控制。为了使函数对当前寄存器组不受影响函数,必须用NOAREGS

17、控制命令编译。,using 函数属性用来指定一个函数所用的寄存器组,using属性为一个0到3的整常数,带操作数的表达式是不允许的,using 属性在函数原型也不允许,using 属性影响如下的函数的目标代码:A) 在函数入口保存当前选择的寄存器组在堆栈中;B) 设置指定的寄存器组;C) 在函数出口恢复前面的寄存器组。使用关键字using在函数中确定一个工作寄存器组时要保证任何寄存器组的切换都只在仔细控制的区域内发生。另外还要注意,带using属性的函数原则上不能返回bit类型的值。并且关键字using不允许用于外部函数。,三、浮点运算支持嵌入式处理器处理能力的限制,有相当多的处理器并不支持浮

18、点运算如sin(x)、cos(x)、a/b等在实际的工程中使用了多种解决方案1)增加浮点协处理器2)使用专门的浮点运算支持库3)自定义函数,8.4 C与汇编混合编程,在线汇编C与汇编的混合调用,一、在线汇编嵌入式开发中,为了代码优化,常常需要在C代码中嵌入汇编代码,称为在线汇编或行内汇编。为此,gcc提供了专门的关键字asm,可以非常简单、方便地在C代码中嵌入汇编代码。在线汇编的基本格式是:,在线汇编的输出部分、输入部分和改变部分有严格的顺序。改变部分如果为空,可以省略不写;输出和输入部分不能省略,但可以为空。,经解释后的等效汇编代码为:,从等效的汇编代码不难看出,这几条语句的功能是向buf中

19、写上count个value值。,二、C与汇编的混合调用考虑到汇编语言也可编写子程序,而子程序的实现与C语言子程序类似可以将汇编子程序直接使用于C语言程序中,只是对汇编程序设计有少许限制。,1、变量与函数 汇编程序中可以直接使用C程序中定义的变量和函数,前提是在调用它们的汇编程序中预先声明为外部变量和函数,格式为:值得注意的是,variablename和functionname之前的下划线”_”必须存在,这是表明该变量或函数符合汇编语言的约束。,2、参数传递嵌入式C语言编译器处理函数参数传递方式有很多,如堆栈、寄存器、固定内存区等,如使用堆栈,也存在从左到右和从右到左两种不同压栈顺序,如使用寄存

20、器,则必须明确寄存器使用方法。C函数参数的入栈次序是从右向左,再加上返回地址,它决定了汇编程序中的使用次序。,例如,一个C程序中使用的汇编函数,反过来,当在汇编子程序中要使用C程序传递来的参数时,必须在汇编子程序开始部分包含两条汇编命令其目的是保存当前的BP寄存器,然后将堆栈栈顶SP赋值给BP,作为基准寄存器访问栈内的参数,如图8.2所示。在汇编子程序结束前,同样必须有指令,3、汇编子程序的返回值C与汇编语言的函数和变量编译后其实都对应一个符号表中的标识符,只要对外部函数和变量使用extern声明,或者汇编向外提供全局的函数和变量,链接工具就可以实现链接。一般来讲,当被调用汇编子程序返回值给调

21、用它的C程序时,寄存器AX和DX被用于传递返回值。,8.5 嵌入式Java,Java发展概况Java技术框架 嵌入式Java程序设计 嵌入式Java的相关问题 嵌入式Java典型应用,一、Java发展概况Java技术取得发展重要的原因:1) Java 可以创建于平台无关的应用软件。2) Java 提供一个受保护的环境,从网络上下载的程序可以以不同的安全级别运行,为系统提供尽可能高的安全保障。3) Java程序中不会出现一些有害的代码,如内存泄漏,保障了程序的健壮性。4) Java 程序以Class文件保存,这种文件体积小,便于程序在网络上传输,使软件更新变得更容易。5) Java 通过对象序列

22、化的API和RMI实现了同时在网络上传递代码和对象,为分布式系统编程创造了新模型,有效的把面向对象编程的优点带到了网络上。,二、Java技术框架整体上看,Java技术包括包括四个独立但相关的组成部分,即Java 程序设计语言、Java Class文件、Java应用程序编程接口(API)和Java 虚拟机。,1、Java 虚拟机Java面向网络的核心就是Java虚拟机(Java Virtual Machine,JVM),它支持面向网络体系结构的三大支柱的所有方面:平台无关性、安全性和网络移动性。 JVM的主要任务是装载class文件并且执行其中的代码。 JVM支持Java语言的各种基本数据类型,

23、包括byte、short、int、long、float、double、char、object、returnAddress等。,2、Java类文件Java类文件(Java class)主要在平台无关性和网络移动性方面使Java更适合于网络1)类文件是一种独立于底层主机平台的二进制文件形式,称为字节码文件,JVM上的指令和数据类型均以字节码形式体现。2)类文件设计紧凑,可以快速的在网上传输。3)由于Java程序是动态连接和扩展的,类文件可以在需要的时候才下载。,3 、Java应用编程接口Java应用编程接口是运行库的集合,它提供一套访问主机系统资源的标准方法。Java API的类文件天生就与主机平

24、台密切相关。,4、 Java 程序设计语言1) 面向对象2) 简单性3) 安全性4) 多线程5) 垃圾回收6) 动态性7) Java Applet8) 丰富的类库,三、嵌入式Java程序设计 1、编写Java代码嵌入式Java属于Java语言的一种特例,编写程序具有明显的面向对象特征,Java程序的共同特性:1) 关键字2) 类3) 类定义4) 执行入口5) 结构控制,2、Java程序结构1) 软件文件名称2) 输入3) 类声明4) 类成员定义5) 类函数A) 函数声明B) 函数变量C) 函数代码,假定WarnTimer是告警定时器类,WarnMsg是告警信息类,测试定时器功能的Java类:,

25、四、 嵌入式Java的相关问题 1、应用领域及成本限制对需要不断与用户通信联系,根据用户要求进行有效管理的便携系统,如手机和PDA,特别适合使用Java编程。但对于需要管理中断来完成重要任务的应用系统和轻型、高效、任务重要、时间确定性要求极高的系统不宜选用Java进行开发;嵌入式Java的使用有时还需要考虑成本问题,Java的使用需要耗费更多的资源,如存储器。,2、加快解析速度对于嵌入式应用而言,常用的Java解析器Java Applet的执行速度太慢。解决方法:超前编译(ahead-of-time,AOT)。 3、减少内存使用解决的两种途径。一是使用AOT编译器协助解决;二是自己开发专用的J

26、ava库。 4、解决时间不确定性解决这个问题主要有:1,改进回收算法 2,采用不同的编程技巧,5、嵌入式Java典型应用1、Java手机2、互联网电视3、 Java智能卡智能卡是一种嵌入计算机芯片的卡片,广泛应用于通信、交通、金融、证券和保险等领域。,8.6 编程规范,模块划分和文件组织 源文件 头文件 程序书写规范 数据类型 命名方法表达式和基本语句 内存使用,一、 模块划分和文件组织1) 每个子模块的源程序分别在不同的目录; 2) 每个子模块必须能在只使用一定的外部头文件的条件下就能被编译。 3) 子模块对外提供的头文件引用只能有一个,只需要在程序中用#include “filename”

27、的方式引用一个头文件; 4) 编程者必须清楚地知道哪些头文件是可以对外的,哪些头文件只能对内,哪些头文件既能对内又能对外。,二、源文件源文件用来定义各种宏、变量、函数以及声明各种外部变量、外部函数。,版权 信息,模块 信息,三、 头文件头文件(即H文件)用于定义各种宏、数据结构类型、外部变量和全局函数的声明等。 四、 程序书写规范1) 使用空行 2) 一行代码只做一件事情3) 使用空格 4) 分界符使用5) 代码行控制6) 注释,五、数据类型编写跨平台或便于移植的软件时一般不使用语言本身的基本数据类型,而是采用重定义的方法处理,以方便以后移植。,六、 命名方法,功能模块名缩写 为BSP的宏定义

28、,功能模块名缩写 为BSP的常数,功能模块名缩写 为BSP的全局变量,模块变量,局部变量,前缀为fn的 全局函数,局部函数,自定义的结构命名 前缀改为“T_”,七、表达式和基本语句表达式和基本语句应以清晰易懂为标准。 八、内存使用内存使用一般分三种:静态存储区、堆(heap)和栈(stack),全局变量、常量和static变量是在静态存储区,malloc和new等动态分配内存是在堆里分配,局部变量、中断切换保存的上下文以及部分编译器支持的快速内存分配是在栈上分配。,小结嵌入式系统是一个软硬/件一体化的系统,本章针对嵌入式软件开发的硬件相关性,叙述了常用的嵌入式软件开发的编程工具,包括了适用于硬

29、件驱动与设置的汇编语言、操作系统扩展开发的C语言、跨平台中间件编程语言Java等,并介绍了运用这些工具开发嵌入式系统的常用编程技巧,规范编程行为。,思考题 1) 什么是程序设计语言?程序设计语言应该包含哪些内容? 2) 在开发嵌入式软件时,应该如何选择合适的程序设计语言? 3) 简述Java语言的编程框架。 4) Java程序设计语言具有哪些特色? 5) 在嵌入式环境下使用Java,应该解决哪些问题? 6) 用汇编语言编写一个计算N!程序。,7) 用C语言编写一个计算sin(x)的程序。要求: 8) 不允许使用C语言的标准库函数; 9) 假定嵌入式处理器不支持浮点运算,即必须使用整数计算。 10) 将计算N!的汇编程序改写成一个子程序,用C或Java语言编写显示主程序,并在主程序中调用汇编子程序,显示计算结果。 11) 编写一个简单的C语言函数,有两个参数和一个返回值(类型可自己定义),用汇编程序调用它。 12) 编写一个简单的Java应用程序,分析该程序在嵌入式环境使用时可能产生的问题。 13) 良好的编程习惯是获得高质量软件的基础。请查阅相关资料,规划一套符合自己编程习惯、方便他人理解的编程准则。,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 高等教育 > 大学课件

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报