我是靠谱客的博主 怕黑大叔,最近开发中收集的这篇文章主要介绍Z-stack的操作系统理解 笔记OSAL的主要功能如下:OSAL工作原理总结,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

  • OSAL的主要功能如下:
  • OSAL工作原理
    • 根据工程中代码看原理
      • 1 指针 tasksEvent 的定义和引用
      • 2 通过指针访问事件表的每一项,查找是否有事件发生
      • 3 有事件发生,跳出循环;查找函数表找到 事件处理函数 进行处理
        • 事件表粗略介绍
          • 事件表
          • 事件表代码
        • 事件处理函数
          • 调用处理函数方式:
          • 处理函数 处理事件 的大致过程
  • 总结

OSAL的主要功能如下:

任务的注册,初始化和分配
任务的同步和异步
存储器的分配和管理
中断的处理

OSAL工作原理

1 通过tasksEvents指针访问事件表的每一项,
2 如果有事件发生,则查找函数表找到事件处理函数进行处理,处理完后,继续访问事件表,查看是否有事件发生,无限循环。
在这里插入图片描述

根据工程中代码看原理

1 指针 tasksEvent 的定义和引用

  1. 在OSAL_GenericApp.c定义了初始化了 tasksEvent
    在这里插入图片描述
  2. 在 OSAL.c中 包含的头文件中OSAL_Tasks.h中 ,用extends 定义了 全局变量 tasksEvent
    在这里插入图片描述在这里插入图片描述

2 通过指针访问事件表的每一项,查找是否有事件发生

定义了个 索引 idx ,用来在事件表中索引。
故此 事件会 根据 索引值, 拥有有不同的 优先级。

第4、5两行,更新系统时钟,同时查看硬件方面是否有事件发生,如串口是否收到数据、是否有按键按下等信息,这部分内容在此可以暂时不予考虑。.??????????
在这里插入图片描述

3 有事件发生,跳出循环;查找函数表找到 事件处理函数 进行处理

先判断是否是 因为有事件发生 而跳出循环。
在这里插入图片描述

事件表粗略介绍

事件表

ZigBee协议栈使用-一个unsigned short 型的变量,
因为unsigned short 类型占2个字节,即16个二进制位,
因此,可以使用每个二进制位表示一-个事件.

事件十六进制二进制
串口接收新数据0x010b00000001
接收到无线数据0x020b00000010
读取温度数据0x040b00000100

系统初始化时,所有的任务初始化为0

事件表代码

SYS_EVENT_MSG 是一个事件集合
是一个事件集合,主要包括以下几个事件(其中前两个较为常用):
AF_INCOMING_MSG_CMD
表示收到了一个新的无线数据。
ZDO_STATE_CHANGE
当网络状态发生变化时,会产生该事件,如终端节点加入网络时,就可以通过判断该事件来决定何时向协调器发送数据包
ZDO_CB_MSG
指示每一-个注册的ZDO响应消息。
AF_DATA_CONFIRM_CMD
调用AF_ DataRequest()发送数据时,有时需要确认信息,该事件与此有关。

在 comdef.h中
#define SYS_EVENT_MSG               0x8000  // A message is waiting event
         

事件处理函数

调用处理函数方式:

通过指针的方式调用 事件处理函数

events = (tasksArr[idx])( idx, events );//调用函数去处理

tasksArr[]定义代码如下:

typedef unsigned short (*pTaskEventHandlerFn)( unsigned char task_id, unsigned short event );//typedef 函数指针
//unsigned short 表示函数返回值,
//pTaskEventHandlerFn 表示函数名,
//( unsigned char task_id, unsigned short event )表示参数

const pTaskEventHandlerFn tasksArr[] = {
  macEventLoop,//函数名
  nwk_event_loop,//函数名
  Hal_ProcessEvent,//函数名。。。。
#if defined( MT_TASK )
  MT_ProcessEvent,
#endif
  APS_event_loop,
#if defined ( ZIGBEE_FRAGMENTATION )
  APSF_ProcessEvent,
#endif
  ZDApp_event_loop,
#if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT )
  ZDNwkMgr_event_loop,
#endif
  GenericApp_ProcessEvent
};
处理函数 处理事件 的大致过程
  1. 通过osal_msg_receive()函数从消息队列上获取一个消息
    该消息包含了 事件接受到的数据
  2. 判断 具体事件类型,执行相应的操作。
  3. 返回未处理的函数(通过异或)。

例子:

UINT16 GenericApp_ProcessEvent( byte task_id, UINT16 events )
{
  afIncomingMSGPacket_t *MSGpkt;//定义一个指向接受消息结构体的指针
  if ( events & SYS_EVENT_MSG )
  {
    MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID );//osal_msg_receive()函数从消息队列上接收消息,返回指向接收的无线数据包的指针
    while ( MSGpkt )
    {
      //判断事件类型
      switch ( MSGpkt->hdr.event )
      {
        case AF_INCOMING_MSG_CMD://接收到 无线数据
          GenericApp_MessageMSGCB( MSGpkt );//执行相应的操作
          break;
        default:
          break;
      }
    
      osal_msg_deallocate( (uint8 *)MSGpkt );//释放消息所占据的存储空间
      MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID );//处理完一个消息后,再从队列里接收消息。
    }
    return (events ^ SYS_EVENT_MSG);
  }
  return 0;
}
void GenericApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
{
	//写入相应的操作.....
}
return (events ^ SYS_EVENT_MSG);

根据 事件粗略介绍中 的 事件表
假设同时发生了串口接收事件和读取温度事件,
则此时events= :0b00000101,即0x05,
假设现在处理完串口接收事件,则应该将第0位清零,如何实现呢?
只需要使用异或运算即可,即enents^0x01 =0x5^0x01=0x04,即0b00000100,
可见使用异或运算恰好可以将处理完的事件清除,仅留下未处理的事件。

总结

可以将OSAL的运行机理总结为:
●通过不断地查询事件表来判断是否有事件发生,如果有事件发生,则查找函数表找到对应的事件处理函数对事件进行处理。
●事件表使用数组来实现,数组的每一项对应一个任务的事件,每-位表示一个事件:函数表使用函数指针数组来实现,数组的每一项是一个函数指针指向了事件处理函数。

最后

以上就是怕黑大叔为你收集整理的Z-stack的操作系统理解 笔记OSAL的主要功能如下:OSAL工作原理总结的全部内容,希望文章能够帮你解决Z-stack的操作系统理解 笔记OSAL的主要功能如下:OSAL工作原理总结所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(63)

评论列表共有 0 条评论

立即
投稿
返回
顶部