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

📄 os_sem.c

📁 ucos_ii在S3C2410上的移植
💻 C
📖 第 1 页 / 共 2 页
字号:
        default:
             OS_EXIT_CRITICAL();
             *err = OS_ERR_INVALID_OPT;
             return (pevent);
    }
}
#endif

/*$PAGE*/
/*
*********************************************************************************************************
*                                          挂起信号量
*
* 函数描述:   该函数用于等待一个信号量
*
* 输入参数:   pevent        指向已建有期望的信号量的ECB的指针
*
*             timeout       选择延时时间。如果非0,则任务等待资源指定的延时时间。如果为0,则任务一直等到
*                           资源有效或事件发生为止。
*
*             err           指向下列值之一的出错代码的指针。可能值:
*
*                           OS_NO_ERR           调用成功,任务占有资源。或正等待事件发生。
*                           OS_TIMEOUT          在指定的延时时间内,没有收到信号量。
*                           OS_ERR_EVENT_TYPE   传递的不是信号量的指针
*                           OS_ERR_PEND_ISR     从ISR中调用该函数,不能挂起。
*                           OS_ERR_PEVENT_NULL  'pevent' 是空指针。
*
* 返回值 :    无
*********************************************************************************************************
*/

void  OSSemPend(OS_EVENT *pevent, INT16U timeout, INT8U *err)
{
#if OS_CRITICAL_METHOD == 3                           /* 为CPU状态寄存器分配存储变量     */
    OS_CPU_SR  cpu_sr;
#endif    

    if (OSIntNesting > 0) 
    {                                                  /* 如果调用来自 ISR ...                    */
        *err = OS_ERR_PEND_ISR;                       /* ... 从 ISR调用将不能挂起                  */
        return;
    }
#if OS_ARG_CHK_EN > 0
    if (pevent == (OS_EVENT *)0) 
    {                                                 /* 空指针 'pevent'                             */
        *err = OS_ERR_PEVENT_NULL;
        return;
    }
    if (pevent->OSEventType != OS_EVENT_TYPE_SEM) 
    {                                                 /* 无效的事件类型                     */
        *err = OS_ERR_EVENT_TYPE;
        return;
    }
#endif
    OS_ENTER_CRITICAL();
    if (pevent->OSEventCnt > 0)                       /* 如果信号量是正,则有效 ...   */
    {                                                 
        pevent->OSEventCnt--;                         /* ... 只有为正,信号量减1.     */
        OS_EXIT_CRITICAL();
        *err = OS_NO_ERR;
        return;
    }
                                                      /* 否则等,直到事件发生       */
    OSTCBCur->OSTCBStat |= OS_STAT_SEM;               /* 资源无效, 挂起     */
    OSTCBCur->OSTCBDly   = timeout;                   /* 在TCB中写入,延时时间                     */
    OS_EventTaskWait(pevent);                         /* 挂起任务直到事件发生或延时时间到    */
    OS_EXIT_CRITICAL();
    OS_Sched();                                       /* 寻找最高优先级任务,就绪运行它        */
    OS_ENTER_CRITICAL();
    if (OSTCBCur->OSTCBStat & OS_STAT_SEM) 
    {                                                 /* 如果仍等待事件发生,就绪任务*/
        OS_EventTO(pevent);
        OS_EXIT_CRITICAL();
        *err = OS_TIMEOUT;                            /* 显示在延时时间内没有等到事件      */
        return;
    }
    OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;         /*  将指向信号量ECB的指针从该任务的TCB中删除  */
    OS_EXIT_CRITICAL();
    *err = OS_NO_ERR;
}
/*$PAGE*/
/*
*********************************************************************************************************
*                                         发送一个信号量
*
* 函数描述:   该函数发送一个信号量
*
* 输入参数  : pevent       指向已建有期望的信号量的ECB的指针
*
* 返回值    : OS_NO_ERR    调用成功信号量被发送
*             OS_SEM_OVF   信号量计数器超过限值.换句话说,信号量的发送数超过OSSemAccept()或OSSemPend()
*                          等待的数目。
*             OS_ERR_EVENT_TYPE     传递的不是信号量的指针
*             OS_ERR_PEVENT_NULL    'pevent' 是空指针.
*********************************************************************************************************
*/

INT8U  OSSemPost (OS_EVENT *pevent)
{
#if OS_CRITICAL_METHOD == 3                                /* 为CPU状态寄存器分配存储变量 */
    OS_CPU_SR  cpu_sr;                               
#endif    


#if OS_ARG_CHK_EN > 0
    if (pevent == (OS_EVENT *)0) 
    {                                                      /* 无效的 'pevent'                        */
        return (OS_ERR_PEVENT_NULL);
    }
    if (pevent->OSEventType != OS_EVENT_TYPE_SEM) 
    {                                                      /* 无效的事件控制块型                */
        return (OS_ERR_EVENT_TYPE);
    }
#endif
    OS_ENTER_CRITICAL();
    if (pevent->OSEventGrp != 0x00)
    {                                                      /* 看是否有任务在等待信号量?    */
        OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM);   /* 就绪等待事件中的最高优先级任务 */
        OS_EXIT_CRITICAL();
        OS_Sched();                                        /* 任务切换,找最高优先级任务就绪运行  */
        return (OS_NO_ERR);
    }
    if (pevent->OSEventCnt < 65535) 
    {                                                  /* 确信信号量没有溢出         */
        pevent->OSEventCnt++;                         /* 加信号量计数器以注册事件   */
        OS_EXIT_CRITICAL();
        return (OS_NO_ERR);
    }
    OS_EXIT_CRITICAL();                               /* 信号量达到最大值       */
    return (OS_SEM_OVF);
}
/*$PAGE*/
/*
*********************************************************************************************************
*                                          得到一个信号量的信息
*
* 函数描述: 该函数得到信号量的信息
*
* 输入参数  : pevent        指向已建有期望的信号量的ECB的指针
*
*              pdata         包含信号量信息的指针结构
*
* 返回值    : OS_NO_ERR           调用成功信息发送
*             OS_ERR_EVENT_TYPE   传递的不是信号量的指针
*             OS_ERR_PEVENT_NULL  'pevent' 是空指针.
*********************************************************************************************************
*/

#if OS_SEM_QUERY_EN > 0
INT8U  OSSemQuery (OS_EVENT *pevent, OS_SEM_DATA *pdata)
{
#if OS_CRITICAL_METHOD == 3                                /* 为CPU状态寄存器分配存储变量 */
    OS_CPU_SR  cpu_sr;
#endif    
    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_SEM) {        /* 无效的事件控制块型                */
        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
    pdata->OSCnt      = pevent->OSEventCnt;                /* 得到信号量计数器                      */
    OS_EXIT_CRITICAL();
    return (OS_NO_ERR);
}
#endif                                                     /* OS_SEM_QUERY_EN                          */
#endif                                                     /* OS_SEM_EN                                */

⌨️ 快捷键说明

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