《单片机原理及基于单片机的嵌入式系统设计》_第1页
《单片机原理及基于单片机的嵌入式系统设计》_第2页
《单片机原理及基于单片机的嵌入式系统设计》_第3页
《单片机原理及基于单片机的嵌入式系统设计》_第4页
《单片机原理及基于单片机的嵌入式系统设计》_第5页
已阅读5页,还剩70页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第12章 嵌入式单片机技术C教程基础12.1C51编程基础12.2串行通信与定时程序12.3嵌入式操作系统 嵌入式51系列单片机的编程语言常用的有二种:汇编语言,C51语言。 汇编语言的机器代码生成效率高但可读性不强,而C51语言在大多数情况下其机器代码生成效率和汇编语言相当,但可读性和可移植性却远远超过汇编语言;而且C51语言还可以嵌入汇编来解决高时效性的代码编写问题。中大型的软件编写用C51语言的开发周期通常要小于汇编语言很多。 C语言的标识符用来标识源程序中某个对象名字。这些对象可以是函数、变量、数组、数据类型、存储方式、语句等。关键字是一类具有固定名称和特定含义的特殊标识符,有时又称为

2、保留字。 ANSI C标准一共规定了32个关健字,表12-1按用途列出了ANSI C标准的关键字。 12.1 C51编程基础12.1.1标志符与关键字表12-1 ANSI C标准的关键字 关键字用途说明auto存储器种类声明用以声明局部变量,默认什为此break程度语句退出最内层循环体case程度语句switch语句中的选择项char数据类型声明单字节整型或字符型const存储类型声明在程度执行中不可修改的变量值continue程度语句转向下一次循环default程序语句switch语句中的失败选择项do程度语句构成do.while循环结构double数据类型声明双精度浮点数else程度语句构

3、成if.else选择结构enum数据类型声明枚举extern存储种类声明在其它程度模块中声明了的全局变量float数据类型声明单精度浮点数for程度语句构成for循环结构goto程度语句构成goto转移结构if程度语句构成if.else选择结构int数据种类声明基本整型数long数据种类声明长整型数register数据种类声明使用CPU内部寄存器的变量return程序语句函数返回short数据种类声明短整型数signed数据种类声明有符号数,二进制数的最高位为符号位sizeof运算符计算表达式或数据类型的字节数static数据种类声明静态变量struct数据种类声明结构类型数据switch程序

4、语句构成switch选择结构typedef数据种类声明重新进行数据类型定义union数据种类声明联合类型数据unsigned数据种类声明无符号数据void数据种类声明无类型数据volatile数据种类声明声明该变量在程度执行中可被隐含的改变while程度语句构成while和.while循环结构C51编绎器除了支持ANSI C标准的关键字以外,还扩展了如表12-2所示的关键字: 表12-2 C51编绎器的扩展关键字 关键字用途说明_at_地址定位为变量进行存储器绝对空间地址定位alien函数特殊声明用以声明与PL/M51兼容的函数bdata存储器类型声明可位寻址的8051内部数据存储器bit位变

5、量声明声明一个位变量或位类型的函数code存储器类型声明8051程度存储器空间compact存储器模式指定使用8051外部分页寻址数据存储器空间data存储器类型声明直接寻址的8051内部数据存储器idata存储器类型声明间接寻址的8051内部数据存储器interrupt中断函数声明定义一个中断服务函数large存储器模式指定使用8051外部数据存储器空间pdata存储器类型声明分页寻址的8051外部数据存储器_priority_多任务优先声明规定RTX51或RTX51 Tiny的任务优先级 reentrant再入函数声明定义一个再入函数sbit位变量声明声明一个可位寻址变量sfr特殊功能寄存

6、器声明声明一个8位的特殊功能寄存器sfr16特殊功能寄存器声明声明一个16位的特殊功能寄存器small存储器模式指定使用8051内部数据存储器空间_task_任务声明定义实时多任务函数usang寄存器组定义定义8051的工作寄存器组xdata存储器类型声明8051外部数据存储器 针对51系列单片机各个可操作部分,C51编绎器定义了如表12-3所示的符号,编程时写出符号名,即可操作单片机对应的部分。 表12-3 C51特殊功能寄存器列表符号地址注释*ACCE0H累加器*BF0H乘法寄存器*PSWD0H程序状态字SP81H堆栈指针DPL82H数据存储器指针低8位DPH83H数据存储器指针高8位*I

7、EA8H中断允许控制器*IPD8H中断优先控制器*P080H端口0*P190H端口1*P2A0H端口2*P3B0H端口3PCON87H电源控制及波特率选择*SCON98H串行口控制器SBUF99H串行数据缓冲器*TCON88H定时器控制TMOD89H定时器方式选择TL08AH定时器0低8位TL18BH定时器1低8位TH08CH定时器0低8位TH18DH定时器1高8位带*号的特殊功能寄存器都是可以位寻址的寄存器下面举例说明特殊功能寄存器的操作方法。例1,欲将单片机P1口的第一根口线DIP封装单片机第一管脚设为报警输出线,低电平报警,则在程序中首先可定义:sbit BJ= P10;这就定义了一个变

8、量BJ对应P1口的第一根口线,sbit声明变量BJ是位寻址数据类型。需要报警时,使用语句:BJ= 0;即可令单片机P1口的第一根口线输出低电平,完成报警。当报警完毕,需要撤销报警时,使用如下语句即可恢复到非报警状态:BJ= 1;例2,欲将单片机P1口的第五根口线至第八根口线设置为构成宽度为4位的双向数据总线,使之既可以接收数据又可以发送数据,则在程序中首先可做如下定义:sbit MT8880_D0= P14; / 双向数据总线sbit MT8880_D1= P15; / 双向数据总线sbit MT8880_D2= P16; / 双向数据总线sbit MT8880_D3= P17; / 双向数据

9、总线收数据时,令各口线为高,处于监听状态:MT8880_D0 = 1;MT8880_D1 = 1;MT8880_D2 = 1;MT8880_D3 = 1;当有数据来时,使用如下语句判断、接收数据:if(MT8880_D3=0 & MT8880_D2=0 & MT8880_D1=0 & MT8880_D0=0) Number_Key=0;if(MT8880_D3=0 & MT8880_D2=0 & MT8880_D1=0 & MT8880_D0=1) Number_Key=1;.用作输出数据时,直接写口线即可:MT8880_D0 = 1;MT8880_D1 = 0;MT8880_D2 = 1;M

10、T8880_D3 = 0; 如把这四根口线看作二进制输出,MT8880_D3是高位,则输出了0101,相当于十进制的5。当然,输出前必须保证总线上的其它设备处于监听状态,即非输出状态,否则会产生冲突,因为总线信号是“与”的关系,比如某根数据线被任一总线设备置为逻辑0,则在同时其它设备无法将其置为逻辑1。12.1.2数据类型C51有如下数据类型:表12-4 C51编绎器能够识别的数据类型数据类型字符类型长度值域unsigned char字符类型单字节0255signed char字符类型单字节-128127unsigned int整型双字节065536unsigned int整型双字节-3276

11、832767unsigned long长整型4字节04294967295signed long长整型4字节-21474836482147483647float浮点型4字节1.175494E-383.4028223E+38*指针型13字节对象的地址bit位类型位0或1sfr特殊功能寄存器单字节0255sfr1616位特殊功能寄存器双字节065536sbit 可寻址位位0或1 指针符号*:表示方法是将*前面冠以数据类型的符号,如char * point1 表示point1是一个字符型的指针变量。下面给出几个例子,说明定义不同数据类型变量的操作方法。例1,定义一个布尔型变量,则有:bit FLAG_

12、BF;例2,定义一个整型变量,则有:int Time_DU;例3,定义一个单字节字符型变量,则有:unsigned char LOCK_JS;例4,定义一个字符型数组,则可在程序开头声明:typedef unsigned char Number20;这就声明了一个长度为20字节的字符型数组,使用赋值语句:Number0=10将值10填入该数组第一个字节。使用赋值语句:Number1=15将值15填入该数组第二个字节。使用赋值语句:MyVarNumber3将该数组的第四个字节赋给变量MyVar。 例5,欲定义一个结构型变量,则有:struct ReadArray unsigned char Nu

13、mber 20; int Serial 5; READARRAY;给结构变量赋值可使用如下语句:READARRAY.Number 0=a;READARRAY.Number 1=b;READARRAY.Number 2=c;READARRAY.Serial 3=32; 12.1.3常量 常量的值在程序执行过程中不能改变。常量的数据类型有整型、浮点型、字符型和字符串型等。分别说明如下:1. 整型常量 整型常量就是整型常数,可表示为: 十进制整数:如12、-5678、0等。 十六进制整数:十六进制数据以0 x开头,数据为09及af。长整数:在数字后面加一个字母L长整数,如2048L、0123L、0

14、xff00L等。2. 浮点型常量浮点型常量有十进制形式和指数表示形式。十进制表示形式又称为定点表示形式,由数字和小数点组成。如0.3141是十进制数表示形式的浮点型常量。3. 字符型常量 字符型常量是单引号内的字符,如a,b等。对于不可显示的控制字符,可以在该字符前面加一个反斜杠组成转义字符。利用转义字符可以完成一些特殊功能和输出时的格式控制。常用转义字符如表12-5所示。表12-5 常用转义字符表 转义字符含义16进制数形式0空字符(NULL) 0 x00 n换行符(LF) 0 x0A r回车符(CR) 0 x0D t水平制表符(HT) 0 x09 b退格符(BS) 0 x08 f换页符(F

15、F) 0 x0C 单引号0 x27 双引号0 x22 反斜杠0 x5C 4. 字符串型常量 字符串型常量由双引号“”内的字符组成,如“ABCD”、“$1234”等都是字符串常量。当双引号内的字符个数为0时,称为空串常量。字符串常量首尾的双引号是界限符,当需要表示双引号字符串时,可用双引号转义字符来表示为:“”“。C语言在存储字符串常量时,要在字符串的尾部加一个转义字符0作为该字符串常量的结束符。因此不要将字符常量与字符串常量混淆,如字符常量a与字符串常量”a“是不一样的。 为了某些编程需要,常常在程序开头使用如下语句定义常量:#define PI 3.14这样,在程序中出现常量PI时,编译器会

16、自动用浮点数3.14代替。12.1.4变量及其存储模式 变量是一种在程序执行过程中,其值能够不断变化的量。使用一个变量之前,必须进行定义,用一个标识符作为变量名并指出它的数据类型和存储格式,以便编绎系统为它分配相应的存储单元。在C51中对变量进行定义的格式如下:存储器种类数据类型存储器类型变量名表 其中,存储器种类和存储器类型是可选项。变量的存储器种类有四种:自动(auto)、外部(extern)、静态(static)和寄存器(register)。定义变量时如果省略存储器种类选项,则该变量格式为自动(auto)。定义一个变量时,C51编绎器允许说明变量的存储器类型。KeilC51编绎器对于每个

17、变量可以准确地赋予其存储器类型,使之能够在单片机系统内准确地定位。表12-6列出了51编绎器所能识别的存储器类型。 表12-6 C51编绎器所能识别的存储器类型存储器类型说明DATA直接寻址的片内数据存储器,访问速度最快BDATA可位寻址的片内数据存储器,允许位与字节混合访问IDATA间接访问的片内数据存储器,允许访问全部片内地址PDATA分页寻址的片外数据存储器,用MOVXRi指令访问XDATA片外数据存储器,用MOVXDPTR指令访问CODE程序存储器,用MOVCA+DPTR指令访问 8051具有一些特殊功能寄存器,如定时器方式控制寄存器TMOD、中断允许控制寄存器IE等。C51编绎器扩充

18、了关键字sfr和sfr16,以便在C语言源程序中直接对特殊功能寄存器进行定义。定义方法如下:sfr P0=0 x80;/*定义I/O口P0,其地址为0 x80*/对于定时器T2,可采用如下方法的方法来定义:sfr16 T2=0 xCC;/*定义TIMER2,其地址为T2L=0 xCC,T2H=0 xCD*/ T2为特殊功能寄存器名,等号后面是它的低字节地址,其高字节地址必须在物理上直接位于低字节之后。访问特殊功能寄存器中的某位,用扩充关键字sbit,1.sbit位变量名=位地址这种方法将位的绝对地址赋给位变量,位地址必须位于0 x800 xFF之间。例如:sbit Y=0 xD7;2.sbit

19、位变量名=特殊功能寄存器名位位置当可位寻址位位于特殊功能寄存器中时,可采用这种方法。位位置是一个07之间的常数。例如:sfr PSW=0 xD0;sbit CY=PSW7;3.sbit位变量名=字节地址位位置以一常数作为基址, 常数在0 x800 xFF之间。位位置是一个07之间的常数。例如:sbit CY=0 xD07;需要注意的是,sbit是一个独立的关键字,不要将它与关键字bit相混淆。关键字bit是C51编绎器的一种扩充数据类型,用来定义一个普通位变量,它的值是二进制数的0或1。例如:static bit direction_bit/*定义一个静态位变量direction_bit*/

20、12.1.5用typedef重新定义数据类型在C51语言程序中,用户还可以根据自己的需要对数据类型重新定义。其方法如下:typedef int Intnew; /*定义Intnew为新的整型数据类型名*/Intnew i,j; /*将i,j定义为Intnew型变量*/一般而言,用typedef定义的新数据类型用大写字母,以便与C语言中原有的数据类型相区别。 12.1.6运算符与表达式 运算符是完成某种特定运算的符号,表达式则是由运算符及运算对换所组成的具有特定含义的式子。C语言是一种表达式语言,在任意一个表达式后面加一个分号;就构成了一个表达式语句。 运算符按其在表达式中所起的作用,可分为:赋

21、值运算符、算术运算符、增量与减量运算符、关系运算符、逻辑运算符、位运算符、复合运算符、逗号运算符、条件运算符、指针和地址运算符、强制类型转换运算符和sizeof运算符等。=在C中赋值运算符,如,x=10。示例如下:a = 0 xFF; /将常数十六进制数FF赋于变量a C51中的算术运算符有如下几个,其中只有取正值和取负值运算符是单目运算符,其它是双目运算符:+ 加或取正值运算符- 减或取负值运算符* 乘运算符/ 除运算符% 取余运算符如:a+b*(10-a), (x+9)/(y-a)两浮点数相除,其结果为浮点数,如10.0/20.0所得值为0.5,两个整数相除时,所得值就是整数,如7/3,值

22、为2。C的运算符有优先级和结合性,可用括号()来改变优先级。12.2串行通信与定时程序 下面给出1个C51完整程序,该例子包含对定时器、中断和串行通信的处理。该程序运行在AT89C51单片机上,该单片机安装在一台下位机上,该下位机接收从PSTN公共电话网传来的数据,然后存储转发给PC机 。12.3嵌入式操作系统12.3.1嵌入式操作系统简介 提高开发效率仅仅依靠编程语言还不够,应该要建立自己的开发平台。嵌入式实时操作系统(RTOS)就是一个很好的嵌入式软件的开发平台。使用RTOS是大势所趋。 RTOS和一般的操作系统有何区别?我们平时熟悉的DOS、Windows、Linux等操作系统都是通用操

23、作系统,它们针对的是PC或是工作站。为了最大幅度地兼容各种软硬件产品,通用操作系统一般面面俱到、体积庞大。 而RTOS很不一样。嵌入式系统中的硬件资源环境一般比较苛刻,嵌入式微处理器和微控制器的内存一般都不大,要在如此紧张的资源下完成复杂的功能,这就要求嵌入式系统软件必须尽量的小巧、稳定和高效。目前广泛用于各种嵌入式智能设备的嵌入式操作系统有美国加州的集成系统公司推出的pSOSystem,简称pSOS。pSOS是高性能、模块化的OS,针对嵌入式微处理器量身打造。该系统提供了多任务处理环境。 pSOS采用模块化体系结构,包括一个实时多任务核心和一系列软件部件、连接库。系统中的每个部分都是封闭式的

24、,相互之间既独立又密切协作。开发人员可以根据不同的应用需求来制定操作系统的功能和所需要的内存大小。pSOS的主要组成部分有:实时多任务核心pSOS、TCP/IP协议堆栈pNA、远程过程调用库pRPC、文件系统管理pHILE、ANSI C标准库pREPC、调试功能模块pROBE、系统信息实时分析工具pMONT等等。pSOS有如下特征:支持多种CPU和驱动器硬件产品;集成了网络技术,对TCP/IP协议支持;多处理器支持;文件系统支持包括ISO9660、MSDOS兼容文件系统和高性能嵌入式文件系统。 另外,Windows CE.Net也是一个应用较广泛的实时嵌入式操作系统,它是微软第一个能够全面支持

25、中文的Windows CE操作系统,适用于快速构建新一代内存少体积小的智能设备,Windows CE.NET也为构建智能移动设备的开发人员提供了新一代的功能强大嵌入式系统平台。Windows CE.NET提供了对无线技术的支持,例如蓝牙技术和零配置的802.11,它还提供了全面的多媒体和Web浏览体验。Windows CE.NET支持各种处理器产品家族,包括x86、Xscale、ARM、MIPS和SH系列。 基于51单片机的RTOS中,有名气的有Keil C51所带的RTX Full和RTX Tiny,C/OSII。RTX51是一个用于8051系列单片机的多任务实时操作系统。有两个不同的版本可

26、用。RTX51 Full使用四个任务优先权完成同时存在时间片轮转调度和抢先的任务切换。RTX51工作在与中断功能相似的状态下,信号和信息可以通过邮箱系统在任务之间互相传递。开发者可以从一存储池中分配和释放内存;可以强迫一个任务等待中断、超时,或者是从另一个任务或中断发出信号、信息。 RTX51 Tiny是一个 RTX51的子集,可以很容易地在没有任何外部存储器的单片8051系统上运转;它仅支持时间片轮转任务切换和使用信号进行任务切换,不支持抢占式的任务切换,不包括消息队列,没有存储器池分配程序。 C/OSII是著名的、源码公开的实时内核,可用于各类8位、16位和32位单片机或DSP。从C/OS

27、算起,该内核已有10余年应用史,并在诸多领域得到广泛应用。C/OSII是一个完整、可移植、可固化和可剪裁的占先式实时多任务内核。C/OSII是用ANSI的C语言编写的,包含一小部分汇编代码,使之可以供不同架构的微处理器使用。至今,从8位到64位,C/OSII已在超过40种不同架构的微处理器上运行。 8051系列一般只有很少的ROM和RAM,如AT89C52只有8 KB Flash和256字节RAM。但RTX51 Full自身代码有6 K多字节,且需要大量外部RAM,不利于学习。RTX Tiny虽然小(自身占用900多字节ROM),但是任务没有优先级和中断管理,无源代码,不实用,也不利于学习。而

28、C/OSII有源代码,有配套图书,利于学习,但规模太大,又需要大量外部RAM,而且所有函数都必须是可重入函数,用在8051系列这类小片内RAM的单片机上有点勉强。 除了上述3种嵌入式操作系统,还有广州周立功公司开发的Small RTOS51,它使用了RTX51 Tiny的堆栈管理机制,并像C/OSII一样是抢占式的。虽然它为51系列单片机编写,但比较容易移植到其他CPU上。目前Small RTOS51的所有版本均可以免费在任何领域使用。12.3.2实时嵌入式操作系统分析所谓操作系统,无非就是处理不同硬件差异的接口,或者说隐蔽硬件,使用户不必和硬件打交道,让应用程序可以在上面操作。通过由操作系统

29、提供出来的系统接口来写应用程序,无须考虑硬件问题。嵌入式操作系统是将所有程序,包括操作系统、驱动程序、应用程序等程序代码全部都烧进一个ROM里面执行,操作系统在其中的角色比较像函数库。 操作系统主要负责三件事:内存管理、任务管理、外围资源管理。这三项机制提供给应用程序开发者很多的好处,但是在嵌入式系统中并非绝对必要,如果系统很简单,可以根本不用操作系统,但对复杂的应用程序,有个操作系统帮忙会省很多麻烦。嵌入式操作系统核心通常很小,往往只有4到20K。下面我们来看看这三项管理机制。内存管理简单方式内存管理不提供任何内存管理机制,但也有好处,用户自行管理内存,用错了系统就宕机了,系统只维护一个已经

30、配置的空间的顶部指针。 位映像方式内存管理是将可以使用的内存总空间分成固定大小的块,系统本身维护一个内存使用位映像来记录内存的使用方式。在内存使用位映像中,每一个位表示一个64bytes大小内存块的使用情况,当位等于0时表示已经有人用过了,当位值等于1时表示没有分配。标签边界内存管理方式中,系统会维护一个顶部指针指向可用的内存块顶端。当用户要求分配内存时,如果申请的空间比较小,比如要存放某个运算中的中间变量,有一个小空间块可供分配,该小空间块以位映像方式来管理。系统先在小空间寻找有无可用内存,若有则分配,若没有则转到调用顶端指针指向的地址去寻找。如果用户要求分配的内存空间大,就直接利用顶端指针

31、去寻找可用的内存块。内存分区(memory partition method)管理方式是将内存分成多个区域,并给每个区域一个识别码(ID),在每个区域中包含几个大小相等的区块(block)。当用户申请内存时,只要告诉系统区域识别码,系统就会从相应的区域中取出一块可用的区块给用户。例如下表所示: 表12-7 内存分区表第几分区分区号区块数目块尺寸1-412501652100326-8315064945012810-165104K如果给定分区号为2,现在在第5分区中的100个区块还没有使用的话,就拿到3K左右内存。任务管理实时嵌入式操作系统的核心内容就是对任务的调度、管理。多任务(Multitas

32、king)在一个操作系统内部,内核kernel是最核心的部件。从表面上看,允许用户并发访问计算机。多个用户似乎可以并行执行多个程序。在操作系统的控制下,每个正在执行的程序就是一个任务。如果一个操作系统能够以这种方法执行多个任务,这就叫做多任务。 多任务操作系统的使用可以简化应用程序的设计:1操作系统的多任务和任务间通信的机制允许复杂的应用程序被分成一系列更小的和更多的可以管理的任务。2程序的划分让软件测试更容易, 团队工作分解,也有利于代码复用。3复杂的定时和先后顺序的细节 可以从应用程序代码中 删除。这成为操作系统的职责。 一个多任务操作系统可以使它看起来好像每个任务并行执行一样。这可以下面

33、的示意图来描述。它显示了有关时间的3个任务的执行模式。任务名用颜色标注出来,写在左手边。时间从左到右增加,相应的颜色的线条 显示该任务在某个特殊时间正在执行。上面的图 演示的是用户所觉察到的并行执行模式,下面的图是实际的多任务执行模式。 图12-2 图12-3 所有可用的任务都好像在执行,但实际上在任何一个时刻都只有一个任务在执行,其它任务被挂起,这也就是时分复用的概念。调度调度器(scheduler)是内核中负责决定在某个特殊时间哪个任务应该执行的部分。下图是内核调度任务的状态转换图。 图12-4 其中,停止指任务已经执行完的状态;就绪指任务满足所有启动条件后进入的状态,挂起指当该任务需要等

34、待某一事件发生。内核可以在任务的运行期间,可能会挂起/恢复该任务许多次,之后才能完成该任务并进入停止状态。 除了被RTOS内核无意的挂起外,一个任务还可以自己挂起自己。如果一个任务想延迟一段固定的时间,或者等待某个资源可用,或者等待一个事件出现(比如一个键按下)。一个阻塞或者睡眠的任务是不能执行的,不会为它分配任何处理时间。 图12-5 上图中提到的编号:1)任务1正在运行;2)t2时刻,内核挂起任务1;3)紧接着,恢复/开始执行任务2;4)任务2正在执行,它工作于独占访问方式,它锁定一个处理器外设; 5)t3时刻,内核挂起任务2;6)紧接着,恢复任务3;7)任务3试图访问同样的处理器外设,发

35、现它被锁定,任务3不能继续,所以自己挂起自己;8)内核恢复任务1;9)接下来,任务2在9处执行。它完成了对处理器外设的访问,所以解锁它;10)再下来,任务3在10处执行。它发现现在可以访问处理器外设了,于是开始执行,直到被内核挂起。 调度策略是调度器用来决定哪个任务在哪个时间点执行的算法,也常被称为排程算法。一个非实时多用户系统的策略很可能分配给每个任务一个公平的处理器时间片,即采用均分的原则。用在实时系统/嵌入式系统的策略会更复杂,一般都属于先占式优先权调度策略,就是先抢先赢再加上优先权排列来改善。普遍有四种方式,我们分别讨论如下:FCFS(first come first service

36、scheduling)策略,在该策略下,最先提出服务要求的执行线程会最先分配到CPU资源,直到结束或自动放弃。PFS(priority first scheduling)策略根据任务的优先权来决定分配CPU资源的先后,若是优先权相同,则采用FCFS调度策略来决定任务的先后顺序。RRS(round-robin scheduling)策略将就绪状态的任务当作一个环状任务,将其放入循环队列中处理,每一个执行线程具有一个时间片的值,以记录可以使用CPU多少时间,每一次时间中断跑起来,时间片值就减一,当时间片值用完之后,就会切换到另外一个任务。PFRRS(priority first with roun

37、d scheduling)就是PFS加上RRS,优先权有高低的时候,采用PFS,若优先权相同,则采用RRS轮流执行。 执行调度策略呢可以在每一个时间中断的时候,每一个标记(tick)开始运行的时候执行,但这样太频繁;也可以在一个任务执行完(即时间片值为零)的时候执行调度策略;另外,还有调用exit、sleep、wait event、give up CPU等时候,都会去执行调度策略。实时调度下面的图演示多任务是如何被时实操作系统调度的。假设RTOS自己已经建立了一个空闲任务idle task,它只在没有其他任务执行的时候才被执行。RTOS idle task 总是处于可以执行的状态(它不会因为等

38、待外设资源而被阻塞,而是处于一种随时待命的状态),通常空闲任务就是检查整个系统还有哪些资源应该回收或是该做些默认的系统动作。图12-6下面来看看上图所示的多任务实时调度过程:1.初始状态,定时器控制任务vControlTask和处理鼠标任务vMouseHandlerTask都不能被执行,vControlTask等待合适的时间开始新的控制循环,vMouseHandlerTask等待鼠标按下。处理器时间分配给 RTOS的idle task。2.在t1时刻,一个鼠标键按下,事件发生,VMouseHandlerTask任务现在可以执行,它比RTOS的idle task有更高的优先级,所以处理器分配时间

39、给它。3.在t2时刻,vMouseHandlerTask已经完成了对按键的处理,并更新了显示输出。它不能继续,直到下一次鼠标键被按下,所以必须挂起它自己。RTOS idle task被恢复执行。4.在t3时刻,一个定时器事件预示可以执行下一个控制循环了。VControlTask现在可以执行,作为最高优先级的任务被立刻分配到处理器时间。5.在t3和t4之间,当vControlTask任务还在执行的时候,一个鼠标键按下。MouseHandlerTask不能被执行,因为它没有vControlTask的优先级高。不能分配到任何处理器时间。6.在t4时刻,vControlTask完成了控制循环的处理,不

40、能够重新开始,直到下一个时间事件出现,所以它自己挂起自己。而vMouseHandlerTask现在是最高优先级的任务,可以运行了,所以,为了处理先前的鼠标键输入事件,分配到了处理器时间。7.在t5时刻,鼠标键已经被处理。VMouseHandlerTask为了等待下一个鼠标键事件,挂起自己。现在,两个任务再度不能执行。RTOS idle task分配到时间。8.在t5和t6之间,一个定时器事件被处理,但是没有更多的鼠标事件出现。9.下一个鼠标键按下出现在t6时刻,但在vMouseHandlerTask完成处理键之前,一个定时器事件出现了。现在两个任务都能被执行,而vControlTask比vMo

41、useHandlerTask 有更多的优先级,所以vMouseHandlerTask在它完成处理键盘之前就被挂起了。VControlTask分配到处理器时间。10.在t8时刻,vControlTask完成处理控制循环,挂起自己以等待下一个事件。VMouseHandlerTask再次成为最高优先级的任务,能够运行,所以分配到处理器时间,从而鼠标键按下事件处理能够完成。11.在t9时刻,vMouseHandlerTask已经完成了对按键的处理,并更新了显示输出。它不能继续,直到下一次鼠标键被按下,所以必须挂起它自己。RTOS idle task又被恢复执行。系统时钟节拍中断系统时钟节拍中断是一种任务间切换的方法,一般称之为RTOS的TICK(标记),一般用tick count变量来度量时间。定时器中断(RTOS tick interrupt) 用严格的时间精度来增加tick count,允许实时内核用一个指定的定时器中断频率精度来测量时间。每次tick count增加后,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论