UCOSIII学习(?)消息传递

10 篇文章 1 订阅
9 篇文章 0 订阅

有时候一个任务要和另外一个或者几个任务进行“交流”,这个“交流”就是消息的传递,
也称之为任务间通信,在 UCOSIII 中消息可以通过消息队列作为中介发布给任务,也可以直接
发布给任务

消息队列

消息一般包含:指向数据的指针,表明数据长度的变量和记录消息发布时刻的时间戳,指针指向的可以是一块数据区或者甚至是一个函数,消息的内容必须一直保持可见性,因为发布数据采用的是引用传递是指针传递而不是值传递,也就说,发布的数据本身不产生数据拷贝。

在 UCOSIII 中对于消息队列的读取既可以采用先进先出(FIFO)的方式,也可以采用后进先出(LIFO)的方式。当任务或者中断服务程序需要向任务发送一条紧急消息时 LIFO 的机制就非常有用了。采用后进先出的方式,发布的消息会绕过其他所有的已经位于消息队列中的消息而最先传递给任务。

消息队列中有一个列表,记录了所有正在等待获得消息的任务,如图 11.1.2 所示为多个任务可以在一个消息队列中等待,当一则消息被发布到队列中时,最高优先级的等待任务将获得该消息,发布方也可以向消息队列中所有等待的任务广播一则消息。
在这里插入图片描述

消息队列相关函数

创建消息队列

void OSQCreate (OS_Q *p_q,
				CPU_CHAR *p_name,
				OS_MSG_QTY max_qty,
				OS_ERR *p_err)

p_q : 指向一个消息队列,消息队列的存储空间必须由应用程序分配,我们采用如下的语句定义一个消息队列。
OS_Q Msg_Que;
p_name : 消息队列的名字。
max_qty : 指定消息队列的长度,必须大于 0。当然,如果 OS_MSGs 缓冲池中没有足够多的 OS_MSGs 可用,那么发送消息将会失败,并且返回相应的错误码,指明当前没有可用的 OS_MSGs
p_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)

p_q : 指向一个消息队列。
timeout : 等待消息的超时时间,如果在指定的时间没有接收到消息的话,任务就会被唤醒,接着运行。这个参数也可以设置为 0,表示任务将一直等待下去,直到接收到消息。
opt : 用来选择是否使用阻塞模式,有两个选项可以选择。
OS_OPT_PEND_BLOCKING 如果没有任何消息存在的话就阻塞任务,一直等待,直到接收到消息。
OS_OPT_PEND_NON_BLOCKING 如果消息队列没有任何消息的话任务就直接返回。
p_msg_size: 指向一个变量用来表示接收到的消息长度(字节数)。
p_ts : 指向一个时间戳,表明什么时候接收到消息。如果这个指针被赋值为NULL的话,说明用户没有要求时间戳。
p_err : 用来保存调用此函数后返回的错误码。

如果消息队列中没有任何消息,并且参数 opt 为 OS_OPT_PEND_NON_BLOCKING 时,那么调用 OSQPend()函数的任务就会被挂起,直到接收到消息或者超时。如果有消息发送给消息队列,但是同时有多个任务在等待这个消息,那么UCOSIII将恢复等待中的最高优先级的任务。

向消息队列发送消息

可以通过函数 OSQPost()向消息队列发送消息

void OSQPost (OS_Q *p_q,
			  void *p_void,
			  OS_MSG_SIZE msg_size,
			  OS_OPT opt,
			  OS_ERR *p_err)

如果有多个任务在等待消息队列的话,那么优先级最高的任务将获得这个消息。如果等待消息的任务优先级比发送消息的任务优先级高,则系统会执行任务调度,等待消息的任务立即恢复运行,而发送消息的任务被挂起。可以通过 opt 设置消息队列是 FIFO 还是 LIFO。
如果有多个任务在等待消息队列的消息,则 OSQPost()函数可以设置仅将消息发送给等待任务中优先级最高的任务(opt 设置为 OS_OPT_POST_FIF 或者 OS_OPT_POST_LIFO),也可以将消息发送给所有等待的任务 (opt 设置为 OS_OPT_POST_ALL)。 如果 opt 设置为OS_OPT_POST_NO_SCHED,则在发送完消息后,会进行任务调度。
p_q : 指向一个消息队列。
p_void : 指向实际发送的内容,p_void 是一个执行 void 类型的指针,其具体含义由用户程序的决定。
msg_size : 设定消息的大小,单位为字节数。
opt : 用来选择消息发送操作的类型,基本的类型可以有下面四种。
OS_OPT_POST_ALL 将消息发送给所有等待该消息队列的任务,需要和选项 OS_OPT_POST_FIFO 或者
OS_OPT_POST_LIFO 配合使用。
OS_OPT_POST_FIFO 待发送消息保存在消息队列的末尾
OS_OPT_POST_LIFO 待发送的消息保存在消息队列的开头
OS_OPT_POST_NO_SCHED 禁止在本函数内执行任务调度。
我们可以使用上面四种基本类型来组合出其他几种类型,如下:
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
p_err : 用来保存调用此函数后返回的错误码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值