好文档就是一把金锄头!
欢迎来到金锄头文库![会员中心]
电子文档交易市场
安卓APP | ios版本
电子文档交易市场
安卓APP | ios版本

语言嵌入式开发ppt课件.ppt

34页
  • 卖家[上传人]:cn****1
  • 文档编号:588805911
  • 上传时间:2024-09-09
  • 文档格式:PPT
  • 文档大小:126KB
  • / 34 举报 版权申诉 马上下载
  • 文本预览
  • 下载提示
  • 常见问题
    • C言语嵌入式开发 纲要•嵌入式C开发背景引见•硬件平台和交叉编译环境•软件构造设计•内存操作•屏幕操作•键盘操作•性能优化 背景•不同于普通方式的软件编程,嵌入式系统编程建立在特定的硬件平台上,势必要求其编程言语具备较强的硬件直接操作才干无疑,汇编言语具备这样的特质但是,由于汇编言语开发的复杂性,它并不是嵌入式系统开发的普通选择而与之相比,C言语--一种"高级的低级"言语,那么成为嵌入式系统开发的最正确选择 硬件平台 •〔1〕 以通用途置器为中心的协议处置模块,用于网络控制协议的处置;〔2〕 以数字信号处置器〔DSP〕为中心的信号处置模块,用于调制、解调和数/模信号转换 硬件阐明•CPU:80186字长是16位,可以寻址到的内存空间为1MB•FLASH和RAM几乎是每个嵌入式系统的必备设备,前者用于存储程序,后者那么是程序运转时指令及数据的存放位置系统所选择的FLASH和RAM的位宽都为16位,与CPU一致•实时钟芯片可以为系统定时,给出当前的年、月、日及详细时间〔小时、分、秒及毫秒〕,主要作用是提供中断判决•NVRAM〔非易失去性RAM〕具有掉电不丧失数据的特性,可以用于保管系统的设置信息 •UART那么完成CPU并行数据传输与RS-232串行数据传输的转换•键盘控制器和显示控制器那么完成系统人机界面的控制 交叉编译环境嵌入式系统需求良好的软件开发环境的支持,由于嵌入式系统的目的机资源受限,不能够在其上建立庞大、复杂的开发环境,因此其开发环境和目的运转环境相互分别。

      嵌入式运用软件的开发方式普通是在宿主机(Host)上建立开发环境,进展运用程序编码和交叉编译,然后宿主机同目的机(Target)建立衔接,将运用程序下载到目的机上进展交叉调试,经过调试和优化,将运用程序固化到目的机中实践运转 软件构造设计•模块划分模块划分 •多义务还是单义务多义务还是单义务 •单义务程序典型架构单义务程序典型架构•中断效力程序中断效力程序•硬件驱动模块硬件驱动模块 •C的面向对象化的面向对象化 模块划分•硬件驱动模块,一种特定硬件对应一个模块;•软件功能模块,其模块的划分应满足低巧合、高内聚的要求 硬件驱动模块硬件驱动模块1.中断效力程序ISR2.硬件初始化3.  a.修正存放器,设置硬件参数〔如UART应设置其波特率,AD/DA设备应设置其采样速率等〕;4.  b.将中断效力程序入口地址写入中断向量表:5.3.设置CPU针对该硬件的控制线 6. a.假设控制线可作PIO〔可编程I/O〕和控制信号用,那么设置CPU内部对应存放器使其作为控制信号;7.  b.设置CPU内部的针对该设备的中断屏蔽位,设置中断方式〔电平触发还是边缘触发〕8.4.提供一系列针对该设备的操作接口函数。

      例如,对于LCD,其驱动模块应提供绘制像素、画线、绘制矩阵、显示字符点阵等函数;而对于实时钟,其驱动模块那么需提供获取时间、设置时间等函数 多义务还是单义务多义务还是单义务 所谓"单义务系统"是指该系统不能支持多义务并发操作,宏观串行地执行一个义务而多义务系统那么可以宏观并行〔微观上能够串行〕地"同时"执行多个义务 单义务用于简单的低端硬件平台,比如哑终端之类的,运用死循环处置义务流程多义务用于较高端的平台,如uclinux,Win ce,Vxworks,运用中断调用途置义务流程 单义务程序典型架构单义务程序典型架构1.从CPU复位时的指定地址开场执行;2.跳转至汇编代码startup处执行;3.跳转至用户主程序main执行,在main中完成:a.初试化各硬件设备; b.初始化各软件模块;c.进入死循环〔无限循环〕,调用各模块的处置函数 中断效力程序中断效力程序 中断是嵌入式系统中重要的组成部分,但是在规范C中不包含中断许多编译开发商在规范C上添加了对中断的支持,提供新的关键字用于标示中断效力程序(ISR),类似于__interrupt、#program interrupt等当一个函数被定义为ISR的时候,编译器会自动为该函数添加中断效力程序所需求的中断现场入栈和出栈代码。

      中断效力程序需求满足如下要求:  (1)不能前往值;  (2)不能向ISR传送参数;  (3) ISR应该尽能够的短小精悍;  (4) printf(char * lpFormatString,…)函数会带来重入和性能问题,不能在ISR中采用 C的面向对象化的面向对象化 •#ifndef C_Class#define C_Class struct#endifC_Class A { C_Class A *A_this; /* this指针 */ void (*Foo)(C_Class A *A_this); /* 行为:函数指针 */ int a; /* 数据 */ int b;}; 我们可以利用我们可以利用我们可以利用我们可以利用C C言语模拟出面向对象的三个特性:封装、承继和多态,言语模拟出面向对象的三个特性:封装、承继和多态,言语模拟出面向对象的三个特性:封装、承继和多态,言语模拟出面向对象的三个特性:封装、承继和多态,但是更多的时候,我们只是需求将数据与行为封装以处理软件构造混乱但是更多的时候,我们只是需求将数据与行为封装以处理软件构造混乱但是更多的时候,我们只是需求将数据与行为封装以处理软件构造混乱但是更多的时候,我们只是需求将数据与行为封装以处理软件构造混乱的问题。

      的问题C C模拟面向对象思想的目的不在于模拟行为本身,而在于处理模拟面向对象思想的目的不在于模拟行为本身,而在于处理模拟面向对象思想的目的不在于模拟行为本身,而在于处理模拟面向对象思想的目的不在于模拟行为本身,而在于处理某些情况下运用某些情况下运用某些情况下运用某些情况下运用C C言语编程时程序整体框架构造分散、数据和函数脱节言语编程时程序整体框架构造分散、数据和函数脱节言语编程时程序整体框架构造分散、数据和函数脱节言语编程时程序整体框架构造分散、数据和函数脱节的问题的问题的问题的问题 内存操作篇 •数据指针•函数指针•数组vs.动态恳求•关键字const•关键字volatile•CPU字长与存储器位宽不一致处置 数据指针数据指针 嵌入式编程中需求指针直接操作内存某I/O芯片被定位在CPU的存储空间而非I/O空间,而且存放器对应于某特定地址; 两个CPU之间以双端口RAM通讯,CPU需求在双端口RAM的特定单元〔称为mail box〕书写内容以在对方CPU产生中断读取在ROM或FLASH的特定单元所烧录的汉字和英文字模unsigned char *p = (unsigned char *)0xF000FF00;*p=11; 函数指针1.C言语中函数名直接对应于函数生成的指令代码在内存中的地址,因此函数名可以直接赋给指向函数的指针;2.调用函数实践上等同于“调转指令+参数传送处置+回归位置入栈〞,本质上最中心的操作是将函数生成的目的代码的首地址赋给CPU的PC存放器;3.由于函数调用的本质是跳转到某一个地址单元的code去执行,所以可以"调用"一个根本就不存在的函数实体 typedef void (*lpFunction) ( ); /* 定义一个无参数、无前往类型的 *//* 函数指针类型 */lpFunction lpReset = (lpFunction)0xF000FFF0; /* 定义一个函数指针,指向*//* CPU启动后所执行第一条指令的位置 */lpReset(); /* 调用函数 */ 数组数组vs.动态恳求动态恳求 在嵌入式系统中动态内存恳求存在比普通系统编程时更严厉的要求,这是由于嵌入式系统的内存空间往往是非常有限的,不经意的内存泄露会很快导致系统的解体 所以一定要保证他的malloc和free成对出现 1.尽能够的选用数组,数组不能越界访问;2.假设运用动态恳求,那么恳求后一定要判别能否恳求胜利了,并且malloc和free应成对出现 关键字关键字const 1. 关键字const的作用是为给读他代码的人传达非常有用的信息。

      例如,在函数的形参前添加const关键字意味着这个参数在函数体内不会被修正,属于“输入参数〞在有多个形参的时候,函数的调用者可以凭仗参数前能否有const关键字,明晰的区分哪些是输入参数,哪些是能够的输出参数2.合理地运用关键字const可以使编译器很自然地维护那些不希望被改动的参数,防止其被无意的代码修正,这样可以减少bug的出现 关键字关键字volatilevolatile变量能够用于如下几种情况并行设备的硬件存放器〔如:形状存放器〕;一个中断效力子程序中会访问到的非自动变量(也就是全局变量);多线程运用中被几个义务共享的变量int a,b,c;a = inWord(0x100); /*读取I/O空间0x100端口的内容存入a变量*/b = a;a = inWord (0x100); /*再次读取I/O空间0x100端口的内容存入a变量*/c = a; int a,b,c;a = inWord(0x100); /*读取I/O空间0x100端口的内容存入a变量*/b = a;c = a; CPU字长与存储器位宽不一致处置字长与存储器位宽不一致处置 •,处理CPU字长与存储器位宽不一致的情况。

      80186的字长为16,而NVRAM的位宽为8,在这种情况下,我们需求为NVRAM提供读写字节、字的接口 屏幕操作篇 •·汉字处置•系统时间显示•动画显示•菜单操作 汉字处置•如今要处理的问题是,嵌入式系统中经常要运用的并非是完好的汉字库,往往只是需求提供数量有限的汉字供必要的显示功能 -不知道日文能否有此情况•要显示特定汉字的时候,只需求从数组中查找内码与要求汉字内码一样的即可获得字模假设前面的汉字在数组中以内码大小顺序陈列,那么可以以二分查找法更高效的查找到汉字的字模 •定义宏:# define EX_FONT_CHAR(value) # define EX_FONT_UNICODE_VAL(value) (value),# define EX_FONT_ANSI_VAL(value) (value),定义构造体:typedef struct _wide_unicode_font16x16 { WORD value; /* 内码 */ BYTE data[32]; /* 字模点阵 */}Unicode;#define CHINESE_CHAR_NUM … /* 汉字数量 */•字模的存储用数组:Unicode chinese[CHINESE_CHAR_NUM] ={{EX_FONT_CHAR("业")EX_FONT_UNICODE_VAL(0x4e1a){0x04, 0x40, 0x04, 0x40, 0x04, 0x40, 0x04, 0x44, 0x44, 0x46, 0x24, 0x4c, 0x24, 0x48, 0x14, 0x50, 0x1c, 0x50, 0x14, 0x60, 0x04, 0x40, 0x04, 0x40, 0x04, 0x44, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00}},{EX_FONT_CHAR("中")EX_FONT_UNICODE_VAL(0x4e2d){0x01, 0x00, 0x01, 0x00, 0x21, 0x08, 0x3f, 0xfc, 0x21, 0x08, 0x21, 0x08, 0x21, 0x08, 0x21, 0x08, 0x21, 0x08, 0x3f, 0xf8, 0x21, 0x08, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00}},{EX_FONT_CHAR("云")EX_FONT_UNICODE_VAL(0x4e91){0x00, 0x00, 0x00, 0x30, 0x3f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xff, 0xfe, 0x03, 0x00, 0x07, 0x00, 0x06, 0x40, 0x0c, 0x20, 0x18, 0x10, 0x31, 0xf8, 0x7f, 0x0c, 0x20, 0x08, 0x00, 0x00}},{EX_FONT_CHAR("件")EX_FONT_UNICODE_VAL(0x4ef6){0x10, 0x40, 0x1a, 0x40, 0x13, 0x40, 0x32, 0x40, 0x23, 0xfc, 0x64, 0x40, 0xa4, 0x40, 0x28, 0x40, 0x2f, 0xfe, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40}}} 系统时间显示系统时间显示•留意刷新问题,没有必要每秒刷新一次分钟和小时的显示 动画显示动画显示 •充分利用定时器•留意刷新问题 菜单操作菜单操作 •* 将菜单的属性和操作"封装"在一同 */typedef struct tagSysMenu{ char *text; /* 菜单的文本 */ BYTE xPos; /* 菜单在LCD上的x坐标 */ BYTE yPos; /* 菜单在LCD上的y坐标 */ void (*onOkFun)(); /* 在该菜单上按下ok键的处置函数指针 */ void (*onCancelFun)(); /* 在该菜单上按下cancel键的处置函数指针 */}SysMenu, *LPSysMenu; 利用了面向对象中的封装思想,就让程序构造明晰,其结果是几乎可以在无需修正程序的情况下在系统中添加更多的菜单,而系统的按键处置函数坚持不变。

      键盘操作篇 •处置功能键•处置数字键•处置用户输入• 处置触摸屏 性能优化篇 •·运用宏定义•运用存放器变量•内嵌汇编•利用硬件特性•活用位操作 运用宏定义运用宏定义在C言语中,宏是产生内嵌代码的独一方法对于嵌入式系统而言,为了能到达性能要求,宏是一种很好的替代函数的方法 宏定义“像〞函数;宏定义不是函数,因此需求括上一切“参数〞;宏定义能够产生副作用因此不要给宏定义传入有副作用的"参数" 运用存放器变量运用存放器变量 •当对一个变量频繁被读写时,需求反复访问内存,从而破费大量的存取时间为此,C言语提供了一种变量,即存放器变量这种变量存放在CPU的存放器中,运用时,不需求访问内存,而直接从存放器中读写,从而提高效率存放器变量的阐明符是register对于循环次数较多的循环控制变量及循环体内反复运用的变量均可定义为存放器变量,而循环计数是运用存放器变量的最好候选者  (1) 只需部分自动变量和形参才可以定义为存放器变量由于存放器变量属于动态存储方式,凡需求采用静态存储方式的量都不能定义为存放器变量,包括:模块间全局变量、模块内全局变量、部分static变量;  (2) register是一个"建议"型关键字,意指程序建议该变量放在存放器中,但最终该变量能够由于条件不满足并未成为存放器变量,而是被放在了存储器中,但编译器中并不报错〔在C++言语中有另一个"建议"型关键字:inline〕。

      内嵌汇编内嵌汇编 •程序中对时间要求苛刻的部分可以用内嵌汇编来重写,以带来速度上的显著提高但是,开发和测试汇编代码是一件辛劳的任务,它将破费更长的时间,因此要慎重选择要用汇编的部分  在程序中,存在一个80-20原那么,即20%的程序耗费了80%的运转时间,因此我们要改良效率,最主要是思索改良那20%的代码 利用硬件特性利用硬件特性CPU对各种存储器的访问速度,根本上是:CPU内部RAM > 外部同步RAM > 外部异步RAM > FLASH/ROM 对于程序代码,曾经被烧录在FLASH或ROM中,我们可以让CPU直接从其中读取代码执行,但通常这不是一个好方法,我们最好在系统启动后将FLASH或ROM中的目的代码拷贝入RAM中后再执行以提高取指令速度;对于UART等设备,其内部有一定容量的接纳BUFFER,我们应尽量在BUFFER被占满后再向CPU提出中断例如计算机终端在向目的机经过RS-232传送数据时,不宜设置UART只接纳到一个BYTE就向CPU提中断,从而无谓浪费中断处置时间;假设对某设备能采取DMA方式读取,就采用DMA读取,DMA读取方式在读取目的中包含的存储信息较大时效率较高,其数据传输的根本单位是块,而所传输的数据是从设备直接送入内存的〔或者相反〕。

      DMA方式较之中断驱动方式,减少了CPU 对外设的干涉,进一步提高了CPU与外设的并行操作程度 活用位操作活用位操作 •运用C言语的位操作可以减少除法和取模的运算在计算机程序中数据的位是可以操作的最小数据单位,实际上可以用“位运算〞来完成一切的运算和操作,因此,灵敏的位操作可以有效地提高程序运转的效率举例如下 •* 方法1 */int i,j;i = 879 / 16;j = 562 % 32; /* 方法2 */int i,j;i = 879 >> 4;j = 562 - (562 >> 5 << 5); 嵌入式开发的中心就是利用最少的资源最高效地实现所需功能谢谢大家! 。

      点击阅读更多内容
      关于金锄头网 - 版权申诉 - 免责声明 - 诚邀英才 - 联系我们
      手机版 | 川公网安备 51140202000112号 | 经营许可证(蜀ICP备13022795号)
      ©2008-2016 by Sichuan Goldhoe Inc. All Rights Reserved.