1、/ Initialize board I/O/*初始化板载IO*/InitBoard( OB_COLD );/ Initialze HAL drivers/*初始化硬件驱动*/HalDriverInit();/ Initialize NV System/*初始化NV系统*/osal_nv_init( NULL );/ Determine the extended address/*拟定扩展地址(64位IEEE/物理地址)*/zmain_ext_addr();/ Initialize basic NV items/*初始化基本NV条目*/zgInit();/ Initialize the MAC
2、/*初始化MAC*/ZMacInit();#ifndef NONWK/ Since the AF isnt a task,call its initialization routineafInit();#endif#ifdef LCD_SUPPORTEDHalLcdInit();/ Initialize the operating system/*初始化操作系统*/osal_init_system();/ Allow interrupts/*启动中断*/osal_int_enable( INTS_ALL );/ Final board initialization/*最后板载初始化*/Init
3、Board( OB_READY );/HalLcdInit();/ Display information about this device/*显示设备信息*/zmain_dev_info();/* Display the device info on the LCD */zmain_lcd_init();osal_start_system();/ No Return from here 没有返回,即进入操作系统!阐明:初始化各软硬件后进入系统主循环函数。 这里重点是两个函数:系统初始化函数 osal_init_system();系统主循环函数 osal_start_system(); 下面
4、记录下个人个人对系统初始化流程和系统主循环流程学习。这里先记录下系统初始化流程。2、系统初始化流程2.1osal_init_system()系统初始化函数byte osal_init_system( void )/ Initialize the Memory Allocation System/*初始化内存分派系统*/osal_mem_init();/ Initialize the message queue/*初始化系统消息队列*/osal_qHead = NULL;#if defined( OSAL_TOTAL_MEM )osal_msg_cnt = 0;/ Initialize the
5、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 ( ZSUCCESS );这里重点是初始化系统任务函数:下面进入系统任务初始化:2.2 osalIn
6、itTasks();任务初始化函数void osalInitTasks( void )uint8 taskID = 0; /osal_mem_alloc()为当前OSAL中各任务分派存储空间(事实上是一种任务数组),函数返回指向任务缓冲 /区指针,因而tasksEvents指向该任务数组(任务队列).注意tasksEvents和背面谈到tasksArr里顺/序是一一相应,tasksArr 中第i个事件解决函数相应于tasksEvents中第i个任务事件.tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt); /
7、osal_memset()把开辟内存所有设立为0;sizeof( uint16 )是4个字节,即一种任务 /长度(同样是uint16定义),乘以任务数量tasksCnt,即所有内存空间osal_memset( tasksEvents,0,(sizeof( uint16 ) * tasksCnt);/OSAL.c中定义macTaskInit( taskID+ ); /初始化各层任务 mac_taskID=0;nwk_init( taskID+ ); /nwk_taskID=1;Hal_Init( taskID+ ); /Hal_taskID=2;#if defined( MT_TASK )MT_
8、TaskInit( taskID+ ); /MT_taskID=3;(if defined)APS_Init( taskID+ ); /APS_taskID=4;ZDApp_Init( taskID+ ); /ZDAPP_taskID=5;SampleApp_Init( taskID );/SampleApp_taskID=6;顾客创立任务任务初始化,就是为系统各个任务分派存储空间,固然,这个空间初始化时为全0(NULL),然后为各任务分派taskID;这里顺序要注意.系统主循环函数里tasksEvents idx和tasksArr idxidx与这里taskID是一一相应关系。背面再分析。指
9、针数组tasksEvents 里面最后分别指向是各任务存储空间指针数组tasksArr 里面最后分别指向是各任务事件解决函数这两个指针数组里面各元素顺序要一一相应,由于背面需要相应任务调用相应事件解决函数.对这两个数组定义请参见背面.问题:对于osal_mem_alloc()这个函数返回是一种指向任务数组指针,看前人分析,我还没有去看这个函数。那么这里重点是各任务初始化,MAC层和NWK层未开源看不到,先记录下顾客自己添加任务初始化函数SampleApp_Init( taskID );2.3 SampleApp_Init( taskID );顾客应用任务初始化函数void SampleApp_
10、Init( uint8 task_id )SampleApp_TaskID = task_id;/osal分派任务ID,这里为6,随着顾客添加任务增多而变化SampleApp_NwkState = DEV_INIT;/设备状态设定为ZDO层中定义初始化状态(无连接)/*初始化应用设备网络类型,设备类型变化都要产生一种事件ZDO_STATE_CHANGE,从字面理解为/ZDO状态发生了变化。因此在设备初始化时候一定要把它初始化为什么状态都没有。那么它就要去检测/整个环境,看与否能重新建立或者加入存在网络。但是有一种状况例外,就是当NV_RESTORE被设立/时候(NV_RESTORE是把信息保存
11、在非易失存储器中),那么当设备断电或者某种意外重启时,由于网络/状态存储在非易失存储器中,那么此时就只需要恢复其网络状态,而不需要重新建立或者加入网络了*/SampleApp_TransID = 0;/消息发送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 i
12、t in main().#if defined ( SOFT_START ) /如果选取了SOFT编译选项,则作为协调器启动/ The Demo target is setup to have SOFT_START and HOLD_AUTO_START/ SOFT_START is a compile option that allows the device to start/ as a coordinator if one isnt found./ We are looking at a jumper (defined in SampleAppHw.c) to be jumpered/
13、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 / SOFT_START#if defined ( HOLD_AUTO_START ) /如果定义了HOLD_AUT
14、O_START选项,则调用层ZDOInitDevice,按照默认顺 /序网络中第一种设备作为协调器,其她设备作为子设备 / 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(0);/* 设立发送数据方式和目地址寻址模式*/-/周期消息,广播发送/ Setup for the periodic messages destination addres
15、s 周期消息事件/ Broadcast to everyone/*广播到所有设备*/SampleApp_Periodic_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast ;/发送模式(广播)SampleApp_Periodic_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;/指定端点号EP20SampleApp_Periodic_DstAddr.addr.shortAddr = 0xFFFF;/指定目网络地址为广播地址/*单播到一种设备*/* WXL_SampleApp_Single_DstAddr.addrMode
16、= (afAddrMode_t)Addr16Bit; WXL_SampleApp_Single_DstAddr.endPoint = WXL_SAMPLEAPP_ENDPOINT;*/-/闪烁消息:发送到组 / Setup for the flash commands destination address - Group1 闪烁消息事件/*设立 endpoint description.*/SampleApp_Flash_DstAddr.addrMode = (afAddrMode_t)afAddrGroup;/(组寻址)SampleApp_Flash_DstAddr.endPoint =
17、SAMPLEAPP_ENDPOINT;/EP20SampleApp_Flash_DstAddr.addr.shortAddr = SAMPLEAPP_FLASH_GROUP; /组号0x0003/- / Fill out the endpoint description./*定义本设备用来通信APS层端点描述符*/SampleApp_epDesc.endPoint = SAMPLEAPP_ENDPOINT;/SampleApp EP描述符EP号:20SampleApp_epDesc.task_id = &SampleApp_TaskID;/SampleApp EP描述符任务ID:SampleA
18、pp_epDesc.simpleDesc = (SimpleDescriptionFormat_t *)&SampleApp_SimpleDesc;/SampleApp EP简朴描述符SampleApp_epDesc.latencyReq = noLatencyReqs;/延时方略/ Register the endpoint description with the AF/*向AF层登记EP描述符*/*登记endpoint description 到AF,要对该应用进行初始化并在AF进行登记,告诉应用层有这样一种EP已经开通可以使用,那么下层要是关于于该应用信息或者应用要对下层做哪些操作,就
19、自动得到下层配合。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 = 0x0003;/组号osal_memcpy( SampleApp_Group.name,Group 3,7 );/设定
20、组名aps_AddGroup( SAMPLEAPP_ENDPOINT,&SampleApp_Group );/把该组登记添加到APS中/*如果支持LCD,显示一串字符*/#if defined ( LCD_SUPPORTED )/HalLcdWriteString( SampleApp,HAL_LCD_LINE_1 );Print8(HAL_LCD_LINE_2,20,1);在SampleAPP例子中,应用层提供了节点间两种逻辑关系:一种是周期性消息发送,另一种是Flash消息发送。我个人以为就是两个簇,例如节点1EP20与节点2EP20通信,(可以单播,广播,间接,组传递),这两种逻辑关系属
21、于两节点EP20简朴描述符下簇列表元素. 且可以看到SampleApp_SendPeriodicMessage( void )与SampleApp_SendFlashMessage( )下clusterID项分别为SAMPLEAPP_PERIODIC_CLUSTERID和 SAMPLEAPP_FLASH_CLUSTERID。 顾客应用任务初始化大体是:设立本应用发送数据方式和目地址寻址模式,登记注册本应用所用到端点,以及配备有关发送模式所需参数.(个人觉得就此应用来说,ZC,ZR,ZD用到都是EP20,详细后来再作记录)以上为OSAL初始化大体流程,OSAL以及各软硬部件初始化完毕后,就进入了
22、系统主循环函数osal_start_system();系统主循环流程个人记录见下篇.OSAL系统主循环函数:void osal_start_system( void )#if !defined ( ZBIT ) /不懂得是什么东西for(;) / Forever Loop uint8 idx = 0; Hal_ProcessPoll();/ This replaces MT_SerialPoll() and osal_check_timer(). /轮询TIMER与UART/执行循环语句:tasksEventsidx是一种指针变量,指向存储任务idx存储空间,初始化时由/osal_memset
23、()设为0,只要不为空类型NULL,/即有相相应任务事件发生,就break跳出循环体,通过下面程序进行任务事件解决。/如果为空,执行判断语句,即idx自增,再返回轮询有无各层任务事件发生。如果/执行完循环语句都没有检测到有事件发生,idx=7,进入睡眠。(对于本例子来说,任务数组里只有七个任务,tasksEvents0tasksEvents6,tasksEvents6就是顾客自已添加任务,idx随着顾客添加任务增多而增大) do if (tasksEventsidx)/ Task is highest priority that is ready. break; while (+idx tas
24、ksCnt);/tasksCnt=7(针对本例子,随着顾客应用任务增多而增大)/- if (idx tasksCnt) uint16 events; halIntState_t intState;/中断位状态 HAL_ENTER_CRITICAL_SECTION(intState);/中断临界状态:保存先前中断状态,然后关中断 events = tasksEventsidx;/uint16 events;相应有事件发生任务 tasksEventsidx = 0;/ Clear the Events for this task. NULL HAL_EXIT_CRITICAL_SECTION(in
25、tState);/跳出中断临界状态:恢复先前中断状态 events = (tasksArridx)( idx,events ); /调用相相应任务事件解决函数解决,各类事件解决函 /数M(task_id,event)返回都是这个任务未被解决事件 tasksEventsidx |= events; / Add back unprocessed events to the current task. /把刚才返回未解决任务事件添加加当前任务中再进行解决 /(跳出此if(idx tasksCnt)循环再进行if (tasksEventsidx)判断并解决)#if defined( POWER_SAVING ) else / Complete pass through a
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2