ucos-iii 消息队列

一  消息队列的相关函数

创建一个消息队列OSQCreate()  OS_CFG_Q_ENOS_Q       CommQ;
OS_ERR   err;
OSQCreate(&CommQ,“Comm Queue”,10,&err); 
删除一个消息队列OSQDel()

OS_CFG_Q_EN

OS_CFG_Q_DEL_EN

OS_Q DispQ;

OS_ERR err;

OSQDel(&DispQ,OS_OPT_DEL_ALWAYS,&err);

清空一个消息队列OSQFlush()  

OS_CFG_Q_EN

OS_CFG_Q_FLUSH_EN

OS_Q       CommQ;
OS_ERR   err;

OS_MSG_QTY entries;

entries = OSQFlush(&CommQ,&err);

等待消息队列OSQPend() OS_CFG_Q_EN

OS_Q         CommQ;

OS_ERR    err;
void           *p_msg;
OS_MSG_SIZE msg_size;
CPU_TS     ts;

OSQPend(&CommQ,100,OS_OPT_PEND_BLOCKING,
&msg_size,&ts,&err);

取消等待消息队列OSQPendAbort() 

OS_CFG_Q_EN

OS_CFG_Q_PEND_ABORT_EN

OS_Q CommQ;

OS_ERR err;
OS_OBJ_QTY nbr_tasks;

nbr_tasks = OSQPendAbort(&CommQ,
OS_OPT_PEND_ABORT_ALL,&err);

向消息队列发送一条消息OSQPost()OS_CFG_Q_EN

OS_Q CommQ;
CPU_INT08U CommRxBuf[100];

OS_ERR err;
OSQPost(&CommQ,&CommRxBuf[0],sizeof(CommRxBuf),
     OS_OPT_POST_OPT_FIFO + OS_OPT_POST_ALL +       OS_OPT_POST_NO_SCHED,&err);

二 使用消息队列

消息队列是uCOS 中任务与任务间、中断与任务间主要的通讯方式,要使用消息队列需要满足下面条件

  • 将宏OS_CFG_Q_EN设置为1
  • 在创建任务时,OS_MSG_QTY参数不能设置为0.

下面是一则使用消息队列的代码示例,一个任务发送消息,一个任务接受消息并进行打印(代码省略了初始化等其他代码)

#include "main.h"

OS_Q msg_q; //声明消息队列

void RR1_task(void *p_arg)
{
    OS_ERR  err;
    p_arg = p_arg;
    while(1)
    {
        /* 发布消息到消息队列 queue */
        OSQPost ((OS_Q *)&msg_q,                    //消息变量指针
                (void *)"msg_q test",               //要发送的数据的指针,将内存块首地址通过队列“发送出去”
                (OS_MSG_SIZE )sizeof ("msg_q test"),//数据字节大小
                (OS_OPT )OS_OPT_POST_FIFO | OS_OPT_POST_ALL, //先进先出和发布给全部任务的形式
                (OS_ERR *)&err);                         //返回错误类型
        OSTimeDly (1000, OS_OPT_TIME_DLY, &err );   //相对性延时1000个时钟节拍(1s)
    }
}

void RR2_task(void *p_arg)
{
    OS_ERR  err;
    CPU_SR_ALLOC();
    p_arg = p_arg;
    OS_MSG_SIZE msg_size;
    //定义一个局部变量,用于保存关中断前的 CPU 状态寄存器
    char * pMsg;
    while(1)
    {
        /* 请求消息队列 queue 的消息 */
        pMsg = OSQPend ((OS_Q *)&msg_q, //消息变量指针
                        (OS_TICK )100, //等待时长
                        (OS_OPT )OS_OPT_PEND_NON_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();
        }
        OSTimeDly (1, OS_OPT_TIME_DLY, &err );
    }
}

 三 任务内置消息队列

向任务发送一条消息OSTaskQPost()OS_CFG_TASK_Q_EN

OS_TCB CommRxTaskTCB;
CPU_INT08U CommRxBuf[100];

OS_ERR err;

OSTaskQPost(&CommRxTaskTCB,&CommRxBuf[0],
sizeof(CommRxBuf),OS_OPT_POST_FIFO,&err);

等待消息OSTaskQPend()OS_CFG_TASK_Q_EN

OS_ERR err;

OS_MSG_SIZE msg_size;

CPU_TS ts;

OSTaskQPend(100,OS_OPT_PEND_BLOCKING,

               &msg_size,&ts,&err);

取消等待消息OSTaskQPendAbort()  

OS_CFG_TASK_Q_EN

 

OS_CFG_TASK_Q_PEND

_ABORT_EN

OS_TCB CommRxTaskTCB;

OS_ERR err;

OSTaskQPendAbort(&CommRxTaskTCB,
OS_OPT_POST_NONE,&err);

清空任务的消息队列OSTaskQFlush() OS_CFG_TASK_Q_ENOSTaskQFlush((OS_TCB *)0,&err);

四  使用任务内置消息队列

led0_task任务中发送消息,led1_task接受消息并将消息通过串口打印

void led0_task(void *p_arg)
{
    OS_ERR  err;
    p_arg = p_arg;
    while(DEF_TRUE){
        HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_1);
        
        // 发送消息到任务内置队列
        OSTaskQPost((OS_TCB* )&DS1TaskTCB, // 向任务 DS1TaskTCB  发送消息
                    (void*  )"task msg",
                    (OS_MSG_SIZE )sizeof("task msg"),
                    (OS_OPT  )OS_OPT_POST_FIFO,
                    (OS_ERR*  )&err);

        OSTimeDly (1000, OS_OPT_TIME_DLY, &err );   //相对性延时1000个时钟节拍(1s)
    }
}

void led1_task(void *p_arg)
{
    OS_ERR  err;
    p_arg = p_arg;
    OS_MSG_SIZE size;
    void *p_msg;
    while(1){
        
        // 请求消息
        p_msg = OSTaskQPend((OS_TICK  )10,                    //等待消息的超时时间
                            (OS_OPT )OS_OPT_PEND_NON_BLOCKING,//是否使用阻塞模式
                            (OS_MSG_SIZE*  )&size,            //指向存放消息大小的变量
                            (CPU_TS* )0,                      //指向一个时间戳,表明什么时候接收到消息。
                            (OS_ERR* )&err );
        if(err == OS_ERR_NONE){
            HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
            printf ("led1_task:%d 字节,内容:%s\r\n", size, (char *)p_msg );
        }
        OSTimeDly (1, OS_OPT_TIME_DLY, &err );   //相对性延时1000个时钟节拍(1s)
    }
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值