OSAL的工作原理.docx

上传人:b****7 文档编号:9169092 上传时间:2023-02-03 格式:DOCX 页数:8 大小:19KB
下载 相关 举报
OSAL的工作原理.docx_第1页
第1页 / 共8页
OSAL的工作原理.docx_第2页
第2页 / 共8页
OSAL的工作原理.docx_第3页
第3页 / 共8页
OSAL的工作原理.docx_第4页
第4页 / 共8页
OSAL的工作原理.docx_第5页
第5页 / 共8页
点击查看更多>>
下载资源
资源描述

OSAL的工作原理.docx

《OSAL的工作原理.docx》由会员分享,可在线阅读,更多相关《OSAL的工作原理.docx(8页珍藏版)》请在冰豆网上搜索。

OSAL的工作原理.docx

OSAL的工作原理

OSAL的工作原理

ZigBee协议栈依据IEEE802.15.4标准和ZigBee协议规范。

ZigBee网络中的各种操作需要,利用协议栈各层所提供的原语操作来共同完成。

原语操作的实现过程往往需要向下一层发起一个原语操作并且通过下层返回的操作结果来判断出下一条要执行的原语操作。

IEEE802.15.4标准和ZigBee协议规范中定义的各层原语操作多达数十条,原语的操作过程也比较复杂,它已经不是一个简单的单任务软件。

对于这样一个复杂的嵌入式通信软件来说,其实现通常需要依靠嵌入式操作系统来完成。

挪威半导体公司Chipcon(目前已经被TI公司收购)作为业界领先的ZigBee一站式方案供应商,在推出其CC2530开发平台时,也向用户提供了自己的ZigBee协议栈软件-Z-Stack。

这是一款业界领先的商业级协议栈,使用CC2530射频芯片,可以使用户很容易的开发出具体的应用程序来。

Z-Stack使用瑞典公司IAR开发的IAREmbeddedWorkbenchforMCS.51作为它的集成开发环境。

Chipcon公司为自己设计的Z-Stack协议栈中提供了一个名为操作系统抽象层OSAL的协议栈调度程序。

对于用户来说,除了能够看到这个调度程序外,其它任何协议栈操作的具体实现细节都被封装在库代码中。

用户在进行具体的应用开发时只能够通过调用API接口来进行,而无权知道Zig,Bee协议栈实现的具体细节。

Z-Stack1.4.3及以后的版本中引入了一个OSAL(OperatingSystemAbstractionLayer操作系统抽象层),但在我们整个的ZigBee协议栈的结构图中,我并没有能够发现这个层在哪个位置。

但是整个的协议栈都要在OS的基础上才能运行。

OSAL和我们通常所说的RTOS,pc上的操作系统还是有很大的不同,ZigBee2006中只是利用了操作系统的概念和思想,利用OS把Z-Stack软件组件从特殊的处理过程相分离,并将软件成分保护了起来。

它提供了如下的管理功能:

◆任务的注册、初始化、开始

◆任务间的消息交换

◆任务同步

◆中断处理

◆时间管理

◆内存分配

OSAL主要是这样一种机制,一种任务分配资源的机制,从而形成了一个简单多任务的操作系统。

首先,osal初始化系统,包括软件系统初始化和资源初始化.其中软件系统初始化就是初始化一些变量,比如osal重要的组成部分任务表,任务结构体和序列号.资源初始化主要包括内存,中断,NV等各种设备模块资源.这就和我们嵌入式系统中的RTOS操作系统μC/OS-II有了很大的相似处。

μC/OS-II中也是通过建立任务把一个问题进行分解,任务之间可以通过消息队列的方式进行通信。

接着,osal通过osal_add_task添加任务到任务表中,形成一个任务链表.这个任务链表是以任务的优先级先后排序的.优先级高的排在前,低者排于后.

最后,开始运行系统,系统是以一个死循环的形式工作的.在循环体当中不断地检测各个任务,看是否要运行等.这就相当于我们平时用的linux和window等多任务系统,把CPU分成N个时间片(有多少任务就分成多少时间片),只要处理频率高,就相当于多任务同时运行了。

下面我们来结合sampleAPP来说明一下OSAL的具体工作情况。

SampleApplication是ZStack协议栈提供的一个非常简单的演示实例,实例中的每个设备都可以发送和接收两种信息:

周期信息和闪烁信息。

周期信息---------当设备加入该网络后,所有设备每隔5S(加上一个随机数,毫秒mS为单位)发送一个周期信息,该信息的数据载荷为发送信息的次数。

闪烁信息---------通过按下按键SW1发送一个控制LED灯闪烁的广播信息,该广播信息只针对组1内的所有设备。

所有设备初始化都被加入组1,所以网络一旦建立完成便可执行LED灯闪烁实验。

可以通过按下设备的SW2退出组1,如果设备退出组1则不再接收来自组1的消息,其按键SW1发送的消息也不再控制组1LED灯的闪烁。

通过再次按下SW2便可让设备再次加入到组1,从而又可以接受来自组1的消息,其SW1也可以控制组1内设备的LED灯闪烁了。

当设备接收到闪烁信息会闪烁LED灯,而当接收到周期信息时协议栈没有提供具体的实验现象,留给了用户自行处理,可以根据实际需要自行更改实验代码。

在该工程中使用了两个按键SW1和SW2。

即ZStack协议栈中的HAL_KEY_SW_1和HAL_KEY_SW_2。

同时工程中也定义了一个事件用来处理周期信息事件,即SAMPLEAPP_SEND_PERIODIC_MSG_EVT[SampleApp.h]。

二、一般工程说明:

在学习ZStack协议栈的时候我们要把握一个重点就是事件的产生和事件的处理。

任务的初始化为事件的产生制造了“温床”,是事件产生的前提,任何工程都需要先初始化。

当有事件产生OS就会调用相应的处理函数进行处理。

在OS循环那一节我们可以看到在任务初始化的最后一项就是应用层的初始化,而在指向处理函数的指针数组中最后一项是对应的应用层的处理函数。

应用层相关事件会由应用层处理函数进行处理。

每一层都是相互对应,各司其职。

程序执行流程如下:

ZMain.c的main()--->osal.c的osal_init_system()---->OSAL_SampleApp.c的

osalInitTasks()之后分两部分执行-------->首先执行SampleApp.c的

SampleApp_Init(),接着执行osal.c中的事件循环,不停的执行

SampleApp_ProcessEvent(),进行应用层事件检测。

两个关键函数

1.SampleApp_Init

2.SampleApp_ProcessEvent

具体代码如下:

SampleApp_init

voidSampleApp_Init(uint8task_id)

{

//osal应用层的任务ID赋值

SampleApp_TaskID=task_id;

//设备状态设定为ZDO层中定义的初始化状态

SampleApp_NwkState=DEV_INIT;

//定义消息ID

SampleApp_TransID=0;

//后面的demo例子中用到这个编译选项

#ifdefined(SOFT_START)

//如果选择了SOFT编译选项,则作为协调器启动

   zgDeviceLogicalType=ZG_DEVICETYPE_COORDINATOR;

#endif//SOFT_START

//如果定义了HOLD_AUTO_START选项,则调用层的ZDOInitDevice,按照默认顺   

//序网络中的第一个设备作为协调器,其他的设备作为子设备

#ifdefined(HOLD_AUTO_START)

ZDOInitDevice(0);

#endif

//定义广播地址

//地址模式

SampleApp_Periodic_DstAddr.addrMode=(afAddrMode_t)AddrBroadcast;

//指定端点号

SampleApp_Periodic_DstAddr.endPoint=SAMPLEAPP_ENDPOINT

//指定目的网络地址为广播地址

SampleApp_Periodic_DstAddr.addr.shortAddr=0xFFFF;

//设定flash中命令即按键命令要发送的目的地址

SampleApp_Flash_DstAddr.addrMode=(afAddrMode_t)afAddrGroup;

SampleApp_Flash_DstAddr.endPoint=SAMPLEAPP_ENDPOINT;

SampleApp_Flash_DstAddr.addr.shortAddr=SAMPLEAPP_FLASH_GROUP;

//定义本设备用来通信的APS层端点描述符

//端点号

SampleApp_epDesc.endPoint=SAMPLEAPP_ENDPOINT;

//任务ID

SampleApp_epDesc.task_id=&SampleApp_TaskID;

//简单描述符

SampleApp_epDesc.simpleDesc

           =(SimpleDescriptionFormat_t*)&SampleApp_SimpleDesc;

//延时策略

SampleApp_epDesc.latencyReq=noLatencyReqs;

//向AF层注册端点描述符

afRegister(&SampleApp_epDesc);

//向osal层注册按键消息

RegisterForKeys(SampleApp_TaskID);

//设定一个新的组

//组号

SampleApp_Group.ID=0x0003;

//设定组名

osal_memcpy(SampleApp_Group.name,"Group3",7);

//把该组添加到网络中

aps_AddGroup(SAMPLEAPP_ENDPOINT,&SampleApp_Group);

#ifdefined(LCD_SUPPORTED)

//如果选择了LCD_SUPPORTED编译选项,会打印一串字符

Print8(HAL_LCD_LINE_2,20,"SampleApp",1);

#endif

}

uint16SampleApp_ProcessEvent(uint8task_id,uint16events)

{

//定义应用层数据包

afIncomingMSGPacket_t*MSGpkt;

//判断osal层的消息类型

//如果系统消息到来

if(events&SYS_EVENT_MSG)

{

   //接收数据包

   MSGpkt=(afIncomingMSGPacket_t*)osal_msg_receive(

SampleApp_TaskID);

  //如果数据包不为空

   while(MSGpkt)

   {

     //判断消息类型

     switch(MSGpkt->hdr.event)

     {

       //如果是按键消息

       caseKEY_CHANGE:

       //调用按键处理函数

         SampleApp_HandleKeys(((keyChange_t*)MSGpkt)->state,

((keyChange_t*)MSGpkt)->keys);

         break;

       //如果是别的组设备周期发送的消息

       caseAF_INCOMING_MSG_CMD:

       //调用对周期消息的处理函数

         SampleApp_MessageMSGCB(MSGpkt);

         break;

       //如果是设备状态变换的命令

       caseZDO_STATE_CHANGE:

       //获取设备状态

         SampleApp_NwkState=(devStates_t)(MSGpkt->hdr.status);

        //如果是三种状态之一

        if((SampleApp_NwkState==DEV_ZB_COORD)

             ||(SampleApp_NwkState==DEV_ROUTER)

             ||(SampleApp_NwkState==DEV_END_DEVICE))

         {

           //按正常间隔启动一个定时器

           osal_start_timerEx(SampleApp_TaskID,

                             SAMPLEAPP_SEND_PERIODIC_MSG_EVT,

                             SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT);

         }

         else

         {

            //设备不在网络中的不做任何处理

           //Deviceisnolongerinthenetwork

         }

         break;

       default:

         break;

     }

     //释放消息占用的存储区

     osal_msg_deallocate((uint8*)MSGpkt);

     //判断操作系统层是否有未处理的数据包,继续处理缓冲区中的包

     MSGpkt=(afIncomingMSGPacket_t*)osal_msg_receive(

SampleApp_TaskID);

   }

   //判断是否有未处理的系统消息,有则接收数据包,放到缓冲区一个个处理

   return(events^SYS_EVENT_MSG);

}

//判断是否有定时消息

if(events&SAMPLEAPP_SEND_PERIODIC_MSG_EVT)

{

   //定时时间到发送一个消息

   SampleApp_SendPeriodicMessage();

   //重新启动定时器

   osal_start_timerEx(SampleApp_TaskID,

SAMPLEAPP_SEND_PERIODIC_MSG_EVT,

       (SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT+(osal_rand()&0x00FF))

);

   //判断是否有未处理的周期消息,有则继续处理

   return(events^SAMPLEAPP_SEND_PERIODIC_MSG_EVT);

}

//其它事件不予处理,直接返回

return0;

}

总之,OSAL实现了类似操作系统的某些功能,但我认为并不能称之为真正意义上的操作系统。

它的复杂性和功能性和通常的操作系统都有所不同。

OSAL层是与协议栈独立的,但是整个协议都要基于OS才能运行。

 

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1