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);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值