06 ZStack的task工作流程分析
来源:互联网 发布:ps淘宝详情页参数 编辑:程序博客网 时间:2024/06/05 07:54
安装ZStack-CC2530-2.5.1a.exe
默认安装到”C:\Texas Instruments\ZStack-CC2530-2.5.1a”目录下.
Components目录里实现 hal层、stack网络协议栈、mac层的封装, 而且也实现了osal操作系统的功能等. 通常情况下我们就是调用里面实现好的功能函数就可以了.
Documents目录里存放有各个分层的的功能函数的说明文档.
Projects目录存放TI提供的应用案例,我们可以基于这些案例上根据项目需要求进行修改.
Tools目录里存放TI提供的,用于在pc端使用的工具.
/////////////////////////////////////////////
打开此目录下的SampleApp.eww工程.
///////////////
在此位置选择要编译的设备类型, 不管是要作协调器,路由器,终端设备都是共用一个工程源码的。只要选择不同的设备类型,在编译时会自动编译加入相应的设备角色功能.
工程里目录说明(摘自开发板文档):
ZStack虽然叫zigbee协议栈,但除了网络数据的协议栈外还有一个多任务的操作系统。
////////////////////////////////////////////////////////////////////////////////////////////////////
协议栈里的操作系统工作原理分析:
里面的操作系统是支持多任务(多进程)同时执行的, 每个任务都是基于事件触发调度的。简单来说, 此系统就是在main函数里用个死循环,循环检查每个任务是否有事件发生, 如有事件发生则调用此任务的事件处理函数。
每个任务都有一个唯一的任务号,根据此任务号可以区别相应的任务。每个任务的事件都由一个uint16类型变量来存放,每种事件占用一位,相应的位为1即表示有相应的事件发生。而且每个任务都有一个事件处理函数,只要有事件发生了,系统就会调用任务的事件处理函数来处理已发生的事件. 除此外,每个任务还有一个初始化函数,用于记录分配的任务号并作任务工作前的初始化工作
在OSAL_SampleApp.c源文件里:
每个任务的事件处理函数地址由全局函数指针数组tasksArr数组来存放。此数组的元素个数即就是系统里的任务个数。同时此数组里是按任务的任务号从小到大顺序来存放的,即可以tasksArr[任务号]得到相应任务的事件处理函数地址.
//协议栈里的每个分层都由一个任务来实现相应的功能。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 SampleApp_ProcessEvent // SampleApp任务的事件处理函数};const uint8 tasksCnt = sizeof( tasksArr ) / sizeof( tasksArr[0] ); //此全局变量记录任务的个数uint16 *tasksEvents; //注意全局指针变量tasksEvents其实相当于一个数组(uint16 tasksEvents[tasksCnt]), 每个任务的事件都由一个uint16元素来记录。 即tasksEvents[任务号]可得到相应任务的事件信息.void osalInitTasks( void ) //系统初始化所有任务的函数,此函数在系统初始化后被调用{ uint8 taskID = 0; //用于分配的任务号 tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt); //这里动态分配空间,用于记录每个任务的事件信息. osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt)); //就是先把每个任务的事件信息清零 //下面是调用每个任务的初始化函数,并传递分配的任务号。注意此顺序需与在tasksArr函数指针数组里的初始化顺序一致. macTaskInit( taskID++ ); nwk_init( taskID++ ); Hal_Init( taskID++ );#if defined( MT_TASK ) MT_TaskInit( taskID++ );#endif APS_Init( taskID++ );#if defined ( ZIGBEE_FRAGMENTATION ) APSF_Init( taskID++ );#endif ZDApp_Init( taskID++ );#if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT ) ZDNwkMgr_Init( taskID++ );#endif SampleApp_Init( taskID ); //调用SampleApp任务的初始化函数}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
系统的具体工作流程:
系统最先是从工程的ZMain目录里的ZMain.c的79行的main函数开始执行的.
//这里只关注任务的调度,其它的就不深入了int main(void){ ... osal_init_system(); //系统初始化函数 ... //里面有调用上面的系统任务函数 osalInitTasks(); ... //再进一步也就会调用各个任务的初始化函数,也包括SampleApp任务的初始化函数 SampleApp_Init( taskID ); ... //main函数最后,就是开始系统工作了 osal_start_system(); //osal_start_system函数里面就是个死循环,循环调用osal_run_system osal_run_system(); //此函数就是任务调度的实现}void osal_run_system( void ){ uint8 idx = 0; //此变量用于记录当前检查的任务的任务号 osalTimeUpdate(); Hal_ProcessPoll(); do { if (tasksEvents[idx]) //不要忘了tasksEvents就是一个记录所有任务事件的数组,以任务号为下标. { break; //如果tasksEvents[idx]不为零,则表示任务号为idx的任务有事件发生需要处理事件, 结束当前循环. } } while (++idx < tasksCnt); //tasksCnt为任务的个数 if (idx < tasksCnt) // 有事件发生的任务需处理 { uint16 events; halIntState_t intState; HAL_ENTER_CRITICAL_SECTION(intState); //进入防止并发处理的状态(上锁) events = tasksEvents[idx]; //先用events变量记录任务的事件 tasksEvents[idx] = 0; // Clear the Events for this task. HAL_EXIT_CRITICAL_SECTION(intState); //退出防止并发的状态(解锁) activeTaskID = idx; events = (tasksArr[idx])( idx, events ); //不要忘了tasksArr是一个全局函数指针变量数组,记录所有任务的事件处理函数的地址. 这里调用有事件发生的任务的事件处理函数,并传递它的任务号及事件信息。最后用events变量存放返回值,返回值为尚未处理的事件信息,如返回0则表示当前已发生事件都已经处理了. ... HAL_ENTER_CRITICAL_SECTION(intState); tasksEvents[idx] |= events; //把没有处理的事件信息存放到tasksEvent数组里,下次检查时,将会处理还没有处理的事件. HAL_EXIT_CRITICAL_SECTION(intState); } ...}
总结,每个任务有一个初始化函数及事件处理函数, 而且所有任务的事件都在tasksEvent里存放起来。任务间的通信可以通过改变相应任务的事件信息来实现.
- 06 ZStack的task工作流程分析
- ZStack 虚拟路由器工作流程
- ZStack协议按键处理流程分析
- HDFS的工作流程分析
- 07 在ZStack里创建自己的task
- [Java] oscache 多线程 工作流程的分析
- 对struts工作流程的分析
- apache shiro的工作流程分析
- apache shiro的工作流程分析
- U-boot的工作流程分析-2440
- U-boot的工作流程分析-6410
- haproxy工作流程分析
- surfaceflinger 工作流程分析
- Zygote工作流程分析
- surfaceflinger 工作流程分析
- hadoop工作流程分析
- 分析Netty工作流程
- uboot工作流程分析
- ubuntu安装wps
- Android全局异常处理(捕获异常,不弹出程序崩溃)
- MYSQL问题解决方案:Access denied for user 'root'@'localhost' (using password:YES)
- Android 自定义View (二) 进阶
- SDK接入遇到的问题
- 06 ZStack的task工作流程分析
- CodeForces
- SQL查询 从第N条记录开始显示M行
- 网络编程—链路层报文、网络层IP报文、传输层TCP报文
- D3.js 数据可视化学习笔记——Hello D3!
- R分类算法-神经网络算法
- 布全Micromine.GBIS.v7.8.0.60矿业专业软件
- Android 自定义View (三) 圆环交替 等待效果
- Android json解析 Gson工具类