车干的ZigBee学习笔记八-浅析协议栈
程序员文章站
2022-03-07 09:33:37
...
一、初识OSAL
- ZigBee协议栈的实时操作系统
- 操作系统抽象层-Operating System Abstraction Layer
- 作用:任务调度,资源分配和管理
- 关键词:任务和事件
- taskCnt–任务总数
- taskEvents–指向事件表首地址的指针
- taskArry–数组,数组中的每一个元素都是指向事件处理函数的指针
二、协议栈运行机制
1、入口在Zmain文件下,Zmain.c的main函数中,其中包含了各种硬件和协议栈的初始化,直到调用osal_start_system()函数,协议栈才开始真正运行起来。
- int main(void)
- {
-
...
-
...
- osal_start_system(); //不再返回
- return 0; //
- }
2、当发生两个事件同时发生时,0SAL处理
- #define SYS_EVENT_MSG 0X8000
- #define SAMPLEAPP_SEND_PERIODIC_MSG_EVT 0X0001
- 如果这两个事件同时发生,则events =0x8001
- 异或运算,同为0,异为1
- events^SYS_EVENT_MSG = 0x0001(只剩下最后一个事件)
- events^SAMPLEAPP_SEND_PERIODIC_MSG_EVT =0x8000(只剩前一个事件)
三、osal_start_system(); 详解
void osal_start_system( void )
{
#if !defined ( ZBIT ) && !defined ( UBIT )
for(;;) //首先是一个FOR的死循环
#endif
{
uint8 idx = 0; //定义变量用来索引事件表
osalTimeUpdate(); //用来更新系统时钟
Hal_ProcessPoll(); // 查看硬件方面是否有事件发生
do {
if (tasksEvents[idx]) // tasksEvents事件表,当有事件发生,idx 会变为一个16进制的数字
{
break;//idx不为0时,跳出do_while循环
}
} while (++idx < tasksCnt); //如果没有事件发生,++idx继续检查下一项是否有事件发生
if (idx < tasksCnt) //跳出任务检查循环后,第一步,保证不超出任务总数
{
uint16 events;
halIntState_t intState;
HAL_ENTER_CRITICAL_SECTION(intState); //进入中断
events = tasksEvents[idx]; //保存事件
tasksEvents[idx] = 0; // 事件表清除为0.
HAL_EXIT_CRITICAL_SECTION(intState); //退出中断
events = (tasksArr[idx])( idx, events );//调用数据处理函数
HAL_ENTER_CRITICAL_SECTION(intState); //进入中断
tasksEvents[idx] |= events; // 把未处理的事件返回给事件表
HAL_EXIT_CRITICAL_SECTION(intState); //退出中断
}
#if defined( POWER_SAVING )
else //完全通过所有没有活动的任务事件?
{
osal_pwrmgr_powerconserve(); // 完全通过所有没有活动的任务事件?
}
#endif
}
}
上一篇: Nordic修改设备名
下一篇: 强制推送本地代码到远程仓库
推荐阅读