资源描述
,单击此处编辑母版标题样式,*,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,第,15,章,RTX51,实时操作系统,RTOS,概述,RTX51,系统特点,RTX51,的程序设计,RTX51,的系统配置,RTX51,的应用举例,1,15.1,RTOS,概述,单任务系统的设计思路:,传统的单片机程序多为单任务系统,其业务逻辑顺序安排在主函数中。主函数是整个程序的入口,一般包含一个死循环,循环过程中通过调用函数来完成相应的操作,而对于一些较短的实时任务则通过中断方式进行处理。,此种程序结构简单、直观、易于实现,但对于较复杂的应用,此种结构极为不便,并且不能满足实时性要求较高的场合,15.1.1,单任务,/,多任务,2,顺序执行的单任务程序设计,void main(),int counter=0;,while(1),check_serial_io();,/,检查串行输入,process_serial_cmds();,/,处理串行输入,check_kbd_io();,/,检查键盘输入,process_kbd_cmds();,/,处理键盘输入,app_execute();,/,应用程序执行,counter+;,/,循环计数,3,顺序执行的单任务程序设计,该例中,每个函数执行一个独立操作或任务。任务依次按顺序执行。,当任务数量增加时,调度会成为问题。例如,若,process_kbd_cmds(),函数的执行耗费大量时间,主循环会很慢才执行到,check_serial_io(),,此时串口数据可能已经丢失。,4,多任务系统的执行特点,多任务系统的设计思路:,各功能模块(如显示、键盘扫描等等)处于等同地位。,各功能模块执行顺序可在程序运行过程中动态地改变。,各子任务在自已的时间片内运行,通过合理设计时间片大小和各任务的优先级,可以自然地满足系统内各种复杂的时序要求。,类似这样的任务管理和调度,就是多任务,OS,的核心。,5,多任务系统的执行特点,check_serial_io(,),process_serial_cmds(,),check_kbd_io(,),process_kbd_cmds(,),app1_execute(,),app2_execute(,),任务调度,时间片轮转、任务优先级设定等功能,6,15.1.2,什么是,RTOS,实时操作系统(,Real-Time,Operating,System,,,RTOS,),是指当外界事件或数据产生时,能够接受并以足够快的速度予以处理,其处理的结果又能在规定的时间之内来控制生产过程或对处理系统作出快速响应,并控制所有实时任务协调一致运行的操作系统。,RTOS,广泛应用于嵌入式计算机技术领域,比如,COS,、,VxWork,、,Linux,、,WinCE,等,,51,单片机上常用的,Small RTOS51,,还有目前手机中广泛使用的,Android,、,iOS,,都是典型的,RTOS,。,7,15.2,RTX51,的特点,RTX51,是一款小巧的针对基于,8051,核心的嵌入式系统的多任务,RTOS,。使用它可以简化比较复杂、有严格时间限制的程序的设计过程。,RTX51,主要有两个不同的可用版本:,标准版(,RTX51-Full,)和精简版(,RTX51-Tiny,)。,在,RTX51-Full,中:既可以以轮循(,Round-Robin,)方式执行任务,也可以按,4,级任务优先级的方式切换不同优先级的任务。以并行方式工作,支持中断管理,信号和消息可以通过邮箱系统在不同任务之间传递。,RTX51-Tiny,是,RTX51-Full,的一个子集,支持,RTX51,中绝大多数的特性,且不需要外部,RAM(XDATA),。,RTX51-Tiny,支持,RTX51-Full,的许多特性,但不具有以下功能:,不支持优先任务切换,不包含信息子程序,无存储器库分配子程序。,8,15.2,RTX51,的特点,描述,RTX51-Full,RTX51-Tiny,任务数量,最多,256,个;可同时激活,19,个,16,个,RAM,需求,4046Byte,的,DATA,空间,20200ByteIDATA,空间,(,用户堆栈,),最小,650,字节,XDATA,空间,7Byte,的,DATA,空间,3,倍于任务数量的,IDATA,空间,代码要求,6KB8KB,900Byte,硬件要求,定时器,0,或定时器,1,定时器,0,系统时钟,1000,到,40000,个周期,1000,到,65535,个周期,中断请求时间,小于,50,个周期,小于,20,个周期,任务切换时间,快速任务:,70100,个周期,标准任务:,180700,个周期,(,取决于堆栈负载,),100700,个周期,(,取决于堆栈负载,),邮箱系统,8,个分别带有整数入口的信箱,不提供,内存池,最多,16,个内存池,不提供,信号量,8,*,1,位,不提供,9,15.3,RTX51,的程序设计,由于,Keil,C,中自带,RTX51-Tiny,版,下面就以,Tiny,版本为例,简要介绍其软件设计方法。,软件环境的要求:,在使用,RTX51-TINY,时,需要以下软件支持:,1,),C51,编译器,2,),BL51,连接定位器,3,),A51,宏汇编器,库文件,RTX51TNY.LIB,必须存储在,C51LIB,下,,必须指定,C51,运行库的路径。,头文件,RTX51TNY.h,必须存储在,C51INC,下,,必须指定,C51,包含文件的路径。,10,15.3,RTX51,的程序设计,运行机制,RTX51Tiny,通过轮循(,Round-Robin,)方式来实现多任务,以达到多个无限循环或任务的准并行执行。,这里的多任务并不是真正同时执行的,而是使用不同的时间片来执行,即只是宏观上的同时执行。它将可用的,CPU,周期分成多个时间片,由,RTX51,把这些时间片分配给每一个任务使用。每个任务只能在预定的时间片里运行,然后,RTX51,再切换到另一个己经准备就绪的任务,让它再执行一定的时间片。,时间片一般是比较短促的,一个时间片大约只有毫秒级时间。正是由于这个原因,在用户看来,多个任务似乎是在同时执行的。,11,15.3,RTX51,的程序设计,运行机制,RTX51,利用了一个由定时器,0,的中断信号驱动的定时程序来实现上述时间片的控制。定时器产生的周期性中断信号用来驱动,RTX51,的定时节拍。,SFR,中的全局中断允许位,EA,或定时器,0,中断允许位,ET0,被屏蔽,都可能使,RTX51-Tiny,停止运行。因此,除非有特殊的应用目的,应该使定时器,0,的中断始终开启,以保证,RTX51-Tiny,的正常运行。,12,15.3,RTX51,的程序设计,任务,在,RTX51,系统中,一个任务体现为一个,C51,函数,,该函数不能有返回值,不能有参数,且函数体必须是一个无限循环,,以保证该函数不能返回。,实际应用中,一个复杂的系统往往被分解成若干可以并行处理的任务,每个任务只完成一个单一的操作,(,如键盘扫描、显示、通信等,),,从而降低系统设计的难度。,在,RTX51-Tiny,系统中一个具体的任务通过下面的格式定:,13,15.3,RTX51,的程序设计,任务,void taskname(void)_task_ num,其中,,num,是任务号,取值为,0-15,;,taskname,是任务名称(亦即函数名)。,下面是一个具体的任务定义,void init(void)_task_ 0,/*,操作语句*,/,while(1),/*,操作语句*,/,RTX51-Tiny,最多只允许处理,16,个任务,14,15.3,RTX51,的程序设计,任务,RTX51,区分,2,类任务:快速任务和标准任务。,快速任务有很快的响应速度,每个快速任务使用,8051,一个单独的寄存器组,并且有自己的堆栈区域。,RTX51,支持最大同时有,3,个快速任务。,标准任务需要多一点的时间来进行任务切换,因此使用的内部,RAM,相对快速任务要少,所有的标准任务共用,1,个寄存器组和堆栈。当任务切换的时候,当前任务的寄存器状态和堆栈内容转移到外部存储器中。,RTX51-Full,支持任务最多达,64,个;,RTX51-Tiny,仅支持标准任务,最多,16,个。这里我们仅讨论标准任务,15,15.3,RTX51,的程序设计,任务状态,RTX51-Tiny,的用户任务有,5,种状态,如下表所示。某一时刻用户任务处在某个状态,在一定条件下任务状态可以发生改变。,状态,描述,运行,(RUNNING),当前正在运行的任务处于,RUNNING,态,同一时刻只能有,1,个任务处于该状态。,就绪,(READY),等待运行的任务处于,READY,态,可能有多个。当前运行的任务时间片完成后,从,READY,态的任务队列中选取下一个任务运行,使其进入,RUNNING,态。,超时,(TIMEOUT),任务由于时间片用完处于,TIMEOUT,态,在仅具有时间片轮循调度方式的,RTX51-Tiny,中,该状态等价于,READY,态。,等待,(WAITING),正在等待一个事件发生的任务处于,WAITING,态。如果该事件发生,则任务进入,READY,态。,删除,(DELETED),尚未启动的任务处于,DELETED,态,16,15.3,RTX51,的程序设计,任务状态,5,种状态之间的转化条件:,READY,态,/,TIMEOUT,态,RUNNING,态,WAITING,态,时间片到来,时间片结束,等待一个事件,事件发生,17,15.3,RTX51,的程序设计,一个示例,#include,#include,uint counter0=0;,uint counter1=0;,void job0()_task_ 0,/,程序的执行从任务,0,开始,os_create_task(1);,/,将任务,1,标记为“,READY,”状态,while(1)counter0+;,/,任务函数内部必须构成死循环,void job1()_task_ 1,while(1)counter1+;,/,任务函数内部必须构成死循环,思考:,counter0,和,counter1,是交替加,1,么?,不能出现,main(),函数,18,15.3,RTX51,的程序设计,用于任务管理的常见系统函数,1,、,os_create_task,函数原型,:,char,os_create_task(unsigned char task_id);,功能说明,:启动已定义的编号为,task_id,的任务,并标记为就绪,准备执行。,返回值,:如果任务成功启动,此函数返回,0,值;如果没有,task_id,说明的任务,则返回,-1,。,2,、,os_delete_task,函数原型,:,char,os_delete_task(unsigned char task_id);,功能说明,:停止编号为,task_id,的任务,并将此任务从任务表中删除。,返回值,:如果任务被成功停止并删除,函数返回,0,值;如果编号为,task_id,的任务没有启动或不存在,则返回,-1,。,19,用于任务管理的常见系统函数,3,、,os_running_task_id,函数原型,:,char,os_running_task_id(void);,功能说明,:检测当前处于运行态的任务编号。,返回值,:返回当前处于运行态的任务编号,返回值为,015,。,4,、,os_set_ready,函数原型,:,void os_set_ready(unsigned char task_id);,功能说明,:将编号为,task_id,的任务设置为就绪态。,返回值,:无,20,用于任务管理的常见系统函数,5,、,os_wait,函数原型,:,char,os_wait(unsigned char event_sel,/*,等待的事件*,/,unsigned char ticks,/*,等待时长,即定时器的溢出次数*,/,unsigned char dummy);,/*Tiny,版未用,恒为,0,*,/,功能说明,:暂停当前执行的任务,并等待一个或多个事件,(,如时间间隔、超时、从另一个任务或中断发出的信号等,),发生。参数,event_sel,说明所等待的一个或几个事件的组合,事件种类如下表所示。,事件,描述,K_SIG,等待一个信号量,K_TMO,等待由,ticks,指定的超时时间,K_IVL,等待由,ticks,指定的时间间隔,21,用于任务管理的常见系统函数,5,、,os_wait,返回值,:当有一个指定的事件发生时,任务被置为就绪态。当任务继续执行时,,os_wait,返回重新启动任务的特定事件。有以下可能的返回值:,事件,描述,RDY_EVENT,任务就绪标志被,os_set_ready,或,isr_set_ready,函数置位,SIG_EVENT,接收到一个信号量,TMO_EVENT,达到超时或间隔时间,NOT_OK,event_sel,参数无效,22,用于任务管理的常见系统函数,6,、,os_wait1,函数原型,:,char os_wait1(unsigned char event_sel);,/*,等待的事件*,/,功能说明,:暂停当前执行的任务,并等待一个事件发生。该函数是,os_wait,函数的一个子集,它不支持所有的事件,参数,event_sel,只能是,K_SIG,。,返回值,:与,os_wait,函数对比,缺少,TMO_EVENT,。,7,、,os_wait2,函数原型,:,char os_wait2(unsigned char event_sel,/*,等待的事件*,/,unsigned char ticks);,/*,等待的定时器时标数*,/,功能说明,:与,os_wait,函数相同,但没有,dummy,参数。,返回值,:与,os_wait,函数相同,23,用于任务管理的常见系统函数,8,、,os_send_signal,函数原型,:,char,os_send_signal(unsigned char task_id);,功能说明,:该函数向编号,task_id,的任务发送一个信号。若该任务已经在等待此信号,本函数将任务置为就绪态;若该任务没有准备接收此信号,则信号将存储在任务的信号标志中。,返回值,:函数执行成功返回,0,;若指定的任务不存在,返回,-1,。,9,、,os_clear_signal,函数原型,:,char,os_clear_signal(unsigned char task_id);,功能说明,:该函数向清楚号,task_id,的任务的信号标志。,返回值,:若信号标志被成功清零,返回,0,;若指定的任务不存在,返回,-1,。,24,用于任务管理的常见系统函数,10,、,isr_send_signal,函数原型,:,char,isr_send_signal(unsigned char task_id);,功能说明,:该函数功能与,os_send_signal,函数完全相同,区别在于只能从中断函数中调用。,返回值,:函数执行成功返回,0,;若指定的任务不存在,返回,-1,。,11,、,isr_set_ready,函数原型,:,void,isr_set_ready(unsigned char task_id);,功能说明,:将编号为,task_id,的任务设置为就绪态。仅能从中断函数中调用。,返回值,:无。,25,用于任务管理的常见系统函数,12,、,os_switch_task,函数原型,:,char,os_switch_task(void);,功能说明,:该函数让调用它的任务暂时停止运行,转而切换至另外一个任务运行。如果调用该函数的任务是唯一一个就绪任务,那么该任务将立即恢复运行。,返回值,:无。,26,用于任务管理的常见系统函数,13,、,os_reset_interval,函数原型,:,void,os_reset_interval(unsigned char ticks);,功能说明,:用于纠正由于,os_wait,函数同时等待,K_SIG,和,K_IVL,事件而产生的时间问题。如果一个信号事件,(K_SIG),引起,os_wait,退出,时间间隔定时器并不调整,这样会导致后续的,os_wait,调用(等待一个时间间隔)延迟的不是预期的时间周期。该函数允许将时间间隔定时器复位,这样,后续对,os_wait,的调用就会按预期的操作进行。,返回值,:无。,27,15.4,RTX51,的系统配置,编写,RTX51,程序需要包含,RTX51TNY.h,文件。在程序中,需要用一个关键字,“,_task_,”,来声明一个函数的任务属性。,RTX51,程序不需要,main,函数。在进行连接处理时,会将执行任务,0,所需要的代码连接进来,作为开始执行的代码。,用户可以更改配置文件,CONF_TNY.A51,中的以下几个参数:,1),系统定时器中断所用的寄存器组,2),系统定时器的时间间隔,3),Round-Robin,的超时(,time-out,)值,4),内部数据存储器的大小,5),RTX5l,启动后的自由堆栈大小,28,15.4,RTX51,的系统配置,以下是配置文件,CONF_TNY.A51,中的部分内容,;-,;RTX51-tiny,的硬件定时器,;,用下面的,EQU,可预置,RTX51,的定时器时间常数,;,用,8051,定时器,0,作为控制软件的定时器,;-,;,定义定时器中断用的寄存器组,INT_REGBANK,EQU,1,;,默认为寄存器,1,组,;,定义,8051,定时器,0,溢出所需的机器周期数,INT_CLOCK,EQU,10000,;,默认周期数为,10000,即,10ms,;,定义,Round-Robin,的,Timeout,所需的定时器溢出次数,TIMESHARING,EQU,5,;,默认为,5,次,;,注意:,Round-Robin,任务切换可用,TIMESHARING,为,0,来屏蔽,基本时间片,任务时间片,=,基本时间片,TIMESHARING,29,15.4,RTX51,的系统配置,以下是配置文件,CONF_TNY.A51,中的部分内容,;-,;RTX51,堆栈空间,;,以下,EQU,语句定义了用于堆栈区的片内,RAM,体积和最小自由,;,堆栈空间,并且定义了当堆栈空间耗尽后所执行的宏代码,;-,;,定义用作,CPU,堆栈的,RAM,的最高地址,RAMTOP,EQU,0FFH,;,默认地址是,255,;,定义最小的堆栈自由空间,FREE_STACK,EQU,20,;,默认为,20,字节堆栈自由空间,;,;,发生堆栈耗尽时的执行代码,STACK_ERROR,MACRO,CLR,EA,;,关闭所有中断,SJMP,$,;,若堆栈空间耗尽,进入死循环,ENDM,30,15.4,RTX51,的系统配置,配置文件,CONF_TNY.A51,中的参数说明,31,15.5,RTX51,的应用举例,流水灯,例,1:,多任务并行执行的基本程序结构,例,2:,常用的系统函数,例,3:,关于,wait,函数中的事件:,1)K_SIG,2)K_TMO,和,K_IVL,的区别,32,15.5,RTX51,的应用举例,ADC0808,模数转换,例,4:ADC0808,模数转换,33,
展开阅读全文