本文共 2700 字,大约阅读时间需要 9 分钟。
sem就是信号量,其使用如下所示:在使用sem之前先要创建semLOS_SemCreate(0, &g_usSemID);创建后,就可以调用LOS_SemPend 来得到一个信号量,调用LOS_SemPost 释放一个信号量static VOID Example_SemTask1(VOID){ UINT32 uwRet; dprintf("Example_SemTask1 try get sem g_usSemID ,timeout 10 ticks.\n"); /* get sem, timeout is 10 ticks */#获取信号量 uwRet = LOS_SemPend(g_usSemID, 10); /* get sem ok */ if (LOS_OK == uwRet) {#成功获取后释放信号量 LOS_SemPost(g_usSemID); return; }}下来我们具体看看如何获取信号量LITE_OS_SEC_TEXT UINT32 LOS_SemPend(UINT32 uwSemHandle, UINT32 uwTimeout){ UINT32 uwIntSave; SEM_CB_S *pstSemPended; UINT32 uwRetErr; LOS_TASK_CB *pstRunTsk; pstSemPended = GET_SEM(uwSemHandle); #得到正在运行的task pstRunTsk = (LOS_TASK_CB *)g_stLosTask.pstRunTask;#将要得到的信号量赋值给当前进程 pstRunTsk->pTaskSem = (VOID *)pstSemPended;#将这个进程插入到pendlist中,并建立一个timer来唤醒这个进程得到信号量 osTaskWait(&pstSemPended->stSemList, OS_TASK_STATUS_PEND, uwTimeout); (VOID)LOS_IntRestore(uwIntSave);#释放cpu LOS_Schedule(); if (pstRunTsk->usTaskStatus & OS_TASK_STATUS_TIMEOUT) { uwIntSave = LOS_IntLock(); pstRunTsk->usTaskStatus &= (~OS_TASK_STATUS_TIMEOUT); uwRetErr = LOS_ERRNO_SEM_TIMEOUT; goto errre_uniSemPend; }#规定的时间内信号量被唤醒,没有timeout则返回成功 return LOS_OK;#否则返回失败,获取信号量失败errre_uniSemPend: (VOID)LOS_IntRestore(uwIntSave); OS_RETURN_ERROR(uwRetErr);}LITE_OS_SEC_TEXT VOID osTaskWait(LOS_DL_LIST *pstList, UINT32 uwTaskStatus, UINT32 uwTimeOut){ LOS_TASK_CB *pstRunTsk; LOS_DL_LIST *pstPendObj; pstRunTsk = g_stLosTask.pstRunTask; osPriqueueDequeue(&pstRunTsk->stPendList); pstRunTsk->usTaskStatus &= (~OS_TASK_STATUS_READY); pstPendObj = &pstRunTsk->stPendList; pstRunTsk->usTaskStatus |= uwTaskStatus;#将这个进程插入到pendlist中 LOS_ListTailInsert(pstList,pstPendObj); if (uwTimeOut != LOS_WAIT_FOREVER) { pstRunTsk->usTaskStatus |= OS_TASK_STATUS_TIMEOUT;#建立一个timer在规定时间内唤醒这个进程 osTaskAdd2TimerList((LOS_TASK_CB *)pstRunTsk, uwTimeOut); }}释放信号量的函数分析如下:LITE_OS_SEC_TEXT UINT32 LOS_SemPost(UINT32 uwSemHandle){ UINT32 uwIntSave; SEM_CB_S *pstSemPosted = GET_SEM(uwSemHandle); LOS_TASK_CB *pstResumedTask;#需要释放的信号量不为null的话 if (!LOS_ListEmpty(&pstSemPosted->stSemList)) {#从需要释放信号量的list中找到第一个task pstResumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(pstSemPosted->stSemList))); /*lint !e413*/#将要唤醒的task的sem置空 pstResumedTask->pTaskSem = NULL;#开始唤醒task osTaskWake(pstResumedTask, OS_TASK_STATUS_PEND);#恢复中断 (VOID)LOS_IntRestore(uwIntSave);#启动调度 LOS_Schedule(); } else {#从这里可以知道信号量可以分别获取和释放多次 pstSemPosted->usSemCount++; (VOID)LOS_IntRestore(uwIntSave); } return LOS_OK;}
转载地址:http://qpnmi.baihongyu.com/