Skip to content

RTOS 驱动架构总览

RTOS 与 Linux 驱动的本质差异

维度Linux 驱动RTOS 驱动
内存保护MMU 隔离用户/内核空间通常无 MMU,所有代码共享地址空间
驱动框架统一的 bus/device/driver 模型各 RTOS 自有框架,差异较大
中断处理硬中断 + 软中断 + workqueueISR + 任务通知/信号量
内存分配丰富的分配器(slab/vmalloc)静态分配为主,动态分配需谨慎
调试手段printk/ftrace/KGDBJTAG/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 对比

特性FreeRTOSZephyrRT-Thread
许可证MITApache 2.0Apache 2.0
内核大小~5KB~10KB+~6KB
驱动框架无统一框架设备驱动模型设备驱动框架
网络栈lwIP(可选)内置SAL(可选)
文件系统FatFS(可选)内置DFS(可选)
包管理westenv
主要用途MCU,极简场景IoT,工业国内嵌入式
支持架构ARM/RISC-V/x86ARM/RISC-V/x86ARM/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()

下一步

褚成志的笔记