Zephyr RTOS 提供了丰富的多任务调度机制,包括线程、优先级、队列、信号量、互斥锁等。
#include <zephyr/kernel.h>
/* 线程栈大小 */
#define STACK_SIZE 1024
/* 线程优先级 */
#define PRIORITY 5
/* 线程函数 */
void my_thread_fn(void *arg1, void *arg2, void *arg3)
{
while (1) {
/* 线程逻辑 */
k_sleep(K_SECONDS(1));
}
}
/* 线程定义 */
K_THREAD_DEFINE(my_thread_id, STACK_SIZE,
my_thread_fn, NULL, NULL, NULL,
PRIORITY, 0, K_NO_WAIT);
#include <zephyr/kernel.h>
/* 线程栈 */
static K_THREAD_STACK_DEFINE(my_stack, STACK_SIZE);
/* 线程控制块 */
static struct k_thread my_thread;
/* 创建线程 */
void start_thread(void)
{
k_thread_create(&my_thread, my_stack,
K_THREAD_STACK_SIZEOF(my_stack),
my_thread_fn,
NULL, NULL, NULL,
PRIORITY, 0, K_NO_WAIT);
}
/* 终止线程 */
void stop_thread(void)
{
k_thread_abort(&my_thread);
}
创建 ──▶ 就绪 ──▶ 运行 ──▶ 挂起 ──▶ 就绪
▲ │
│ ▼
└────── 阻塞 ◀───┘
| 状态 | 描述 |
|---|---|
| READY | 可运行 |
| RUNNING | 正在执行 |
| PENDING | 等待事件 |
| SUSPENDED | 暂停 |
| DEAD | 已终止 |
# prj.conf
CONFIG_NUM_COOP_PRIORITIES=16
CONFIG_NUM_PREEMPT_PRIORITIES=8
/* 协作线程 - 优先级 0-15 */
K_THREAD_DEFINE(coop_thread, STACK_SIZE,
coop_fn, NULL, NULL, NULL,
5, K_COOP_THREAD, K_NO_WAIT);
/* 放弃 CPU */
void coop_fn(void *arg)
{
while (1) {
/* 执行工作 */
do_work();
/* 主动让出 CPU */
k_yield();
}
}
/* 抢占线程 - 优先级 0-7 */
K_THREAD_DEFINE(preempt_thread, STACK_SIZE,
preempt_fn, NULL, NULL, NULL,
2, K_PREEMPT_THREAD, K_NO_WAIT);
/* 抢占线程会被高优先级线程抢占 */
void preempt_fn(void *arg)
{
while (1) {
/* 执行工作 */
k_sleep(K_MSEC(100));
}
}
/* 时间片线程 */
K_THREAD_DEFINE(sliced_thread, STACK_SIZE,
sliced_fn, NULL, NULL, NULL,
K_LOWEST_THREAD_PRIORITY, K_PREEMPT_THREAD | K_INHERIT_PERMS,
K_NO_WAIT);
/* 设置时间片 */
void set_slice(struct k_thread *thread, size_t slice)
{
k_thread_time_slice_set(thread, slice, 0);
}
#include <zephyr/kernel.h>
/* 消息队列定义 */
K_MSGQ_DEFINE(my_msgq, sizeof(struct msg), 10, 4);
/* 消息结构 */
struct msg {
uint32_t type;
uint32_t value;
};
/* 发送消息 */
void send_msg(uint32_t type, uint32_t value)
{
struct msg m = { .type = type, .value = value };
int err = k_msgq_put(&my_msgq, &m, K_NO_WAIT);
if (err) {
printk("Queue full!\n");
}
}
/* 接收消息 */
void recv_msg(void)
{
struct msg m;
k_msgq_get(&my_msgq, &m, K_FOREVER);
printk("Got msg: type=%u, value=%u\n", m.type, m.value);
}
/* 线程函数 */
void producer(void *arg)
{
while (1) {
send_msg(1, counter++);
k_sleep(K_MSEC(100));
}
}
void consumer(void *arg)
{
while (1) {
recv_msg();
}
}
#include <zephyr/kernel.h>
/* 管道定义 - 字节流 */
K_PIPE_DEFINE(my_pipe, 256, 4);
/* 写入管道 */
void pipe_write(const uint8_t *data, size_t len)
{
size_t written;
k_pipe_put(&my_pipe, data, len, &written, 1, K_NO_WAIT);
}
/* 读取管道 */
void pipe_read(uint8_t *buf, size_t len)
{
size_t read;
k_pipe_get(&my_pipe, buf, len, &read, 1, K_FOREVER);
}
#include <zephyr/kernel.h>
/* 邮箱定义 */
K_MBOX_DEFINE(my_mailbox);
/* 邮件结构 */
struct mail {
uint32_t header;
uint32_t data[4];
};
/* 发送邮件 */
void send_mail(uint32_t header, uint32_t *data)
{
struct mail m = { .header = header };
memcpy(m.data, data, sizeof(m.data));
k_mbox_put(&my_mailbox, &m, K_NO_WAIT);
}
/* 接收邮件 */
void receive_mail(void)
{
struct mail m;
k_mbox_get(&my_mailbox, &m, NULL, K_FOREVER);
printk("Mail: header=%u\n", m.header);
}
#include <zephyr/kernel.h>
/* 信号量定义 - 初始值 0 */
K_SEM_DEFINE(my_sem, 0, 1);
/* 等待信号量 */
void wait_sem(void)
{
k_sem_take(&my_sem, K_FOREVER);
printk("Semaphore taken!\n");
}
/* 释放信号量 */
void signal_sem(void)
{
k_sem_give(&my_sem);
}
/* 计数信号量 */
K_SEM_DEFINE(count_sem, 0, 5);
/* 获取多个 */
void take_multiple(void)
{
k_sem_take(&count_sem, K_MSEC(100)); // 等待
}
/* 释放多个 */
void give_multiple(void)
{
k_sem_give(&count_sem);
}
#include <zephyr/kernel.h>
/* 互斥锁定义 */
K_MUTEX_DEFINE(my_mutex);
/* 使用互斥锁保护共享资源 */
void access_shared_resource(void)
{
k_mutex_lock(&my_mutex, K_FOREVER);
/* 临界区 */
shared_counter++;
printk("Counter: %d\n", shared_counter);
k_mutex_unlock(&my_mutex);
}
/* 带超时的锁 */
bool try_lock(void)
{
return k_mutex_lock(&my_mutex, K_MSEC(100)) == 0;
}
#include <zephyr/kernel.h>
/* 条件变量 */
K_CONDVAR_DEFINE(my_condvar);
/* 等待条件 */
void wait_condition(void)
{
k_mutex_lock(&my_mutex, K_FOREVER);
while (!data_ready) {
k_condvar_wait(&my_condvar, &my_mutex, K_FOREVER);
}
/* 处理数据 */
process_data();
k_mutex_unlock(&my_mutex);
}
/* 唤醒等待者 */
void signal_condition(void)
{
k_mutex_lock(&my_mutex, K_FOREVER);
data_ready = true;
k_condvar_signal(&my_condvar);
k_mutex_unlock(&my_mutex);
}
/* 唤醒所有 */
void broadcast_condition(void)
{
k_condvar_broadcast(&my_condvar);
}
#include <zephyr/kernel.h>
/* 事件组定义 */
K_EVENT_DEFINE(my_event);
/* 等待事件 */
void wait_events(void)
{
uint32_t events = k_event_wait(&my_event, 0xF, true, K_FOREVER);
if (events & 0x1) {
printk("Event 0 occurred\n");
}
}
/* 设置事件 */
void set_events(void)
{
k_event_set(&my_event, 0xF); // 设置所有
}
/* 清除事件 */
void clear_events(void)
{
k_event_clear(&my_event, 0xF);
}
/* 线程本地存储 */
__thread int tls_counter;
/* 或者使用 _Thread_local */
_Thread_local uint32_t tls_id = 0;
#include <zephyr/kernel.h>
/* 线程自定义数据 */
int tls_key;
/* 初始化 TLS 键 */
void init_tls(void)
{
tls_key = k_thread_custom_data_get();
}
/* 设置线程数据 */
void set_thread_data(void *data)
{
k_thread_custom_data_set(data);
}
/* 获取线程数据 */
void *get_thread_data(void)
{
return k_thread_custom_data_get();
}
#include <zephyr/kernel.h>
/* 定时器定义 */
static struct k_timer my_timer;
/* 定时器回调 */
void my_timer_handler(struct k_timer *timer)
{
printk("Timer expired!\n");
}
/* 初始化定时器 */
k_timer_init(&my_timer, my_timer_handler, NULL);
/* 启动定时器 - 周期 */
k_timer_start(&my_timer, K_MSEC(100), K_MSEC(100));
/* 启动定时器 - 单次 */
k_timer_start(&my_timer, K_MSEC(1000), K_NO_WAIT);
/* 停止定时器 */
k_timer_stop(&my_timer);
/* 获取剩余时间 */
k_timeout_t remaining = k_timer_remaining_get(&my_timer);
#include <zephyr/kernel.h>
/* 工作队列定义 */
static struct k_work_q my_work_q;
/* 初始化工作队列 */
k_work_queue_start(&my_work_q, my_stack, STACK_SIZE, PRIORITY, NULL);
/* 工作项定义 */
static struct k_work my_work;
/* 工作处理函数 */
void work_handler(struct k_work *work)
{
printk("Work item handled!\n");
}
/* 初始化工作 */
k_work_init(&my_work, work_handler);
/* 提交工作 */
k_work_submit_to_queue(&my_work_q, &my_work);
#include <zephyr/kernel.h>
/* 延迟工作 */
static struct k_work_delayable my_delayed_work;
/* 初始化 */
k_work_init_delayable(&my_delayed_work, work_handler);
/* 调度延迟工作 */
k_work_schedule(&my_delayed_work, K_MSEC(1000));
/* 取消 */
k_delayed_work_cancel(&my_delayed_work);
#include <zephyr/kernel.h>
/* 内存池定义 */
K_HEAP_DEFINE(my_heap, 4096);
/* 分配内存 */
void *alloc_mem(size_t size)
{
return k_heap_alloc(&my_heap, size, K_NO_WAIT);
}
/* 释放内存 */
void free_mem(void *ptr)
{
k_heap_free(&my_heap, ptr);
}
#include <zephyr/kernel.h>
/* 内存块结构 */
struct block {
uint8_t data[64];
};
/* 固定池定义 */
K_MEM_POOL_DEFINE(my_pool, 256, 4096, 1, 4);
/* 分配 */
void *alloc_block(void)
{
return k_mem_pool_alloc(&my_pool, K_NO_WAIT);
}
/* 释放 */
void free_block(void *block)
{
k_mem_pool_free(block);
}
CONFIG_THREAD_ANALYZER=y
CONFIG_THREAD_ANALYZER_RUN_UNLOCKED=y
#include <zephyr/kernel.h>
/* 打印所有线程 CPU 使用率 */
void print_cpu_usage(void)
{
thread_analyzer_print();
}
/* 中断服务例程中不能使用的函数 */
void isr_fn(void)
{
// ✅ 可以用
k_is_in_isr();
k_queue_get(&my_queue, K_NO_WAIT);
// ❌ 不能用 - 会阻塞
k_mutex_lock(&my_mutex, K_FOREVER);
k_msgq_get(&my_msgq, &msg, K_FOREVER);
}
/* 零延迟唤醒 */
void wake_immediately(struct k_thread *thread)
{
k_wakeup(thread);
}
/* 推荐优先级分配 */
#define PRIORITY_HIGH 0 // 关键任务
#define PRIORITY_MEDIUM 5 // 普通任务
#define PRIORITY_LOW 10 // 后台任务
#define PRIORITY_IDLE 15 // 空闲任务
/* 使用互斥锁避免优先级反转 */
k_mutex_lock(&my_mutex, K_FOREVER);
/* 使用消息队列代替共享缓冲区 */
# Shell 命令
uart:~$ kernel threads
uart:~$ kernel stack <thread_id>
CONFIG_DEBUG_THREAD_INFO=y
CONFIG_EXCEPTION_STACK_TRACE=y
学习日期: 2026-03-21 笔记编号: #59 作者: 小白 🤖