事件处理

事件管理会创建一个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操作系统抽象层学习笔记 (五)---事件处理及运行方式相关推荐

  1. WSF操作系统抽象层学习笔记(四)---定时器

    定时器 定时器的实现方式: 使用OS自带的定时器模块,建立一个定时器,定时间隔为自定义TICKS,定时器的回调函数中设置定时器到时的事件. 定时器模块定义了一个定时器的链表,用于定时器的管理. 操作定 ...

  2. WSF操作系统抽象层学习笔记 (一) ---简介和内存管理

    一.简介 WSF(wireless software foundation)是对操作系统的一个简单的封装,提供对操作系统的简单编程,提供简单的系统服务 功能简介: 事件.消息传递和处理. 定时器功能. ...

  3. WSF操作系统抽象层学习笔记(三)---消息列队

    消息 WSF的消息服务用于传递消息到对应的事件处理句柄. 实现机制和使用方法 基于内存管理,从内存中申请sizeof(wsfMsg_t) + 消息长度的内存.添加头部描述,返回给申请者除去头部的指针位 ...

  4. WSF操作系统抽象层学习笔记(二)---列队(单向链表)

    队列 队列的管理使用单向链表结构.个人认为使用双向链表更易于维护. 注意: 每个以列队为基础管理的结构都必须将第一个元素设定为列队元件的指针. 进行列队操作时都需要关闭任务调度,防止多线程操作的信息同 ...

  5. 【操作系统】Oranges学习笔记(五) 第六章 进程

    文章目录 6.1 迟到的进程 6.2 进程概述 6.2.1 进程介绍 6.2.2 未雨绸缪--形成进程的必要考虑 6.2.3 参考的代码 6.3 最简单的进程 6.3.1 简单进程的关键技术预测 1. ...

  6. ZigBee学习之7——OSAL(操作系统抽象层)API解读

    根据Z-Stack1.4.3-1.2.0中OSAL API_F8W-2003-0002_.pdf文档翻译. Z-Stack1.4.3及以后的版本中引入了一个OS的概念,把应用层和堆栈层进行了分离,但是 ...

  7. 哈工大操作系统学习笔记五——内核级线程实现

    哈工大os学习笔记五(内核级线程实现) 文章目录 哈工大os学习笔记五(内核级线程实现) 一. 中断入口.中断出口(前后两段) 1. 从int中断进入内核(中断入口第一段) 2.中断出口(最后一段) ...

  8. python函数是一段具有特定功能的语句组_Python学习笔记(五)函数和代码复用

    本文将为您描述Python学习笔记(五)函数和代码复用,具体完成步骤: 函数能提高应用的模块性,和代码的重复利用率.在很多高级语言中,都可以使用函数实现多种功能.在之前的学习中,相信你已经知道Pyth ...

  9. OSAL(操作系统抽象层)

    OSAL为Operating System Abstraction Layer,即操作系统抽象层,支持多任务运行,所有的应用程序(app)都在其上运行,它并不是一个传统意义上的操作系统,但是实现了部分 ...

最新文章

  1. Slam十四讲(第二版):1、习题
  2. Ubuntu 16.04 安装Django
  3. 流放之路材质过滤怎么设置_三种不同材质的精密过滤设备特点
  4. NARF 特征点提取
  5. 应不应该使用inline-block代替float
  6. 大道至简第三章读后感
  7. springboot+jwt实现token登陆权限认证
  8. JS-继承(es5,es6)
  9. python使用ORM之如何调用多对多关系
  10. java jtextfield 居中_有什么办法可以使JFrame的中心居中吗? - java
  11. 【干货】比赛后期大招之stacking技术分享
  12. LINUX SHELL中大小写转换及注意事项
  13. UE4(虚幻4)基础:免费资源下载(材质/动作/模型/环境/效果/插件)
  14. IT大学生应该经常浏览的十大网站
  15. 堪萨斯州立大学计算机专业,全美顶尖大学:堪萨斯州立大学
  16. OVM学习--持续更新
  17. java实现聊天室(websocket)
  18. 软件测试周刊(第81期):能够对抗消极的不是积极,而是专注;能够对抗焦虑的不是安慰,而是具体。
  19. 计算机连接打印机连接打印机,怎么连接打印机.教您怎么连接打印机
  20. java手机解锁_Android手机屏幕敲击解锁功能代码

热门文章

  1. Flutter IOS 新建打包发布全流程 2023 版
  2. 可以发布外链的平台有哪些
  3. Java反射机制--是什么,为什么,怎么用
  4. html语言教案模版,【精选】大班教案模板六篇
  5. 为什么计量型低压电流互感器二次侧不允许开路
  6. Win08R2变脸Win7第三招立户
  7. LabVIEW控制DO通道输出一个精确定时的数字波形
  8. 虚拟机不能启动问题解决
  9. IPO在即,Uber让你从“拼车”到“拼吃”
  10. SystemVue 使用(2)