RTOS 驱动架构总览
RTOS 与 Linux 驱动的本质差异
| 维度 | Linux 驱动 | RTOS 驱动 |
|---|---|---|
| 内存保护 | MMU 隔离用户/内核空间 | 通常无 MMU,所有代码共享地址空间 |
| 驱动框架 | 统一的 bus/device/driver 模型 | 各 RTOS 自有框架,差异较大 |
| 中断处理 | 硬中断 + 软中断 + workqueue | ISR + 任务通知/信号量 |
| 内存分配 | 丰富的分配器(slab/vmalloc) | 静态分配为主,动态分配需谨慎 |
| 调试手段 | printk/ftrace/KGDB | JTAG/SWD + 串口打印 |
| 实时性 | 可选(PREEMPT_RT) | 天然硬实时 |
RTOS 驱动的通用设计原则
1. HAL 抽象层
良好的 RTOS 驱动应该分层:
应用层
│ 统一 API(read/write/ioctl)
▼
HAL 层(Hardware Abstraction Layer)
│ 平台无关接口
▼
BSP 层(Board Support Package)
│ 具体寄存器操作
▼
硬件寄存器c
/* HAL 接口定义(平台无关) */
typedef struct {
int (*init)(uint32_t baud_rate);
int (*send)(const uint8_t *data, size_t len, uint32_t timeout_ms);
int (*recv)(uint8_t *data, size_t len, uint32_t timeout_ms);
void (*deinit)(void);
} uart_hal_t;
/* BSP 实现(STM32 平台) */
static const uart_hal_t stm32_uart1 = {
.init = stm32_uart1_init,
.send = stm32_uart1_send,
.recv = stm32_uart1_recv,
.deinit = stm32_uart1_deinit,
};2. 中断安全 API
RTOS 提供两套 API:任务上下文和 ISR 上下文:
c
/* FreeRTOS 示例 */
/* 任务上下文 */
xSemaphoreGive(sem);
xQueueSend(queue, &data, portMAX_DELAY);
/* ISR 上下文(函数名带 FromISR) */
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xSemaphoreGiveFromISR(sem, &xHigherPriorityTaskWoken);
xQueueSendFromISR(queue, &data, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken); /* 必要时触发任务切换 */3. 静态内存优先
嵌入式系统内存有限,优先使用静态分配:
c
/* ✅ 静态分配(推荐) */
static StaticQueue_t uart_queue_buf;
static uint8_t uart_queue_storage[QUEUE_SIZE * sizeof(uart_msg_t)];
QueueHandle_t uart_queue = xQueueCreateStatic(
QUEUE_SIZE, sizeof(uart_msg_t),
uart_queue_storage, &uart_queue_buf
);
/* ⚠️ 动态分配(需确保堆足够大) */
QueueHandle_t uart_queue = xQueueCreate(QUEUE_SIZE, sizeof(uart_msg_t));4. 超时处理
所有阻塞操作必须有超时,避免任务永久挂起:
c
/* ✅ 带超时的等待 */
if (xSemaphoreTake(sem, pdMS_TO_TICKS(1000)) != pdTRUE) {
/* 超时处理 */
log_error("UART TX timeout");
return -ETIMEDOUT;
}
/* ❌ 永久等待(仅在确定不会死锁时使用) */
xSemaphoreTake(sem, portMAX_DELAY);主流 RTOS 对比
| 特性 | FreeRTOS | Zephyr | RT-Thread |
|---|---|---|---|
| 许可证 | MIT | Apache 2.0 | Apache 2.0 |
| 内核大小 | ~5KB | ~10KB+ | ~6KB |
| 驱动框架 | 无统一框架 | 设备驱动模型 | 设备驱动框架 |
| 网络栈 | lwIP(可选) | 内置 | SAL(可选) |
| 文件系统 | FatFS(可选) | 内置 | DFS(可选) |
| 包管理 | 无 | west | env |
| 主要用途 | MCU,极简场景 | IoT,工业 | 国内嵌入式 |
| 支持架构 | ARM/RISC-V/x86 | ARM/RISC-V/x86 | ARM/RISC-V |
驱动开发流程对比
FreeRTOS:
1. 直接操作寄存器(CMSIS/HAL 库)
2. 在 ISR 中用 FromISR API 通知任务
3. 任务中处理数据
Zephyr:
1. 实现 struct device + driver_api
2. 在 Kconfig 中声明驱动
3. 在 DTS 中描述硬件
4. 用 device_get_binding() 获取设备
RT-Thread:
1. 实现 rt_device_ops
2. 调用 rt_device_register() 注册
3. 应用层用 rt_device_find() + rt_device_open()下一步
- FreeRTOS 驱动开发 — 最广泛使用的 RTOS
- Zephyr 驱动开发 — 现代化驱动框架
- RT-Thread 驱动开发 — 国内主流 RTOS