1、嵌入式系统软件基础嵌入式系统软件基础博创兴业公司博创兴业公司 2005 博创科技北北 京京 博博 创 兴 业 科科 技技 有有 限限 公公 司司BEIJNG UNIVERSAL PIONEERING TECHNOLOGY Co.,LTD博创科技 嵌入互动23第一章、嵌入式系统软件概述第一章、嵌入式系统软件概述1 13 32 24 4嵌入式软件体系结构嵌入式软件体系结构设备驱动程序设备驱动程序嵌入式操作系统嵌入式操作系统嵌入式中间件嵌入式中间件5 5嵌入式嵌入式C程序设计程序设计41.1 1.1 嵌入式软件体系结构嵌入式软件体系结构l无操作系统的情形无操作系统的情形在嵌入式系统的发展初期,由于硬
2、件的配置在嵌入式系统的发展初期,由于硬件的配置比较低,对于是否有系统软件的支持,要求比较低,对于是否有系统软件的支持,要求还不是很强烈。在那个阶段,嵌入式软件的还不是很强烈。在那个阶段,嵌入式软件的设计主要是以应用为核心,应用软件直接建设计主要是以应用为核心,应用软件直接建立在硬件上,没有专门的操作系统。立在硬件上,没有专门的操作系统。l有操作系统的情形有操作系统的情形5无操作系统的情形无操作系统的情形l循环轮询系统:(循环轮询系统:(Polling Loop)l最简单的软件结构,程序依次检查系统的每个最简单的软件结构,程序依次检查系统的每个输入条件,一旦条件成立就进行相应的处理。输入条件,一
3、旦条件成立就进行相应的处理。Initialize();while(1)if(condition_1)action_1();if(condition_2)action_2();if(condition_n)acition_n();6l事件驱动系统:(事件驱动系统:(Event-Driven system)l事件驱动系统是能对外部事件直接响应的系统。事件驱动系统是能对外部事件直接响应的系统。它包括前后台、实时多任务、多处理器等,是它包括前后台、实时多任务、多处理器等,是嵌入式实时系统的主要形式。嵌入式实时系统的主要形式。l应用程序是一个无限循环,循环中调用相应的应用程序是一个无限循环,循环中调用相
4、应的函数完成相应操作,这部分可以看成后台行为函数完成相应操作,这部分可以看成后台行为(background)。中断服务程序处理异步事)。中断服务程序处理异步事件,这部分可看成前台行为(件,这部分可看成前台行为(foreground)。l后台也可以叫做任务级,前台也叫中断级。后台也可以叫做任务级,前台也叫中断级。7l例如,很多基于微处理器的产品采用前后例如,很多基于微处理器的产品采用前后台系统设计,如微波炉、电话机、玩具等。台系统设计,如微波炉、电话机、玩具等。从省电的角度出发,平时微处理器处在停从省电的角度出发,平时微处理器处在停机状态,所有的事都靠中断服务来完成。机状态,所有的事都靠中断服务
5、来完成。8前后台系统(后台循环、前台中断)前后台系统(后台循环、前台中断)ISRISR后台后台 前台前台ISR时间时间9有操作系统的情形有操作系统的情形硬件板级初始化设备驱动层以太网驱动串口驱动LCD驱动键盘驱动操作系统层中间件层应用软件层TCP/IP网络系统文件系统内核嵌入式GUI嵌入式CORBA嵌入式JAVA嵌入式DCOM面向领域的中间件WWW浏览器MP3播放器电子邮件10l为什么要有设备驱动程序?为什么要有设备驱动程序?嵌入式硬件设备本身无法工作,需要软件来嵌入式硬件设备本身无法工作,需要软件来驱动,如初始化、控制、数据读写等。驱动,如初始化、控制、数据读写等。l什么是设备驱动程序?什么
6、是设备驱动程序?直接与硬件打交道、对硬件进行控制和管理直接与硬件打交道、对硬件进行控制和管理的软件。的软件。l在一个嵌入式系统中,设备驱动程序是在一个嵌入式系统中,设备驱动程序是必不可必不可少少的。的。1.2 设备驱动程序设备驱动程序1112设备驱动程序的结构设备驱动程序的结构硬件上层接口-硬件接口设备驱动程序分层结构硬件上层接口硬件接口设备驱动程序混合结构131.3 嵌入式操作系统嵌入式操作系统l嵌入式操作系统包括嵌入式内核、嵌入嵌入式操作系统包括嵌入式内核、嵌入式式TCP/IP网络系统、嵌入式文件系统、网络系统、嵌入式文件系统、嵌入式嵌入式GUI系统和电源管理等部分;系统和电源管理等部分;
7、l嵌入式内核是基础和核心,其他部分要嵌入式内核是基础和核心,其他部分要根据嵌入式系统的需要来确定。根据嵌入式系统的需要来确定。141.4 嵌入式中间件嵌入式中间件l中间件中间件(Middleware):在):在OS内核、设备驱内核、设备驱动程序和应用软件之外的所有系统软件;动程序和应用软件之外的所有系统软件;l中间件的基本思路:把原本属于应用软件层的中间件的基本思路:把原本属于应用软件层的一些通用的功能模块抽取出来,形成独立的一一些通用的功能模块抽取出来,形成独立的一层软件,从而为运行在其上的各个应用软件提层软件,从而为运行在其上的各个应用软件提供一个灵活、安全、移植性好、相互通信、协供一个灵
8、活、安全、移植性好、相互通信、协同工作的平台;同工作的平台;l优点:实现软件的可重用,降低应用软件的复优点:实现软件的可重用,降低应用软件的复杂性,降低开发成本。杂性,降低开发成本。15中间件的基本思路:把原本属于应用软件层的一些通用的功能模块抽取出来,形成独立的一层软件,从而为运行在其上的各个应用软件提供一个灵活、安全、移植性好、相互通信、协同工作的平台;call _bar#如果相同,调用bar()函数/把第3位设置为0C语言有很多位操作运算符:$L5:#case 5if-then-else语句的汇编代码jmp$ENDcall _fooint Times2(int value);main()
9、int number;printf(“请输入一个整数:”);scanf(“%d”,&number);printf(“该数的两倍是:%d”,Times2(number);case 3:cee();break;myShoes+;“which of the following programming languageshave you used for embedded systems in the last12 months”OperatorTimeOperatorTime+(int)1+(double)140*(int)1*(double)110/(int)7/(double)220 80.0)
10、myShoes+;myMoney=myMoney 80.0;#define COST_OF_SHOES 80.0if(myMoney COST_OF_SHOES)myShoes+;myMoney=myMoney COST_OF_SHOES;不用不用此法此法一次一次定义定义多次多次使用使用20(2)const常量常量 常量数据:整数(常量数据:整数(12)、字符()、字符(a)、)、字符串(字符串(“hello”)和实数()和实数()等;)等;以变量的形式来定义的一个量,并且通以变量的形式来定义的一个量,并且通 过使用关键字过使用关键字const,来表明这个变量的,来表明这个变量的 值不能被改变
11、如:值不能被改变。如:const int x =1。21指针与常量:指针本身是常量;指针指向的变量是常量指针与常量:指针本身是常量;指针指向的变量是常量.void test(char *p)char s =“hello”;const char *pc =s;/正确正确,指向常量字符,指向常量字符 pc3 =g;/错误错误,常量不能被修改常量不能被修改 pc =p;/正确正确,指针本身可以变指针本身可以变 char *const cp =s;/正确正确,指针本身是常量,指针本身是常量 cp3=a;/正确正确,指针指向的是变量指针指向的是变量 cp =p;/错误错误,指针本身是常量指针本身是常量
12、2223(3)算术运算)算术运算整数的算术运算整数的算术运算最快最快带有硬件支持的浮点运算带有硬件支持的浮点运算较慢较慢用软件来实现的浮点运算用软件来实现的浮点运算非常慢非常慢,快快sqrt,sin,log,etc慢慢24for(i=0;i 10000;+i)/*各种算术运算操作各种算术运算操作*/实验平台:桌面实验平台:桌面Intel Pentium4,带硬件浮点支持,带硬件浮点支持OperatorTimeOperatorTime+(int)1+(double)5*(int)5*(double)5/(int)12/(double)10(int)2sqrt28sin48pow275小实验小实验
13、125实验平台:实验平台:400MHz Intel PXA250 Xscale(ARM)处处理器理器OperatorTimeOperatorTime+(int)1+(double)140*(int)1*(double)110/(int)7/(double)220(int)1sqrt500sin3300pow820小实验小实验226结论:结论:尽量使用整数(尽量使用整数(char、short、int和和long)的加)的加法和减法;法和减法;如果没有硬件支持,尽量避免使用乘法;如果没有硬件支持,尽量避免使用乘法;尽量避免使用除法;尽量避免使用除法;如果没有硬件支持,尽量避免使用浮点数;如果没有硬
14、件支持,尽量避免使用浮点数;数学库函数使用得越少越好。数学库函数使用得越少越好。27重复重复10700次,右边需要次,右边需要1 1毫秒,左边需要毫秒!毫秒,左边需要毫秒!struct int a;char b;int c;foo10;int i;for(i=0;ia=77;fp-b=88;fp-c=99;28(4)位运算)位运算C语言有很多位操作运算符:语言有很多位操作运算符:&与操作;与操作;|或操作;或操作;异或操作;异或操作;取反操作;取反操作;右移操作;右移操作;左移操作。左移操作。29a|=0 x4b&=0 x4c&=(1 3)d=(1=2/把第把第2位设置为位设置为1/把第把第2
15、位设置为位设置为0/把第把第3位设置为位设置为0/把第把第5位反转位反转/把把 e 除以除以430int x,num=99,count=0;x=num;while(x)count+;x=x&(x 1);printf(result:%d,count);result:4311.5.2 分支语句分支语句if(a=1)ant();else if(a=2)bar();else if(a=3)cee();else if(a=4)due();else if(a=5)eat();else if(a=6)foo();switch(a)case 1:ant();break;case 2:bar();break;c
16、ase 3:cee();break;case 4:due();break;case 5:eat();break;case 6:foo();break;Any Differences?32if-then-else语句的汇编代码语句的汇编代码$L1:cmp dword ptrebp-4,1#把把a与常量与常量1进行进行比较比较 jne$L2#如果不相同,跳到如果不相同,跳到$L2继续比较下继续比较下一个值一个值 call _ant#如果相同,调用如果相同,调用ant()函数函数 jmp$END#跳转到这段代码的末尾跳转到这段代码的末尾$L2:cmp dword ptrebp-4,2#把把a与常量与
17、常量2进行比较进行比较 jne$L3#如果不相同,跳到如果不相同,跳到$L3继续比较下继续比较下一个值一个值 call _bar#如果相同,调用如果相同,调用bar()函数函数 jmp$END#跳转到这段代码的末尾跳转到这段代码的末尾$L3:.$END:33switch语句的汇编代码语句的汇编代码-1 JmpTable dword$L1,$L2,$L3,$L4,$L5,$L6 mov eax,dword ptr ebp-4#取出变量取出变量a的值的值 mov dword ptr ebp-8,eax#保存在临时变量中保存在临时变量中 mov ecx,dword ptr ebp-8#取出,放在取出
18、放在ecx中中 sub ecx,1#减减1 mov dword ptr ebp-8,ecx#保存回去保存回去 cmp dword ptr ebp-8,5#与与5进行比较进行比较 ja$END#若大于若大于5,结束,结束 mov edx,dword ptr ebp-8#取出该值,放取出该值,放edx jmp dword ptr edx*4+JmpTable#跳转到相应的跳转到相应的#case标记标记34switch语句的汇编代码语句的汇编代码-2$L1:#case 1 call _ant jmp$END$L2:#case 2 call _bar jmp$END.$L5:#case 5 call
19、 _eat jmp$END$L6:#case 6 call _foo$END:35结论:结论:假设假设a的取值个数为的取值个数为n,对于,对于if-then-else语句,语句,时间复杂度为时间复杂度为O(n),而对于,而对于switch语句,时间复语句,时间复杂度为杂度为O(1);如果如果n的值较小,两种语句均可;的值较小,两种语句均可;如果如果n的值较大,则的值较大,则switch语句更佳。语句更佳。361.5.3 函数函数函数原型函数原型main()函数函数调用用 函数定函数定义函数的使用模式函数的使用模式声明该函数声明该函数定义一个函数定义一个函数使用该函数使用该函数37操作系统操作系
20、统代码代码栈帧栈帧2栈帧栈帧1全局变量全局变量内内存存分分布布状状况况全局变量区域全局变量区域静态分配静态分配栈栈自动分配自动分配堆堆动态分配动态分配38主函数的执行过程主函数的执行过程int z;void main()int x,y;x =1;y =2;z =x+y;main()z =0全局变量区域全局变量区域栈帧栈帧(main)x =y =程序程序12339控制流与数据流控制流与数据流控制流控制流:程序当前执行位置的流向;:程序当前执行位置的流向;数据流数据流:函数调用发生及结束时,数据在:函数调用发生及结束时,数据在 函数之间流转的过程。函数之间流转的过程。40当一个函数被调用时:当一个
21、函数被调用时:1.在内存的栈空间当中为其分配一个栈帧,用来在内存的栈空间当中为其分配一个栈帧,用来存放该函数的形参和局部变量存放该函数的形参和局部变量;2.把实参变量的值复制到相应的形参变量;把实参变量的值复制到相应的形参变量;3.控制转移到该函数的起始位置;控制转移到该函数的起始位置;4.该函数开始执行;该函数开始执行;5.控制流和返回值返回到函数调用点。控制流和返回值返回到函数调用点。函数调用过程函数调用过程41控制流的变化控制流的变化void main()double x,y,z;y =6.0;x =Area(y/3.0);.z =3.4*Area(7.88);./*给定半径,定半径,计
22、算一算一个个圆的面的面积*/double Area(double r)return(3.14*r*r);42一个简单的例子一个简单的例子int Times2(int value);int Times2(int value);main()main()int number;int number;printf(“printf(“请输入一个整数:请输入一个整数:”);”);scanf(“%d”,&number);scanf(“%d”,&number);printf(“printf(“该数的两倍是:该数的两倍是:%d”,%d”,Times2(number)Times2(number););int Tim
23、es2(int value)int Times2(int value)return(2*value);return(2*value);mainnumber343int Times2(int value);int Times2(int value);main()main()int number;int number;printf(“printf(“请输入一个整数:请输入一个整数:”);”);scanf(“%d”,&number);scanf(“%d”,&number);printf(“printf(“该数的两倍是:该数的两倍是:%d”,Times2(number);%d”,Times2(numb
24、er);int Times2(int value)int Times2(int value)return(2*value);return(2*value);mainnumber3Times2valueTimes2也得到一也得到一个栈帧个栈帧,它的参数看成局部它的参数看成局部变量量44int Times2(int value);int Times2(int value);main()main()int number;int number;printf(“printf(“请输入一个整数:请输入一个整数:”);”);scanf(“%d”,&number);scanf(“%d”,&number);pr
25、intf(“printf(“该数的两倍是:该数的两倍是:%d”,Times2(number);%d”,Times2(number);int Times2(int value)int Times2(int value)return(2*value);return(2*value);mainnumber3Times2value3“值传递”,把把实参的参的值传给形参。形参。45int Times2(int value);int Times2(int value);main()main()int number;int number;printf(“printf(“请输入一个整数:请输入一个整数:”);
26、);scanf(“%d”,&number);scanf(“%d”,&number);printf(“printf(“该数的两倍是:该数的两倍是:%d”,Times2(number);%d”,Times2(number);int Times2(int value)int Times2(int value)return(2*value);return(2*value);main3把把Times2的的栈帧栈帧叠在主叠在主函数的函数的栈帧栈帧之上,之上,说明明在在执行行Times2函数函数时,主函数中的主函数中的变量是不可量是不可见的。的。Times2value346int Times2(int v
27、alue);int Times2(int value);main()main()int number;int number;printf(“printf(“请输入一个整数:请输入一个整数:”);”);scanf(“%d”,&number);scanf(“%d”,&number);printf(“printf(“该数的两倍是:该数的两倍是:%d”,Times2(number);%d”,Times2(number);int Times2(int value)int Times2(int value)return(2*value);return(2*value);mainnumber36Times2
28、函数的返回函数的返回值被被放在函数的放在函数的调用位置上,用位置上,然后,分配然后,分配给Times2函函数的堆数的堆栈区域被区域被释放。放。47变量的存储与作用域变量的存储与作用域/*全局变量,固定地址,其他源文件可见全局变量,固定地址,其他源文件可见*/int global_static;/*静态全局变量,固定地址,但只在本文件中可见静态全局变量,固定地址,但只在本文件中可见*/static int file_static;/*函数参数:位于栈帧当中,动态创建,动态释放函数参数:位于栈帧当中,动态创建,动态释放*/int foo(int auto_param)/*静态局部变量,固定地址,只
29、在本函数中可见静态局部变量,固定地址,只在本函数中可见*/static int func_static;/*普通局部变量,位于栈帧当中,只在本函数可见普通局部变量,位于栈帧当中,只在本函数可见*/int auto_i,auto_a10;/*动态申请的内存空间,位于堆当中动态申请的内存空间,位于堆当中*/double*auto_d=malloc(sizeof(double)*5);return auto_i;48各个变量的内存地址各个变量的内存地址auto_d0 x004300d0main函数函数0 x00401070global_static0 x004225a4file_static0 x0
30、042259cfunc_static0 x004225a0auto_param0 x0012ff30auto_i0 x0012ff24auto_a0 x0012fefc49可重入函数可重入函数-1可以被一个以上的任务调用,而不必担心数据的破坏。可以被一个以上的任务调用,而不必担心数据的破坏。可重入型函数任何时候都可以被中断,一段时间以后又可可重入型函数任何时候都可以被中断,一段时间以后又可以运行,而相应数据不会丢失。可重入型函数只使用局部以运行,而相应数据不会丢失。可重入型函数只使用局部变量,即变量保存在变量,即变量保存在CPUCPU寄存器或栈中。寄存器或栈中。一个不可重入型函数的例子一个不可重入型函数的例子int temp;void swap(int*x,int*y)temp=*x;*x=*y;*y=temp;50可重入函数可重入函数-2一个可重入型函数的例子一个可重入型函数的例子void swap(int*x,int*y)int temp;temp=*x;*x=*y;*y=temp;51谢谢 谢谢 各各 位位
©2010-2025 宁波自信网络信息技术有限公司 版权所有
客服电话:4009-655-100 投诉/维权电话:18658249818