LOADING
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 机制为线程级数据存储提供了便捷的抽象。在实际项目中,建议优先使用静态线程分配以避免内存碎片问题。

ChibiOS/RT 线程管理
/posts/chibios-rt-threads/
作者
JJZBQA
发布于
2024-12-17
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时