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

从零玩转RT-Thread(19):

本课时介绍如何让任务睡眠,从而让任务暂停运行指定的时间。

为什么要延时

在实际项目中,我们经常会用到让任务睡眠相关的接口,从而实现以下功能。

  • 避免CPU占用过多(如忙等)
  • 控制执行节奏(如LED闪烁、采样周期)
  • 给其他任务运行机会

工作原理

当任务需要睡眠时,RT-Thread会将其加入到定时器列表里。这样一来,任务就不会参与调度,无法运行。

只有当任务睡眠时间结束时,任务才会从定时器列表移回就绪队列。

相关接口

在RT-Thread中,与睡眠相关的接口如表所示:

函数名

说明

rt_thread_mdelay(ms)

毫秒级延时(常用)

rt_thread_delay(tick)

等同于rt_thread_sleep()

rt_thread_sleep(tick)

tick数延时,单位为系统节拍数

rt_thread_delay_until(&tick, inc_ticks)

从*tick开始的时间,睡眠inc_ticks时间

其中,rt_thread_mdelay()以毫秒为单位,其余函数以系统时钟节拍周期为单位。该周期由如下配置宏来决定:

#define RT_TICK_PER_SECOND 1000

示例代码:每秒闪烁 LED

下面给出了一个简单的示例,展示了部分睡眠函数的作用。

#include <rtthread.h> #include "base.h" void task1_entry(void *param) { RT_UNUSED(param); while (1) { rt_kprintf("Task 1 is running\n"); rt_thread_delay(RT_TICK_PER_SECOND); // 延时1秒 } } void task2_entry(void *param) { RT_UNUSED(param); rt_tick_t ticks = rt_tick_get(); while (1) { rt_kprintf("Task 2 is running\n"); rt_thread_delay_until(&ticks, RT_TICK_PER_SECOND); } } int main(void) { hardware_init(); rt_thread_t t1 = rt_thread_create( "t1", task1_entry, RT_NULL, 1024, 20, // 相同优先级 20 // 时间片为5个tick ); rt_thread_t t2 = rt_thread_create( "t2", task2_entry, RT_NULL, 1024, 20, // 相同优先级 40 ); if (t1) rt_thread_startup(t1); if (t2) rt_thread_startup(t2); return 0; }

注意事项

睡眠的时间精度取决于系统时钟节拍周期

RT-Thread 使用系统时钟节拍定时器来周期性触发任务调度。该时钟节拍由RT_TICK_PER_SECOND宏配置。

假设RT_TICK_PER_SECOND=1000,那么一个tick时间= 1ms。也就说,此时睡眠的最小单位就是 1 Tick。

如果调用睡眠时间的函数时间点卡得不够好,则可能睡眠过多或过多少,具体如下图所示。

从上图可以看出,实际的睡眠时间比期望的要短或长一些,但是差距不超过一个tick(假设任务在睡眠完之后,能够立即运行)

而如果有其它任何干扰,如更高优先级的任务抢占CPU、同优先级其它任务正在运行,则实际延时时间要更长一些。

因此,在 RTOS 中我们说延时是“近似的、最小保证的延时”,不能用于精密定时(如 1ms 级别的 PWM 控制),而应使用硬件定时器或定时器中断实现更高精度的控制。

课程推荐

  • 全新升级的手写RTOS课程:从原理到实战,一次掌握操作系统的核心

  • 用10000+行代码手写一个TCP/IP协议栈

  • 硬核项目,从0手搓一个RISC-V模拟器!

作者介绍 李述铜,嵌入式系统与底层架构领域讲师,专注于操作系统、CPU 架构、RTOS 内核与系统软件实现原理的教学与研究。 出版作品《从0手写x86计算机操作系统》,主讲课程包括:《从0手写嵌入式操作系统》《从0手写TCP/IP协议栈》《从0手写FAT32文件系统》等。

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

相关文章:

  • 双重遗忘机制对比实验传统Sigmoid激活与ReLU变体的优劣分析
  • 万亿参数大模型成本直降80%:Kimi K2如何用MoE架构重塑企业AI应用
  • 用du命令数据构建实时磁盘监控仪表盘
  • 告别重复劳动:useEffect最佳实践提升开发效率
  • 对比实验:LangChain-ChatChat vs 传统对话开发效率
  • 政务工作的救星ChatPPT:演讲稿生成PPT 真的超棒!
  • 用Spyder快速验证你的数据科学想法
  • PHPCompatibility:轻松解决PHP版本兼容性问题的终极工具
  • 终极指南:5分钟掌握NewGAN-Manager,打造真实足球经理球员面部效果
  • Mac性能调优终极指南:告别过热与续航焦虑
  • ChatBox与Ollama连接故障快速诊断手册
  • 想入门网络安全?这份超详细知识图谱与学习路线图,看这篇就够了!
  • 【bug】bug记录学习,Win系统下爆栈的表现, chkstk.asm 实际是栈溢出
  • 收藏!大模型总“胡说八道”?用RAG根治幻觉,附Cherry Studio实战教程
  • B站视频下载神器:BiliDownloader完全使用手册
  • Stable Diffusion AIGC 视觉设计实战教程之 05-模型应用
  • OpenMetadata Docker极速部署指南:5分钟搭建完整元数据平台
  • 深入解析Sentinel熔断机制
  • AR远程指导:工业行业的新型生产力引擎
  • 网络安全从入门到精通:一份为零基础小白打造的超详细系统学习路线
  • Swin Transformer语义分割终极指南:从入门到精通的完整教程
  • 必藏|程序员别卷CRUD了!AI大模型才是未来5年的高薪密码
  • Chrome浏览器安装Zotero文献收集插件的完整指南
  • 欧冠夜西甲惨负 英超碾压皇马挺帅
  • MySQL 知识点复习- 6.MySQL语法顺序
  • AI如何自动诊断和修复Internal Server Error
  • Java集成PaddlePaddle OCR:让文字识别变得如此简单
  • 协议翻译大师:耐达讯自动化EtherCAT转Devicenet,电动缸的‘毫秒级指令执行专家’
  • Boss Show Time高效调试实战指南:从开发到优化的完整流程
  • 46、网络与文件系统相关技术解析