Ztack学习笔记(2)-系统初始化分析
main函数先执行初始化工作,包括硬件、网络层、任务等的初始化。
一 系统初始化
系统初始化函数主要完成内存分配、消息队列头、定时器、电源管理、任务系统及内存栈等的初始化,具体如下代码所示:
//osal.c
1 uint8 osal_init_system( void )
{
// Initialize the Memory Allocation System
osal_mem_init();/*初始化内存分配系统*/ // Initialize the message queue
osal_qHead = NULL; /*初始化系统消息队列*/ // Initialize the timers
osalTimerInit(); /*初始化定时器*/ // Initialize the Power Management System
osal_pwrmgr_init(); /*初始化电源管理系统*/ // Initialize the system tasks.
osalInitTasks();/*初始化系统任务*/ // Setup efficient search for the first free block of heap.
osal_mem_kick(); return ( SUCCESS );
}
二 任务初始化
任务初始化,就是为系统的各个任务分配存储空间,初始化后,内存空间为全0(NULL),然后为各任务分配任务标识号taskID。即,这里重点是各任务的初始化,MAC层和NWK层的未开源看不到。
//OSAL_SampleApp.c
1 void osalInitTasks( void )
{
uint8 taskID = ; tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);//为当前OSAL中的各任务分配存储空间(实际上是一个任务数组),函数返回指向任务缓冲区的指针,因此tasksEvents指向该任务数组的首地址。
osal_memset( tasksEvents, , (sizeof( uint16 ) * tasksCnt));
//把开辟的内存全部设置为0;sizeof( uint16 )是4个字节,即一个任务的长度(同样是uint16定义),乘以任务数量tasksCnt,即全部内存空间
macTaskInit( taskID++ );//初始化各层任务 mac_taskID=0;
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_taskID=6;用户创建的任务
}
系统主循环函数里tasksEvents[ idx]和tasksArr[ idx]的idx与这里taskID是一一对应关系。数组tasksEvents[]里面元素是各任务事件,不是指向任务事件的指针,数组tasksArr[ ]是这个指针数组,里面元素是指向各任务事件处理函数的指针,这两个指针数组里面各元素的顺序要一一对应,因为后面需要相应任务调用相应事件处理函数。如下代码所示,其中的xx_loop与上面的yy_init是一一对应的关系。
//OSAL_Tasks.h
typedef unsigned short (*pTaskEventHandlerFn)( unsigned char task_id, unsigned short event );
//OSAL_SampleApp.c
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
}; const uint8 tasksCnt = sizeof( tasksArr ) / sizeof( tasksArr[] );
三 应用初始化
void SampleApp_Init( uint8 task_id )
{
SampleApp_TaskID = task_id;//osal分配的任务ID,这里为6,随着用户添加任务的增多而改变
SampleApp_NwkState = DEV_INIT;//设备状态设定为ZDO层中定义的初始化状态(无连接)
SampleApp_TransID = ;//消息发送ID(多消息时有顺序之分)
// Device hardware initialization can be added here or in main() (Zmain.c).
// If the hardware is application specific - add it here.
// If the hardware is other parts of the device add it in main().
//以下是通过跳线判断是路由器还是协调器
#if defined ( BUILD_ALL_DEVICES )
// The "Demo" target is setup to have BUILD_ALL_DEVICES and HOLD_AUTO_START
// We are looking at a jumper (defined in SampleAppHw.c) to be jumpered
// together - if they are - we will start up a coordinator. Otherwise,
// the device will start as a router.
if ( readCoordinatorJumper() )
zgDeviceLogicalType = ZG_DEVICETYPE_COORDINATOR;
else
zgDeviceLogicalType = ZG_DEVICETYPE_ROUTER;
#endif // BUILD_ALL_DEVICES
//以下是决断是通过外部按键触发还是系统启动过程中触发启动芯片
#if defined ( HOLD_AUTO_START )
// HOLD_AUTO_START is a compile option that will surpress ZDApp
// from starting the device and wait for the application to
// start the device.
ZDOInitDevice();
#endif
//以下代码设置网络的通讯方式
// Setup for the periodic message's destination address
// Broadcast to everyone
SampleApp_Periodic_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast;
SampleApp_Periodic_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
SampleApp_Periodic_DstAddr.addr.shortAddr = 0xFFFF; // Setup for the flash command's destination address - Group 1
SampleApp_Flash_DstAddr.addrMode = (afAddrMode_t)afAddrGroup;
SampleApp_Flash_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
SampleApp_Flash_DstAddr.addr.shortAddr = SAMPLEAPP_FLASH_GROUP; // Fill out the endpoint description.
SampleApp_epDesc.endPoint = SAMPLEAPP_ENDPOINT;
SampleApp_epDesc.task_id = &SampleApp_TaskID;
SampleApp_epDesc.simpleDesc
= (SimpleDescriptionFormat_t *)&SampleApp_SimpleDesc;
SampleApp_epDesc.latencyReq = noLatencyReqs; // Register the endpoint description with the AF
afRegister( &SampleApp_epDesc ); // Register for all key events - This app will handle all key events
RegisterForKeys( SampleApp_TaskID ); // By default, all devices start out in Group 1
SampleApp_Group.ID = 0x0001;
osal_memcpy( SampleApp_Group.name, "Group 1", );
aps_AddGroup( SAMPLEAPP_ENDPOINT, &SampleApp_Group ); #if defined ( LCD_SUPPORTED )
HalLcdWriteString( "SampleApp", HAL_LCD_LINE_1 );
#endif
}
以上为OSAL初始化大体流程,OSAL以及各软硬部件初始化完成后,就进入了系统主循环函数osal_start_system(),下节将介绍此。
四 参考链接
Ztack学习笔记(2)-系统初始化分析的更多相关文章
- Ztack学习笔记(4)-系统网络分析
协调器的组网,终端设备和路由设备发现网络以及加入网络 //第一步:Z-Stack 由 main()函数开始执行,main()函数共做了 2 件事:一是系统初始化,另外一件是开始执行轮转查询式操作系统 ...
- Linux学习笔记-Linux系统简介
Linux学习笔记-Linux系统简介 UNIX与Linux发展史 UNIX是父亲,Linux是儿子. UNIX发行版本 操作系统 公司 硬件平台 AIX IBM PowerPC HP-UX HP P ...
- Symfony2 学习笔记之系统路由
mfony2 学习笔记之系统路由 漂亮的URL绝对是一个严肃的web应用程序必须做到的,这种方式使index.php?article_id=57这类的丑陋URL被隐藏,由更受欢迎的像 /read/ ...
- SPSS学习笔记之——Kaplan-Meier生存分析
SPSS学习笔记之--Kaplan-Meier生存分析 一.概述 关于生存分析的相关概念,Kaplan-Meier用于估计生存函数,允许有一个分组变量进行生存率的组间比较,还容许一个分层变量.若不考虑 ...
- Nginx学习笔记4 源码分析
Nginx学习笔记(四) 源码分析 源码分析 在茫茫的源码中,看到了几个好像挺熟悉的名字(socket/UDP/shmem).那就来看看这个文件吧!从简单的开始~~~ src/os/unix/Ngx_ ...
- Ztack学习笔记(3)-系统启动分析
一 系统启动 //OSAL.cvoid osal_start_system( void ) { #if !defined ( ZBIT ) && !defined ( UBIT ) f ...
- Hadoop学习笔记—20.网站日志分析项目案例(三)统计分析
网站日志分析项目案例(一)项目介绍:http://www.cnblogs.com/edisonchou/p/4449082.html 网站日志分析项目案例(二)数据清洗:http://www.cnbl ...
- Hadoop学习笔记—20.网站日志分析项目案例
1.1 项目来源 本次要实践的数据日志来源于国内某技术学习论坛,该论坛由某培训机构主办,汇聚了众多技术学习者,每天都有人发帖.回帖,如图1所示. 图1 项目来源网站-技术学习论坛 本次实践的目的就在于 ...
- Ztack学习笔记(1)-初识Ztack
一.Zigbee协议 Zigbee是IEEE 802.15.4协议的代名词,是一种短距离.低功耗的无线通信技术.这一名称来源于蜜蜂的八字舞,因为蜜蜂(bee)是靠飞翔和“嗡嗡”(zig)地抖动翅膀的“ ...
随机推荐
- CSDN中根据文章自动生成文章目录
概述 CSDN中有根据文件内容中H标签在文章中自动生成文章目录,看起来比较专业,就想把它搬到自己的博客园中.类似下图 提取JS脚本 通过浏览器开发者工具(IE/Chrome)找到产生文章目录javas ...
- 【Android Api 翻译2】Android Testing(1) 浅尝Android测试的奥秘
------- 源自梦想.永远是你IT事业的好友.只是勇敢地说出我学到! ---------- 仅供学习和交流使用,翻译不好勿喷,请只摘除不合适的地方 Testing The Android fram ...
- LRU算法实现
JDK中的实现 在JDK中LinkedHashMap可以作为LRU算法以及插入顺序的实现,LinkedHashMap继承自HashMap,底层结合hash表和双向链表,元素的插入和查询等操作通过计算h ...
- 如何将你自己的Python package发布到PyPI上
零.前言 最近做了一个小工具,查询IP或者域名的归属地.做完之后想发布到PyPI上,这样大家就可以通过pip来安装了. 在发布的过程中遇到了一些问题,也学到了很多东西.记录到这篇文章中.希望对大家有所 ...
- [转]Android 应用的自动升级、更新模块的实现
本文转自:http://www.oschina.net/question/163910_28462 我们看到很多Android应用都具有自动更新功能,用户一键就可以完成软件的升级更新.得益于Andro ...
- codeforces Good Bye 2013 379D New Year Letter
题目链接:http://codeforces.com/problemset/problem/379/D [题目大意] 告诉你初始字符串S1.S2的长度和递推次数k, 使用类似斐波纳契数列的字符串合并的 ...
- Java作业
1.实现一个名为Person的类和它的子类Employee,Employee有两个子类Faculty和Staff.具体要求如下: (1)Person类中的属性有:姓名name(String类型),地址 ...
- 使用Boost asio实现同步的TCP/IP通信
可以先了解一下Boost asio基本概念,以下是Boost asio实现的同步TCP/IP通信: 服务器程序部分,如果想保留套接字之后继续通信,可以动态申请socket_type,保存指针,因为so ...
- mac下apache的多站点配置
以下操作均建立在 已经配置好了php环境 从网上搜索了下,后来自己配置了下还是比较简单的! 我的环境目录是在/Library/webServer/Documents 测试的时候可以直接在这里建立 ...
- [转]oracle 实现插入自增列
本文转自:http://blog.csdn.net/love_zt_love/article/details/7911104 刚使用oracle,它和sql server 好多地方还是有所不同的,简单 ...