901 字
5 分钟
ChibiOS/RT 线程管理
ChibiOS/RT 是一个高性能的实时操作系统内核,其线程管理机制是整个 RTOS 的核心。本文将深入讲解 ChibiOS/RT 的线程创建、控制、状态机以及线程抽象层(TLS)的使用方法。
线程创建
ChibiOS/RT 提供了多种线程创建函数,适用于不同的使用场景。
静态线程定义
使用 THD_WORKING_AREA 宏在编译时分配线程的工作区:
/* 定义 256 字的工作区 */THD_WORKING_AREA(waThread1, 256);线程描述符
thread_descriptor_t 结构体描述了一个静态线程的完整信息:
static THD_WORKING_AREA(waThread1, 256);
static const thread_descriptor_t thread1_desc = { .name = "worker", .func = thread1_func, .arg = NULL, .wabase = waThread1, .sizeof_msgq = 0, .prio = NORMALPRIO};chThdCreate
动态创建线程,内核自动分配工作区:
thread_t *chThdCreate(const os_thread_descriptor_t *tdp);示例:
static const thread_descriptor_t thread_desc = { .name = "dynamic_thread", .func = thread_func, .arg = NULL, .wabase = NULL, /* 动态分配 */ .sizeof_msgq = 0, .prio = NORMALPRIO};
void start_thread(void) { thread_t *tp = chThdCreate(&thread_desc); (void)tp;}chThdCreateStatic
使用预分配的工作区创建线程,适合内存受限的嵌入式系统:
static THD_WORKING_AREA(waWorker, 512);
void start_worker(void) { static const thread_descriptor_t worker_desc = { .name = "worker", .func = worker_thread, .arg = (void *)0x1234, .wabase = waWorker, .sizeof_msgq = 0, .prio = NORMALPRIO + 1 }; chThdCreateStatic(&worker_desc);}chThdCreateI
中断上下文中的线程创建变体:
thread_t *chThdCreateI(const os_thread_descriptor_t *tdp);在 ISR 中创建线程时使用,不会立即切换上下文,而是标记为待调度。
chThdCreateSuspended
创建处于挂起状态的线程,需要手动恢复执行:
thread_t *chThdCreateSuspended(const os_thread_descriptor_t *tdp);示例:
thread_t *tp = chThdCreateSuspended(&thread_desc);/* 线程已创建但未运行 */chThdResume(tp); /* 恢复线程执行 */线程控制
chThdResume
恢复挂起的线程:
void chThdResume(thread_t *tp);chThdSuspend
挂起当前线程:
void chThdSuspend(void);chThdTerminate
终止指定线程:
void chThdTerminate(thread_t *tp);调用后线程进入 CH_STATE_FINAL 状态,等待被回收。
chThdRelease
释放已终止线程的资源:
void chThdRelease(thread_t *tp);通常在 chThdTerminate 后调用,彻底清除线程残留数据。
线程状态机
ChibiOS/RT 线程具有完整的状态机模型:
| 状态 | 说明 |
|---|---|
CH_STATE_READY | 就绪态,等待被调度器选中 |
CH_STATE_CURRENT | 正在运行 |
CH_STATE_WTSTART | 等待启动(挂起状态) |
CH_STATE_SNDMSG | 正在发送消息 |
CH_STATE_WTMSG | 等待接收消息 |
CH_STATE_WTSEMAPHORE | 等待信号量 |
CH_STATE_WTMTX | 等待获取互斥锁 |
CH_STATE_WTCOND | 等待条件变量 |
CH_STATE_WTEVENT | 等待事件标志 |
CH_STATE_WTBOX | 等待邮箱消息 |
CH_STATE_WTFIFO | 等待 FIFO 缓冲区 |
CH_STATE_WTQUEUE | 等待队列 |
CH_STATE_WTOREVT | 等待其他事件 |
CH_STATE_SUSPENDED | 挂起态 |
CH_STATE_FINAL | 已终止,等待回收 |
线程状态流转示例:
static THD_WORKING_AREA(waDemo, 256);
static void demo_thread(void *arg) { (void)arg;
/* CH_STATE_CURRENT - 线程正在执行 */ chSysLock(); /* 检查当前线程状态 */ chSysUnlock();
chThdSleep(MS2ST(100)); /* 期间经历: CH_STATE_CURRENT -> CH_STATE_WTEVENT -> CH_STATE_READY -> CH_STATE_CURRENT */
chThdExit(); /* 最终状态: CH_STATE_FINAL */}
void demo_init(void) { chThdCreateStatic(waDemo, sizeof(waDemo), NORMALPRIO, demo_thread, NULL);}线程抽象层(TLS)
TLS(Thread Local Storage)允许每个线程存储自定义数据。
TLS 钥匙管理
注册一个 TLS 钥匙:
tls_key_t tls_mydata;
void init_tls(void) { chThdInitTLS(); tls_mydata = chThdAllocTLS();}
void set_mydata(void *data) { chThdSetTLS(tls_mydata, data);}
void *get_mydata(void) { return chThdGetTLS(tls_mydata);}线程命名和注册
chThdSetName
为线程设置可读名称,方便调试:
void worker_thread(void *arg) { chThdSetName("worker"); /* 后续代码中 chThdGetNameX() 返回 "worker" */ /* ... */}chThdGetTicksX
获取系统滴答计数:
systime_t ticks = chThdGetTicksX();可用于测量线程执行时间或实现超时机制。
总结
ChibiOS/RT 的线程管理提供了从创建、控制到状态监控的完整 API 体系。静态线程适合资源受限的场景,动态线程则更加灵活。理解线程状态机有助于调试复杂的多线程系统,而 TLS 机制为线程级数据存储提供了便捷的抽象。在实际项目中,建议优先使用静态线程分配以避免内存碎片问题。
部分信息可能已经过时