Skip to content

先搞懂它是什么

  • 设备模型:SDK 通过 HOSAL 统一外设层把所有外设抽象成“设备结构体”(hosal_uart_dev_thosal_gpio_dev_t 等),应用直接定义一个结构体变量(如 hosal_uart_dev_t uart0;),再通过 &uart0 把它传给该外设的 API——写法上所有外设都一致。
  • 驱动分层:应用调用的 hosal_xxx_* 是“驱动 API”,驱动内部再操作寄存器(LL 层)控制硬件。
  • 三种数据通路:轮询(程序主动读)、中断(硬件通知)、DMA(硬件直接搬数据)——理解了它们就理解了外设实现的核心。

层层拆解原理

1. 统一设备模型

HOSAL 把每个外设抽象成一个设备结构体 hosal_xxx_dev_t(xxx 为 uart/gpio/i2c/spi/timer…),外设使用前先定义结构体变量并填入配置:

c
hosal_uart_dev_t uart0;   /* 定义 UART 设备结构体 */
hosal_gpio_dev_t gpio;    /* 定义 GPIO 设备结构体 */

hosal_xxx_dev_t 里存着该外设的端口号(port)、引脚/模式/速率等配置(config)字段,填好之后所有 hosal_uart_*/hosal_gpio_* API 都以它的地址(&dev)为第一个参数——这是 WB2 SDK 所有外设例程的统一套路。

2. 驱动分层结构

  • API 层:面向应用,提供 hosal_xxx_inithosal_xxx_send/recv/output_set/input_get 等。
  • HAL/LL 层:直接读写寄存器(如时钟门控 GLB_CGEN_*,见 SDK 的 bl602_glb.h;数据寄存器),不同芯片实现不同,但 API 层保持一致——这也是“换芯片不换代码风格”的原因。

3. 初始化与操作的统一流程

几乎每个外设例程都是这个流程:

例:UART 是定义 hosal_uart_dev_t uart0(config 里配波特率/数据位/校验/停止位)→ hosal_uart_init(&uart0) → 接收中断或轮询 hosal_uart_receive

4. 三种数据通路对比

方式原理优点缺点适用场景
轮询程序循环查状态寄存器简单、易调试占用 CPU低频、简单收发
中断硬件触发回调,CPU 现场处理不阻塞主流程、响应快中断里不能做耗时操作按键、串口接收
DMA硬件把数据直接搬进内存CPU 几乎不参与、速度快配置复杂、要处理内存一致性大数据量(Flash、音频、显示)

结合 SDK 看实现

以 GPIO 为例,把“设备模型 + 初始化 + 操作”串起来:

c
hosal_gpio_dev_t gpio;                                              /* 定义设备结构体 */
hosal_gpio_init(&gpio, GPIO_PIN_12, HOSAL_GPIO_OUTPUT_PUSH_PULL);  /* 初始化模式:推挽输出 */
hosal_gpio_output_set(&gpio, 1);                                    /* 操作:输出高电平 */

所有基础外设页(GPIO/UART/SPI/I2C/ADC/PWM/Timer…)都遵循同一骨架,学会一个就能举一反三。

常见考点 / 面试题

为什么要用 HOSAL 设备结构体而不是直接操作寄存器?

统一设备模型让驱动 API 与具体芯片解耦:换芯片/换实例只需重新定义结构体并修改配置,应用代码风格不变;也方便驱动管理中断、时钟等资源。

中断和 DMA 有什么区别?

中断是“硬件叫 CPU 来处理数据”;DMA 是“硬件自己搬数据,搬完再通知 CPU”。DMA 让 CPU 从搬运中解放,适合大数据量。

为什么外设初始化都要先定义设备结构体?

结构体封装了端口号、引脚、模式、速率等配置,驱动 API 通过它访问具体外设;这也是“同一份代码操作多个同类型外设(如两路串口)”的基础——各定义一个结构体实例即可。

LL 层和 API 层的关系?

API 层面向应用、跨芯片稳定;LL/HAL 层面向寄存器、随芯片变化。改动硬件平台时通常只需换 LL 层实现,应用代码基本不动。

轮询方式什么时候不可接受?

当外设事件稀疏而程序任务繁重时(如同时收串口、扫按键、跑界面),轮询会占用大量 CPU 且响应延迟;此时应改用中断或 DMA。

遇到问题?

如有其他问题,请到统一的提问与讨论区:Ai-Thinker Discussions

Released under the MIT License. Build Time 2026-09-11 14:52:23