RT_Thread_空闲线程

本文探讨了空闲线程在嵌入式操作系统中的作用,重点讲解其作为系统线程的特性、低优先级及回收资源的功能。同时,介绍了如何设置和删除空闲线程的钩子函数,以及在钩子函数中实现LED闪烁示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、空闲线程(idle)说明

1.1、线程类型:系统线程

1.2、优先级:最低

1.3、线程状态:就绪态

当系统中无其他就绪线程存在时,调度器将调度到空闲线程,它通常是一个死循环,且永远不能被挂起。例如 rt_thread_delay(),rt_sem_take() 等可能会导致线程挂起的函数都不能使用。并且,由于 malloc、free 等内存相关的函数内部使用了信号量作为临界区保护,因此在钩子函数内部也不允许调用此类函数!

空闲线程必须有得到执行的机会,即其他线程不允许一直while(1) 死卡 ,必须调用具有阻塞性质的函数;否则例如线程删除、回收等操作将无法得到正确执行。


1.4、功能1:回收资源

若某线程运行完毕,系统将自动删除线程:

执行 rt_thread_exit() 函数,先将该线程从系统就绪队列中删除,再将该线程的状态更改为关闭状态,不再参与系统调度,然后挂入 rt_thread_defunct 僵尸队列(资源未回收、处于关闭状态的线程队列)中,最后空闲线程会回收被删除线程的资源。


1.5、功能2:钩子函数

在空闲线程运行时会调用设置的钩子函数,适合钩入功耗管理、看门狗喂狗等工作。

2、设置和删除钩子函数

2.1、设置钩子函数 rt_thread_idle_sethook

rt_err_t rt_thread_idle_sethook(void (*hook)(void));
函数参数描述
hook设置的钩子函数
返回——
RT_EOK设置成功
-RT_EFULL设置失败

设置的钩子函数在rt_thread_idle_entry()中被调用,由函数的实现可以看到最多可设置4个空闲钩子函数,是以链表的形式对钩子函数调用。 

2.2、删除钩子函数 rt_thread_idle_delhook

rt_err_t rt_thread_idle_delhook(void (*hook)(void));
函数参数描述
hook删除的钩子函数
返回——
RT_EOK删除成功
-RT_ENOSYS删除失败

3、代码

空闲钩子函数里设置运行指示灯1s闪烁一次;

//翻转LED0
void led0_turn()
{
	if(rt_pin_read(LED0_PIN))
		rt_pin_write(LED0_PIN, PIN_LOW);
	else
		rt_pin_write(LED0_PIN, PIN_HIGH);
}

/* 空闲任务钩子函数 */
static void idle_hook()
{
	static rt_tick_t tick_num=0,tick_num_last=0;
	tick_num = rt_tick_get();
	if(tick_num-tick_num_last > 1000){
		led0_turn();//翻转LED
		tick_num_last = tick_num;
	}
}

int main()
{
	rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);
	led0_off();

    /* 设置空闲线程钩子 */
    rt_thread_idle_sethook(idle_hook);
}
### RT-Thread 操作系统线程切换机制及实现 #### 线程切换概述 在 RT-Thread 中,线程切换是通过抢占式调度器完成的。调度器负责从就绪线程列表中选择具有最高优先级的线程来执行。当更高优先级的线程变为可运行状态时,调度器会立即暂停当前正在运行的较低优先级线程,并将CPU资源交给高优先级线程[^2]。 #### 上下文保存与恢复 每当发生线程切换时,RT-Thread 需要保存即将被替换掉的那个线程的状态信息(即上下文),以便稍后可以准确地从中断处继续执行。这涉及到寄存器内容以及其他必要的硬件状态数据。之后,新选中的线程之前存储好的上下文会被加载回处理器寄存器和其他相关位置上,从而使得新的线程可以从上次停止的地方无缝接续工作[^4]。 #### 设置线程切换钩子函数 为了方便开发者监控或记录每次发生的线程转换情况,RT-Thread 提供了一个API用于注册回调函数——也就是所谓的“钩子”。一旦定义并设置了这样的钩子,则每经历一次完整的线程迁移过程(无论是因为时间片轮转还是由于更紧急的任务到来而引起的强制性转移),该特定的用户自定义处理逻辑就会被执行一次。 ```c // 注册线程切换钩子函数的例子 void my_thread_switch_hook(struct rt_thread *from, struct rt_thread *to) { /* 用户在这里编写想要在线程切换前后做的操作 */ } int main(void) { // 安装线程切换通知钩子 rt_thread_switch_hook_add(my_thread_switch_hook); return 0; } ``` #### 特殊线程的角色 值得注意的是,在整个RTOS环境中还存在着一些特殊的线程实例,比如空闲(idle)线程。它是系统默认创建的一个低优先级常驻进程;当没有任何其他活动任务可供调度的时候,默认情况下idle线程总是处于准备就绪状态并且获得CPU控制权。尽管如此,它实际上并不做任何实际的工作而是进入一个无限循环等待直到下一个事件的发生[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值