UCOSIII操作系统——消息队列篇(2)任务消息队列

UCOSIII其他内容导航不迷路
UCOSIII操作系统-简介
UCOSIII操作系统——任务篇(1)创建任务
UCOSIII操作系统——任务篇(2)相关API函数
UCOSIII操作系统——系统初始化篇(1)系统初始化
UCOSIII操作系统——系统初始化篇(2)CPU,SysTick,内存初始化
UCOSIII操作系统——硬件初始化篇(1)硬件初始化以及开始运行系统
正在更新整理…

说在前面:
这个内容不适合0基础的人,因为这里只讲了应用层面的东西,并没有深入内核讲解,所以要从零开始学UCOSIII的朋友,可以先去学完入门内容,再来观看这个笔记加深印象。
这篇文章是个人学习整理,如有错误请指正

UCOSIII操作系统——消息队列篇(2)任务消息队列

消息队列常用函数

函数 描述
OSTaskQPost() 任务消息队列发送
OSTaskQPend() 任务消息队列获取

消息队列概念简介

任务消息队列跟任务信号量一样,均隶属于某一个特定任务,不需单独创建,任务在则任务消息队列在,只有该任务才可以获取(接收)这个任务消息队列的消息,其他任务只能给这个任务消息队列发送消息,却不能获取
任务内建消息队列,达到消息的一对一发送接收

任务消息队列发送->OSTaskQPost()

注意:想要使用任务消息队列,就必须将OS_ CFG_ TASK_ Q EN宏定义配置为1,该宏定义位于os_ _cfg.h 文件中。

  • 函数原型
#if OS_CFG_TASK_Q_EN > 0u					//如果使能了任务消息队列
void  OSTaskQPost (OS_TCB       *p_tcb,		//目标任务
                   void         *p_void,	//消息内容地址
                   OS_MSG_SIZE   msg_size,	//消息长度
                   OS_OPT        opt,		//选项
                   OS_ERR       *p_err)		//返回错误类型
  • 消息内容
    要发送的数据的指针,将内存块首地址通过队列“发送出去”,可以是"字符串"也可以是数组,在接受消息队列的时候可以通过指针取出具体消息。
  • opt
指定发送操作的类型,LIFO 和FIFO只能二选一。
OS OPT POST FIFO待发送消息保存在消息队列的末尾
OS OPT POST LIFO待发送的消息保存在消息队列的开头
上面两个选项可以搭配下面这个选项一起使用。
OS_ OPT_ POST_ NO_ SCHED 指定该选项时,在发送后不会进行任务调度,因.此,该函数的调用者还可以继续运行。

  • 由于要使用任务msgdis_task的内建消息队列,因此在创建任务msgdis_task的时候我们需要设置任务msgdis task 内建消息队列的大小,也就是函数OSTaskCreate()的参数q size;
    在这里插入图片描述
  • 应用实例1
OS_ERR err;

/* 发布消息到任务 AppTaskPend */
OSTaskQPost ((OS_TCB *)&AppTaskPendTCB, //目标任务的控制块
			(void *)"YeHuo uCOS-III", //消息内容
			(OS_MSG_SIZE )sizeof ( "YeHuo uCOS-III" ), //消息长度
			(OS_OPT )OS_OPT_POST_FIFO,
			//发布到任务消息队列的入口端
			(OS_ERR *)&err); //返回错误类型

任务消息队列获取->OSTaskQPend()

  • 函数原型
#if OS_CFG_TASK_Q_EN > 0u						//如果使能了任务消息队列
void  *OSTaskQPend (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 BI OCKING如果没有任何消息存在的话就阻塞任务,一直等待,直到接收到消息。
OS_ OPT_ PEND NON_ BLOCKING如果消 息队列没有任何消息的话任务就直接返回。
  • 时间戳
    指向一个时间戳,表明什么时候接收到消息。如果这个指针被赋值为NULL的话,说明用户没有要求时间戳。
  • 应用实例
/*
*********************************************************************************************************
*                                          PEND TASK
*********************************************************************************************************
*/
static  void  AppTaskPend ( void * p_arg )
{
	OS_ERR         err;
	OS_MSG_SIZE    msg_size;
	CPU_TS         ts;
	CPU_INT32U     cpu_clk_freq;
	CPU_SR_ALLOC();
	
	char * pMsg;

	(void)p_arg;
				 
 	cpu_clk_freq = BSP_CPU_ClkFreq();                 //获取CPU时钟,时间戳是以该时钟计数

	while (DEF_TRUE) {                                           //任务体
		/* 阻塞任务,等待任务消息 */
		pMsg = OSTaskQPend ((OS_TICK        )0,                    //无期限等待
						  (OS_OPT         )OS_OPT_PEND_BLOCKING, //没有消息就阻塞任务
						  (OS_MSG_SIZE   *)&msg_size,            //返回消息长度
						  (CPU_TS        *)&ts,                  //返回消息被发送的时间戳
						  (OS_ERR        *)&err);                //返回错误类型

		ts = OS_TS_GET() - ts;                            //计算消息从发送到被接收的时间差
		
		OS_CRITICAL_ENTER();                              //进入临界段,避免串口打印被打断

		printf ( "\r\n接收到的消息的内容为:%s,长度是:%d字节。",pMsg, msg_size );  

		printf ( "\r\n任务消息从被发送到被接收的时间差是%dus\r\n",ts / ( cpu_clk_freq / 1000000 ) );  
						
		OS_CRITICAL_EXIT();                               //退出临界段		
	}
}

指针的用法很重要,在获取具体的消息的时候需要用到

发布了10 篇原创文章 · 获赞 1 · 访问量 120

猜你喜欢

转载自blog.csdn.net/iiinoname/article/details/105193494