rtx51小型实时操作系统的应用体会.docx
《rtx51小型实时操作系统的应用体会.docx》由会员分享,可在线阅读,更多相关《rtx51小型实时操作系统的应用体会.docx(18页珍藏版)》请在冰豆网上搜索。
rtx51小型实时操作系统的应用体会
rtx51小型实时操作系统的应用体会
2007年06月27日星期三23:
53
最近在做设计的时候老遇到一些几个任务需要同时进行的情况,刚开始想自己去做一个多任务的程序(因为称不上系统),想用一个脉冲计数的方法来实现多任务切换,但是感觉实现起来比较麻烦。
无意中发现了51单片机下个rtx51实时操作系统(本人以前不知道的),后来就去找相关资料。
发现这方面的资料在网上很少,也很杂乱。
经过一段时间的学习,我有了个大概的了解。
下面给大家讲述一下:
RTX51是一个用于8051系列处理器多任务实时操作系统。
RTX51可以简化那些复杂而且时间要求严格的工程的软件设计工作。
有二个不同的RTX51版本可以利用:
RTX51Full使用四个任务优先权完成同时存在时间片轮转调度和抢先的任务切换RTX51工作在与中断功能相似的状态下信号和信息可以通过邮箱系统在任务之间互相传递你可以从一存池中分配和释放内存你可以强迫一个任务等待中断超时或者是从另一个任务或中断发出的信号或信息RTX51Tiny是一个RTX51的子集它可以很容易地在没有任何外部存储器的单片8051系统上运转。
除了下列例外RTX51Tiny支持许多在RTX51中的特征。
RTX51Tiny仅支持时间片轮转任务切换和使用信号进行任务切换不支持抢先式的任务切换。
不包括消息历程。
没有存储器池分配程序。
RTX51使用一个8051硬件计时器中断作为定时程序。
产生的周期性中断用于驱动RTX51时钟。
RTX51不需要在你的程序中拥有一个主函数它将自动开始执行任务0如果你确实有一个主函
数你必须利用RTX51Tiny中的os_create_task函数或RTX51中的os_start_system函数手工启动RTX51。
下列例子显示一个只使用时间片轮转任务调度的简单的RTX51应用程序在本程序里的二个任务
是简单计数器回路rtx51开始执行函数名为job0的任务0。
这些功能添加了另一个叫做job1任务。
在job0运行一会儿以后RTX51切换到job1。
在job0运行一会儿以后、RTX51转回到job0。
这个过程将不确定地重复下去
#include
intcounter0;
intcounter1;
voidjob0(void)_task_0{
os_create
(1);/*marktask1asready*/
while
(1){/*loopforever*/
counter0++;/*updatethecounter*/
}
}
voidjob1(void)_task_1{
while
(1){/*loopforever*/
counter1++;/*updatethecounter*/
}
}
今天夜已很深了,明早还有考试,对不起了,不写了。
我介绍几个资料的下载地址,大家自己去看吧!
【转】KEILRTX51TINY内核的分析与应用
2011年04月18日星期一19:
28
转载自lan042
最终编辑lan042
特性:
最大任务数:
16
最大激活的任务数:
16
所需的CODE空间:
最大900Byte
DATA空间:
7字节
STACK空间:
3字节
XDATA空间:
0字节
时钟数:
0个
系统时钟分频:
1000-----65535
中断嵌套:
小于20层
任务切换时间:
100-700时钟周期
工具要求:
以下软件应用需要用RTX51Tiny
C51纺编译器
A51MarcoAssembler
BL51LinkerorLx51Linker
RTX51TNY.LIB和RTX51BT.LIB必需存储在库路径上,一般是文件夹\KEIL\C51\LIB
RTX51TNY.H包含文件必须存储在包含文件路径上,一般是文件夹\KEIL\C51\INC
目标要求:
应用程序可能需要外部分的数据存储空间,但内核并不需要外部存储空间
KEILC51支持各种存储模式:
选择存储模式只影响应用程序的存的数据存储,操作系统的变量和堆栈只存在于51的内存中,即DATA和IDATA,一般情况下,RTX51Tiny的应用只需要小存储模式
在RTX51Tiny中每个应用程序运行的时间是固定的,支持cooperative任务切换和round-robin任务切换,不支持preemptive任务切换和任务优先级。
如果应用程序需要preemptive任务切换则必须使用RTX51FULL-TimeExecutive版本。
中断:
RTX51Tiny的工作与中断函数是并行工作的。
中断服务程序可以向RTX51Tiny的任务发信号(使用函数isr_send_signal),也可以置位作任务的Ready标志(使用函数isr_set_ready)
在RTX51Tiny中必须使能中断,但是在RTX51Tiny没有中断服务管理
RTX51Tiny使用Timer0和Timer0中断。
全局中断禁能和Timer0中断禁能会使RTX51Tiny停止工作,所以只能在短时间内禁能中断。
可重入函数
非可重入的C函数不能被多个任务或中断过程调用。
非可重入的函数的参数和变量保存在静态存储空间中,当它们同时被多个任务调用时,这些参数和变量就可能被覆盖了。
你可以在多任务系统中调用非可重入函数如果你能保证他们不会同进行。
不过,这就意味着必须能round-robin任务调度,并且非可重入函数不可以调用RTX51Tiny的功能函数。
只使用寄存器就量和自动变量的函数自然地就是可重入函数,可以毫无限制地在RTX51Tiny中调用。
C51编译器支可重入函数。
可重入函把参数和局部变量保存在堆栈中。
这样就可以保证他们被多个任务同时使用。
RTX51Tiny并不管理可重入函数的堆栈,因些,如果你在应用程序中使用了可重入函数,你必须确保这些功能函数不调用任务RTX51Tiny的系统函数,并且可重入函数不会被round-robin任务切换所中断。
注意:
如果你打自在多个任务或中断中调用可重入或非可重入函数必须禁止round-robin任务切换。
运行时库:
所有的C51可重入运行时库可能毫无限制地在所用任务中使用。
非可重入时库的要与可重入函数的要求相同。
多个数据指针
C51编译器允许使用多个数据指针。
RTX51Tiny对他们不进行管理,所以在应用中你必须小心
Essentially,你必须确保在改变数据指针时不会发生round-robin切换。
注意:
当你打算使用多数据指针时你最好禁止round-robin切换。
算术单元
(说法与多个数据指针相同)
工作寄存器组
RTX51Tiny的所有任务都使用工作组0。
因些,所有的任务都必须使用C51默认的编译选项:
REGISTERBANK(0)
中断函数可能会使用其他的工作寄存器组。
然而RTX51Tiny在工作寄存器组中永远需要6个字节。
RTX51Tiny在工作寄存器组中使用的这些字节可以参考配置文件
单个任务程序
嵌入式和标准C程序都mian()函数开始。
在入式应用中,main函数一般都是一个死循环,我们也可以把它看作是一个连续执行的任务。
如:
voidmain(void)
{
while
(1)/*repeatforever*/
{
do_something();/*executethedo_something'task'*/
}
}
在这个例子中,do_something()函数可以认为是一个单任务,既然只有一个任务在执行,就不需要具有多任务能力或多任务操作系统。
多任务程序
许多成熟的C程序使用一种叫做pseudo多任务的策略,把多个作协做为一循环,如:
voidmain(void)
{
intcounter=0;
while
(1)/*repeatforever*/
{
check_serial_io();/*checkforserialinput*/
process_serial_cmds();/*processserialinput*/
check_kbd_io();/*checkforkeyboardinput*/
process_kbd_cmds();/*processkeyboardinput*/
adjust_ctrlr_parms();/*adjustthecontroller*/
counter++;/*incrementcounter*/
}
}
在这个例子中,每个函数完成一个独立的操作或任务。
这些函数是一个一个顺序执行的
当添加更多的任务时调度就行了一个问题。
比方说,如果函数process_kbd_cmds执行的时间比较长,主循环就需要很长时间才能再执行到函数check_serial_io,这时候串口的数据可能会丢失。
当然check_serial_io可以在主循环中多调用几次来解决这个问题,但最终这种方法并不是最有效的。
RTX51Tiny的程序
当使用RTX51Tiny时,你可以为每一个任务生成一个独立的函数,如:
voidcheck_serial_io_task(void)_task_1
{
/*ThistaskchecksforserialI/O*/
}
voidprocess_serial_cmds_task(void)_task_2
{
/*Thistaskprocessesserialcommands*/
}
voidcheck_kbd_io_task(void)_task_3
{
/*ThistaskchecksforkeyboardI/O*/
}
voidprocess_kbd_cmds_task(void)_task_4
{
/*Thistaskprocesseskeyboardcommands*/
}
voidstartup_task(void)_task_0
{
os_create_task
(1);/*Createserial_ioTask*/
os_create_task
(2);/*Createserial_cmdsTask*/
os_create_task(3);/*Createkbd_ioTask*/
os_create_task(4);/*Createkbd_cmdsTask*/
os_delete_task(0);/*DeletetheStartupTask*/
}
在这个例子中,每个函数定义了一个RTX51Tiny的任务。
RTX51Tiny程序没有主C函数,RTX51Tiny首先执行任务0。
作为一个典型的应用,任务0只是简单地用来生成其他的所有任务。
工作原理
RTX51Tiny使用并管理你的目标资源,这一部分讲述RTX51Tiny如何使用这些资源。
RTX51Tiny的许多方面都可以根据工程需要进行配置。
时间片中断
RTX51Tiny使用标准的8051的定时器0来产生定时中断。
这个中断就是RTX51Tiny的时钟片。
RTX51Tiny运行时库中用的时等待时间都是以这个时间片为单位的
RTX51Tiny的默认的时间片是10000个机器周期。
因此,标准的8051运行在12MHz的时钟下的时候,时间片有0.01S或着说是100Hz。
这个值可以在CONF_TNY.A51配置文件中更改。
注意:
你在以RTX51Tiny时间片中断中编辑你自己的代码,参考:
CONF_TNY.A51
任务:
RTX51Tiny可以看作是一个任务切换器。
要生成RTX51Tiny程序,你必须生成一个具有一个或多个任务的应用。
以下细节可以帮你更快地理解RTX51
任务必须用C语言编写,并且用KeilC51支持的关键词声明
RTX51Tiny使用准确的状态维护任务。
同时只有一个任务可以处于运行状态
可能会有多个任务处于就绪,等待,删除或超时状态
空闲任务总是处于就绪状态,即使使用你的所有任务都处于block状态
任务管理
RTX51Tiny的任务总是处于以下状态中一确定的状态
RUNNING:
任务处于运行状态,os_running_task_id返回正在运行的任务的编号
READY:
任务处于就绪状态。
当一个正在运行的任务运行完毕,RTX51Tiny就会启动下一个就绪状态的任务。
一个任务可以通设置他的READY标志位os_set_readyorisr_set_ready使它立即进入就绪状态(即使它可能正在等待时间到或等一个信号)
WAITTING:
处于等待一个事件的任务就处于等待状态。
当所等待的事件发生后,任务就转换到就绪状态,函数os_wait用来使一个作任务进行等待状态
DELETED:
没有开始运行的任务或被删除的任务处于DELETED状态。
函数os_delete_task使一个已经启动(使用函数os_create_task)的任务进入DELETED状态
TIME-OUT:
被round-robinTime-Out中断的任务处于TIME-OUT状态。
这个状态在round-robin程序中等效于READY状态
事件(Events)
在实时操作系统中事件可以用来控制任务的执行。
一个可能会等待一个事件,也可能给其他任务设置事件标志。
函数os_wait允许任务等待一个或多个事件。
任务等待的是最普通的事件就是Timeout,一个简单的Timeout就是一定数量的clockticks,当一个任务等待的时间耗尽时,它就可以继续执行了,当它等待时,其他的任务就可以运行
variantoftheTimeoutistheInterval.Anintervalislikeatimeoutexceptthatthespecifiednumberofclockticksisrelativetothelasttimetheos_waitfunctionwasinvokedbythetask.TheIntervalmaybeusedtogenerateataskwhichisrunonaregular,synchronousschedule(likeonceeverysecond)regardlessofhowlongthetasktakesbetweencallstotheos_waitfunction.(以上内容是说,interval类似于timeout,但与timeout不同的是interval参考的不是上一次任务执行后的时间,而是某个特定的时间点,从而是一个规律性的、周期性的运行的任务:
比如说每秒一次)
信号是任务间通信的一种简单的形式,一个任务可以等待其他作任务给他发一个信号(使用os_send_signalandisr_send_signal函数)。
每个任务的READY标志都可能被其他任务置位(使用os_set_readyandisr_set_ready函数)。
一个等timeout,interval,或信号的任务都可以通过置位READY标志重新启动。
RTX51Tiny会为每个事件维护一个标志。
以下事件选择项可以被用来表明等待什么:
事件选项描述
K_IVL等待特定数目的Interval
K_SIG等待一个信号
K_TMO等待Timeout
当函数os_wait返回,发生的事件被返回值标志
返回值描述
RDY_EVENT任务的就绪标志被置位
SIG_EVENT信号已收到
TMO_EVENT一个Timeout已经结束或一个interval已经完毕
函数os_wait可能会等待以下事件组合
K_SIG|K_TMO:
os_wait延迟任务直到一个信号已经发给他,或直到设定的clocktick耗尽
K_SIG|K_IVL:
os_wait延迟任务直到一个信号已经发给他,或直到设定的interval耗尽
注意:
上面的两个事件也可能不组合。
任务调度器
任务调度器是RTX51Tiny的一部分,用来将处理器交给任务。
任务调度器根据以下规则决定具体执行哪一个任务。
当出现以下情况将中断当前任务
任务调用函数os_wait,并且等待的任务还没有发生
任务执行的时间超过了设定的round-robin时间片
其他的任务在出现以下条件时开始运行
没有其他任务正在运行
将启动的任务正处于就绪状态或TIME-OUT状态
RTX51tiny
(2)
Round-robin任务切换
RTX51Tiny可以配置成使用round-robin多任务。
Round-robinp容许quasi-parallel执行多任务。
任务并不是连续执行的,而是分时间片执行的(可用的CPU时间被分成时间片,RTX51Tiny把时间片分配给各个任务)。
时间片的时间很短(以毫秒为单位),所以任务看起来像连续执行一样
任务在分配给他的时间片内执行(除非放弃)。
然后切换到下一个就绪的任务。
RTX51 tiny(3)
编译连接
有两种方法编译和连接RTX51Tiny应用程序
RTX51Tiny(4)
os_set_ready
Summary:
#include
charos_set_ready(
unsignedchartask_id);/*Tasktomakeready*/
Description:
使编号为task_id的任务就入就绪状态,可以任务中调用该函数
ReturnValue:
None.
原创:
RTX51 Tiny操作系统实例应用
0
推荐
/******************************************************************************/
/* */
/* RCPU.C:
C-51COMPILER */
/* */
/******************************************************************************/
charcodetitle[]=
"RCPU\n"
"GLOBALTECH2005\n"
"VERSION2.0\n";
#include /*specialfunctionregisters8052 */
#include /*RTX-51tinyfunctions&defines */
#include /*standardI/O.h-file */
#include
#include"keyname.h"
#include"vfd.h"
#include"tmr2.h"
/*constantsforos_taskfunction*/
#defineINIT 0 /*tasknumberoftask:
init */
#definePROCKEY 1 /*tasknumberoftask:
prockey */
#definePROCPIR 2 /*tasknumberoftask:
procpir */
#defineVFDCODE 3 /*tasknumberoftask:
vfdcode */
#defineNECCODE 4 /*tasknumberoftask:
neccode */
#defineUSARTSEND5 /*tasknumberoftask:
usartsend */
#defineCLOCK 7 /*tasknumberoftask:
clock */
#defineTICK 6 /*tasknumberoftask:
procrst */
#defineVIEWCON 8
/*constantsforUsartSendfunction*/
#defineUsartSendMotor1 /*CommandforcontroltoMOTOboard */
#defineUsartSendQCB 2 /*CommandforcontroltoQCBboard */
#defineUsartSendTime 3 /*Systemtime */
#defineUsartSendVFD 4 /*IDEstate */
#defineUsartSendPIR 5 /*pir */
#defineUsartSendNEC 6 /*NECcode */
#defineUsartSendKey 7 /*keycode */
#defineUsartSendPIREN8 /*PIR_EN */
#defineIDEFREE 1
#defineIDEPLAY 2
#def