InitBoard()看注释上说是初始化板子上的I/O资源,进入到该函数实现体中,
void InitBoard( byte level ) { if ( level == OB_COLD ) { // Interrupts off osal_int_disable( INTS_ALL ); // Turn all LEDs off HalLedSet( HAL_LED_ALL, HAL_LED_MODE_OFF ); // Check for Brown-Out reset ChkReset(); } else // !OB_COLD { #ifdef ZTOOL_PORT MT_SysResetInd(); #endif /* Initialize Key stuff */ OnboardKeyIntEnable = HAL_KEY_INTERRUPT_DISABLE; HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback); } }
从主函数中传递进来的是OB_COLD,该值为0,进来之后又是关闭中断,(貌似前面也没有打开过),之后进入HalLedSet()函数中,关闭所有LEDs,进入该函数中,
uint8 HalLedSet (uint8 leds, uint8 mode) { #if (defined (BLINK_LEDS)) && (HAL_LED == TRUE) uint8 led; HalLedControl_t *sts; switch (mode) { case HAL_LED_MODE_BLINK: /* Default blink, 1 time, D% duty cycle */ HalLedBlink (leds, 1, HAL_LED_DEFAULT_DUTY_CYCLE, HAL_LED_DEFAULT_FLASH_TIME); break; case HAL_LED_MODE_FLASH: /* Default flash, N times, D% duty cycle */ HalLedBlink (leds, HAL_LED_DEFAULT_FLASH_COUNT, HAL_LED_DEFAULT_DUTY_CYCLE, HAL_LED_DEFAULT_FLASH_TIME); break; case HAL_LED_MODE_ON: case HAL_LED_MODE_OFF: case HAL_LED_MODE_TOGGLE: led = HAL_LED_1; leds &= HAL_LED_ALL; sts = HalLedStatusControl.HalLedControlTable; while (leds) { if (leds & led) { if (mode != HAL_LED_MODE_TOGGLE) { sts->mode = mode; /* ON or OFF */ } else { sts->mode ^= HAL_LED_MODE_ON; /* Toggle */ } HalLedOnOff (led, sts->mode); leds ^= led; } led <<= 1; sts++; } break; default: break; } #elif (HAL_LED == TRUE) LedOnOff(leds, mode); #else // HAL LED is disabled, suppress unused argument warnings (void) leds; (void) mode; #endif /* BLINK_LEDS && HAL_LED */ return ( HalLedState ); }
typedef struct { uint8 mode; /* Operation mode */ uint8 todo; /* Blink cycles left */ uint8 onPct; /* On cycle percentage */ uint16 time; /* On/off cycle time (msec) */ uint32 next; /* Time for next change */ } HalLedControl_t;
/* Modes */ #define HAL_LED_MODE_OFF 0x00 #define HAL_LED_MODE_ON 0x01 #define HAL_LED_MODE_BLINK 0x02 #define HAL_LED_MODE_FLASH 0x04 #define HAL_LED_MODE_TOGGLE 0x08
/* Defaults */ #define HAL_LED_DEFAULT_MAX_LEDS 4 #define HAL_LED_DEFAULT_DUTY_CYCLE 5 #define HAL_LED_DEFAULT_FLASH_COUNT 50 #define HAL_LED_DEFAULT_FLASH_TIME 1000进入HalLedBlink函数查看
void HalLedBlink (uint8 leds, uint8 numBlinks, uint8 percent, uint16 period) { #if (defined (BLINK_LEDS)) && (HAL_LED == TRUE) uint8 led; HalLedControl_t *sts; if (leds && percent && period) { if (percent < 100) { led = HAL_LED_1; leds &= HAL_LED_ALL; sts = HalLedStatusControl.HalLedControlTable; while (leds) { if (leds & led) { /* Store the current state of the led before going to blinking */ preBlinkState |= (led & HalLedState); sts->mode = HAL_LED_MODE_OFF; /* Stop previous blink */ sts->time = period; /* Time for one on/off cycle */ sts->onPct = percent; /* % of cycle LED is on */ sts->todo = numBlinks; /* Number of blink cycles */ if (!numBlinks) sts->mode |= HAL_LED_MODE_FLASH; /* Continuous */ sts->next = osal_GetSystemClock(); /* Start now */ sts->mode |= HAL_LED_MODE_BLINK; /* Enable blinking */ leds ^= led; } led <<= 1; sts++; } osal_set_event (Hal_TaskID, HAL_LED_BLINK_EVENT); } else { HalLedSet (leds, HAL_LED_MODE_ON); /* >= 100%, turn on */ } } else { HalLedSet (leds, HAL_LED_MODE_OFF); /* No on time, turn off */ } #elif (HAL_LED == TRUE) percent = (leds & HalLedState) ? HAL_LED_MODE_OFF : HAL_LED_MODE_ON; HalLedOnOff (leds, percent); /* Toggle */ #else // HAL LED is disabled, suppress unused argument warnings (void) leds; (void) numBlinks; (void) percent; (void) period; #endif /* BLINK_LEDS && HAL_LED */ }一进来是宏定义判断,没啥可说的,然后对参数进行判断,得保证参数正确才行,之后将led赋值为LED1,leds与LED_ALL相与得到需要闪烁的leds值,后面用到了一个HalLedStatusControl变量,查看定义
#ifdef BLINK_LEDS static HalLedStatus_t HalLedStatusControl; #endif typedef struct { HalLedControl_t HalLedControlTable[HAL_LED_DEFAULT_MAX_LEDS]; uint8 sleepActive; } HalLedStatus_t; #define HAL_LED_DEFAULT_MAX_LEDS 4
static uint8 preBlinkState; // Original State before going to blink mode // bit 0, 1, 2, 3 represent led 0, 1, 2, 3
用于存储进入闪烁模式之前的状态,以及HalLedState变量,存储当前LED状态,HalLedState变量的值在别处有修改,跟其他结合着看就明白了,然后就是为sts指向的HalLedControl_t成员变量赋值,if (!numBlinks) sts->mode |= HAL_LED_MODE_FLASH;这句话说是继续的意思,但目前没理解还,先继续往下看,用到一个osal_GetSystemClock()函数:
uint32 osal_GetSystemClock( void ) { return ( osal_systemClock ); }
// Milliseconds since last reboot static uint32 osal_systemClock;
uint8 Hal_TaskID; #define HAL_LED_BLINK_EVENT 0x0002
uint8 osal_set_event( uint8 task_id, uint16 event_flag ) { if ( task_id < tasksCnt ) { halIntState_t intState; HAL_ENTER_CRITICAL_SECTION(intState); // Hold off interrupts tasksEvents[task_id] |= event_flag; // Stuff the event bit(s) HAL_EXIT_CRITICAL_SECTION(intState); // Release interrupts } else return ( INVALID_TASK ); return ( SUCCESS ); }
const uint8 tasksCnt = sizeof( tasksArr ) / sizeof( tasksArr[0] ); 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 };
typedef unsigned short (*pTaskEventHandlerFn)( unsigned char task_id, unsigned short event );
#define HAL_ENTER_CRITICAL_SECTION(x) st( x = EA; HAL_DISABLE_INTERRUPTS(); ) #define HAL_EXIT_CRITICAL_SECTION(x) st( EA = x; )
回到HalLedBlink()函数,当percent大于等于100时,也就是超过100%,LED应当长亮即HalLedSet()函数来实现,当leds、percent、period有不合法的值时LED长灭,通用是用HalLedSet()函数实现,跑到HalLedBlink()函数的调用者去了,先把HalLedBlink()函数看完之后再去继续查看HalLedSet()函数吧,当没有定义BLINK_LEDS时,只是改变LED的状态,这里他用percent存储结果有点误人,不过这样可以充分利用内存资源,不用重新定义一个变量存储结果,加个注释会更好,leds和HalLedState相与得到当前状态,如果为1,那么就利用HalLedOnOff()函数关闭它,如果为0,就打开它,总之就是使得LED状态取反。这一节涉及到的函数实在是太多了,不晓得后面会不会更多?
HalLedOnOff()函数比较简单
void HalLedOnOff (uint8 leds, uint8 mode) { if (leds & HAL_LED_1) { if (mode == HAL_LED_MODE_ON) { HAL_TURN_ON_LED1(); } else { HAL_TURN_OFF_LED1(); } } if (leds & HAL_LED_2) { if (mode == HAL_LED_MODE_ON) { HAL_TURN_ON_LED2(); } else { HAL_TURN_OFF_LED2(); } } if (leds & HAL_LED_3) { if (mode == HAL_LED_MODE_ON) { HAL_TURN_ON_LED3(); } else { HAL_TURN_OFF_LED3(); } } if (leds & HAL_LED_4) { if (mode == HAL_LED_MODE_ON) { HAL_TURN_ON_LED4(); } else { HAL_TURN_OFF_LED4(); } } /* Remember current state */ if (mode) { HalLedState |= leds; } else { HalLedState &= (leds ^ 0xFF); } }
在switch的判断中只剩下ON、OFF、以及TOGGLE三个case了,共用一段代码,比BLINK的简单多了也,有一个不理解的地方,当mode为TOGGLE时sts->mode又和ON异或了一下,除非当前mode是OFF,之后就会执行点亮LED操作,而当模式为On,都是执行的关掉LED操作,其他模式执行的也是关闭操作,但却为HalLedState相应位置1,总感觉有点矛盾?!当系统没有定义LED闪烁的时候直接调用LedOnOff()函数,可惜没有找到实现体,虽然这个函数的确不会执行。至此,HalLedSet()函数查看完毕了,返回上一层InitBoard()函数,进入到ChkRest()函数中,进行低压复位检测,进入该函数查看
void ChkReset( void ) { uint8 led; uint8 rib; // Isolate reset indicator bits rib = SLEEPSTA & LRESET; if ( rib == RESETPO ) { // Put code here to handle Power-On reset } else if ( rib == RESETEX ) { // Put code here to handle External reset } else if ( rib == RESETWD ) { // Put code here to handle WatchDog reset } else { // Unknown, hang and blink HAL_DISABLE_INTERRUPTS(); led = HAL_LED_4; while ( 1 ) { HalLedSet( led, HAL_LED_MODE_ON ); MicroWait( 62500 ); MicroWait( 62500 ); HalLedSet( led, HAL_LED_MODE_OFF ); MicroWait( 37500 ); MicroWait( 37500 ); if ( !(led >>= 1) ) led = HAL_LED_4; } } }
当值不是00,01,10的情况下,就是我们所需要的检测
// Reset bit definitions #define LRESET 0x18 // Last reset bit mask #define RESETPO 0x00 // Power-On reset #define RESETEX 0x08 // External reset #define RESETWD 0x10 // WatchDog reset
在else中即非冷启动下有一个宏定义,通过查找定义找到如下代码
#if defined (ZTOOL_P1) #define ZTOOL_PORT SERIAL_PORT1 #elif defined (ZTOOL_P2) #define ZTOOL_PORT SERIAL_PORT2 #else #undef ZTOOL_PORT #endif
取的是第一个定义,但是ZTOOL_P1却找不到定义,也许在别处还有吧,进入MT_SystemResetInd()函数中查看
void MT_SysResetInd(void) { uint8 retArray[6]; retArray[0] = ResetReason(); /* Reason */ retArray[1] = 0x00; /* Transport Revision */ retArray[2] = 0x00; /* Product */ retArray[3] = 0x00; /* Major Revision */ retArray[4] = 0x00; /* Minor Revision */ retArray[5] = 0x00; /* Hardware Revision */ /* Send out Reset Response message */ MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_SYS), MT_SYS_RESET_IND, sizeof(retArray), retArray); }
/* Reset reason for reset indication */ #define ResetReason() ((SLEEPSTA >> 3) & 0x03) typedef enum { MT_RPC_CMD_POLL = 0x00, MT_RPC_CMD_SREQ = 0x20, MT_RPC_CMD_AREQ = 0x40, MT_RPC_CMD_SRSP = 0x60, MT_RPC_CMD_RES4 = 0x80, MT_RPC_CMD_RES5 = 0xA0, MT_RPC_CMD_RES6 = 0xC0, MT_RPC_CMD_RES7 = 0xE0 } mtRpcCmdType_t; typedef enum { MT_RPC_SYS_RES0, /* Reserved. */ MT_RPC_SYS_SYS, MT_RPC_SYS_MAC, MT_RPC_SYS_NWK, MT_RPC_SYS_AF, MT_RPC_SYS_ZDO, MT_RPC_SYS_SAPI, /* Simple API. */ MT_RPC_SYS_UTIL, MT_RPC_SYS_DBG, MT_RPC_SYS_APP, MT_RPC_SYS_MAX /* Maximum value, must be last */ /* 10-32 available, not yet assigned. */ } mtRpcSysType_t; #define MT_SYS_RESET_IND 0x80