OSAL的工作原理Word文档下载推荐.docx
- 文档编号:19521404
- 上传时间:2023-01-07
- 格式:DOCX
- 页数:6
- 大小:19.16KB
OSAL的工作原理Word文档下载推荐.docx
《OSAL的工作原理Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《OSAL的工作原理Word文档下载推荐.docx(6页珍藏版)》请在冰豆网上搜索。
◆任务间的消息交换
◆任务同步
◆中断处理
◆时间管理
◆内存分配
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);
}
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);
//如果是设备状态变换的命令
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
default:
//释放消息占用的存储区
osal_msg_deallocate((uint8*)MSGpkt);
//判断操作系统层是否有未处理的数据包,继续处理缓冲区中的包
//判断是否有未处理的系统消息,有则接收数据包,放到缓冲区一个个处理
return(events^SYS_EVENT_MSG);
//判断是否有定时消息
SAMPLEAPP_SEND_PERIODIC_MSG_EVT)
//定时时间到发送一个消息
SampleApp_SendPeriodicMessage();
//重新启动定时器
SAMPLEAPP_SEND_PERIODIC_MSG_EVT,
(SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT+(osal_rand()&
0x00FF))
);
//判断是否有未处理的周期消息,有则继续处理
return(events^SAMPLEAPP_SEND_PERIODIC_MSG_EVT);
//其它事件不予处理,直接返回
return0;
总之,OSAL实现了类似操作系统的某些功能,但我认为并不能称之为真正意义上的操作系统。
它的复杂性和功能性和通常的操作系统都有所不同。
OSAL层是与协议栈独立的,但是整个协议都要基于OS才能运行。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- OSAL 工作 原理