本文共 4370 字,大约阅读时间需要 14 分钟。
event的API的使用例程使用如下:首先初始化一个eventstatic EVENT_CB_S example_event;uwRet = LOS_EventInit(&example_event);然后读这个event uwEvent = LOS_EventRead(&example_event, event_wait, LOS_WAITMODE_AND, 100); if(uwEvent == event_wait) { dprintf("Example_Event,read event :0x%x\n",uwEvent); uwRet = LOS_InspectStatusSetByID(LOS_INSPECT_EVENT, LOS_INSPECT_STU_SUCCESS); if (LOS_OK != uwRet) { dprintf("Set Inspect Status Err\n"); } } else { dprintf("Example_Event,read event timeout\n"); uwRet = LOS_InspectStatusSetByID(LOS_INSPECT_EVENT, LOS_INSPECT_STU_ERROR); if (LOS_OK != uwRet) { dprintf("Set Inspect Status Err\n"); } }最后写这个event /* write event */ dprintf("Example_TaskEntry_Event write event .\n"); uwRet = LOS_EventWrite(&example_event, event_wait); if(uwRet != LOS_OK) { dprintf("event write failed .\n"); return LOS_NOK; }我们首先看看event的初始化LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventInit(PEVENT_CB_S pstEventCB){#如果event id 为null,则返回,本例中event id是静态定义的 if (pstEventCB == NULL) { return LOS_ERRNO_EVENT_PTR_NULL; }#将eventId 赋值为零 pstEventCB->uwEventID = 0;#每个event 有个list,这里将list置空 LOS_ListInit(&pstEventCB->stEventList); return LOS_OK;}可以看到list将next和prev都指向了自己LITE_OS_SEC_ALW_INLINE STATIC_INLINE VOID LOS_ListInit(LOS_DL_LIST *pstList){ pstList->pstNext = pstList; pstList->pstPrev = pstList;}下来我们看看event的read函数LITE_OS_SEC_TEXT UINT32 LOS_EventRead(PEVENT_CB_S pstEventCB, UINT32 uwEventMask, UINT32 uwMode, UINT32 uwTimeOut){ UINT32 uwRet = 0; UINTPTR uvIntSave; LOS_TASK_CB *pstRunTsk;#保存中断 uvIntSave = LOS_IntLock();#这里的poll其实就是判断pstEventCB->uwEventID 和 uwEventMask, 以及uwMode直接的关系,并没有任何poll的动作 uwRet = LOS_EventPoll(&(pstEventCB->uwEventID), uwEventMask, uwMode); if (uwRet == 0) { pstRunTsk = g_stLosTask.pstRunTask; pstRunTsk->uwEventMask = uwEventMask; pstRunTsk->uwEventMode = uwMode;#将当前task加到event的srEventList中,这里的uwTimeOut 如果不等于forever的话,还会建立一个timer在uwTimeOut到期后#唤醒这个task osTaskWait(&pstEventCB->stEventList, OS_TASK_STATUS_PEND, uwTimeOut);#恢复中断 (VOID)LOS_IntRestore(uvIntSave);#当前task让出cpu LOS_Schedule();#当再次执行task时判断这个task是否在timeout后才被唤醒的 if (pstRunTsk->usTaskStatus & OS_TASK_STATUS_TIMEOUT) { uvIntSave = LOS_IntLock(); pstRunTsk->usTaskStatus &= (~OS_TASK_STATUS_TIMEOUT); (VOID)LOS_IntRestore(uvIntSave); return LOS_ERRNO_EVENT_READ_TIMEOUT; } uvIntSave = LOS_IntLock();#如果不是timeout唤醒的,说明已经调用过event write,才被唤醒的,说明>uwEventID已经被更新了#再次判断这三者>uwEventID,uwEventMask,uwMode的关系后退出。 uwRet = LOS_EventPoll(&pstEventCB->uwEventID,uwEventMask,uwMode); (VOID)LOS_IntRestore(uvIntSave); } else { (VOID)LOS_IntRestore(uvIntSave); } return uwRet;}最后再在看看event write函数LITE_OS_SEC_TEXT UINT32 LOS_EventWrite(PEVENT_CB_S pstEventCB, UINT32 uwEvents){ LOS_TASK_CB *pstResumedTask; LOS_TASK_CB *pstNextTask = (LOS_TASK_CB *)NULL; UINTPTR uvIntSave; UINT8 ucExitFlag = 0; uvIntSave = LOS_IntLock(); pstEventCB->uwEventID |= uwEvents;#首先检测event的list是否为null,因为前面已经调用过event read函数了,所以这里肯定不为null if (!LOS_ListEmpty(&pstEventCB->stEventList)) { for (pstResumedTask = LOS_DL_LIST_ENTRY((&pstEventCB->stEventList)->pstNext, LOS_TASK_CB, stPendList);/*lint !e413*/ &pstResumedTask->stPendList != (&pstEventCB->stEventList);) {#找到event list中第一个需要wakeup的task pstNextTask = LOS_DL_LIST_ENTRY(pstResumedTask->stPendList.pstNext, LOS_TASK_CB, stPendList); /*lint !e413*/ if (((pstResumedTask->uwEventMode & LOS_WAITMODE_OR) && (pstResumedTask->uwEventMask & uwEvents) != 0) || ((pstResumedTask->uwEventMode & LOS_WAITMODE_AND) && (pstResumedTask->uwEventMask & pstEventCB->uwEventID) == pstResumedTask->uwEventMask)) {#设置flags,后面用于调度 ucExitFlag = 1;#wakeup这个task osTaskWake(pstResumedTask, OS_TASK_STATUS_PEND); } pstResumedTask = pstNextTask; } if (ucExitFlag == 1) { (VOID)LOS_IntRestore(uvIntSave);#由于flag被置为1,说明有task 要被唤醒,开始调度 LOS_Schedule(); return LOS_OK; } } (VOID)LOS_IntRestore(uvIntSave); return LOS_OK;}
转载地址:http://hpnmi.baihongyu.com/