初次接触zstack
来源:互联网 发布:mac开启root权限 编辑:程序博客网 时间:2024/06/07 13:56
zstack安装了之后得到了不是一大堆文件夹吗?里面包含了很多TI开源的代码和不开源的一些库,我们在编程的时候需要用到这些代码和库,就像我们写c语言程序的时候很多#include这些,很多都是库文件一样,而且Ti给了很多例子程序给我们,我们开始学习就从这些例子程序开始学起,特别重要的就是学习不是只看懂TI的例程就可以了,还要学会去修改TI的例程,把一个实现的简单的功能的程序,改编成一个实现复杂功能的程序。
我们先来看看我们装完zstack之后得到的目录结构
在图中我们可以看到好几个目录,我在第一篇中都解析过这些目录里面有啥干啥用的,如果你不想在你安装的目录去弄这些东西,你完全可以把这些文件拷贝到别的地方去弄,我就把他铐到了G盘去,这样子做的好处就是,就算你够衰把文件搞不见了,你还有原来的那个,不至于又要重装一次。现在我们先来看看Projects这个文件夹,里面是Ti给我们的一些例子程序之类的东西。,Projects->zstack之后我们可以看到这样子的一堆目录
同样来说说这些目录都是干啥的,第一个就够霸气了,HomeAutomation,会英文的都知道,这是智能家居的例子,里面包含了一个开关程序例子,灯光例子,还有一个空中升级的例子。Libraies我就不说了,这是库的文件夹,OTA是啥来的呢?这是Ti提供的一个空中升级的插件程序,你的程序不一定要用到。Samples这个文件夹放得是一下简单的例子程序,好了,其他的不说了,ZMain放的是main函数的文件,因为协议栈用到了很多种的板子,所以提供了不同类型板子的程序模块。我们一般用到的是TI2530DB里面的那部分程序。
- /*********************************************************************
- * @fn main
- * @brief First function called after startup.
- * @return don't care
- */
- int main( void )
- {
- // Turn off interrupts
- osal_int_disable( INTS_ALL );
- // Initialization for board related stuff such as LEDs
- HAL_BOARD_INIT();
- // Make sure supply voltage is high enough to run
- zmain_vdd_check();
- // Initialize board I/O
- InitBoard( OB_COLD );
- // Initialze HAL drivers
- HalDriverInit();
- // Initialize NV System
- osal_nv_init( NULL );
- // Initialize the MAC
- ZMacInit();
- // Determine the extended address
- zmain_ext_addr();
- #if defined ZCL_KEY_ESTABLISH
- // Initialize the Certicom certificate information.
- zmain_cert_init();
- #endif
- // Initialize basic NV items
- zgInit();
- #ifndef NONWK
- // Since the AF isn't a task, call it's initialization routine
- afInit();
- #endif
- // Initialize the operating system
- osal_init_system();
- // Allow interrupts
- osal_int_enable( INTS_ALL );
- // Final board initialization
- InitBoard( OB_READY );
- // Display information about this device
- zmain_dev_info();
- /* Display the device info on the LCD */
- #ifdef LCD_SUPPORTED
- zmain_lcd_init();
- #endif
- #ifdef WDT_IN_PM1
- /* If WDT is used, this is a good place to enable it. */
- WatchDogEnable( WDTIMX );
- #endif
- osal_start_system(); // No Return from here
- return 0; // Shouldn't get here.
- } // main()
也许有人会问,大循环去哪啦?别着急,其实main做了一大堆东西之后在osal_start_system这里就进入大循环了,我们先来看看osal_start_system做了什么事情
- void osal_start_system( void )
- {
- #if !defined ( ZBIT ) && !defined ( UBIT )
- for(;;) // Forever Loop
- #endif
- {
- osal_run_system();
- }
- }
这会儿你看到你可爱的大循环了吧,继续看看osal_run_system做了什么东西
- void osal_run_system( void )
- {
- uint8 idx = 0;
- osalTimeUpdate();
- Hal_ProcessPoll();
- do {
- if (tasksEvents[idx]) // Task is highest priority that is ready.
- {
- break;
- }
- } while (++idx < tasksCnt);
- if (idx < tasksCnt)
- {
- uint16 events;
- halIntState_t intState;
- HAL_ENTER_CRITICAL_SECTION(intState);
- events = tasksEvents[idx];
- tasksEvents[idx] = 0; // Clear the Events for this task.
- HAL_EXIT_CRITICAL_SECTION(intState);
- activeTaskID = idx;
- events = (tasksArr[idx])( idx, events );
- activeTaskID = TASK_NO_TASK;
- HAL_ENTER_CRITICAL_SECTION(intState);
- tasksEvents[idx] |= events; // Add back unprocessed events to the current task.
- HAL_EXIT_CRITICAL_SECTION(intState);
- }
- #if defined( POWER_SAVING )
- else // Complete pass through all task events with no activity?
- {
- osal_pwrmgr_powerconserve(); // Put the processor/system into sleep
- }
- #endif
- /* Yield in case cooperative scheduling is being used. */
- #if defined (configUSE_PREEMPTION) && (configUSE_PREEMPTION == 0)
- {
- osal_task_yield();
- }
- #endif
- }
也许现在你看不明白他写了什么,放心总有一天你看得明白的,可是有个疑问会不会冒出来了呢?那我自己的代码写在哪啊!,难道我还得改这个大循环不成?!别急,现在我们来说说这协议栈是怎么工作的。
首先,我们要来说的就是zstack的操作系统---OSAL,我们的协议栈其实是运行在TI的OSAL操作系统之上的,我们的程序(在程序中叫做task)和协议栈的各层都是作为osal的一个个任务在运行,由osal来调度的。我们刚才看到的是如何去启动了osal系统而已,既然我们的程序和协议栈都是osal的一个任务,那么我们如何把自己的任务注册进来呢?这是接下来我们要说的问题,至于osal的基本机制,我们以后再说,现在要做的是先让大家能够下载些程序下去玩玩,满足一下虚荣之心先。
3.建立自己的任务
还是按照例子来说比较好说,那么我们挑选的例子就是TI的一个基本的例子,实现了一些最基本的入网和收发数据亮灯程序。我挑选了ZStack-CC2530-2.5.1a\Projects\zstack\Samples\GenericApp这个工程来说明如何建立自己的任务,打开ZStack-CC2530-2.5.1a\Projects\zstack\Samples\GenericApp\CC2530DB里面的IAR工程,我们可以看到这样子的架构
当然你重头到尾建立这样子一个工程是挺费劲的,TI已经提供好了,那就用TI的例子修改就行了,没必要重头到尾建立一次,我建过,还是要看着TI的配置来做,很麻烦,很多配置东西你要清楚才能配置好。我们要建立自己任务,那么这些东西都在App这个Group里面,看看里面有啥东西
可以看出只有三个文件,这三个文件却大有头,这样子的架构几乎成了TI的zstack的程序架构,几乎所有的都是这样子写的,GenericApp.h放的是一些用户的宏定义,GenericApp.c实现我们自己的任务代码,OSAL_GenericApp.c主要是实现osal协议的协议初始化接口的编写,我们的任务添加,就靠这三个文件了!好,我们先不看我们的任务代码是怎么实现的,我们先看OSAL_GenericApp.c是怎么添加我们的任务的和初始化osal的任务的,内容不多,就全放上来吧
- #include "ZComDef.h"
- #include "hal_drivers.h"
- #include "OSAL.h"
- #include "OSAL_Tasks.h"
- #if defined ( MT_TASK )
- #include "MT.h"
- #include "MT_TASK.h"
- #endif
- #include "nwk.h"
- #include "APS.h"
- #include "ZDApp.h"
- #if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT )
- #include "ZDNwkMgr.h"
- #endif
- #if defined ( ZIGBEE_FRAGMENTATION )
- #include "aps_frag.h"
- #endif
- #include "GenericApp.h"
- /*********************************************************************
- * GLOBAL VARIABLES
- */
- // The order in this table must be identical to the task initialization calls below in osalInitTask.
- 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
- GenericApp_ProcessEvent
- };
- const uint8 tasksCnt = sizeof( tasksArr ) / sizeof( tasksArr[0] );
- uint16 *tasksEvents;
- /*********************************************************************
- * FUNCTIONS
- *********************************************************************/
- /*********************************************************************
- * @fn osalInitTasks
- *
- * @brief This function invokes the initialization function for each task.
- *
- * @param void
- *
- * @return none
- */
- void osalInitTasks( void )
- {
- uint8 taskID = 0;
- tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);
- osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));
- 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
- GenericApp_Init( taskID );
- }
其实里面就两样东西是重要的,一个是tasksArr这个数组,一个是osalInitTasks这个函数
tasksArr其实就是osal的一个任务列表,里面包含了osal系统中所有的任务,里面有我们任务处理事件的循环,当有消息是给我们的任务的时候osal就会调用我们的任务处理循环GenericApp_ProcessEvent,当然啦,osal没有win系统那么牛叉,更没有linux系统那么让人感到可爱,他是一个让人感到不恶心,可是不讨人喜欢的小小的实时操作系统。osalInitTasks这个其实就是任务初始化函数,在上面的osal_start_system之前会被调用,而且这个函数会调用很多任务的初始化函数,同样包括我们自己的任务的初始化函数GenericApp_Init,至于GenericApp_ProcessEvent和GenericApp_Init等下再说,我们先来看看到底是啥时候调用了osalInitTasks,以及tasksArr是如何被osal使用的。
我们回到main函数中,可以看到这样子的一个函数被调用了osal_init_system,我们再看看看osal_init_system做了什么
- 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 );
- }
很明显,在这里他不但初始化了osal的内存管理,电源管理,并且调用了我们的osalInitTasks函数来初始化osal的所有task,所以在系统进入大循环之前,这些任务是被初始化了的,而osal是如何知道我们的这些任务的呢,就是通过tasksArr这个数组。我们来看看osal_run_system可以看到这样子一段events = (tasksArr[idx])( idx, events );由此可以看出,我们的任务是这样子被添加进来的,并且任务初始化的时候每个task都带了一个taskID,osal就是根据这个taskID来区分每个task,event是哪个task发起的,应该发给哪个task。
- 初次接触zstack
- zigbee学习笔记4----初次接触zstack
- zigbee学习笔记4----初次接触zstack
- 接触ZStack
- 初次接触
- 初次接触
- 初次接触
- 08 ZStack初步接触
- 初次接触EJB
- 初次接触MFC
- 《英雄无敌 V》初次接触!
- 初次接触linux 总结:
- 初次接触power architecture
- 初次接触Hibernate
- 初次接触Hibernate
- 初次接触GDIplus
- 初次接触ASP.NET
- 初次接触asp.net
- python常用技巧
- pcap文件解析
- 应用RecyclerView实现Gallery相册效果——注意引入recyclerview-v7的版本
- Android之Activity(一):活动简介
- Linux--内核Uevent事件机制 与 Input子系统
- 初次接触zstack
- LINUX设备驱动之platform总线
- 浅谈iOS开发中方法延迟执行的几种方式
- iOS下的DES加密
- [学习笔记]初识javascript
- 同步/异步 阻塞/非阻塞
- 【CodeForces】624A - Save Luke(数学小问题)
- css层叠样式的次序y
- Android_eclispe的单词提示