您的位置:首页 > 其它

UCOS消息队列的使用【转+原创】

2009-05-17 18:20 190 查看
消息队列的使用

1、 需在以下文件中配置如下内容

OS_CFG.H

OS_MAX_QS N 你需要的值

根据需要自己配置

#define OS_Q_EN 1 /* Enable (1) or Disable (0) code generation for QUEUES */

#define OS_Q_ACCEPT_EN 1 /* Include code for OSQAccept() */

#define OS_Q_DEL_EN 1 /* Include code for OSQDel() */

#define OS_Q_FLUSH_EN 1 /* Include code for OSQFlush() */

#define OS_Q_POST_EN 1 /* Include code for OSQPost() */

#define OS_Q_POST_FRONT_EN 1 /* Include code for OSQPostFront() */

#define OS_Q_POST_OPT_EN 1 /* Include code for OSQPostOpt() */

#define OS_Q_QUERY_EN 1 /* Include code for OSQQuery() */

2、 建立一个指向消息数组的指针和数组的大小,该指针数组必须申明为void类型,如下:

void *MyArrayOfMsg[SIZE];

3、 声明一个OS_EVENT类型的指针指向生成的队列,如下:

OS_EVENT *QSem;

4、 调用OSQcreate()函数创建消息队列,如下:

QSem = OSQcreate(&MyArrayOfMsg[0],SIZE);

5、 等待消息队列中的消息,OSQPend()。

void *OSQPend (OS_EVENT *pevent, INT16U timeout, INT8U *err):

必须保证消息队列已经被建立。

timeout定义的是等待超时时间,如果为0则表示无期限的等待

err表示的是在等待消息队列出错时的返回类型,有以下几种:

OS_ERR_PEVENT_NULL //消息队列不存在

OS_ERR_EVENT_TYPE

OS_TIMEOUT //消息队列等待超时

OS_NO_ERR //消息队列接收到消息

获得消息队列示例

type *GETQ;

INT8U err;

GETQ = (type *)OSQPend(QSem, time, &err);

if(err == OS_NO_ERR){

无错处理

}

else{

出错处理

}



6.1 向消息队列发送一则消息(FIFO),OSQPost(); INT8U OSQPost (OS_EVENT *pevent, void *msg):

函数返回值有:

OS_ERR_PEVENT_NULL

OS_ERR_POST_NULL_PTR

OS_ERR_EVENT_TYPE

OS_Q_FULL

OS_NO_ERR

参数:pevent,*msg

6.2 向消息队列发送一则消息(LIFO) INT8U OSQPostFront (OS_EVENT *pevent, void *msg)

6.3 向消息队列发送一则消息(LIFO或者FIFO) INT8U OSQPostOpt (OS_EVENT *pevent, void *msg, INT8U opt)

参数: opt

如果经opt参数中的OS_POST_OPT_BROADCAST位置为1,则所有正在等待消息的任务都能接收到这则消息,并且被OS_EventTaskRdy()从等待列表中删除

如果不是广播方式,则只有等待消息的任务中优先级最高的任务能够进入就绪态。然后,OS_EventTaskRdy()从等待列表中把等待消息的任务中优先级最高的任务删除。

注: 如果此函数由ISR调用,则不会发生任务切换,直到中断嵌套的最外层中断服务子程序调用OSIntExit()函数时,才能进行任务切换

7、 无等待的从消息队列中获得消息,OSQAccept(); void *OSQAccept (OS_EVENT *pevent, INT8U *err)

err可能的返回值:

OS_ERR_PEVENT_NULL

OS_Q_EMPTY

OS_NO_ERR

函数的返回值:消息,0

8、 清空消息队列 INT8U OSQFlush (OS_EVENT *pevent)

函数返回值:

OS_ERR_PEVENT_NULL

OS_ERR_EVENT_TYPE

OS_NO_ERR

9、 获取消息队列的状态,OSQQuery(); INT8U OSQQuery (OS_EVENT *pevent, OS_Q_DATA *p_q_data)

函数返回值:

OS_ERR_PEVENT_NULL

OS_ERR_EVENT_TYPE

OS_NO_ERR

OS_Q_DATA数据结构在ucos_ii.h中

==================================华丽的分割线===================================

现在来说一下这个消息队列所传递的数据类型和特性。

首先,这个消息队列不是真正意义上的“队列”,它呢只会把每次存入的数据指针排队,而不会保存该数据。所以调用OSQPost时如果每次都是相同的指针,那就说明 白放了,因为读取的时候读到的是同一个指针,他总是最新的数据,老的没了,何来队列?

其次,该队列可以保存void*类型指针,即所有数据类型都适用,管他是整型还是结构体。

现在这个队列不是真队列,那怎么解决?莫急,看下面:

我这里提一种简单的方法,复杂的各位资格解决吧。

1、定义一个存放数据的缓冲区数组,这样每次向对列添加时就可以用不同的地址。例如struct my_struct data_array[10]

2、然后就是怎么变这个数组下标的问题,直接定义一个变量来寻找,然后使用++,到最后再折回来就好了,例如:

int idx=0;

idx++;

idx %= BUF_SIZE;

3、对于速度能及时解决的任务,那下标这样搞就可以,如果不行,那可能要重新考虑覆盖的问题了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: