嵌入式驱动开发核心指南

Evek Golden Lv4

写好驱动程序(Driver)是嵌入式软件工程师的基本功。驱动不仅仅是让硬件动起来,更需要考虑性能、可移植性和可维护性。本文总结了一些驱动开发的关键点。

1. 寄存器操作技巧

驱动开发最底层的操作就是读写寄存器。在 C 语言中,我们通常使用位操作(Bit Manipulation)。

1.1 位掩码 (Bit Masking)

不要直接赋值,尽量使用位运算来修改特定位,而不影响其他位。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 定义寄存器和位定义
#define CR1_PE_Bit (1 << 0) // Peripheral Enable
#define CR1_TXE_Bit (1 << 7) // Transmit Enable

// 错误做法:直接赋值(会清除其他位的配置)
// UART->CR1 = CR1_TXE_Bit;

// 正确做法:置位 (Set bit)
UART->CR1 |= CR1_TXE_Bit;

// 正确做法:清除 (Clear bit)
UART->CR1 &= ~CR1_PE_Bit;

// 正确做法:翻转 (Toggle bit)
UART->CR1 ^= CR1_TXE_Bit;

2. 三种数据传输模式

2.1 轮询 (Polling)

CPU 死循环检查状态寄存器。

  • 优点:逻辑简单,无上下文切换开销。
  • 缺点:浪费 CPU 资源,系统响应慢。
  • 适用:系统初始化阶段,或者对实时性要求不高且不允许中断的场景。

2.2 中断 (Interrupt)

硬件完成事件后通过中断线触发 CPU 暂停当前任务,执行 ISR (Interrupt Service Routine)。

  • 优点:CPU 利用率高,实时性好。
  • 缺点:频繁中断会带来上下文切换开销(Context Switch Overhead)。
  • 注意ISR 必须快进快出。不要在 ISR 里面延时、打印日志或进行复杂运算。

2.3 DMA (Direct Memory Access)

DMA 控制器负责总线上的数据搬运,不需要 CPU 参与。

  • 优点:解放 CPU,适合大数据量传输(如 ADC 采样、各种总线数据块传输)。
  • 适用:高速通信、大量数据采集。

3. 驱动架构设计:分层思想

为了让应用层代码与硬件解耦,驱动设计必须分层。

  1. **寄存器层 (LL / Register Definition)**:直接对应手册的寄存器地址,通常由厂商提供的头文件覆盖。
  2. **硬件抽象层 (HAL / Low Level Driver)**:针对具体外设的操作(如 Uart_SendByte)。这一层依赖具体的 MCU 型号。
  3. **板级支持包 (BSP)**:针对开发板的具体连接,管理 GPIO 引脚分配等。
  4. 设备驱动层 (Device Driver):针对外接模块(如传感器 MPU6050、屏幕 OLED)。这一层应调用 HAL 层接口,做到与 MCU 无关

最佳实践:如果你的 MPU6050 驱动代码里面直接写了 STM32_SPI_Write(...),那就是设计耦合了。应该传入一个函数指针,或者调用一个通用的 SPI_Write(...) 接口。

4. 可重入性 (Reentrancy) 与线程安全

在 RTOS 环境下,驱动函数可能会被多个任务同时调用。

  • 问题:如果两个任务同时调用 UART_Send,数据可能会穿插在一起,导致乱码。
  • 解决:使用互斥锁(Mutex)或信号量(Semaphore)保护临界区。
1
2
3
4
5
void UART_Send(uint8_t *data, uint16_t len) {
xSemaphoreTake(uartMutex, portMAX_DELAY); // 上锁
HAL_UART_Transmit(..., data, len, ...); // 发送
xSemaphoreGive(uartMutex); // 解锁
}

总结

优秀的驱动代码应该像一篇优美的文章:结构清晰(分层)、逻辑严密(处理各种硬件异常)、且易于阅读(规范的命名和注释)。

  • Title: 嵌入式驱动开发核心指南
  • Author: Evek Golden
  • Created at : 2023-07-05 00:05:00
  • Updated at : 2026-06-12 08:57:02
  • Link: https://blog.cocodemo.uno/posts/drv3k9s/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments