事件处理
事件管理会创建一个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);
}