当前位置: 首页 > news >正文

【计算机基础】-23-RT-Thread-如何保障调度器能执行?

RT-Thread 通过多层次机制确保调度器(Scheduler)能够在正确时机被触发并执行,从而实现任务的切换与系统实时性。其核心思想是:“调度请求可被记录,但调度动作必须在线程上下文中安全执行”

以下是 RT-Thread 保障调度器能执行的关键机制:


一、调度器触发的两种场景

1.线程上下文主动触发

  • 当前线程调用rt_thread_delay()rt_sem_take()等阻塞函数时:
    • 线程将自己挂起;
    • 直接调用rt_schedule()触发调度;
    • 调度器立即选择下一个就绪线程运行。

✅ 此时调度器在线程上下文中执行,安全且高效。


2.中断上下文被动触发(关键!)

  • 在 ISR 中调用rt_sem_release()rt_mb_send_irq()等函数时:
    • 可能唤醒更高优先级线程;
    • ISR 中不能直接执行调度(中断上下文不能切换线程栈);
    • RT-Thread 采用“延迟调度”机制设置调度请求标志,待退出中断后再执行调度。

🔑 这是保障调度器能执行且安全执行的核心设计。


二、核心机制:调度请求标志 + PendSV / 异常返回时调度

RT-Thread 利用 Cortex-M 的PendSV 异常(或类似机制)实现“中断退出后调度”

工作流程(以 Cortex-M 为例):

NewThread调度器PendSV 异常中断服务程序当前线程NewThread调度器PendSV 异常中断服务程序当前线程CPU 检测到 PendSV 挂起被中断打断调用 rt_schedule() → 但实际只设置 rt_scheduler_need = 1触发 PendSV 异常(挂起)中断返回(硬件自动恢复部分寄存器)自动进入 PendSV Handler执行完整上下文切换(rt_hw_context_switch)切换到新线程

关键步骤详解:

1.在 ISR 中设置调度请求
// rt_schedule() 在 ISR 中的行为 void rt_schedule(void) { if (rt_interrupt_get_nest() > 0) { /* 在中断中:仅标记需要调度 */ rt_scheduler_need = 1; /* 触发 PendSV 异常 */ SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk; } else { /* 在线程中:立即调度 */ _rt_scheduler_run(); } }
2.PendSV 异常处理调度
  • PendSV 是 Cortex-M 的可挂起异常,优先级通常设为最低;
  • 它会在所有高优先级中断处理完毕后才执行;
  • 在 PendSV Handler 中完成:
    • 保存当前线程寄存器到 TCB;
    • 选择下一个就绪线程;
    • 恢复新线程寄存器;
    • 返回即进入新线程。

优势

  • 避免在 ISR 中做复杂操作;
  • 确保上下文切换在线程模式下安全完成。

三、其他保障机制

1.系统节拍(SysTick)驱动时间片轮转

  • SysTick中断定期触发;
  • 若启用时间片(RT_USING_SCHED_RR),会检查是否需切换同优先级线程;
  • 同样通过PendSV 延迟调度实现。

2.关中断保护调度器数据结构

  • 调度器内部的就绪队列、TCB 等关键数据结构,在修改时会临时关中断
    rt_base_t level = rt_hw_interrupt_disable(); /* 修改就绪队列 */ rt_hw_interrupt_enable(level);
  • 防止 ISR 与调度器同时访问导致数据不一致。

3.idle 线程兜底

  • 若无任何就绪线程,调度器会运行idle 线程
  • idle 线程可执行功耗管理(如WFI指令),但始终保证系统有可运行线程

四、为什么这样设计?

问题RT-Thread 的解决方案
ISR 中不能切换线程栈→ 用 PendSV 延迟到线程上下文执行
多个 ISR 可能连续触发调度→ PendSV 只挂起一次,合并调度请求
调度器数据结构需原子访问→ 关中断保护关键操作
必须保证系统永不“无事可做”→ idle 线程兜底

五、验证方法

1. 查看 PendSV 配置(Cortex-M)

// 在 startup_xxx.s 中 PendSV_Handler: B rt_hw_context_switch_exit

2. 调度请求标志(内核变量)

  • rt_scheduler_need:全局调度请求标志;
  • rt_schedule()中设置,在 PendSV 中清除。

✅ 总结:RT-Thread 如何保障调度器能执行?

  1. 线程上下文:直接调用调度器,立即执行;
  2. 中断上下文
    • 仅设置调度请求标志
    • 通过PendSV 异常中断退出后、线程模式下安全执行调度;
  3. 数据一致性:关键操作关中断保护;
  4. 系统兜底:idle 线程确保总有可运行任务。

🔑核心思想
“调度决策可在中断中做出,但调度执行必须在线程上下文中完成。”
这一设计兼顾了实时响应性系统安全性,是 RTOS 调度器的经典实现范式。

http://www.jsqmd.com/news/373999/

相关文章:

  • 四元数散度和旋度 - 26
  • 2026年知名的硬岩钻裂一体机/挖改钻裂一体机可靠供应商参考推荐几家 - 品牌宣传支持者
  • 信创OA系统如何解决CKEditor粘贴Word公式路径映射问题?
  • 盘点2026年热门门窗品牌,唐潮门窗口碑如何,哪家更值得选? - 工业推荐榜
  • Nodejs+vue+ElementUI框架的网咖网吧会员计费管理系统
  • 汽车制造行业,JAVA如何实现大文件上传?
  • Nodejs+vue+ElementUI框架的数字乡村旅游景点预约平台的设计与实现
  • 关注运行静音:这些磁力泵品牌表现如何?不锈钢螺杆泵/柱塞式计量泵/工业循环水离心泵/液压隔膜计量泵,磁力泵企业哪家靠谱 - 品牌推荐师
  • Nodejs+vue+ElementUI框架的网上交易平台设计与实现
  • JAVA环境下JSP如何实现文件夹上传功能?
  • 聊聊国际本科2+2项目,苏州南昌等地哪家品牌更值得选择 - myqiye
  • Nodejs+vue+ElementUI框架的网上家庭烹饪学习系统的设计与实现
  • 聊聊2026年哈尔滨四轮定位服务,哪家性价比高值得选择 - myqiye
  • 2026年知名的车载点烟器充电线/车载点烟器转换器高评分品牌推荐(畅销) - 品牌宣传支持者
  • Nodejs+vue+ElementUI框架的校园自习室预约管理系统设计与实现
  • 教育行业里,JAVA如何处理大文件上传需求?
  • 2026年热门的大连考公机构/大连考公综合推荐 - 品牌宣传支持者
  • 政务CMS如何用CKEditor实现PDF表单公式到Word的映射?
  • VibeLand正在补上vibe coding的“最后一公里”
  • Nodejs+vue+ElementUI框架的校运会综合管理系统
  • 方达炬〖发明未知种品〗:大规模所有权扩大指数;大规模基金增加值指数;大规模现金增加值指数;
  • Nodejs+vue+ElementUI框架的校园新闻资讯系统的设计与实现
  • 秒懂SKILLS: 模块化的RULES + 轻量化脚本
  • 汽车研发系统如何通过CKEditor实现MATLAB公式Word导入?
  • 2026年全屋定制品牌推荐:智能家居趋势评测,涵盖起居与厨房场景一体化痛点 - 品牌推荐
  • 互联网教育如何通过CKEditor实现Word公式转LaTeX代码?
  • 标准事件委托2(实用)
  • 参考文献崩了?8个AI论文平台测评:本科生毕业论文+科研写作全攻略
  • 图像分割:目标检测、语义分割和实例分割
  • 2026年全屋定制品牌发布:以木里木外为代表的标杆企业深度解析 - 品牌推荐