rtx51小型实时操作系统的应用体会

上传人:y****n 文档编号:157354200 上传时间:2022-09-29 格式:DOCX 页数:19 大小:23.46KB
收藏 版权申诉 举报 下载
rtx51小型实时操作系统的应用体会_第1页
第1页 / 共19页
rtx51小型实时操作系统的应用体会_第2页
第2页 / 共19页
rtx51小型实时操作系统的应用体会_第3页
第3页 / 共19页
资源描述:

《rtx51小型实时操作系统的应用体会》由会员分享,可在线阅读,更多相关《rtx51小型实时操作系统的应用体会(19页珍藏版)》请在装配图网上搜索。

1、rtx51小型实时操作系统的应用体会2007年06月27日 星期三 23:53最近在做设计的时候老遇到一些几个任务需要同时进行的情况,刚开始想自己去做一个多任务的程序(因为称不上系统),想用一个脉冲计数的方法来实现多任务切换,但是感觉实现起来比较麻烦。无意中发现了51单片机下个rtx51实时操作系统(本人以前不知道的),后来就去找相关资料。发现这方面的资料在网上很少,也很杂乱。经过一段时间的学习,我有了个大概的了解。下面给大家讲述一下:RTX51是一个用于8051系列处理器多任务实时操作系统。RTX51可以简化那些复杂而且时间要求严格的工程的软件设计工作。有二个不同的RTX51版本可以利用:R

2、TX51 Full 使用四个任务优先权完成同时存在时间片轮转调度和抢先的任务切换 RTX51工作在与中断功能相似的状态下 信号和信息可以通过邮箱系统在任务之间互相传递 你可以从一存池中分配和释放内存 你可以强迫一个任务等待中断 超时或者是从另一个任务或中断发出的信号或信息RTX51 Tiny 是一个 RTX51的子集 它可以很容易地在没有任何外部存储器的单片8051系统上运转。 除了下列例外 RTX51 Tiny支持许多在RTX51中的特征。RTX51 Tiny仅支持时间片轮转任务切换和使用信号进行任务切换 不支持抢先式的任务切换。不包括消息历程。没有存储器池分配程序 。RTX51使用一个80

3、51硬件计时器中断作为定时程序。 产生的周期性中断用于驱动 RTX51时钟。 RTX51不需要在你的程序中拥有一个主函数 它将自动开始执行任务 0 如果你确实有一个主函数 你必须利用 RTX51 Tiny中的 os_create_task函数或 RTX51中的 os_start_system函数手工启动 RTX51。 下列例子显示一个只使用时间片轮转任务调度的简单的 RTX51应用程序 在本程序里的二个任务是简单计数器回路 rtx51开始执行函数名为 job0的任务 0 。 这些功能添加了另一个叫做 job1任务。 在 job0运行一会儿以后 RTX51切换到 job1。 在 job0运行一会

4、儿以后、RTX51转回到job0。 这个过程将不确定地重复下去 #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 */ 今天夜已很深了

5、,明早还有考试,对不起了,不写了。我介绍几个资料的下载地址,大家自己去看吧!【转】 KEIL RTX51 TINY内核的分析与应用2011年04月18日 星期一 19:28转载自 lan042最终编辑 lan042特性:最大任务数:16最大激活的任务数:16所需的CODE空间:最大900ByteDATA空间:7字节STACK空间:3字节XDATA空间:0字节时钟数:0个系统时钟分频:1000-65535中断嵌套:小于20层任务切换时间:100-700时钟周期工具要求:以下软件应用需要用 RTX51 TinyC51纺编译器A51 Marco AssemblerBL51 Linker or Lx5

6、1 LinkerRTX51TNY.LIB 和 RTX51BT.LIB必需存储在库路径上,一般是文件夹KEILC51LIBRTX51TNY.H包含文件必须存储在包含文件路径上,一般是文件夹KEILC51INC目标要求:应用程序可能需要外部分的数据存储空间,但内核并不需要外部存储空间KEIL C51支持各种存储模式:选择存储模式只影响应用程序的存的数据存储,操作系统的变量和堆栈只存在于51的内存中,即DATA和IDATA,一般情况下,RTX51 Tiny的应用只需要小存储模式在RTX51 Tiny中每个应用程序运行的时间是固定的,支持cooperative任务切换和round-robin任务切换,

7、不支持preemptive任务切换和任务优先级。如果应用程序需要preemptive任务切换则必须使用RTX51 FULL-Time Executive版本。中断:RTX51 Tiny的工作与中断函数是并行工作的。中断服务程序可以向RTX51 Tiny的任务发信号(使用函数isr_send_signal),也可以置位作任务的Ready标志(使用函数isr_set _ready)在RTX51 Tiny中必须使能中断,但是在RTX51 Tiny没有中断服务管理RTX51 Tiny使用Timer0和Timer0中断。全局中断禁能和Timer0中断禁能会使RTX51 Tiny停止工作,所以只能在短时间

8、内禁能中断。可重入函数非可重入的C函数不能被多个任务或中断过程调用。非可重入的函数的参数和变量保存在静态存储空间中,当它们同时被多个任务调用时,这些参数和变量就可能被覆盖了。你可以在多任务系统中调用非可重入函数如果你能保证他们不会同进行。不过,这就意味着必须能 round-robin任务调度,并且非可重入函数不可以调用RTX51 Tiny的功能函数。只使用寄存器就量和自动变量的函数自然地就是可重入函数,可以毫无限制地在RTX51 Tiny中调用。C51编译器支可重入函数。可重入函把参数和局部变量保存在堆栈中。这样就可以保证他们被多个任务同时使用。RTX51 Tiny并不管理可重入函数的堆栈,因

9、些,如果你在应用程序中使用了可重入函数,你必须确保这些功能函数不调用任务RTX51 Tiny的系统函数,并且可重入函数不会被round-robin任务切换所中断。注意:如果你打自在多个任务或中断中调用可重入或非可重入函数必须禁止round-robin任务切换。运行时库:所有的C51可重入运行时库可能毫无限制地在所用任务中使用。非可重入时库的要与可重入函数的要求相同。多个数据指针C51编译器允许使用多个数据指针。RTX51 Tiny对他们不进行管理,所以在应用中你必须小心Essentially,你必须确保在改变数据指针时不会发生round-robin切换。注意:当你打算使用多数据指针时你最好禁止

10、round-robin切换。算术单元(说法与多个数据指针相同)工作寄存器组RTX51 Tiny的所有任务都使用工作组0。 因些,所有的任务都必须使用C51默认的编译选项:REGISTERBANK (0)中断函数可能会使用其他的工作寄存器组。然而RTX51 Tiny在工作寄存器组中永远需要6个字节。RTX51 Tiny在工作寄存器组中使用的这些字节可以参考配置文件单个任务程序嵌入式和标准C程序都mian()函数开始。在入式应用中, main函数一般都是一个死循环,我们也可以把它看作是一个连续执行的任务。如:void main (void)while (1) /* repeat forever *

11、/do_something (); /* execute the do_something task */在这个例子中,do_something ()函数可以认为是一个单任务,既然只有一个任务在执行,就不需要具有多任务能力或多任务操作系统。多任务程序许多成熟的C程序使用一种叫做pseudo多任务的策略,把多个作协做为一循环,如:void main (void)int counter = 0;while (1) /* repeat forever */check_serial_io (); /* check for serial input */process_serial_cmds (); /

12、* process serial input */check_kbd_io (); /* check for keyboard input */process_kbd_cmds (); /* process keyboard input */adjust_ctrlr_parms (); /* adjust the controller */counter+; /* increment counter */在这个例子中,每个函数完成一个独立的操作或任务。这些函数是一个一个顺序执行的当添加更多的任务时调度就行了一个问题。比方说,如果函数process_kbd_cmds执行的时间比较长,主循环就需要

13、很长时间才能再执行到函数check_serial_io ,这时候串口的数据可能会丢失。当然check_serial_io 可以在主循环中多调用几次来解决这个问题,但最终这种方法并不是最有效的。RTX51 Tiny的程序当使用RTX51 Tiny时,你可以为每一个任务生成一个独立的函数,如:void check_serial_io_task (void) _task_ 1/* This task checks for serial I/O */void process_serial_cmds_task (void) _task_ 2/* This task processes serial co

14、mmands */void check_kbd_io_task (void) _task_ 3/* This task checks for keyboard I/O */void process_kbd_cmds_task (void) _task_ 4/* This task processes keyboard commands */void startup_task (void) _task_ 0os_create_task (1); /* Create serial_io Task */os_create_task (2); /* Create serial_cmds Task */

15、os_create_task (3); /* Create kbd_io Task */os_create_task (4); /* Create kbd_cmds Task */os_delete_task (0); /* Delete the Startup Task */在这个例子中,每个函数定义了一个RTX51 Tiny的任务。RTX51 Tiny程序没有主C函数,RTX51 Tiny首先执行任务0。作为一个典型的应用,任务0只是简单地用来生成其他的所有任务。工作原理RTX51 Tiny使用并管理你的目标资源,这一部分讲述RTX51 Tiny如何使用这些资源。RTX51 Tiny的许多

16、方面都可以根据工程需要进行配置。时间片中断RTX51 Tiny使用标准的8051的定时器0来产生定时中断。这个中断就是RTX51 Tiny的时钟片。RTX51 Tiny运行时库中用的时等待时间都是以这个时间片为单位的RTX51 Tiny的默认的时间片是10000个机器周期。因此,标准的8051运行在12MHz的时钟下的时候,时间片有0.01S或着说是100Hz。这个值可以在CONF_TNY.A51 配置文件中更改。注意:你在以RTX51 Tiny时间片中断中编辑你自己的代码,参考:CONF_TNY.A51任务:RTX51 Tiny可以看作是一个任务切换器。要生成RTX51 Tiny程序,你必须

17、生成一个具有一个或多个任务的应用。以下细节可以帮你更快地理解RTX51任务必须用C语言编写,并且用Keil C51支持的关键词声明RTX51 Tiny使用准确的状态维护任务。同时只有一个任务可以处于运行状态可能会有多个任务处于就绪,等待,删除或超时状态空闲任务总是处于就绪状态,即使使用你的所有任务都处于block状态任务管理RTX51 Tiny的任务总是处于以下状态中一确定的状态RUNNING:任务处于运行状态,os_running_task_id返回正在运行的任务的编号READY:任务处于就绪状态。当一个正在运行的任务运行完毕,RTX51 Tiny就会启动下一个就绪状态的任务。一个任务可以通

18、设置他的READY标志位os_set_ready or isr_set_ready使它立即进入就绪状态(即使它可能正在等待时间到或等一个信号)WAITTING:处于等待一个事件的任务就处于等待状态。当所等待的事件发生后,任务就转换到就绪状态,函数os_wait用来使一个作任务进行等待状态DELETED:没有开始运行的任务或被删除的任务处于DELETED状态。函数os_delete_task使一个已经启动(使用函数os_create_task)的任务进入DELETED状态TIME-OUT:被round-robin Time-Out中断的任务处于TIME-OUT状态。这个状态在round-robi

19、n程序中等效于READY状态事件(Events)在实时操作系统中事件可以用来控制任务的执行。一个可能会等待一个事件,也可能给其他任务设置事件标志。函数os_wait允许任务等待一个或多个事件。任务等待的是最普通的事件就是Timeout,一个简单的Timeout就是一定数量的clock ticks,当一个任务等待的时间耗尽时,它就可以继续执行了,当它等待时,其他的任务就可以运行variant of the Timeout is the Interval. An interval is like a timeout except that the specified number of clock

20、 ticks is relative to the last time the os_wait function was invoked by the task. The Interval may be used to generate a task which is run on a regular, synchronous schedule (like once every second) regardless of how long the task takes between calls to the os_wait function.(以上内容是说,interval类似于timeou

21、t,但与timeout不同的是interval参考的不是上一次任务执行后的时间,而是某个特定的时间点,从而是一个规律性的、周期性的运行的任务:比如说每秒一次)信号是任务间通信的一种简单的形式,一个任务可以等待其他作任务给他发一个信号(使用 os_send_signal and isr_send_signal 函数)。每个任务的READY标志都可能被其他任务置位(使用 os_set_ready and isr_set_ready 函数)。一个等timeout, interval, 或信号的任务都可以通过置位READY标志重新启动。RTX51 Tiny会为每个事件维护一个标志。以下事件选择项可以被

22、用来表明等待什么:事件选项 描述K_IVL 等待特定数目的IntervalK_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耗尽注意:上面的

23、两个事件也可能不组合。任务调度器任务调度器是RTX51 Tiny的一部分,用来将处理器交给任务。任务调度器根据以下规则决定具体执行哪一个任务。当出现以下情况将中断当前任务任务调用函数os_wait,并且等待的任务还没有发生任务执行的时间超过了设定的round-robin时间片其他的任务在出现以下条件时开始运行没有其他任务正在运行将启动的任务正处于就绪状态或TIME-OUT状态RTX51 tiny(2)Round-robin 任务切换RTX51 Tiny可以配置成使用round-robin多任务。Round-robinp容许quasi-parallel执行多任务。任务并不是连续执行的,而是分时间

24、片执行的(可用的CPU时间被分成时间片,RTX51 Tiny把时间片分配给各个任务)。时间片的时间很短(以毫秒为单位),所以任务看起来像连续执行一样任务在分配给他的时间片内执行(除非放弃)。然后切换到下一个就绪的任务。RTX51tiny(3)编译连接有两种方法编译和连接RTX51 Tiny应用程序RTX51 Tiny(4)os_set_readySummary:i nclude char os_set_ready (unsigned char task_id); /* Task to make ready */Description:使编号为task_id的任务就入就绪状态,可以任务中调用该函

25、数Return Value: None.原创:RTX51Tiny操作系统实例应用0推荐/*/* */* RCPU.C: C-51 COMPILER */* */*/char code title = RCPUn GLOBAL TECH 2005n VERSION 2.0n;i nclude /* special function registers 8052 */i nclude /* RTX-51 tiny functions & defines */i nclude /* standard I/O .h-file */i nclude i nclude keyname.hi nclude

26、vfd.hi nclude tmr2.h/* constants for os_task function */#define INIT 0 /* task number of task: init */#define PROCKEY 1 /* task number of task: prockey */#define PROCPIR 2 /* task number of task: procpir */#define VFDCODE 3 /* task number of task: vfdcode */#define NECCODE 4 /* task number of task:

27、neccode */#define USARTSEND 5 /* task number of task: usartsend */#define CLOCK 7 /* task number of task: clock */#define TICK 6 /* task number of task: procrst */#define VIEWCON 8/* constants for UsartSend function */#define UsartSendMotor 1 /* Command for control to MOTO board */#define UsartSendQ

28、CB 2 /* Command for control to QCB board */#define UsartSendTime 3 /* System time */#define UsartSendVFD 4 /* IDE state */#define UsartSendPIR 5 /* pir */#define UsartSendNEC 6 /* NEC code */#define UsartSendKey 7 /* key code */#define UsartSendPIREN 8 /* PIR_EN */#define IDEFREE 1#define IDEPLAY 2#

29、define IDESETUP 3#define IDERECORD 4#define IDENOSIG 5#define VIEWIDE 1#define VIEWQUAD1 2#define VIEWQUAD2 3unsigned char QUAD_NOW_BAK;unsigned char CAM_NOW_QUAD1;unsigned char CAM_NOW_QUAD2;unsigned char TickCounter;unsigned char MotorCmd;unsigned char NECCmd;unsigned char UsartSendData;unsigned c

30、har UsartSendCmd;unsigned char IDEStatus;unsigned char rst6s,stopcount;unsigned int rst4h;bit PWFlag;bit viewportbak;bit StopFlagBit;/*/* Task 0 init: Initialize */*/void init (void) _task_ INIT /* program execution starts here */ serial_init (); /* initialize the serial interface */ VIEW_SA = 0; VI

31、EW_SB = 0; os_create_task (PROCKEY); /* key sample task */ os_create_task (PROCPIR); /* PIR sample task */ os_create_task (VFDCODE); /* VFDCODE incepted from IDE board */ os_create_task (NECCODE); /* send NECCODE to IDE board */ os_create_task (USARTSEND); /* send data to USART port */ os_create_tas

32、k (CLOCK); /* start clock task */ os_create_task (TICK); /* process tick */ os_create_task (VIEWCON); os_delete_task (INIT); /* stop init task (no longer needed) */char code motordata =0x01,0x09,0x0,0x08,0x03,0x0B,0x02,0x0A,0x0D,0x05,0x0C,0x04,0x0F,0x07,0x0E,0x06;/*/* Task 1 prockey: monitor key inc

33、epted */*/void prockey (void) _task_ PROCKEY while (1) /* prockey is an endless loop */ KEY_NOW = _getkey (); /* key is incepted */ TickCounter = 0; if (KEY_NOW =)continue; if (KEY_NOW = SLEEP)continue; switch (KEY_NOW) /* */ case PANUP: if (CAM_NOW != 0)&(IDEStatus != IDESETUP) /* motor control */

34、MotorCmd = motordata(CAM_NOW-1)*4; UsartSendCmd = UsartSendMotor; os_send_signal (USARTSEND); break; case PANDOWN: if (CAM_NOW != 0)&(IDEStatus != IDESETUP) /* motor control */ MotorCmd = motordata(CAM_NOW-1)*4+1; UsartSendCmd = UsartSendMotor; os_send_signal (USARTSEND); break; case PANLEFT: if (ID

35、EStatus = IDESETUP) break; if (CAM_NOW = 0) /* QCB control */ CAM_NOW_QUAD1 = 0; QUAD_NOW = 1; UsartSendCmd = UsartSendQCB; os_send_signal (USARTSEND); NECCmd = TOQUAD1; os_send_signal (NECCODE); else /* motor control */ MotorCmd = motordata(CAM_NOW-1)*4+2; UsartSendCmd = UsartSendMotor; os_send_sig

36、nal (USARTSEND); break; case PANRIGHT: if (IDEStatus = IDESETUP) break; if (CAM_NOW = 0) /* QCB control */ CAM_NOW_QUAD2 = 0; QUAD_NOW = 2; UsartSendCmd = UsartSendQCB; os_send_signal (USARTSEND); NECCmd = TOQUAD2; os_send_signal (NECCODE); else /* motor control */ MotorCmd = motordata(CAM_NOW-1)*4+

37、3; UsartSendCmd = UsartSendMotor; os_send_signal (USARTSEND); break; case QUAD: /* QCB control */ if (IDEStatus = IDESETUP) break; if (CAM_NOW != 0) CAM_NOW = 0; UsartSendCmd = UsartSendQCB; os_send_signal (USARTSEND); if (QUAD_NOW=1)CAM_NOW_QUAD1 = CAM_NOW; if (QUAD_NOW=2)CAM_NOW_QUAD2 = CAM_NOW; b

38、reak; case CAMERA1: /* QCB control */ if (IDEStatus = IDESETUP) break; if (CAM_NOW = 0) CAM_NOW = 1; UsartSendCmd = UsartSendQCB; os_send_signal (USARTSEND); if (QUAD_NOW=1)CAM_NOW_QUAD1 = CAM_NOW; if (QUAD_NOW=2)CAM_NOW_QUAD2 = CAM_NOW; break; case CAMERA2: /* QCB control */ if (IDEStatus = IDESETU

39、P) break; if (CAM_NOW = 0) CAM_NOW = 2; UsartSendCmd = UsartSendQCB; os_send_signal (USARTSEND); if (QUAD_NOW=1)CAM_NOW_QUAD1 = CAM_NOW; if (QUAD_NOW=2)CAM_NOW_QUAD2 = CAM_NOW; break; case CAMERA3: /* QCB control */ if (IDEStatus = IDESETUP) break; if (CAM_NOW = 0) CAM_NOW = 3; UsartSendCmd = UsartS

40、endQCB; os_send_signal (USARTSEND); if (QUAD_NOW=1)CAM_NOW_QUAD1 = CAM_NOW; if (QUAD_NOW=2)CAM_NOW_QUAD2 = CAM_NOW; break; case CAMERA4: /* QCB control */ if (IDEStatus = IDESETUP) break; if (CAM_NOW = 0) CAM_NOW = 4; UsartSendCmd = UsartSendQCB; os_send_signal (USARTSEND); if (QUAD_NOW=1)CAM_NOW_QU

41、AD1 = CAM_NOW; if (QUAD_NOW=2)CAM_NOW_QUAD2 = CAM_NOW; break; case STOP: if (StopFlagBit = 0) NECCmd = KEY_NOW; os_send_signal (NECCODE); /* send NECCom to IDE */ break; default : NECCmd = KEY_NOW; os_send_signal (NECCODE); /* send NECCom to IDE */ break; if (KEY_NOW = STOP) /* stop check */ StopFla

42、gBit = 1; /* stop counter start */ else StopFlagBit = 0; /* stop counter stop */ /*/* Task 2 procpir: PIR signal manage */*/void procpir (void) _task_ PROCPIR unsigned char pirport,pirportn; while(1) if (IDEStatus = IDEFREE) pirport = P2; /* PIR Signal Sample */ if (pirport!=0xFF) pirportn = pirport

43、; UsartSendData = pirport; UsartSendCmd = UsartSendPIR; os_send_signal (USARTSEND); if (pirportn&0x01)!=0) if (PIR_EN&0x80)!=0) CAM_NOW = CAM_NOW_QUAD1; QUAD_NOW = 1; NECCmd = TRIG_Q1; os_send_signal (NECCODE); if (pirportn&0x02)!=0) if (PIR_EN&0x40)!=0) CAM_NOW = CAM_NOW_QUAD1; QUAD_NOW = 1; NECCmd = TRIG_Q1; os_send_signal (NECCODE); if (pirportn&0x04)!=0) if (PIR_EN&0x20)!=0) CAM_NOW = CAM_NOW_QUAD1; QUAD_NOW = 1; NECCmd = TRIG_Q1; os_send_signal (NECCODE); if (pirportn&0x08)!=0) if (PIR_EN&0x10)!=0) CAM_NOW = CAM_NOW_QUAD1; QUAD_NOW = 1; NECCmd = TRIG_Q1; os_send_signal (NECCODE);

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

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!