ZigBee_CC2530_08H_HAL层分析

来源:互联网 发布:js 点击保存图片 编辑:程序博客网 时间:2024/05/16 14:31

  Zigbee的HAL层提供了开发板所有硬件设备(例如LED、LCD、KEY、UART等)的驱动函数和接口。HAL文件夹为硬件平台的抽象层,包含commonincludetarget三个文件夹。

1 Common文件夹

  common文件夹下包含有hal_assert.c和hal_drivers.c两个文件。其中hal_assert.c是声明文件,用于调试,hal_drivers.c是驱动文件

1.1 hal_assert.c

  在hal_assert.c文件中包含两个重要的函数:halAssertHandler()和halAssertHazardLights()。

1.1.1 halAssertHandle()函数

  halAssertHandler()函数为硬件系统检测函数。如果定义了ASSERT_RESET宏,系统将调用HAL_SYSTEM_RESET复位,否则将调用halAssertHazardLights()执行闪烁LED命令。

void halAssertHandler(void){  /* execute code that handles asserts */  //如果定义了ASSERT_RESET宏定义#ifdef ASSERT_RESET  //系统复位  HAL_SYSTEM_RESET();#elif !defined ASSERT_WHILE//当检测到错误,LED灯闪烁命令函数  halAssertHazardLights();#else  while(1);#endif}

1.1.2 halAssertHazardLights()函数

  halAssertHazardLights()函数控制LED灯闪烁,根据不同的硬件平台定义的LED的个数来决定闪烁的LED的不同。其控制LED灯闪烁代码如下:

//如果硬件平台定义的LED灯的个数是1#if (HAL_NUM_LEDS >= 1)      //LED1闪烁      HAL_TOGGLE_LED1();#if (HAL_NUM_LEDS >= 2)      HAL_TOGGLE_LED2();#if (HAL_NUM_LEDS >= 3)      HAL_TOGGLE_LED3();#if (HAL_NUM_LEDS >= 4)      HAL_TOGGLE_LED4();#endif#endif#endif#endif
其完整定义可自行查看。

1.2 hal_drivers.c

  hal_drivers.c文件中包含了与硬件相关的初始化和事件处理函数。此文件中有4个比较重要的函数:硬件初始化函数Hal_Init()、硬件驱动初始化函数HalDriverInit()、硬件事件处理函数Hal_ProcessEvent()和询检函数Hal_ProcessPoll()。

1.2.1Hal_Init()函数

  Hal_Init()函数是硬件初始化函数,其功能是通过“注册任务ID号”以实现在OSAL层注册,从而允许硬件驱动的消息和事件由OSAL处理。其函数内容为:

void Hal_Init( uint8 task_id ){  /* Register task ID */  Hal_TaskID = task_id;  #ifdef CC2591_COMPRESSION_WORKAROUND    osal_start_reload_timer( Hal_TaskID, PERIOD_RSSI_RESET_EVT, PERIOD_RSSI_RESET_TIMEOUT );#endif  }

1.2.2 HalDriverInit()函数

  HalDriverInit()函数被main()函数调用,用于初始化与硬件设备有关的驱动。HalDriverInit()函数的具体功能如下:

void HalDriverInit (void){  /* TIMER */  //如果定义了定时器则初始化定时器#if (defined HAL_TIMER) && (HAL_TIMER == TRUE)  //在Zstack-CC2530-2.5.1a版本中移除了定时器的初始化,但不影响Zstack的运行。  #error "The hal timer driver module is removed."#endif  /* ADC */  //如果定义了ADC,初始化ADC#if (defined HAL_ADC) && (HAL_ADC == TRUE)  HalAdcInit();#endif  /* DMA */  //如果定义了DMA,初始化DMA#if (defined HAL_DMA) && (HAL_DMA == TRUE)  // Must be called before the init call to any module that uses DMA.  HalDmaInit();#endif  /* AES */  //如果定义了AES,初始化AES#if (defined HAL_AES) && (HAL_AES == TRUE)  HalAesInit();#endif  /* LCD */  //如果定义了LCD,初始化LCD#if (defined HAL_LCD) && (HAL_LCD == TRUE)  HalLcdInit();#endif  /* LED */  //如果定义了LED,初始化LED#if (defined HAL_LED) && (HAL_LED == TRUE)  HalLedInit();#endif  /* UART */  //如果定义了UART,初始化UART#if (defined HAL_UART) && (HAL_UART == TRUE)  HalUARTInit();#endif  /* KEY */  //如果定义了按键,初始化KEY#if (defined HAL_KEY) && (HAL_KEY == TRUE)  HalKeyInit();#endif  /* SPI */  //如果定义了SPI,初始化SPI#if (defined HAL_SPI) && (HAL_SPI == TRUE)  HalSpiInit();#endif  /* HID */  //如果定义了USB,初始化USB,只限CC2531#if (defined HAL_HID) && (HAL_HID == TRUE)  usbHidInit();#endif}

1.2.3 Hal_ProcessEvent()函数

  Hal_ProcessEvent()函数在APP层中的任务事件处理中被调用,用于对相应的硬件事件作出处理,具体包括系统消息事件、LED闪烁事件、按键处理事件和睡眠模式等。

uint16 Hal_ProcessEvent( uint8 task_id, uint16 events ){  uint8 *msgPtr;    (void)task_id;  // Intentionally unreferenced parameter  //系统消息事件  if ( events & SYS_EVENT_MSG )  {    msgPtr = osal_msg_receive(Hal_TaskID);    while (msgPtr)    {      /* Do something here - for now, just deallocate the msg and move on */      /* De-allocate */      osal_msg_deallocate( msgPtr );      /* Next */      msgPtr = osal_msg_receive( Hal_TaskID );    }    return events ^ SYS_EVENT_MSG;  }  //LED闪烁事件  if ( events & HAL_LED_BLINK_EVENT )  {#if (defined (BLINK_LEDS)) && (HAL_LED == TRUE)    HalLedUpdate();#endif /* BLINK_LEDS && HAL_LED */    return events ^ HAL_LED_BLINK_EVENT;  }  //按键处理事件  if (events & HAL_KEY_EVENT)  {#if (defined HAL_KEY) && (HAL_KEY == TRUE)    /* Check for keys */    HalKeyPoll();    /* if interrupt disabled, do next polling */    if (!Hal_KeyIntEnable)    {      osal_start_timerEx( Hal_TaskID, HAL_KEY_EVENT, 100);    }#endif // HAL_KEY    return events ^ HAL_KEY_EVENT;  }//睡眠模式#ifdef POWER_SAVING  if ( events & HAL_SLEEP_TIMER_EVENT )  {    halRestoreSleepLevel();    return events ^ HAL_SLEEP_TIMER_EVENT;  }#endif#ifdef CC2591_COMPRESSION_WORKAROUND  if ( events & PERIOD_RSSI_RESET_EVT )  {    macRxResetRssi();    return (events ^ PERIOD_RSSI_RESET_EVT);  }#endif      /* Nothing interested, discard the message */  return 0;}

1.2.4 Hal_ProcessPoll()函数

  Hal_ProcessPoll()函数在main()函数中被osal_start_system()调用,用来对可能产生的硬件事件进行询检。函数原型为:

void Hal_ProcessPoll (){  /* Timer Poll */  //定时器询检#if (defined HAL_TIMER) && (HAL_TIMER == TRUE)  #error "The hal timer driver module is removed."#endif  /* UART Poll */  //UART询检,即串口询检#if (defined HAL_UART) && (HAL_UART == TRUE)  HalUARTPoll();#endif    /* SPI Poll */#if (defined HAL_SPI) && (HAL_SPI == TRUE)  HalSpiPoll();#endif  /* HID poll */  //USB询检(仅限CC2530)#if (defined HAL_HID) && (HAL_HID == TRUE)  usbHidProcessEvents();#endif    //如果定义了休眠模式#if defined( POWER_SAVING )  /* Allow sleep before the next OSAL event loop */  //允许在下一个事件到来之前进入休眠模式  ALLOW_SLEEP_MODE();#endif}

  硬件驱动初始化函数HalDriverInit()和硬件事件处理函数Hal_ProcessEvent()是Zigbee协议栈固有的,一般不需要作出较大范围的修改,只需直接使用即可。

2. Include文件夹

Include目录头文件类型头文件说明头文件说明hal_adc.hADC驱动头文件hal_driver.h驱动通用头文件hal_key.h按键驱动头文件hal_sleep.h休眠/省电模式头文件hal_lcd.hLCD驱动头文件hal_assert.h调试头文件hal_led.hLED驱动头文件hal_board.h板级配置头文件hal_timer.h定时器驱动头文件hal_flash.hFlash接口文件hal_uart.h串口驱动头文件hal_ccm.h安全接口头文件hal_defs.h宏定义  

3. Target文件夹

  Target目录下包含了某个设备类型下的硬件驱动文件、硬件开发板上的配置文件、MCU信息和数据类型。

  CC2530EB中的字符EB是TI公司的Zstack在某个硬件上实现的版本号。例如:BB是电池版(Battery Board);DB是开发版(Development Board),EB是评估版(Evaluate Board)

  在CC2530EB文件夹下包含了三个子文件夹,分别是Config、Derive、Includes

3.1 Config文件夹

  Config文件夹中包含了hal_board_cfg.h,在hal_board_cfg.h中定义了硬件CC2530硬件资源的配置,比如GPIO、DMA、ADC等。

  在hal_board_cfg.h文件中可以定义开发版的硬件资源。以LED为例,TI官方的CC2530EB版本定义了两个LED:LED1和LED2,其在hal_board_cfg.h中定义如下:

/* 1 - Green *///有关LED1的宏定义#define LED1_BV           BV(0)#define LED1_SBIT         P1_0#define LED1_DDR          P1DIR#define LED1_POLARITY     ACTIVE_HIGH//如果定义了HAL_BOARD_CC2530EB_REC17,则定了LED2和LED3#if defined (HAL_BOARD_CC2530EB_REV17)  /* 2 - Red */  //有关LED2的宏定义  #define LED2_BV           BV(1)  #define LED2_SBIT         P1_1  #define LED2_DDR          P1DIR  #define LED2_POLARITY     ACTIVE_HIGH  /* 3 - Yellow */  //有关LED3的宏定义  #define LED3_BV           BV(4)  #define LED3_SBIT         P1_4  #define LED3_DDR          P1DIR  #define LED3_POLARITY     ACTIVE_HIGH#endif

  LED宏定义完成之后,设置LED的打开和关闭,其代码在hal_board_cfg.h文件中,代码如下:

#if defined (HAL_BOARD_CC2530EB_REV17) && !defined (HAL_PA_LNA) && !defined (HAL_PA_LNA_CC2590)  #define HAL_TURN_OFF_LED1()       st( LED1_SBIT = LED1_POLARITY (0); )  #define HAL_TURN_OFF_LED2()       st( LED2_SBIT = LED2_POLARITY (0); )  #define HAL_TURN_OFF_LED3()       st( LED3_SBIT = LED3_POLARITY (0); )  #define HAL_TURN_OFF_LED4()       HAL_TURN_OFF_LED1()  #define HAL_TURN_ON_LED1()        st( LED1_SBIT = LED1_POLARITY (1); )  #define HAL_TURN_ON_LED2()        st( LED2_SBIT = LED2_POLARITY (1); )  #define HAL_TURN_ON_LED3()        st( LED3_SBIT = LED3_POLARITY (1); )  #define HAL_TURN_ON_LED4()        HAL_TURN_ON_LED1()  #define HAL_TOGGLE_LED1()         st( if (LED1_SBIT) { LED1_SBIT = 0; } else { LED1_SBIT = 1;} )  #define HAL_TOGGLE_LED2()         st( if (LED2_SBIT) { LED2_SBIT = 0; } else { LED2_SBIT = 1;} )  #define HAL_TOGGLE_LED3()         st( if (LED3_SBIT) { LED3_SBIT = 0; } else { LED3_SBIT = 1;} )  #define HAL_TOGGLE_LED4()         HAL_TOGGLE_LED1()  #define HAL_STATE_LED1()          (LED1_POLARITY (LED1_SBIT))  #define HAL_STATE_LED2()          (LED2_POLARITY (LED2_SBIT))  #define HAL_STATE_LED3()          (LED3_POLARITY (LED3_SBIT))  #define HAL_STATE_LED4()          HAL_STATE_LED1()

3.2 Derivers文件夹

硬件资源驱动文件文件说明文件说明hal_adc.cADC驱动hal_uart.c串口驱动hal_key.c按键驱动hal_dma.cDMA驱动hal_lcd.cLCD驱动hal_startup.c启动代码初始化hal_led.cLED驱动hal_sleep.c睡眠/电源管理hal_timer.c定时器驱动hal_flash.c闪存驱动

  以最常用的LED为例,在hal_led.c文件中提供了两个封装好的函数,在应用层可以直接调用,以控制LED。这两个函数是:

uint8 HalLedSet (uint8 leds, uint8 mode);void HalLedBlink (uint8 leds, uint8 numBlinks, uint8 percent, uint16 period);

3.2.1 HalLedSet()函数

  HalLedSet()函数控制LED的亮灭:

参数leds,指LED的名称,取值可以是HAL_LED_1HAL_LED_2、HAL_LED_3HAL_LED_4

参数mode,指LED的状态,取值可以是:HAL_LED_MODE_ONHAL_LED_MODE_OFFHAL_LED_MODE_TOGGLE

3.2.2 HalLedBlink()函数

  HalLedBlink()函数控制LED灯闪烁:

             参数numBlinks:闪烁次数。

             参数percent:LED亮和灭的所用时间占空比。

             参数period:LED闪烁一个周期所需要的时间,以毫秒为单位。


原创粉丝点击