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); }}启动顺序
- 硬件初始化:时钟、GPIO、中断配置
chSysInit():- 初始化内核数据结构
- 创建空闲线程(优先级 0)
- 启动系统 tick 定时器
- 启用调度器
- 创建应用线程
- 主循环或主线程终止
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 的第一步。后续文章将深入探讨调度器配置和系统管理。
部分信息可能已经过时