UCOSIII消息队列

任务间消息传递2种途径

全局变量
发布消息

主结构体

typedef struct os_q OS_Q;
struct  os_q {                            /* Message Queue */

    OS_OBJ_TYPE          Type;            /* Should be set to OS_OBJ_TYPE_Q */
    CPU_CHAR            *NamePtr;         /* Pointer to Message Queue Name (NUL terminated ASCII) */
    OS_PEND_LIST         PendList;        /* List of tasks waiting on message queue */
#if OS_CFG_DBG_EN > 0u
    OS_Q                *DbgPrevPtr;
    OS_Q                *DbgNextPtr;
    CPU_CHAR            *DbgNamePtr;
#endif

    OS_MSG_Q             MsgQ;            /* List of messages */
};

typedef struct os_msg_q OS_MSG_Q;
struct  os_msg_q {                        /* OS_MSG_Q */
    OS_MSG              *InPtr;           /* Pointer to next OS_MSG to be inserted in the queue */
    OS_MSG              *OutPtr;          /* Pointer to next OS_MSG to be extracted from the queue */
    OS_MSG_QTY           NbrEntriesSize;  /* Maximum allowable number of entries in the queue */
    OS_MSG_QTY           NbrEntries;      /* Current number of entries in the queue */
    OS_MSG_QTY           NbrEntriesMax;   /* Peak number of entries in the queue */
};

typedef struct os_msg OS_MSG;
struct  os_msg {                          /* MESSAGE CONTROL BLOCK */
    OS_MSG              *NextPtr;         /* Pointer to next message */
    void                *MsgPtr;          /* Actual message */
    OS_MSG_SIZE          MsgSize;         /* Size of the message (in # bytes) */
    CPU_TS               MsgTS;           /* Time stamp of when message was sent */
};

1

API函数

//创建
void OSQCreate (OS_Q *p_q,
                CPU_CHAR *p_name,
                OS_MSG_QTY max_qty,
                OS_ERR *p_err);

#if OS_CFG_Q_DEL_EN > 0u
//删除
OS_OBJ_QTY OSQDel (OS_Q *p_q,
                   OS_OPT opt,
                   OS_ERR *p_err);
#endif

#if OS_CFG_Q_FLUSH_EN > 0u
//清空
OS_MSG_QTY OSQFlush (OS_Q *p_q,
                     OS_ERR *p_err);
#endif

//等待-1,接收消息
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);

#if OS_CFG_Q_PEND_ABORT_EN > 0u
//取消等待
OS_OBJ_QTY OSQPendAbort (OS_Q *p_q,
                         OS_OPT opt,
                         OS_ERR *p_err);
#endif

//释放+1,发送消息
void OSQPost (OS_Q *p_q,
              void *p_void,
              OS_MSG_SIZE msg_size,
              OS_OPT opt,
              OS_ERR *p_err);

应用举例

#define DATAMSG_Q_NUM   4   //发送数据的消息队列的数量
OS_Q DATA_Msg;              //定义一个消息队列,用于发送数据

void start_task(void *p_arg)
{
    OS_CRITICAL_ENTER();    //进入临界区

    //创建消息队列DATA_Msg
    OSQCreate ((OS_Q*       )&DATA_Msg, 
                (CPU_CHAR*  )"DATA Msg",    
                (OS_MSG_QTY )DATAMSG_Q_NUM, 
                (OS_ERR*    )&err); 

    //创建定时器
    OSTmrCreate((OS_TMR     *)&tmr,         //定时器
                (CPU_CHAR   *)"tmr",        //定时器名字
                (OS_TICK     )0,            //0ms
                (OS_TICK     )50,           //50*10=500ms
                (OS_OPT      )OS_OPT_TMR_PERIODIC, //周期模式
                (OS_TMR_CALLBACK_PTR)tmr_callback,//定时器回调函数
                (void       *)0,            //参数为0
                (OS_ERR     *)&err);        //返回的错误码

    //创建msgpend任务
    OSTaskCreate((OS_TCB    * )&Msgpend_TaskTCB,        
                 (CPU_CHAR  * )"msgpend task",      
                 (OS_TASK_PTR )msgpend_task,            
                 (void      * )0,                   
                 (OS_PRIO     )MSGPEND_TASK_PRIO,     
                 (CPU_STK   * )&MSGPEND_TASK_STK[0],    
                 (CPU_STK_SIZE)MSGPEND_STK_SIZE/10, 
                 (CPU_STK_SIZE)MSGPEND_STK_SIZE,        
                 (OS_MSG_QTY  )0,                   
                 (OS_TICK     )0,                   
                 (void      * )0,                   
                 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,
                 (OS_ERR    * )&err);

    OS_CRITICAL_EXIT(); //退出临界区
}

//定时器的回调函数
void tmr_callback(void *p_tmr,void *p_arg)
{
    u8 *pbuf;
    static u8 msg_num;
    OS_ERR err;

    pbuf = mymalloc(SRAMIN,10); //申请10个字节
    if(pbuf)    //申请内存成功
    {
        msg_num++;
        sprintf((char*)pbuf,"ALIENTEK %d",msg_num);
        printf("tmr_callback: %s\r\n", pbuf);
        //发送消息
        OSQPost((OS_Q*      )&DATA_Msg,     
                (void*      )pbuf,
                (OS_MSG_SIZE)10,
                (OS_OPT     )OS_OPT_POST_FIFO,
                (OS_ERR*    )&err);
        if(err != OS_ERR_NONE)
        {
            myfree(SRAMIN,pbuf);    //释放内存
            OSTmrStop(&tmr,OS_OPT_TMR_NONE,0,&err); //停止定时器
            printf("TMR STOP!\r\n");
        }
    }   
}

//等待消息队列中的消息
void msgpend_task(void *p_arg)
{
    u8 *p;
    OS_MSG_SIZE size;
    OS_ERR err; 
    while(1)
    {
        //请求消息
        p=OSQPend((OS_Q*        )&DATA_Msg,   
                  (OS_TICK      )0,
                  (OS_OPT       )OS_OPT_PEND_BLOCKING,
                  (OS_MSG_SIZE* )&size, 
                  (CPU_TS*      )0,
                  (OS_ERR*      )&err);
        printf("msgpend_task: %s\r\n", p);
        myfree(SRAMIN,p);   //释放内存
        OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_PERIODIC,&err); //延时1s
    }
}

实验现象
1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值