单任务程序

一个标准的 C语言程序从主函数开始执行。在一个嵌入式应用中,主函数通常是一段无限循环的代码,可以认为是一个连续执行的单独任务。

例如∶

 

int counter;

 

void main (void) {

  counter = 0;

  while (1) {                  /* 始终重复 */

  counter++;                   /* 计数器加1 */

  }

}

 

 

时间片轮转程序

一种更高级的 C语言程序可以在不使用实时操作系统的情况下实现时间片轮转拟多任务系统。在这种系统中、任务或功能被一段无限循环程序重复调用。

 例如∶

int counter;

void main (void) {

   counter = 0;

   while (1) {                               /* 始终重复 */

   check_serial_io ();

   process_serial_cmds ();                /* 处理串行输入 */

   check_kbd_io ();

   process_kbd_cmds ();                    /* 处理键盘输入 */

   adjust_ctrlr_parms ();                  /* adjust the controller */

   counter++;                                /* increment counter */

  }

}

 

 

用 RTX51进行时间片轮转调度

rtx51也能完成多重任务时间片轮转,而且允许准并行执行多个无限循环或任务。任务并不是并行执行的而是按时间片执行的。可利用的中央处理器时间被分成时间片由 RTX51分配一个时间片给各个任务。每个任务允许执行一个预先确定的时间。然后,rtx51切换到另一准备运行的任务并且允许这个任务执行片刻。时间片非常短、通常为几个毫秒。因此、它表现得如同各个任务是同时地执行的。

 

RTX51使用一个8051硬件计时器中断作为定时程序,产生的周期性中断用于驱动 RTX51时钟。RTX51不需要在你的程序中拥有一个主函数。它将自动开始执行任务 0。如果你确实有一个主函数,你必须利用 RTX51 Tiny中的 os_create_task函数或 RTX51中的 os_start_system函数手工启动 RTX51。

下面的例子显示一个只使用时间片轮转任务调度的简单的 RTX51应用程序。在本程序里的二个任务是简单的计数器回路。rtx51启动时执行函数名为 job0的任务 0。这个函数添加了另一个叫做 job1 的任务。在 job0 运行一会儿以后、RTX51切换到 job1。在 job1运行一会儿以后、RTX51转回到 job0。这个过程将不确定地重复下去。

 

#i nclude <rtx51tny.h>

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 */

    }

}

 

RTX51事件

即使是在等待一个任务的时间片到达时,你也可以使用 os_wait函数通知 RTX51它可以让另一个任务开始执行。这个功能中止正在运行的当前任务然后等待一个指定事件的发生。在这个时候、任意数量的其他任务仍可以执行。

使用 RTX51的时间溢出事件

你可以用 os_wait函数等待的最简单的事件是 RTX51时钟报时信号周期溢出。这类事件可被用于任务中需要延迟一段时间的地方。这可用于查询一个开关状态的代码中。在这样的应用中,只须每隔 50ms左右查询一次开关状态。下一个例子示范了如何在允许其他的任务执行的时候使用 os_wait功能延迟任务的执行。

 

 


#i nclude <rtx51tny.h>

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 */

    os_wait (K_TMO, 3);               /* pause for 3 clock ticks */

    }

}

void job1 (void) _task_ 1 {

     while (1) {                           /* loop forever */

     counter1++;                           /* update the counter */

     os_wait (K_TMO, 5);                  /* pause for 5 clock ticks */

     }

}

 

在上面的例子中、job0像前面叙述的一样启动 job1。然后,在增加 counter0计数以后,job0调用 os_wait函数以暂停3个时钟报时信号。这时,rtx51切换到下一个任务 job1。在 job1增加 counter1计数以后、它也调用 os_wait以暂停5个时钟报时信号。现在、rtx51没有其他的任务需要执行,因此在它可以延续执行 job0之前它进入一个空循环等待3个时钟报时信号过去。

这个例子运行的结果是 counter0每3个时钟报时周期加1,而 counter1每5个时钟报时周期加 1。

 

 

使用 RTX51的信号

你可以使用 os_wait功能暂停一个任务并等待从另一个任务发出的信号(或旗标)。这可以用于协调两个或更多的任务。等待一个信号会如下面所诉工作∶如果一任务在等待一个信号,并且信号标志是 0,在这个信号被发送之前,这个任务将一直处于挂起状态。如果信号标志已经是 1,当任务查询信号时、信号标志会被清除,并且继续执行任务。

 

以下例子说明了这种应用∶

#i nclude <rtx51tny.h>

int counter0;

int counter1;

void job0 (void) _task_ 0 {

     os_create (1);                   /* mark task 1 as ready */

     while (1) {                      /* loop forever */

     if (++counter0 == 0)           /* update the counter */

     os_send_signal (1);            /* signal task 1 */

    }

}

void job1 (void) _task_ 1 {

    while (1) {                      /* loop forever */

    os_wait (K_SIG, 0, 0);         /* wait for a signal */

    counter1++;                      /* update the counter */

    }

}

 

在上述例子中,job1一直处于等待状态,直到它接收到从任何其他任务发出的信号。当它接收到一个信号时、它将使 counter1加 1然后继续等待另一个信号。job0将连续地增加 counter0直到它溢出到 0。当溢出发生时、job0发送一个信号给 job1同时 RTX51标记 job1为执行状态。在 RTX51到达下一个时钟报时周期前,job1不会开始执行。

 

优先权和抢先机制

上述程序的缺点是当 job0发出信号时 job1并不是立即开始执行。在一些情况下,由于时间的原因这是不受欢迎的。RTX51允许你指定任务的优先级。一个具有较高优先级的任务变成可用的时,会中断一个低优先级任务或抢在它前面执行。这叫做优先型多任务或仅仅称之为抢先机制。

 

注意 RTX51 Tiny不支持抢先机制和优先权。

 

你可以变更上述函数 job1的说明给它一个比 job0高的优先级。全部任务的默认优先级均为 0。这是最低的优先级。优先级可以设定为 0-3。下面的例子说明如何定义 job1的优先级为1。

 

void job1 (void) _task_ 1 _priority_ 1 {

    while (1) {                        /* loop forever */

    os_wait (K_SIG, 0, 0);           /* wait for a signal */

    counter1++;                        /* update the counter */

    }

}

 

现在、每当 job0发送一个信号给 job1时,job1将立即开始执行。

用 RTX51进行编译和连接

rtx51是完全地统一到 c51程序设计语言中的。这使得很容易熟悉如何生成 RTX51应用程序。上述的例子是可执行的 RTX51程序。你不需要书写任何 8051汇编程序或函数。你唯一需要做的是用c51编译你的 RTX51程序并把他们用 BL51 Linker/Locator连接在一起。例如:如果你使用 RTX51 Tiny的话,你将使用以下命令行命令进行编译和连接:

C51 EXAMPLE.C

BL51 EXAMPLE.OBJ RTX51TINY

 

如果你使用 RTX51 的话,你将使用以下命令行命令进行编译和连接:

C51 EXAMPLE.C

BL51 EXAMPLE.OBJ RTX51

 

中断

RTX51工作在与中断功能相似的状态下。中断函数可以与 RTX51通信并且可以发送信号或消息给 RTX51任务。RTX51 Full允许将中断指定给一个任务。

 

消息传送

RTX51 Full支持使用以下函数在任务间进行消息交换:SEND、 RECEIVE MESSAGE和 WAIT for MESSAGE。消息是一个可以解释为指向存储块的指示字的 16位数值。RTX51 Full支持使用可分配存储区系统、可变大小的消息。

 

CAN通信

局域网控制器可以很容易地用 RTX51/CAN实现。RTX51/CAN是一个统一在 RTX51 Full中的 CAN任务。RTX51 CAN任务实现经由 CAN网络的信息传送。其他的CAN工作站既可以使用 RTX51 配置也可以不使用 RTX51 配置。

 

BITBUS通信

RTX51 Full 包括支持用 Intel 8044传送信息的主和从 BITBUS任务。

 

事件

RTX51的等待功能支持以下事件∶

 

·超时(Timeout)∶挂起运转的任务指定数量的时钟报时周期。

 

·间隔( Interval)∶(仅在 RTX51 Tiny中使用)类似于超时,但是软件定时器没有复位来产生循环的间隔(时钟所需要的)。

 

·信号(Signal)∶用于任务内部协调。

 

·消息(Message)∶(仅适用于 RTX51 Full)用于消息的交换。

 

·中断( Interrupt)∶(仅适用于 RTX51 Full)一个任务可以等待 8051硬件中断。

 

·旗标标志( Semaphore)∶(仅适用于 RTX51 Full)旗标标志用于管理共享的系统资源。

posted on 2013-03-19 21:36  爱哎唉  阅读(2359)  评论(0)    收藏  举报