源码分析SampleApp.xls
《源码分析SampleApp.xls》由会员分享,可在线阅读,更多相关《源码分析SampleApp.xls(60页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、关于Zigbee协议的C语言实现一、协议:Zigbee联盟规范了协议,具体的协议编程语言表述则由IC厂商指定,如德州仪器TI公司的基于CC2430与CC2530的Z-Stack意法半导体ST等公司也有自己的Zigbee协议的实现方式二、开源:虽然宣称的Zigbee是开源的,但是跟底层硬件(如CC2530的寄存器具体配置)密切相关部分:MAC层与NWK层TI并未开源,而是以lib(库)配合相应的头文件(用户接口)实现,lib库的位置在:ZStack-CC2530-2.4.0-1.4.0ProjectszstackLibraries下所以更上的AF(应用程序框架),ZCL,ZDO等层只要包含lib
2、对应的头文件,即可调用库里的API函数三、Z-Stack:Z-Stack几乎都是C语言写的,即便是平时经常用C写过单片机程序的,读Z-Stack代码是还是有点困难的,原因如下1、用了大量的宏定义。程序中把用到的常量统统用宏定义表示,这样程序维护起来很方便2、用到大量的结构体struct与枚举emun比如简单的类型定义int,char,unsigned char等,只能表示简单的数据结构,复杂的数据结构用struct定义。如描述EndPoint的数据结构endPointDesc_t定义如下:此数据结构中又包含一层数据结构:SimpleDescriptionFormat_t最后在编写应用程序时,只
3、要用像 int num;一样定义一个变量就可以描述很复杂的数据了枚举:enum协议里的状态值基本上都是enum定义的值,如在SampleApp中的devStates_t SampleApp_NwkState;函数的状态返回值一般是用uint8(unsigned char)类型定义的,但是这样不够直观,不能通过名称表达返回的状态属于谁所以经过层层的typedef 定义得到 afStatus_t退去一层typedeftypedef ZStatus_t afStatus_t;再退去一层typedeftypedef Status_t ZStatus_t;最后得到的uint8typedef uint8
4、Status_t;到这一层定义我们就熟悉的typedef unsigned char uint8;unsigned char则是C语言中的基本数据类型3、随处可见的指针、引用(以下例子在上图的AF_DataRequest()函数的参数中抽取)协议里的指针有如下几种3.1最简单的指针类型uint8*buf 即一维数组3.2结构体指针afAddrType_t*dstAddr3.3函数指针2tasksArr其实是函数指针类型定义的函数指针数据,说得有点绕,看下图pTaskEventHandlerFn是可以定义形如下面语句的 指针数据类型即可以定义像这样的函数:unsigned short Funct
5、ion(参数1,参数2)其中unsigned short是返回值这样 就可以用pTaskEventHandlerFn定义 函数变量 了pTaskEventHandlerFn taskArr,由于taskArr是数组类型,所以只要给taskArr指定不同的索引值就可以调用不同的函数OSAL层的任务切换就是通过此方法协议里的引用引用是函数参数传递的一种变种,因为函数要求参数传递要一一对应,如上参数afAddrType_t*dstAddr的,所以当调用AF_DataRequest()函数时,必须传递一个afAddrType_t类型的指针变量但是,请看,在SampleApp.c文件中并不是结构体指针,
6、而是普通的结构体变量,所以在AF_DataRequest()函数调用时要使用引用,此时函数获得的仍然是此变量的地址,而不是变量的值四四、OSALOSALZ-Stack中引入了操作系统层OSAL,这样大大提高编程的灵活性,并且提高了CPU的运行效率但是此OS不是真正意义上的OS,因为他是通过在OS的一个主循环不停的调用task任务函数来实现任务调度的,并未实现真正的上下文切换Z-Stack的难度之一是OSAL层的编程,还有task、events、msg的理解,还有任务切换的方法具体分析请看Sheet2表五、最后是对协议本身的理解对TI提供的文档阅读几遍是必要的,即使不能完全理解,但是多读几遍会有
7、一个整体的理解,这样在code中遇到的陌生词汇ZDO、ZCL,AF等就不会陌生这样再去翻阅具体的ZDO等部分就会理解更深了对协议最简单的概述(我的理解过程)PD-SAP、MLDE-SAP、NLDE-SAP等都是协议各层的数据实体,也就是数据交换的接口,有具体的API函数PLME-SAP、MLME-SAP,等是协议各层的管理实体,也有具体的API函数建议:初学Zigbee或者单纯的开发简单的通信任务程序,根本不用管这些东西,看了反而更加复杂安全服务部分:最简单的安全设置就是修改那一串密钥了,暂时也不用管这些与应用程序编写 相关的部分有:Zigbee设备对象ZDO,应用支持子层AFS,还有协议族Z
8、CL这三个部分要好好的理解,对协议的理解和应用程序的编写都离不开他们,最好是对照协议的描述看他们对应的API函数注意ZCL层,Zigbee联盟为了使不同的IC厂商,不同的终端公司提供的zigbee设备都能互相访问而设置的ZCL与profile(我的理解)所以ZCL这一层与profile初学时也不必深究应用程序对象1240这里的1240就是EndPoint对应的值,0被zdo保留,240以上被协议保留,所以应程序可以定义的是1240这个功能是为复杂的程序应用提供的了方便,EndPoint相当于入口点,或者说是TCP/IP里的端口号,比如网页访问的80端口所以在一个程序中可以有多个EndPoint
9、,SampleApp实例中只用到了一个Profile,这个东西要从zigbee联盟获取商用的时候,但是实验室可以用公用的profile,只要相互访问的设备中保证profile的值相同就可以了在sheet2中分析OSAL层在sheet3中分析SampleApp示例程序的流程一、协议:Zigbee联盟规范了协议,具体的协议编程语言表述则由IC厂商指定,如德州仪器TI公司的基于CC2430与CC2530的Z-Stack二、开源:虽然宣称的Zigbee是开源的,但是跟底层硬件(如CC2530的寄存器具体配置)密切相关部分:MAC层与NWK层TI并未开源,而是以lib(库)配合相应的头文件(用户接口)实
10、现,lib库的位置在:ZStack-CC2530-2.4.0-1.4.0ProjectszstackLibraries下所以更上的AF(应用程序框架),ZCL,ZDO等层只要包含lib对应的头文件,即可调用库里的API函数三、Z-Stack:Z-Stack几乎都是C语言写的,即便是平时经常用C写过单片机程序的,读Z-Stack代码是还是有点困难的,原因如下比如简单的类型定义int,char,unsigned char等,只能表示简单的数据结构,复杂的数据结构用struct定义。最后在编写应用程序时,只要用像 int num;一样定义一个变量就可以描述很复杂的数据了协议里的状态值基本上都是enu
11、m定义的值,如在SampleApp中的devStates_t SampleApp_NwkState;函数的状态返回值一般是用uint8(unsigned char)类型定义的,但是这样不够直观,不能通过名称表达返回的状态属于谁3、随处可见的指针、引用(以下例子在上图的AF_DataRequest()函数的参数中抽取)tasksArr其实是函数指针类型定义的函数指针数据,说得有点绕,看下图即可以定义像这样的函数:unsigned short Function(参数1,参数2)pTaskEventHandlerFn taskArr,由于taskArr是数组类型,所以只要给taskArr指定不同的索
12、引值就可以调用不同的函数引用是函数参数传递的一种变种,因为函数要求参数传递要一一对应,如上参数afAddrType_t*dstAddr的,所以当调用AF_DataRequest()函数时,必须传递一个afAddrType_t类型的指针变量并不是结构体指针,而是普通的结构体变量,所以在AF_DataRequest()函数调用时要使用引用,此时函数获得的仍然是此变量的地址,Z-Stack中引入了操作系统层OSAL,这样大大提高编程的灵活性,并且提高了CPU的运行效率但是此OS不是真正意义上的OS,因为他是通过在OS的一个主循环不停的调用task任务函数来实现任务调度的,并未实现真正的上下文切换Z-
13、Stack的难度之一是OSAL层的编程,还有task、events、msg的理解,还有任务切换的方法对TI提供的文档阅读几遍是必要的,即使不能完全理解,但是多读几遍会有一个整体的理解,这样在code中遇到的陌生词汇ZDO、ZCL,AF等就不会陌生PD-SAP、MLDE-SAP、NLDE-SAP等都是协议各层的数据实体,也就是数据交换的接口,有具体的API函数建议:初学Zigbee或者单纯的开发简单的通信任务程序,根本不用管这些东西,看了反而更加复杂与应用程序编写 相关的部分有:Zigbee设备对象ZDO,应用支持子层AFS,还有协议族ZCL这三个部分要好好的理解,对协议的理解和应用程序的编写都
14、离不开他们,最好是对照协议的描述看他们对应的API函数注意ZCL层,Zigbee联盟为了使不同的IC厂商,不同的终端公司提供的zigbee设备都能互相访问而设置的ZCL与profile(我的理解)这里的1240就是EndPoint对应的值,0被zdo保留,240以上被协议保留,所以应程序可以定义的是1240这个功能是为复杂的程序应用提供的了方便,EndPoint相当于入口点,或者说是TCP/IP里的端口号,比如网页访问的80端口Profile,这个东西要从zigbee联盟获取商用的时候,但是实验室可以用公用的profile,只要相互访问的设备中保证profile的值相同就可以了OSAL层的运行
15、方式的,任务的调度,msg消息的传递,以及事件的响应总述:其实Z-Stack已经把协议封装的很好了,要用到了API函数就那么几个,所以研究Zigbee初期的重点在OSAL运行流程的理解一、OSAL运行流程main函数在Zmain.c文件中上图是main函数的末尾部分osal_start_system()函数里调用了函数大循环,所有的任务调度都在这里面实现在系统运行之前还要有一些初始化:硬件初始化UART,LED,KEY等,还有就是任务初始化在OSAL.c文件中主循环在osal_run_system()中,在文件OSAL.c中osal_run_system()的流程图Osal runosalTi
16、meUpdate()Hal_ProcessPoll()If(tasksEventsidx)HAL_ENTER _CRITICAL_SECTIONevents=(tasksArridx)(idx,events)HAL_EXIT_CRITICAL_SECTIONtasksEventsidx=events是否If(+idx tasksCnt)是否更新Time硬件查询(keys)判断每个task的tasksEvents是否有事件存在taskEvents为uint16类型的数据,16位,因此每个tasks最多可以有16个内部事件每个tasks调度前必须关闭中断,进入绝对控制阶段tasksArr为函数指针
17、数据,通过指定idx索引实现调用不同的函数,并且给被调用的函数传递了两个参数:idx,events退出绝对控制保存尚未处理的事件OS的tasks任务每次只处理一个事件,保证每个tasks不会占用太多CPU时间二,tasks任务流程OS里面已经做好所有工作用户只需编写自己的tasks函数,tasks初始化函数即可然后在任务列表tasksArr中添加任务与用户有关的OS层的代码在OSAL_SampleApp.c中的,(这样的OSAL_XXXApp.c)OSAL_SampleApp.cOsal runosalTimeUpdate()Hal_ProcessPoll()If(tasksEventsidx
18、)HAL_ENTER _CRITICAL_SECTIONevents=(tasksArridx)(idx,events)HAL_EXIT_CRITICAL_SECTIONtasksEventsidx=events是否If(+idx tasksCnt)是否更新Time硬件查询(keys)判断每个task的tasksEvents是否有事件存在taskEvents为uint16类型的数据,16位,因此每个tasks最多可以有16个内部事件每个tasks调度前必须关闭中断,进入绝对控制阶段tasksArr为函数指针数据,通过指定idx索引实现调用不同的函数,并且给被调用的函数传递了两个参数:idx,e
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 源码 分析 SampleApp
限制150内