UCOSIII操作系统
- UCOSIII操作系统——消息队列篇(1)消息队列
- 消息队列常用函数
- 消息队列概念简介
- 创建消息队列->OSQCreate()
- 消息队列删除->OSQDel()
- 消息队列发送->OSQPost()
- 消息队列获取->OSQPend()
UCOSIII其他内容导航不迷路
UCOSIII操作系统-简介
【UCOSIII操作系统】任务篇(1)创建任务
【UCOSIII操作系统】任务篇(2)相关API函数
【UCOSIII操作系统】系统初始化篇(1)系统初始化
【UCOSIII操作系统】系统初始化篇(2)CPU,SysTick,内存初始化
【UCOSIII操作系统】硬件初始化篇(1)硬件初始化以及开始运行系统
【UCOSIII操作系统】消息队列篇(2)任务消息队列
【UCOSIII操作系统】信号量与互斥量篇(1)信号量
【UCOSIII操作系统】信号量与互斥量篇(2)互斥量
【UCOSIII操作系统】信号量与互斥量篇(3)任务信号量
【UCOSIII操作系统】事件篇
【UCOSIII操作系统】中断管理篇
【UCOSIII操作系统】临界段篇
【UCOSIII操作系统】软件定时器篇
【UCOSIII操作系统】内存管理篇
已完结
说在前面:
这个内容不适合0基础的人,因为这里只讲了应用层面的东西,并没有深入内核讲解,所以要从零开始学UCOSIII的朋友,可以先去学完入门内容,再来观看这个笔记加深印象。
这篇文章是个人学习整理,如有错误请指正
UCOSIII操作系统——消息队列篇(1)消息队列
消息队列常用函数
函数 | 描述 |
---|
OSQCreate() | 创建消息队列 |
OSQDel() | 消息队列删除 |
OSQPost() | 消息队列发送 |
OSQPend() | 消息队列获取 |
消息队列概念简介
队列又称消息队列,是一种常用于任务间通信的数据结构,队列可以在任务与任务间、中断和任务间传递信息,实现了任务接收来自其他任务或中断的不固定长度的消息,任务能够从队列里面读取消息。
创建消息队列->OSQCreate()
void OSQCreate (OS_Q *p_q,
CPU_CHAR *p_name,
OS_MSG_QTY max_qty,
OS_ERR *p_err)
- 在调用创建消息队列函数之前要定义一个消息队列结构体
OS_Q queue;
OSQCreate ((OS_Q *)&queue,
(CPU_CHAR *)"Queue For Test",
(OS_MSG_QTY )20,
(OS_ERR *)&err);
消息队列删除->OSQDel()
队列删除函数是根据队列结构体(队列句柄)直接删除的,删除之后这个消息队列的所有信息都会被系统清空,而且不能再次使用这个消息队列了,但是需要注意的是,如果某个消息队列没有被定义,那也是无法被删除的。想要使用消息队列删除函数就必须将OS_CFGQ_DEL_EN宏定义配置为1
#if OS_CFG_Q_DEL_EN > 0u
OS_OBJ_QTY OSQDel (OS_Q *p_q,
OS_OPT opt,
OS_ERR *p_err)
- 选项
OS_OPT_DEL_NO_PEND: //如果只在没有任务等待的情况下删除队列
OS_OPT_DEL_ALWAYS: //无论如何必须删除消息队列 - 应用实例
OSQDel ((OS_Q *)&queue,
OS_OPT_DEL_NO_PEND,
(OS_ERR *)&err);
消息队列发送->OSQPost()
void OSQPost (OS_Q *p_q,
void *p_void,
OS_MSG_SIZE msg_size,
OS_OPT opt,
OS_ERR *p_err)
- 消息指针
要发送的数据的指针,将内存块首地址通过队列“发送出去”,可以是"字符串"也可以是数组,在接受消息队列的时候可以通过指针取出具体消息。 - 选项
#define OS_OPT_POST_FIFO (OS_OPT) (0x0000u) /* 默认采用FIFO 方式发送 */
#define OS_OPT_POST_LIFO (OS_OPT) (0x0010u) /*采用LIFO 方式发送消息*/
#define OS_OPT_POST_1 (OS_OPT) (0x0000u) /*将消息发布到最高优先级的等待任务*/
#define OS_OPT_POST_ALL (OS_OPT) (0x0200u) /*向所有等待的任务广播消息*/
#define OS_OPT_POST_NO_SCHED (OS_OPT) (0x8000u) /*发送消息但是不进行任务调度*/
我们可以使用,上面基本类型来组合出其他几种类型,如下:
OS_OPT_POST_FIFO+ OS_OPT_POST_ALL
OS_OPT_POST_LIFO +OS_OPT_POST_ALL
OS_OPT_POST_FIFO+ OS_OPT_POST_NO_SCHED
OS_OPT_POST_LIFO + OS_OPT_POST_NO_SCHED
OS_OPT_POST_FIFO + OS_OPT_POST_ALL + OS_OPT_POST_NO_SCHED
OS_OPT_POST_LIFO + OS_OPT_POST_ALL+ OS_OPT_POST_NO_SCHED
OSQPost ((OS_Q *)&queue,
(void *)"Fire uC/OS-III",
(OS_MSG_SIZE )sizeof ( "Fire uC/OS-III" ),
(OS_OPT )OS_OPT_POST_FIFO | OS_OPT_POST_ALL,
(OS_ERR *)&err);
u8 buffer[3];
OSQPost ((OS_Q *)&queue,
(void *)&buffer,
(OS_MSG_SIZE )3,
(OS_OPT )OS_OPT_POST_FIFO | OS_OPT_POST_ALL,
(OS_ERR *)&err);
消息队列获取->OSQPend()
void *OSQPend (OS_Q *p_q,
OS_TICK timeout,
OS_OPT opt,
OS_MSG_SIZE *p_msg_size,
CPU_TS *p_ts,
OS_ERR *p_err)
- 等待期限timeout
等待消息的超时时间,如果在指定的时间没有接收到消息的话,任务就会被唤醒,
接着运行。这个参数也可以设置为0,表示任务将一直等待下去,直到接收到消息。 - 选项opt
用来选择是否使用阻塞模式,有两个选项可以选择。
oS_ OPT_ PEND_ BLOCKING如果没有任何消息存在的话就阻塞任务,一直等待,直到接收到消息。
oS_ OPT_ PEND_ NON_ BLOCKING如果消息队列没有任何消息的话任务就直接返回。
- 时间戳
指向一个时间戳,表明什么时候接收到消息。如果这个指针被赋值为NULL的话,说明用户没有要求时间戳。 - 应用实例1
static void AppTaskPend ( void * p_arg )
{
OS_ERR err;
OS_MSG_SIZE msg_size;
CPU_SR_ALLOC();
char * pMsg;
(void)p_arg;
while (DEF_TRUE) {
pMsg = OSQPend ((OS_Q *)&queue,
(OS_TICK )0,
(OS_OPT )OS_OPT_PEND_BLOCKING,
(OS_MSG_SIZE *)&msg_size,
(CPU_TS *)0,
(OS_ERR *)&err);
if ( err == OS_ERR_NONE )
{
OS_CRITICAL_ENTER();
printf ( "\r\n接收消息的长度:%d字节,内容:%s\r\n", msg_size, pMsg );
OS_CRITICAL_EXIT();
}
}
}
static void AppTaskStart2 (void *p_arg)
{
OS_ERR err;
OS_MSG_SIZE msg_size;
CPU_SR_ALLOC();
u8 a,b,c;
char * pMsg;
(void)p_arg;
while (DEF_TRUE){
GPIO_WriteBit(LEDPORT, LED2, (BitAction)(1-GPIO_ReadOutputDataBit(LEDPORT, LED2)));
pMsg = OSQPend ((OS_Q *)&queue,
(OS_TICK )0,
(OS_OPT )OS_OPT_PEND_BLOCKING,
(OS_MSG_SIZE *)&msg_size,
(CPU_TS *)0,
(OS_ERR *)&err);
if ( err == OS_ERR_NONE )
{
a=*pMsg;
pMsg++;
b=*pMsg;
pMsg++;
c=*pMsg;
printf ( "\r\n接收消息:%d,%d,%d°C \r\n", a,b,c);
OS_CRITICAL_EXIT();
}
}
}
指针的用法很重要,在获取具体的消息的时候需要用到
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)