⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_q.c

📁 ucos_ii在S3C2410上的移植
💻 C
📖 第 1 页 / 共 3 页
字号:
        OS_EXIT_CRITICAL();
        return (OS_Q_FULL);
    }
    if (pq->OSQOut == pq->OSQStart) 
    {                                                                  /* 检查边界 */
        pq->OSQOut = pq->OSQEnd;
    }
    pq->OSQOut--;
    *pq->OSQOut = msg;                                /* 把消息插入队列                        */
    pq->OSQEntries++;                                 /* 增加队列中的消息数        */
    OS_EXIT_CRITICAL();
    return (OS_NO_ERR);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
*                                        发送消息到队列
*
* 函数描述: 该函数发送一个消息到队列。该函数减少了代码量因为它能代替OSQPost() 和 OSQPostFront()。同时,该
*           函数广播发送消息给所有等待消息队列的任务。
*
* 输入参数  : pevent        指向带有期望队列的ECB的指针
*
*              msg           指向发送消息的指针.  不要发送空指针
*
*              opt           发送的类型:
*                            OS_POST_OPT_NONE         发送给单独的等待任务 (与 OSQPost()功能一致)
*                            OS_POST_OPT_BROADCAST    发送给所有正等待消息队列的任务
*                            OS_POST_OPT_FRONT        作为 LIFO 发送 (近似 OSQPostFront())
*
*                            下面是这些标志的所有可能组合的列表:
*
*                                 1) OS_POST_OPT_NONE
*                                    与 OSQPost()一致
*
*                                 2) OS_POST_OPT_FRONT
*                                    与 OSQPostFront() 一致
*
*                                 3) OS_POST_OPT_BROADCAST
*                                    与 OSQPost()一致,而且还有广播给所有等待的任务的消息。
*
*                                 4) OS_POST_OPT_FRONT + OS_POST_OPT_BROADCAST  
*                                    与OSQPostFront()一致,而且还有广播给所有等待的任务的消息
*
* 返回值  :    OS_NO_ERR               调用成功,消息被发送
*              OS_Q_FULL               队列由于满不接收更多的消息
*              OS_ERR_EVENT_TYPE       没有传递一个指向队列的指针
*              OS_ERR_PEVENT_NULL      'pevent' 是一个空指针
*              OS_ERR_POST_NULL_PTR    发送一个空指针
*
* 警告    :  如果广播发送,中断将禁止较长时间。事实上,中断禁止时间正比于等待消息队列的任务的数量。
*********************************************************************************************************
*/

#if OS_Q_POST_OPT_EN > 0
INT8U  OSQPostOpt (OS_EVENT *pevent, void *msg, INT8U opt)
{
#if OS_CRITICAL_METHOD == 3                      /* 为CPU状态寄存器分配存储变量            */
    OS_CPU_SR  cpu_sr;
#endif
    OS_Q      *pq;


#if OS_ARG_CHK_EN > 0
    if (pevent == (OS_EVENT *)0) 
    {                                                                 /* 无效的 'pevent'            */
        return (OS_ERR_PEVENT_NULL);
    }
    if (msg == (void *)0) 
    {                                                   /* 没有发送一个空指针   */
        return (OS_ERR_POST_NULL_PTR);
    }
    if (pevent->OSEventType != OS_EVENT_TYPE_Q) 
    {                                                              /* 无效的事件块类型       */
        return (OS_ERR_EVENT_TYPE);
    }
#endif
    OS_ENTER_CRITICAL();
    if (pevent->OSEventGrp != 0x00)                     /* 看是否任务正在等待消息队列    */
    {                                                      
        if ((opt & OS_POST_OPT_BROADCAST) != 0x00)         /* 需要广播发送吗? */
        {                                                
            while (pevent->OSEventGrp != 0x00) 
            {                                /* 是,广播发送给所有等待消息队列的任务,在相应的TCB中放消息 */
                OS_EventTaskRdy(pevent, msg, OS_STAT_Q);
            }
        } 
        else 
        {
            OS_EventTaskRdy(pevent, msg, OS_STAT_Q);  /* 不,发送给等待队列的HPT,在其TCB中放消息       */
        }
        OS_EXIT_CRITICAL();
        OS_Sched();                                   /* 寻找最高优先级就绪运行  */
        return (OS_NO_ERR);
    }
    pq = (OS_Q *)pevent->OSEventPtr;                  /* 指向QCB       */
    if (pq->OSQEntries >= pq->OSQSize) 
    {                                                              /* 检查消息是否已满?    */
        OS_EXIT_CRITICAL();
        return (OS_Q_FULL);
    }
    if ((opt & OS_POST_OPT_FRONT) != 0x00)            /* 是否发送到队列的前端?   */
    {                                                        
        if (pq->OSQOut == pq->OSQStart) 
        {                                                /* 是, 以后进先出发送 ... */
            pq->OSQOut = pq->OSQEnd;                  /*     如果取队列为头,调整取队列指针为尾 */
        }
        pq->OSQOut--;
        *pq->OSQOut = msg;                            /*      把消息插入队列                 */
    }
     else
    {                                                  /* 否,  以先入先出发送      */
        *pq->OSQIn++ = msg;                           /*      把消息插入队列                */
        if (pq->OSQIn == pq->OSQEnd) 
        {                                           /*      如果插入指针为尾,调整插入指针为头    */
            pq->OSQIn = pq->OSQStart;
        }
    }
    pq->OSQEntries++;                                 /* 增加队列中的消息数         */
    OS_EXIT_CRITICAL();
    return (OS_NO_ERR);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
*                                        查询消息队列
*
* 函数描述: 该函数得到消息队列的信息
*
* 输入参数  : pevent        指向带有期望队列的ECB的指针
*
*              pdata         指向包含消息队列的数据结构的指针
*
* 返回值    : OS_NO_ERR           调用成功,消息被发送
*              OS_ERR_EVENT_TYPE   从一个非消息队列中获取信息
*              OS_ERR_PEVENT_NULL  'pevent' 是一个空指针
*********************************************************************************************************
*/

#if OS_Q_QUERY_EN > 0
INT8U  OSQQuery (OS_EVENT *pevent, OS_Q_DATA *pdata)
{
#if OS_CRITICAL_METHOD == 3                                   /* 为CPU状态寄存器分配存储变量       */
    OS_CPU_SR  cpu_sr;
#endif
    OS_Q      *pq;
    INT8U     *psrc;
    INT8U     *pdest;


#if OS_ARG_CHK_EN > 0
    if (pevent == (OS_EVENT *)0) 
    {                                                            /* 无效的 'pevent'                */
        return (OS_ERR_PEVENT_NULL);
    }
    if (pevent->OSEventType != OS_EVENT_TYPE_Q) 
    {                                                                  /* 无效的事件块类型         */
        return (OS_ERR_EVENT_TYPE);
    }
#endif
    OS_ENTER_CRITICAL();
    pdata->OSEventGrp = pevent->OSEventGrp;                       /* 复制消息队列等待列表           */
    psrc              = &pevent->OSEventTbl[0];
    pdest             = &pdata->OSEventTbl[0];
#if OS_EVENT_TBL_SIZE > 0
    *pdest++          = *psrc++;
#endif

#if OS_EVENT_TBL_SIZE > 1
    *pdest++          = *psrc++;
#endif

#if OS_EVENT_TBL_SIZE > 2
    *pdest++          = *psrc++;
#endif

#if OS_EVENT_TBL_SIZE > 3
    *pdest++          = *psrc++;
#endif

#if OS_EVENT_TBL_SIZE > 4
    *pdest++          = *psrc++;
#endif

#if OS_EVENT_TBL_SIZE > 5
    *pdest++          = *psrc++;
#endif

#if OS_EVENT_TBL_SIZE > 6
    *pdest++          = *psrc++;
#endif

#if OS_EVENT_TBL_SIZE > 7
    *pdest            = *psrc;
#endif
    pq = (OS_Q *)pevent->OSEventPtr;
    if (pq->OSQEntries > 0) 
    {
        pdata->OSMsg = *pq->OSQOut;                        /* 如果有效得到下一条消息返回  */
    } 
    else 
    {
        pdata->OSMsg = (void *)0;
    }
    pdata->OSNMsgs = pq->OSQEntries;
    pdata->OSQSize = pq->OSQSize;
    OS_EXIT_CRITICAL();
    return (OS_NO_ERR);
}
#endif                                                     /* OS_Q_QUERY_EN                            */

/*$PAGE*/
/*
*********************************************************************************************************
*                                      初始化队列
*
* 函数描述 : 该函数由 uC/OS-II 调用初始化消息队列。应用程序不必调用。
*
* 输入参数   :  无
*
* 返回值     : 无
*
*********************************************************************************************************
*/

void  OS_QInit (void)
{
#if OS_MAX_QS == 1
    OSQFreeList         = &OSQTbl[0];            /* 只有一个队列                                  */
    OSQFreeList->OSQPtr = (OS_Q *)0;
#endif

#if OS_MAX_QS >= 2
    INT16U  i;
    OS_Q   *pq1;
    OS_Q   *pq2;


    pq1 = &OSQTbl[0];
    pq2 = &OSQTbl[1];
    for (i = 0; i < (OS_MAX_QS - 1); i++) 
    {                                                    /* 初始化空余QCB            */
        pq1->OSQPtr = pq2;
        pq1++;
        pq2++;
    }
    pq1->OSQPtr = (OS_Q *)0;
    OSQFreeList = &OSQTbl[0];
#endif
}
#endif                                                     /* OS_Q_EN                                  */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -