Silicon Labs HAL(Hardware Abstraction Layer,硬件抽象层)是系统硬件与软件之间的程序代码,为运行在多个不同硬件平台上的应用提供一致的接口。HAL 是为使用 EmberZNet PRO(EFR32MG 系列)和 EM3x MCU 系列的开发人员而设计的。应用应通过 HAL 提供的 API 访问硬件,而不是直接操作寄存器——这样在迁移到新硬件时,只需更新 HAL 层,应用层代码保持不变,大幅降低了移植成本。Documentation Index
Fetch the complete documentation index at: https://mintlify.com/dsyx/docs.silabs.com_zh/llms.txt
Use this file to discover all available pages before exploring further.
HAL API 组织结构
HAL API 按功能划分为以下几个主要模块:通用微处理器函数
控制 MCU 行为和配置的 API,包括
halInit()、halSleep()、halReboot() 和 halResetWatchdog()。大多数应用只需调用这几个核心函数。Token 访问与非易失性存储
用于访问模拟 EEPROM(SimEEPROM)和 NVM3 的 API。Token 由键(key)和关联数据组成,通过键值系统对应用屏蔽底层存储位置。
外设访问
控制和访问片上外设的 API,涵盖 ADC、BUTTON、LED、BUZZER、SPI、UART 等。默认 HAL 为所有必需外设及常用外设提供实现。
系统定时器控制
用于控制秒级或毫秒级低分辨率定时事件的 API。高分辨率(微秒级)时序通过中断在内部管理。
符号定时器控制
供 Zigbee MAC 层使用的射频符号定时器 API,不应从应用中直接调用。
Bootloader 接口
与 Gecko Bootloader 和 Ember Legacy Bootloader 交互的 API,支持运行时固件加载和更新。
命名约定
HAL 函数通过前缀约定明确了调用者身份和修改权限:| 前缀 | 说明 | 可修改? |
|---|---|---|
hal | 示例应用使用的 API | ✅ 可按需删除或修改 |
halCommon | 协议栈使用且应用可调用的 API | ⚠️ 修改时必须保持功能 |
halStack | 仅供协议栈使用的 API | ⚠️ 不应从应用直接调用 |
halInternal | HAL 内部 API,仅在 halStack 或 halCommon 函数中调用 | ⚠️ 修改时需保持相关上层函数功能 |
大多数应用只调用
halXXX 和 halCommonXXX 函数,无需修改 HAL。若需要特殊 HAL 实现,建议先阅读完整文档并参考 Silicon Labs 平台的数据手册,必要时联系客户支持。API 文件与目录结构
HAL 目录结构(位于developer/sdks/gecko_sdk_suite/<version>/platform/base/hal)组织如下:
HAL API 功能详解
Token 访问与非易失性数据存储
网络协议栈使用持久性存储来维护制造和网络配置信息,这些数据存储在 Token 中。Token 由两部分组成:用于映射到物理位置的键以及与该键关联的数据。支持的非易失性存储实现
支持的非易失性存储实现
Silicon Labs 为 EM3x 和 EFR32 平台提供多种非易失性存储实现:
- SimEEv1:ARM Cortex MCU 使用 4 kB 或 8 kB(默认)上层 Flash 存储模拟 EEPROM,每个虚拟页由 2 个物理 Flash 页组成。
- SimEEv2:需要 36 kB 上层 Flash,使用 3 个虚拟页(每个由 6 个物理页组成),通过分散复制减少最坏情况下的写入时间。
- NVM3:第三代非易失性存储驱动程序,仅适用于 EFR32 平台,支持 Connect、Bluetooth 和动态多协议应用共享单一存储实例。
外设访问
网络协议栈需要访问某些片上外设。默认 HAL 为所有必需外设及常用外设提供了完整实现。Silicon Labs 建议在 HAL 框架内实现自定义外设控制,以便将来轻松移植和升级。 主要 HAL 源模块:| 模块 | 说明 |
|---|---|
Adc | 访问 SoC 内置模数转换器 |
Button | 访问开发板上的按钮 |
Led | 操控 LED 指示灯 |
Flash | Flash 的读取、擦除和写入 |
Spi | 访问 SPI 外设 |
Uart | 串行输入/输出低级 API |
sim-eeprom | 在 SoC 中存储 Token 的模拟 EEPROM 系统 |
symbol-timer | 协议栈所需的高精度符号定时器 |
system-timer | 协议栈使用的毫秒时间基准 |
diagnostic | 看门狗复位和异常行为诊断 |
Random | 伪随机数生成器(协议栈初始化时以真随机数为种子) |
系统定时器
halCommonGetInt16uMillisecondTick() 可获取当前毫秒计数,结合先前存储的值可实现毫秒级延迟,避免占用稀缺的 Flash 空间重复实现定时逻辑。
HAL 实用程序
HAL 实用程序默认提供以下功能:- 崩溃和看门狗诊断:辅助识别未知的看门狗复位原因
- 随机数生成:基于硬件种子的伪随机数生成器
- CRC 计算:可利用硬件加速的标准 16 位 CRC 及 CCITT CRC(用于 802.15.4)
自定义 HAL
编译时配置
必需的预处理器定义
以下定义必须在项目文件中设置:
PLATFORM_HEADER:平台头文件路径,如hal/micro/cortexm3/compiler/iar.hBOARD_HEADER:板头文件路径(EFR32 使用硬件配置器替代)PLATFORMNAME:如CORTEXM3PLATFORMNAME_MICRONAME:如CORTEXM3_EM3588PHY_PHYNAME:如PHY_EFR32BOARD_BOARDNAME:如BOARD_BRD4151ACONFIGURATION_HEADER:自定义配置选项头文件
自定义 PCB
EFR32 平台:使用 Simplicity Studio 中的硬件配置器(Hardware Configurator)为目标硬件创建自定义 GPIO 配置,通过图形界面配置外设和外设属性。 EM35x 平台:基于现有板头文件副本生成新的板头文件,编辑其中的外设引脚分配定义以匹配自定义硬件,更新BOARD_HEADER 预处理器定义指向新文件。
板头文件中定义的初始化宏:
调试通道
HAL 实现了与 Simplicity Studio 通信的调试通道,为协议栈和应用提供双向带外机制,用于发送调试统计信息。调试库
| 库 | 功能 |
|---|---|
| 基础调试库(Debug Basic Library) | 节点重置消息、断言输出、核心转储、Virtual UART 输入/输出、基本节点信息 |
| 扩展调试库(Debug Extended Library) | API 调用跟踪、调试错误输出、调试打印输出(EFR32 上 VUART 必需) |
Virtual UART(VUART)
VUART(也称”双向调试”)允许在 SerialWire 调试通道上复用串行输入/输出。启用后,VUART 在软件中被指定为串行端口 0。 与普通串行 UART 的行为差异:emberSerialWaitSend()不等待数据完成发送emberSerialGuaranteedPrintf()不保障输出EMBER_SERIALn_BLOCKING可能不会实际阻塞
VUART 与 EFR32 板级支持包(BSP)中通过
com_device.h 提供的 **Virtual COM 端口(VCOM)**不同。VCOM 通过 WSTK 板载 TTL-to-USB 转换器路由 USART0 物理串口,两者相互独立,可单独或同时启用。