ZigBee_CC2530_08H_HAL层分析
来源:互联网 发布:js 点击保存图片 编辑:程序博客网 时间:2024/05/16 14:31
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文件夹
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文件夹
以最常用的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闪烁一个周期所需要的时间,以毫秒为单位。
- ZigBee_CC2530_08H_HAL层分析
- web层框架分析
- DAL数据处理层分析
- RIL 层分析
- nginx网络层分析
- Rabbitmq网络层分析
- Rild层代码分析
- 分析:Android_Wifi_HAL层
- LIBSAS层分析
- 分析:Android_Wifi_HAL层
- framework层服务分析
- RIL层源码分析
- input 层简单分析
- IP 层分析
- RIL层源码分析
- Ril层源代码分析
- 分析http应用层
- RIL层源码分析
- 单独管理image
- LintCode#80FindMedian(利用快排找中位数)
- 正册表达式匹配文件名
- 计算机跟学习板通信
- 危险系数
- ZigBee_CC2530_08H_HAL层分析
- ES6(八) 对象的扩展
- 使用spring task或spring quartz执行任务执行两次
- Socket编程(ServerScoket, Socket) 回声例子
- Android
- Java I/O关于缓冲区部分提高性能的源码分析【Stream】
- mac 安装python虚拟环境,多版本共存
- (转载)Linux内核源代码情景分析---第四章 进程与进程调度
- 三角形法恢复空间点深度