本文最后更新于 120 天前,其中的信息可能已经有所发展或是发生改变。
OSAL介绍
OSAL即操作系统抽象层。对于协议栈来说,没有操作系统的支撑可以运行,但是一系列逻辑处理需要用户自己定义;从Z-Stack1.4.3及以后开始引入OSAL系统。
OSAL是可以理解为是一位“管家”。是一种基于事件驱动的轮询式操作系统,所提供的管理功能有:
- 任务登记、任务初始化、任务触发
- 任务间信息传递
- 任务同步
- 中断处理
- 计时器
- 内存分配
任务调用
整个操作系统是通过osal_run_system()不断轮询便利所有任务事件,事件被置位后就会被调度执行该任务。
需注意的是每次任务呗调度时都只处理一个事件,并在处理完后清除该事件。
任务执行
任务相当于一个函数,执行任务就是执行对应的函数。
任务的函数组是以指针的形式呈现的,任务数组taskArr[]中的任务定义。
unsigned short(*pTaskEventHandlerFn)(unsigned char task_id, unsigned short event);
- pTaskEventHandlerFn:函数名
- task_id:函数ID
- event:对应事件
osalInitTasks:任务初始化函数。
事件从何而来?
- 每个事件相当于一个16位的短整型(unsigned short),有一个变量指针(taskEvents)
- 取出事件号,events = taskEvents[task_id];//task_id(任务号),并判断events是不是非0。
- 当前任务清零,taskEvents[task_id] = 0;
- 处理事件,并返回除了idx该事件,剩余未被处理的事件,events = tasksArr[idx](idx, events);
- 剩下事件再次传递给 taskEvents[task_id],等待下次事件调度处理, taskEvents[task_id] |= events;
每个任务最多可以同时设置16个事件,但有些位已经被系统定义事件占用,所以自定义事件时最好不要与其冲突
- 任务间消息收发事件,SYS_EVENT_MSG = 0x8000
taskEvents事件要和zigbee协议栈中的afIncomingMSGPacket_t->har.event这个8biit的消息事件加以区别。
相关函数
- 指定任务添加事件
- osal_set_event(uint8 task_id, uint16 event_flag);
tasksEvents[task_id] |= event_flag;
- 指定任务删除事件
- osal_clear_event(uint8 task_id, uint16 event_flag);
tasksEvents[task_id] &= ~event_flag;
如何实现任务调度
任务事件被置位,即任务带哦都,主要通过一下两种途径实现:
- 直接通过调用osal_set_event()给任务事件置位。
- 任务调度结束后返回,通过返回未处理完的事件位重新置位。
还有间接通过osal_set_event()置位的情况,例如:
- 一个任务给另一个任务发消息
- 定时器触发事件设置osal_start_timerEx()
- zigbee协议栈底层触发调用