首先想说一句别把麻烦管理员我的帖子转到其他地方,因为这里的人群旺!!高手多!!
进来发现keil自带的实时操作系统RTX(由于ARM,RTX-51是针对51的)的资源非常丰富,集成了TCP/IP、CAN、USB、FS等协议栈。
因为我以前有UCOS-II的基础,所以很快就看完了,比较而言:
1、RTX在调度方式上增加了 时间片轮转的方式
2、RTX的邮箱集成了UCOS的邮箱和消息队列的功能,但是没有“广播”的功能
3、RTX的软件定时器功能一般般。可能是用的不多的原因。
4、UCOS的用户群庞大,资料丰富 ,但是需要自己移植其他协议栈,如LwIP等,RTX资源丰富。
我在调试RTX的邮箱(\Keil\ARM\RL\RTX\Examples\Mailbox)这个例子的时候遇到不解的问题:
这个例子非常简单,由于演示邮箱的基本用法,具体是这样的:
建立的两个任务:一个是邮箱发送任务,发送三条消息,然后删除自己。另一个是邮箱接收任务,在无限循环中等待邮箱消息并处理(即调用os_dly_wait()函数挂起任务直到消息到来),两个任务都是同样的优先级,使能了时间片轮转的功能,在邮箱发送任务中,每调用一次 os_mbx_send(邮箱发送函数) 之后都会调用 os_dly_wait(系统延时函数)来调度任务,以便让邮箱接收任务处理发送任务发送的消息。这个没问题。 我在单步执行的时候观察,在任务发送任务中切换到接收的任务的时候是在执行os_dly_wait(系统延时函数) 时, 不是在执行完os_mbx_send(邮箱发送函数) ,这是正确的因为两个任务是同样的优先级。刚刚发送完消息之后接收任务只是处于“就绪态”当调用os_mbx_send()后交出了执行权。
然后我就想,那我要是改变两个任务的优先级,让接收任务的优先级比发送任务邮箱级高,那么现象应该是:在发送任务执行完 os_mbx_send(邮箱发送函数) 后就应该发生调度,在ucos中是这样的,因为这就是优先级抢占的基本思想。但是奇怪的是:这样改变优先级后,无论是执行os_mbx_send()还是os_dly_wait()都不会产生任务调度,也就是说发送消息“丢失了”。
然后我尝试改变两者优先级为:发送任务高,接收任务低,现象正确。
请教各路高手 这是为什么?发送任务优先级低,接收任务优先级高,就不会产生任务调度。。。。。。。
我还是贴一下源代码吧!!!
#include <RTL.h> /* RTX kernel functions & defines */
#include <LPC21xx.H> /* LPC21xx definitions */
#include <stdio.h>
OS_TID tsk1; /* assigned identification for task 1 */
OS_TID tsk2; /* assigned identification for task 2 */
typedef struct { /* Message object structure */
float voltage; /* AD result of measured voltage */
float current; /* AD result of measured current */
U32 counter; /* A counter value */
} T_MEAS;
os_mbx_declare (MsgBox,16); /* Declare an RTX mailbox */
_declare_box (mpool,sizeof(T_MEAS),16);/* Dynamic memory pool */
__task void send_task (void);
__task void rec_task (void);
/*----------------------------------------------------------------------------
* Initialize serial interface
*---------------------------------------------------------------------------*/
void init_serial () {
PINSEL0 = 0x00050000; /* Enable RxD1 and TxD1 */
U1LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */
U1DLL = 97; /* 9600 Baud Rate @ 15MHz VPB Clock */
U1LCR = 0x03; /* DLAB = 0 */
}
/*----------------------------------------------------------------------------
* Task 1: RTX Kernel starts this task with os_sys_init (send_task)
*---------------------------------------------------------------------------*/
__task void send_task (void) {
T_MEAS *mptr;
os_tsk_prio_self (5); // 修改发送消息任务的优先级 为“5”
tsk1 = os_tsk_self (); /* get own task identification number */
tsk2 = os_tsk_create (rec_task, 7); // 接收消息任务的优先级为“7” /* start task 2 */
os_mbx_init (MsgBox, sizeof(MsgBox));/* initialize the mailbox */
os_dly_wait (5); /* Startup delay for MCB21xx */
mptr = _alloc_box (mpool); /* Allocate a memory for the message */
mptr->voltage = 223.72; /* Set the message content */
mptr->current = 17.54;
mptr->counter = 120786;
os_mbx_send (MsgBox, mptr, 0xffff); /* Send the message to the mailbox */
IOSET1 = 0x10000;
os_dly_wait (100);
mptr = _alloc_box (mpool);
mptr->voltage = 227.23; /* Prepare a 2nd message */
mptr->current = 12.41;
mptr->counter = 170823;
os_mbx_send (MsgBox, mptr, 0xffff); /* And send it. */
os_tsk_pass (); /* Cooperative multitasking */
IOSET1 = 0x20000;
os_dly_wait (100);
mptr = _alloc_box (mpool);
mptr->voltage = 229.44; /* Prepare a 3rd message */
mptr->current = 11.89;
mptr->counter = 237178;
os_mbx_send (MsgBox, mptr, 0xffff); /* And send it. */
IOSET1 = 0x40000;
os_dly_wait (100);
os_tsk_delete_self (); /* We are done here, delete this task */
}
/*----------------------------------------------------------------------------
* Task 2: RTX Kernel starts this task with os_tsk_create (rec_task, 0)
*---------------------------------------------------------------------------*/
__task void rec_task (void) {
T_MEAS *rptr;
for (;;) {
os_mbx_wait (MsgBox, (void **)&rptr, 0xffff); /* wait for the message */
printf ("\nVoltage: %.2f V\n",rptr->voltage);
printf ("Current: %.2f A\n",rptr->current);
printf ("Number of cycles: %d\n",rptr->counter);
_free_box (mpool, rptr); /* free memory allocated for message */
}
}
/*----------------------------------------------------------------------------
* Main: Initialize and start RTX Kernel
*---------------------------------------------------------------------------*/
int main (void) { /* program execution starts here */
IODIR1 = 0xFF0000; /* P1.16..22 defined as Outputs */
init_serial (); /* initialize the serial interface */
_init_box (mpool, sizeof(mpool), /* initialize the 'mpool' memory for */
sizeof(T_MEAS)); /* the membox dynamic allocation */
os_sys_init (send_task); /* initialize and start task 1 */
}
/*----------------------------------------------------------------------------
* end of file
*---------------------------------------------------------------------------*/
问题已经解决了!原因出在例程的邮箱初始化被放在了接收消息任务的创建之前,所以导致接收任务执行出错!原来还发现创建接收任务时,由于改变接收任务的优先级比创建接收任务的发送任务优先级高,接收任务执行一次,但是,后来这种现象又消失了!在把创建接收任务的语句放在邮箱初始化语句后,程序运行正常!!!
在这里要非常感谢ucos-II 版主 wstrom 老师对我的帮助!!!
[ 本帖最后由 历史的天空 于 2011-7-25 09:22 编辑 ]