标题：Round Robin
Round-robin
RTX51 Tiny可以配置成使用round-robin多任务。Round-robin容许quasi-parallel执行多任务。任务并不是连续执行的，而是分时间片执行的（可用的CPU时间被分成时间片，RTX51 Tiny把时间片分配给各个任务）。时间片的时间很短（以毫秒为单位），所以任务看起来像连续执行一样。任务在分配给他的时间片内执行（除非放弃）。然后切换到下一个就绪的任务。这个时间片在RTX51 Tiny Configuration.配置文件中定义.
下面的例子是一个使用round-robin多任务的RTX51 Tiny的程序。这个程序中的两个任务都是循环计数器。RTX51 Tiny执行称为job0的任务0。这个函数创建了另一个任务job1。Job0执行完它的时间片后，RTX51 Tiny开始执行job1。Job1执行完它的时间片后，RTX51 Tiny又返回到job0开始执行。然后再切换到job1，如此循环。
＃include
int counter0;
int counter1;
void job0 (void) _task_ 0 {
os_create (1);    /* mark task 1 as ready */
while (1) {   /* loop forever */
counter0++; /* update the counter */
}
}
void job1 (void) _task_ 1 {
while (1) {   /* loop forever */
counter1++; /* update the counter */
}
}
注意：除了一个任务的时片到时，也可以使用函数os_wait 或函数os_switch_task通知RTX51 Tiny可以切换到另一个任务。函数os_wait挂起当前任务直到特定的事件发生。在这期间任何其他的任务都可以执行。
Cooperative 任务切换??如果你禁止了round-robin多任务，你必须设计并执行你的任务从而让他你们以cooperativ方式工作。特别地，你必须在每个任务的某个地方调用。这些函数告知RTX51 Tiny切换到另一任务。
函数os_wait 和函数os_switch_task的不同之处在于os_wait可以让你的任务等待某一事件的发生，而函数os_switch_task直接切换到另一个准务就绪的任务。
空闲任务
当没有任务需要运行时，RTX51 Tiny执行空闲任务。空闲任务只是一个简单的无限循环，比如：
SJMP $
有些8051器件提供了空闲模式，通过持起任务的执行以降低功耗，直到出现中断。在这种模式下，所有外围设备包括中断系统仍然在继续工作。
RTX51 Tiny允许你在空闲任务中初始化空闲模式（没有其他任务需要执行）。当RTX51 Tiny时钟节拍中断（或任何其他中断）出现，微控制器恢复执行程序。空闲任务执行的代码可以通过配置文件CONF_TNY.A51进行配置并使能
堆栈管理
RTX51 Tiny在8051的IDATA内存区为每个任务维持一个堆栈。当一个任务执行时，给他准备了最大可能需要地堆栈。当任务切换时，前一个任务的堆栈被压栈并重定位，而把当前任务的堆栈被重定位并弹栈。STACK是堆栈的起始地址。在这个例子中，位于堆栈中的对像包括全局变量，寄存器和位地止内存，剩下的内存用作任务堆栈。内存的顶端在配置文件中定义。配置RTX51 Tiny?RTX51 Tiny可以由根据用户的应用来定制。
配置
RTX51 Tiny必须根据你的嵌入式应用来配置。所有地配置参数都在椟置文件CONF_TNY.A51中，这个文件位于\KEIL\C51\RTXTINY2\文件夹中，文件中的椟置选可以你做如下事情。
指定时钟节拍中断寄存器组
指定时钟节拍间隔（多个8051机器周期）
指定在时钟节拍中断中执用的用户代码
指定round-robin溢出时间
使能禁能round-robin任务切换
指定你的应用程序包含了长时间的中断
指定是否使用了code banking
定义RTX51 Tiny的栈顶
指令需要最小的堆栈空间
指定堆栈错误时执行代码
定义空闲任务操作
CONF_TNY.A51的默认配置包含在RTX51 Tiny的库中。然而，要在就用中使用配置文件，必须把配置文件拷贝到你的工程文件夹并添加到工程中。
要定制RTX51 Tiny的配置，必须改变CONF_TNY.A51的设置
注意：
如果在工程中不包括配置文件，默认的配置文件将会自动地包含到工程中。后事存在库中的配置文件可能会对你的应用起到相反效果
硬件时钟
以下参数指定了如何配置制RTX51 Tiny的配件时钟
INT_REGBANK 指定制RTX51 Tiny时钟中断使用的寄存器组，默认的是寄存器组1
INT_CLOCK 指定时钟产生中断前的周期数据。这个值的范围是1000~65535。较小的值产生中断较快。这个值用来计算时钟的重新装载值（65536-INT_CLOCK）。缺省值是10000。
HW_TIMER_CODE 是一个宏定义，它用来指定在制RTX51 Tiny时钟节拍中断中执的代码。这个宏缺省的设置是从中断中返回（RETI）如：
HW_TIMER_CODE MACRO
; Empty Macro by default
RETI
ENDM
Round-robin
Round-robin切换是默认使能的，以下参数用来设定Round-robin切换的时间或禁能Round-robin切换
TIMESHARING 指定任务在进行Round-robin切换前执行的RTX51 Tiny时钟节拍数。当这个值为0时禁止Round-robin切换。缺省值是5个时钟节拍。
长时间中断
一般情况下，中断服务程序（ISRs）都要求很快执行完毕。有时候，中断服务程序可能需执行很长一段时间。如果一个高优先级的中断执的时间超过了节拍间隔，RTX51的时钟中断就可能被这个更高优先级的中断中断了，并且被以后的RTX51 时钟中断重入了。
如果使用了需要运行很长时间的高优先级中断，就应该考虑减少中断服务程序的工作量，改变RTX51 时钟节拍的速率，或考使用以下配置。
LONG_USR_ISR 指定是否使用执行时间超过时钟节拍的中断。当这个值置为1时，RTX51 Tiny就会把保护RTX51 Tiny时钟节拍中断重入的代码包含进去。这个值缺省为0
Code banking
以下设置指定RTX51 Tiny应用中是否使用code banking
CODE_BANKING 置1使用code banking，清0不使用code banking。缺省值为0
注意：L51_BANK.A51的2.2或更高版本需要RTX51 Tiny 程序使用code banking
堆栈
堆栈的配置选项有几个。以下参指定了用于堆栈的内存空间的大小和堆栈的最小空间。当CPU的堆栈空间不够时用一个宏指定去执行哪一段代码。
RAMTOP指定栈顶地址。最好不要修改这个地址除非你在这个堆栈的上面使用了IDATA变量。
FREE_STACK指定堆栈上的最少可用空间。当切换到一个任务是时，如果RTX51 Tiny检测到可用的堆栈空间小于这个值，STACK_ERROR宏就会被执行。置为0将禁止对堆栈的检查，缺省值为20字节
STACK_ERROR是一个宏，它代表了一段在堆栈出现错误时执行的代码。这个宏的缺省代码为禁能中断并进入一个无限循环。如
STACK_ERROR MACRO
CLR EA ; disable interrupts
SJMP $ ; endless loop if stack space is exhausted
ENDM
空闲任务
没有任务需要执行时，RTX51 Tiny就执行空闲任务。空闲任务什么都不做，只是等待RTX51 Tiny的时钟节拍中断并切换到另一个就绪的任务。以下参数用来配置RTX51 Tiny空闲任务的不同方面
CPU_IDLE 这是一个宏，代表了在空闲任务中执行的代码。缺省指令是设置寄存器PCON的空闲模式位。这样就可以通过挂起程序节省能耗。如
CPU_IDLE MACRO
ORL PCON,#1 ; set 8051 CPU to IDLE
ENDM
CPU_IDLE_CODE 指定CPU_IDLE宏在空闲任务中是否执行。缺省值为0，这样空闲任务将不包含CPU_IDLE宏
库文件
RTX51 Tiny包括两个库文件
RTX51TNY.LIB is used for non-banking RTX51 Tiny programs
RTX51BT.LIB is used for code-banking RTX51 Tiny programs.
The RTXTINY2.PRJ project found in the \KEIL\C51\RTXTINY2\SOURCECODE\ folder is used to build these two libraries.
注意：不需要在应用显式地包含这两个文件。如果你使用μVision2 IDE或command-line linker时这两个文件会自动地包含进去。
如果要建立RTX51 Tiny的库，缺省的配置文件会加入进去。如果不显式地声明包含配置文件，默认的配置文件会包含进去。以后对配置文件做的修改会对就用产生意想不到的效果。
优化
可以通过以下方式优化RTX51 Tiny程序
如果可能，禁能round-robin任务切换。Round-robin需要13字节堆栈空间来存储任务地址和所有寄存器。如果任务切换是通过RTX51 Tiny运行时库（比如os_wait或 os_switch_task）来触发的就不需要这些空间了。
使用os_wait而不是使用round-robin的时间耗尽来切换任务。这些会提高系统的反应时间和任务的反应速度
避免把系统时钟节拍的中断速率设的太高。把时钟溢出的时间设的比较短增加了每秒的时钟节拍数但是减少了每个任的可用时间，因为每个时钟节拍中断会使用100-200个周期来运行。所以要把湔出时间设的足够的小从而减小时钟节拍中断带来的副作用。
使用RTX51 Tiny
要使用RTX51 Tiny，必须成功地生成RTX51程序并编译连接他们
编写程序
定义RTX51程序使用关键字 _task_ 
以RTX51TNY.H的模板使用RTX51 Tiny的内核
包含文件
RTX51 Tiny只需包含一个文件RTX51TNY.H。所有的运行时库来常量都在这个头文件中定义。可以采用以下方式包含它：
＃include <rtx51tny.h>
编程指南
使用RTX51 Tiny编程时须遵循下规则：
包含文件rtx51tny.h
不要创建C主函数，RTX51 Tiny有它自已的主要函数
程序至少创建一个任务
程序必须至少调用一次RTX51 Tiny运行时库（如os_wait）。否则，连接器将不会把RTX51 Tiny库包含进去
任务0是你的程序执行的第一任务。必须调用在任务0中调用os_create_task函数来运行其他任务
任务永不返回或退出。任务必须使用while(1)或类似的结构。使用os_delete_task函数可以挂起一个任务
必须在μVision2中或在连接编译命令行中指定RTX51 Tiny
定义任务
实时或多任务应用由一个或多个完成特定功能的任务组成。RTX51 Tiny支持最多16个任务
任务必须是用_task_声明的C函数，返回值和参数都必须是void类型的，如
void func (void) _task_ task_id
这里
func         is the name of the task function.
task_id     is a task ID number from 0 to 15
以下例子定义了函数job0作为一个任务，任务编号为0。
void job0 (void) _task_ 0 {
while (1) {
counter0++; /* increment counter */
}
}
注意：所有的任务都必须通过循环实现，而且永不返回