当前位置:首页 > 芯闻号 > 充电吧
[导读]  Zigbee的HAL层提供了开发板所有硬件设备(例如LED、LCD、KEY、UART等)的驱动函数和接口。HAL文件夹为硬件平台的抽象层,包含common、include和target三个文件夹。

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

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.h ADC驱动头文件 hal_driver.h 驱动通用头文件 hal_key.h 按键驱动头文件 hal_sleep.h 休眠/省电模式头文件 hal_lcd.h LCD驱动头文件 hal_assert.h 调试头文件 hal_led.h LED驱动头文件 hal_board.h 板级配置头文件 hal_timer.h 定时器驱动头文件 hal_flash.h Flash接口文件 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.c ADC驱动 hal_uart.c 串口驱动 hal_key.c 按键驱动 hal_dma.c DMA驱动 hal_lcd.c LCD驱动 hal_startup.c 启动代码初始化 hal_led.c LED驱动 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_1、HAL_LED_2、HAL_LED_3和HAL_LED_4;

参数mode,指LED的状态,取值可以是:HAL_LED_MODE_ON、HAL_LED_MODE_OFF和HAL_LED_MODE_TOGGLE。

3.2.2 HalLedBlink()函数

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

             参数numBlinks:闪烁次数。

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

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


本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭