LOADING
1141 字
6 分钟
ChibiOS/RT 简介与内核概念

ChibiOS/RT 概述#

ChibiOS/RT 是一款面向深度嵌入式系统的轻量级实时操作系统(RTOS)。它以极小的内存占用、高性能和可移植性著称,广泛应用于工业控制、消费电子、医疗器械等领域。

核心特点#

  • 开源 MIT 许可证:可自由用于商业项目,无 GPL 传染性
  • 极小 footprint:内核 ROM 最小约 1KB,RAM 最小约 1KB
  • 高性能:上下文切换时间通常在数百纳秒级别
  • 可移植性:支持 ARM Cortex-M/R/A、AVR、RISC-V、PowerPC 等架构
  • STM32 系列深度支持:提供 HAL 和 PAL 层,可直接驱动 STM32 外设
/* ChibiOS/RT 内核结构示意 */
+-------------------+
| 应用层 (Threads) |
+-------------------+
| OS 服务层 | ← 同步原语、消息、内存管理
+-------------------+
| 内核对象层 | ← 线程、定时器、信号量、互斥锁
+-------------------+
| 硬件抽象层 (HAL) | ← GPIO、UART、SPI、I2C...
+-------------------+
| 硬件 (MCU) |
+-------------------+

主要特性#

抢占式调度器#

ChibiOS/RT 采用基于优先级的抢占式调度器。当高优先级线程就绪时,调度器立即切换到该线程执行,保证实时性。

同步原语#

  • 二值信号量:用于线程间同步
  • 计数信号量:资源计数管理
  • 互斥锁:支持优先级继承,防止优先级反转
  • 事件标志组:多位事件等待
  • 消息队列:线程间通信

内存管理#

  • 静态内存池(Memory Pool)
  • 堆内存管理(Heap)
  • 内存碎片化控制

OS 库#

ChibiOS/RT 提供丰富的 OS 库:邮箱、消息队列、虚拟定时器、循环屏障等。

SMP 支持#

对称多处理(SMP)支持,允许多个核心运行独立线程或共享线程池。

内核对象概念#

ChibiOS/RT 的一个核心设计理念是:所有内核实体都是对象

对象结构#

每个内核对象都继承自 struct ch_object,包含一个指向类描述符的指针:

struct ch_object {
ch_class_t vmt; /* 虚方法表指针 */
};

内核对象包括但不限于:

对象类型说明
thread_t线程
semaphore_t信号量
mutex_t互斥锁
event_source_t事件源
virtual_timer_t虚拟定时器
memory_pool_t内存池
mailbox_t邮箱
msg_t消息

静态与动态分配#

/* 静态分配:在编译时确定内存 */
static WORKING_AREA(waThread1, 128);
static thread_t *thread1;
/* 动态分配:运行时从堆分配 */
thread_t *tp = chThdCreateFromHeap(NULL,
THD_WA_SIZE(256),
NORMALPRIO,
threadFunc,
NULL);

线程模型#

线程结构#

线程是 ChibiOS/RT 中最基本的执行单元。每个线程拥有:

  • 独立的栈空间(Working Area)
  • 优先级(数值越大优先级越高)
  • 线程状态
  • 指向线程函数的入口

线程状态机#

┌──────────┐
启动 │ │ 阻塞等待
┌───────────►│ 就绪 │◄──────────┐
│ │ (Ready) │ │
│ │ │ │
│ └────┬─────┘ │
│ │ │
│ 调度执行 │ 唤醒
│ │ │
│ ▼ │
│ ┌──────────┐ │
│ │ │ 超时/ │
│ │ 运行 │ 事件 │
│ │ (Running)│───────────┘
│ │ │
│ └────┬─────┘
│ │
│ 终止 │
│ ▼
│ ┌──────────┐
└───────────│ 终止 │
新线程 │(Terminated)│
└──────────┘

优先级规则#

  • 数值越大,优先级越高
  • 建议预留优先级 0 给空闲线程
  • 使用 NORMALPRIO 宏定义普通优先级
  • 优先级继承由互斥锁自动管理

工作区(Working Area)#

工作区即线程栈空间,必须满足最小对齐要求:

/* 定义工作区:128 个 stack_msg(每个 4 字节) */
WORKING_AREA(waThread1, 128);
/* 定义线程入口函数 */
static msg_t thread1_func(void *arg) {
chRegSetThreadName("worker");
while (true) {
/* 线程工作 */
chThdSleepMilliseconds(500);
}
return MSG_OK;
}
/* 创建线程并启动 */
thread_t *tp = chThdCreateStatic(waThread1,
sizeof(waThread1),
NORMALPRIO,
thread1_func,
NULL);

系统启动流程#

chSysInit#

系统启动的入口是 chSysInit(),通常在 main() 函数的最开始调用:

int main(void) {
halInit(); /* HAL 初始化 */
chSysInit(); /* OS 内核初始化 */
/* 启动线程 */
chThdCreateStatic(waThread1,
sizeof(waThread1),
NORMALPRIO,
thread1_func,
NULL);
/* 主线程可以继续工作或终止 */
while (true) {
chThdSleepSeconds(1);
}
}

启动顺序#

  1. 硬件初始化:时钟、GPIO、中断配置
  2. chSysInit()
    • 初始化内核数据结构
    • 创建空闲线程(优先级 0)
    • 启动系统 tick 定时器
    • 启用调度器
  3. 创建应用线程
  4. 主循环或主线程终止

OS 实例(SMP)#

在 SMP 系统中,每个核心需要独立的 OS 实例:

/* 主核心 OS 实例 */
static OS_INSTANCE(os_instance_main);
/* 从核心 OS 实例 */
static OS_INSTANCE(os_instance_extra);
int main(void) {
/* 初始化主核心 */
os_instance_main_init(&os_instance_main);
/* 启动从核心 */
os_instance_start(&os_instance_extra);
}

总结#

ChibiOS/RT 以简洁的对象模型、清晰的线程管理和高效的调度器,为嵌入式开发者提供了一个可靠且高性能的 RTOS 平台。理解内核对象、线程模型和启动流程,是掌握 ChibiOS/RT 的第一步。后续文章将深入探讨调度器配置和系统管理。

ChibiOS/RT 简介与内核概念
/posts/chibios-rt-intro/
作者
JJZBQA
发布于
2024-12-15
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时