WSF操作系统抽象层学习笔记 (五)---事件处理及运行方式
生活随笔
收集整理的這篇文章主要介紹了
WSF操作系统抽象层学习笔记 (五)---事件处理及运行方式
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
事件處理
事件管理會創建一個OS的事件,用于進行WSF無運行需求時任務的阻塞。
//事件管理結構 typedef struct {uint16_t??????? param;????????? //參數uint8_t???????? event;????????? //事件值uint8_t???????? status;???????? //狀態值 } wsfMsgHdr_t;?
設置事件
設置對應handleID 對應的event標志。
調用OS事件接口發送事件,將阻塞的接口重新調用。
//給對應的handle發送事件消息 void WsfSetEvent(wsfHandlerId_t handlerId, wsfEventMask_t event) {WSF_CS_INIT(cs);WSF_ASSERT(WSF_HANDLER_FROM_ID(handlerId) < WSF_MAX_HANDLERS);WSF_TRACE_INFO2("WsfSetEvent handlerId:%u event:%u", handlerId, event);WSF_CS_ENTER(cs);/* 給對應的handle設置對應的event Mask */wsfOs.task.handlerEventMask[WSF_HANDLER_FROM_ID(handlerId)] |= event;/* 設置task的事件標志 */wsfOs.task.taskEventMask |= WSF_HANDLER_EVENT;WSF_CS_EXIT(cs);/* 調用os的事件接口,給WSF task設置事件 */WsfSetOsSpecificEvent(); }//OS接口發送事件,移植需要更新這個函數。這里是使用的FREERTOS void WsfSetOsSpecificEvent(void) {if(xRadioTaskEventObject != NULL) {BaseType_t xHigherPriorityTaskWoken, xResult;if(xPortIsInsideInterrupt() == pdTRUE) {//// Send an event to the main radio task//xHigherPriorityTaskWoken = pdFALSE;xResult = xEventGroupSetBitsFromISR(xRadioTaskEventObject, 1,&xHigherPriorityTaskWoken);//// If the radio task is higher-priority than the context we're currently// running from, we should yield now and run the radio task.//if ( xResult != pdFAIL ){portYIELD_FROM_ISR(xHigherPriorityTaskWoken);} }else {xResult = xEventGroupSetBits(xRadioTaskEventObject, 1);//// If the radio task is higher priority than the context we're currently// running from, we should yield now and run the radio task.//if ( xResult != pdFAIL ){portYIELD();}}} }?
WSF對應OS task結構
/* 任務結構 */ typedef struct {wsfEventHandler_t handler[WSF_MAX_HANDLERS]; //事件句柄wsfEventMask_t handlerEventMask[WSF_MAX_HANDLERS]; //每個句柄的事件掩碼wsfQueue_t msgQueue; //消息隊列wsfTaskEvent_t taskEventMask; //WSF任務的事件掩碼uint8_t numHandler; //記錄句柄的個數 } wsfOsTask_t;WSF os的初始化
//wsf 抽象層的初始化 void WsfOsInit(void) {memset(&wsfOs, 0, sizeof(wsfOs));if( xRadioTaskEventObject == NULL){//使用當前OS的接口創建一個事件,用于進行WSF task的阻塞xRadioTaskEventObject = xEventGroupCreate();WSF_ASSERT(xRadioTaskEventObject != NULL);} }設置當前task可以運行了,實現的本質還是基于事件來實現。
void WsfTaskSetReady(wsfHandlerId_t handlerId, wsfTaskEvent_t event) {/* Unused parameter */(void)handlerId;WSF_CS_INIT(cs);WSF_CS_ENTER(cs);//設置task事件掩碼wsfOs.task.taskEventMask |= event;WSF_CS_EXIT(cs);/* 調用OS事件發送接口,取消WSF task的阻塞 */WsfSetOsSpecificEvent(); }WSF任務驅動函數。這個函數應當一直在while(1)中被調用
//WSF任務驅動函數 void wsfOsDispatcher(void) {wsfOsTask_t *pTask;void *pMsg;wsfTimer_t *pTimer;wsfEventMask_t eventMask;wsfTaskEvent_t taskEventMask;wsfHandlerId_t handlerId;uint8_t i;WSF_CS_INIT(cs);pTask = &wsfOs.task;//更新定時器列表WsfTimerUpdateTicks();//循環處理task所有事件while (pTask->taskEventMask){/* 清除事件標志 */WSF_CS_ENTER(cs);taskEventMask = pTask->taskEventMask;pTask->taskEventMask = 0;WSF_CS_EXIT(cs);/* 消息列隊的事件 */if (taskEventMask & WSF_MSG_QUEUE_EVENT){/* 從消息列隊中的取出消息進行處理 */while ((pMsg = WsfMsgDeq(&pTask->msgQueue, &handlerId)) != NULL){WSF_ASSERT(handlerId < WSF_MAX_HANDLERS);/* 調用處理句柄,進行消息處理 */(*pTask->handler[handlerId])(0, pMsg);WsfMsgFree(pMsg);}}/* 定時器事件 */if (taskEventMask & WSF_TIMER_EVENT){/* 取出一個到時的定時器 */while ((pTimer = WsfTimerServiceExpired(0)) != NULL){WSF_ASSERT(pTimer->handlerId < WSF_MAX_HANDLERS);/* 調用定時器處理函數 */(*pTask->handler[pTimer->handlerId])(0, &pTimer->msg);}}/* 句柄事件 */if (taskEventMask & WSF_HANDLER_EVENT){/* 循環所有句柄 */for (i = 0; i < WSF_MAX_HANDLERS; i++){if ((pTask->handlerEventMask[i] != 0) && (pTask->handler[i] != NULL)){WSF_CS_ENTER(cs);eventMask = pTask->handlerEventMask[i];pTask->handlerEventMask[i] = 0;WSF_CS_EXIT(cs);/* 調用函數,處理事件 */(*pTask->handler[i])(eventMask, NULL);}}}}/* 處理完畢后繼續等待OS發出的事件,進行任務的阻塞 */xEventGroupWaitBits(xRadioTaskEventObject, 1, pdTRUE,pdFALSE, portMAX_DELAY); }?
總結
以上是生活随笔為你收集整理的WSF操作系统抽象层学习笔记 (五)---事件处理及运行方式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: STM32的一键下载CH340 DTR
- 下一篇: Webpack教程二