RTOS系统延时与普通软延时的特点与区别

2023-05-16

我们知道,在RTOS中会提供若干延时函数的API。对于没有仔细了解过RTOS的同学而言,可能会产生这样疑惑:这些API与普通自写的延时函数相比究竟有何优势呢?为什么要额外提供这些API?

在这篇文章中,我们来分析下这些API接口的工作原理、特点以及其相比自写的延时函数,究竟有什么优缺点,我们该如何选择。

普通延时方式

在没有使用RTOS之前,我们可能通过以下方式实现延时或定时。

指令软延时

在比较简单、各条指令执行时间可预测的MCU上,也许你写过如下类似的代码。

void delay () {
    int i, j;
    for (i = 0; i < 100; i++) {
        for (j = 0; j < 1000; j++) {
        }
    }
}

对于上面这种方式,要实现特定时长的延时,有两种办法:一、根据实际测量的时间,调整比较数值,使得整体时长接近期望值;二、用汇编指令实现,根据每条指令运行时长及运行的次数总和,统计出整个函数的运行时长,然后再同样调整计数值,使得时长接近期望值。由此可见,这种方式用起来也很麻烦。

这种方式有着明显的缺点:受CPU主频的强烈影响,一旦主频发生变化,上面的延时函数必须调整。 所以这种方式只适合不精确的延时,以及主频确定不会发生变化的场合。

定时器软延时

有的同学可能会借助于定时器实现软延时,代码大致如下:

void delay () {
    initTimer();    
    startTimer();
    while (!timerIsOverFlow()); // 等待定时器溢出
}

这种方式的工作原理是给定时器设置定时值,然后程序不断检查定时器是否溢出或计数到达。相对前一种方式,显然我们不再需要进行麻烦的计算和统计就能更加容易的设定好延时时间。虽然定时器本身的工作频率是由硬件决定(可能也由主频决定),但是我们可以通过程序根据不同的主频自动计算出相应的配置值,所以其不易受主频影响。

但这种方式也有着明显的缺点:为了延时而占用一个硬件定时器资源。

定时中断处理

上述两种方式还存在另一个问题;在延时期间,程序什么也干不了,只能原地等待。 也许有的人会在等待期间插入一些代码来减少一些无谓的箸待开销;但这种做法并不多见。

所以,有时我们会考虑设定定时器,配置定时器中断,在定时器中断中执行相应的功能;或者在中断中设置时间到达标记,然后在主程序中处理。例如:

void timerISR () {
    timeoutFlag = 1;
}

int main () {
    setTimer();
    for (;;) {
        if (timeoutFlag) {
            // do something
            timeoutFlag = 0;
            setTimer();
        }
    }
    return 0;
}

这种方式存在着同样的缺点:为了延时而占用一个硬件定时器资源。相比之下,可以减少很多CPU空转的消耗。

上面几种方式,同时还存在几个严重的问题,很难做到同时给多个任务使用。例如

  • 指令/定时器软延时,延时过程中会死等,空耗CPU。这在RTOS环境上不能容忍的;
  • 不同任务延时时长可能差异很大,很难做到写一个通用的指令软延时函数;
  • 定时器延时/中断方式,一次只能够一个任务使用;如果多个任务使用还得考虑定时器资源竞争。

所以, RTOS还有必要提供另一种模式的延时API。

系统延时方式

RTOS提供的延时API,相比于软延时,其最大的特点是:在任务延时过程中,能够切换到其它任务去运行。这样就避免了死等,可用于执行一些其它功能的代码。显然CPU的利用率就大大提高。 实种接口的实现原理大体类似:

通过一个硬件定时器定期产生中断,称之为时间节拍。在每个时钟节拍发生时,递减任务内部的一个延时计数器,当延时计数器减至0时,将任务插入到就绪列表等待获取CPU运行。而在延时期间,任务一直在延时队列中,此时CPU执行其它非延时任务。

可以看到,只需要一个定时器资源,就要以给系统中所有任务提供延时功能。每次延时的基本单位是一个时钟节拍周期。也就是说每次任务延时,必须至少延时1个周期长。这正是使用这种方式存在的问题,即不能实现更小的时间延时。

此外,在实际使用过程 ,我们会发现在某些情况下会出现延时存在较大误差的情况,下图中说明了这种情况。

延时精度问题

因此,这种方式是通过软件资源+牺牲了一定的功能条件下,换取了CPU利用率的提升以及可被多任务通用。

方式比较

前面介绍的几种方式,在实际使用时,并不一定说某种延时方式是最好的。

各种延时方式各有优缺点,根据实际需要选择。

  • 如果提升CPU利用率,且延时时间>=1个时钟节拍周期,可考虑延时API,但要注意可能存在最大1个时钟节拍周期的偏差;
  • 如果需要延时的精度小于1个周期节拍周期,就只能考虑软延时/定时器延时
    • 如果定时器资源足够,且想提升CPU利用率,在定时中断中处理或者中断中向任务发送信号量处理事件
    • 也可考虑使用指令软延时/定时器软延时。如果使用定时器软延时,由于要执行配置、启动、检查等操作,代码执行时间较长。如果延时小于执行时长,无法采用此种方式,应考虑用指令延时。

当然,以上只是建议,并不是绝对的。在实际使用过程,还要考虑个人习惯、精度要求等。在某些要求并不苛刻的应用中,有少量的延时误差或者CPU利用率不高,其实也没有多大关系。没有最好的方式,只有最适合的方式!

该文章同时发布在:http://01ketang.cc/rtos/rtos-sys-delay.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

RTOS系统延时与普通软延时的特点与区别 的相关文章

  • Android布局常用

    1 控件隐藏 在XML 文件里设置属性隐藏 android visibility 61 34 invisible 34 android visibility 61 34 visible 34 android visibility 61 34
  • 乘法

    乘法 请仔细把下面的看懂 xff0c 看完后 xff0c 也许你能口算出 1 xff5e 199 之间数的平方 xff0c 或许能口算出多个数的结果 1 乘法的本质 xff1a 乘法的本质就是求和 从上面两张图片中 xff0c 你可以知道
  • Android Activity之间跳转与传值

    一 Activity 跳转与传值 xff0c 主要是通过 Intent 类来连接多个 Activity xff0c 通过 Bundle 类来传递数据 最常见最一般的页面跳转代码 xff0c 很简单 xff0c 如下 xff1a Intent
  • URLEncoder.encode和decode

    http www apkbus com forum php mod 61 viewthread amp tid 61 13853 amp fromuid 61 3402
  • JPCT-AE资料相关

    JPCT AE相关 1 网站参考 xff1a 官方网站 http www jpct net download html API http www jpct net jpct ae doc JPCT AE wiki http www jpct
  • 分享本人VSCode配色(如何修改VSCode各种颜色)

    按下Command 43 Shift 43 P打开命令面板输入settings Open Settings为用户自定义设置Open Default Settings为默认设置 xff08 只读 xff0c 不能修改的 xff09 选中Ope
  • ROS学习番外篇12—Mac M1(Pro+Max)安装ROS1或ROS2须知

    由于苹果换了芯片架构 xff0c 因此裸机安装ROS2或者源码安装ROS1和ROS2变得非常困难 使用Parallels Desktop或者其他虚拟机 xff08 比如UTM xff09 安装Ubuntu然后再在Ubuntu上安装ROS是目
  • stm32cubemx hal学习记录:PWR 低功耗停止模式

    一 低功耗停止模式 1 所有时钟都已经停止 2 进入方式 xff1a 配置PWR CR寄存器的PDDS 43 LPDS位 43 SLEEPDEEP位 43 WFI或WFE命令 3 唤醒方式 xff1a 任意外部中断 4 关闭所有1 8v区域
  • Ubuntu下查看文件、文件夹和磁盘空间的大小

    在实际使用ubuntu时候 xff0c 经常要碰到需要查看文件以及文件夹大小的情况 有时候 xff0c 自己创建压缩文件 xff0c 可以使用 ls hl 查看文件大小 参数 h 表示Human Readable xff0c 使用GB MB
  • stm32cubemx hal学习记录:FreeRTOS任务管理

    一 基本配置 1 配置RCC USART1 时钟84MHz 2 配置SYS xff0c 将Timebase Source修改为除滴答定时器外的其他定时器 xff0c 因为滴答定时器被用于时钟基准 xff0c 可以实现任务切换 Timebas
  • 【面试笔试-c/c++】2013年校园招聘创新工场笔试题(北邮场)

    2013年校园招聘创新工场笔试题 xff08 北邮场 xff09 及一面 题目节后补上 回家了 xff0c 上网不方便 面试题 一面 xff1a 1 手写二叉树的中序非递归遍历 xff0c 一步一步解释代码 xff0c 给个二叉树示范代码流
  • PX4驱动分析之MPU6000

    PX4驱动分析之MPU6000 前言 xff1a 首先分析PX4中MPU6000传感器驱动的注册 xff0c 调用 xff0c 实例的过程 xff0c 先要理解一个事情 就是PX4是使用了一个类Linux操作系统的Nuttx操作系统 也就是
  • PX4分析系列之添加北醒TOF传感器(使用UART)

    PX4分析系列之添加北醒TOF传感器 xff08 使用UART xff09 提示 xff1a 一个飞行器爱好者 xff0c 才疏学浅 通过自己学习PX4源码的过程 xff0c 进行分析和记录 欢迎各路大神讨论 xff0c 并指正文中错误 x
  • 产品化的理解

    我对产品化的理解 产品化的时机是看业务的需要 xff0c 不管是对前景的落实 xff0c 还是项目转化成产品 xff0c 这些都不是技术人员能考虑的 xff0c 业务的发展和策划 xff0c 如何进行市场细化等如果都由技术人员考虑 xff0
  • JS对象转insert语句

    function obj2Sql tablename obj var sqls 61 34 34 f 61 34 34 v 61 34 34 obj forEach o 61 gt f 61 34 34 v 61 34 34 for let
  • HTML5小试 双人贪吃蛇

    lt html gt lt head gt lt head gt lt body gt lt div style 61 34 float left 34 gt 当前速度1 xff1a lt button nclick 61 34 jianc
  • 九个Console命令,让js调试更简单

    九个Console命令 xff0c 让js调试更简单 一 显示信息的命令 lt DOCTYPE html gt lt html gt lt head gt lt title gt 常用console命令 lt title gt lt met
  • echarts自定义功能按钮图片 网络路径格式

    toolbox show true orient 39 vertical 39 x 39 left 39 top 39 20 39 feature myTool show true title 39 自定义扩展方法 39 icon 39 i
  • 上班摸鱼逛博客,逮到一个字节8年测试开发,聊过之后羞愧难当......

    老话说的好 xff0c 这人呐 xff0c 一旦在某个领域鲜有敌手了 xff0c 就会闲得某疼 前几天我在上班摸鱼刷博客的时候认识了一位字节测试开发大佬 xff0c 在字节工作了8年 xff0c 因为本人天赋比较高 xff0c 平时工作也兢
  • Ubuntu下USB权限问题以及udev规则文件笔记

    在ubuntu系统下使用传感器的时候 xff0c 通常会遇到一些权限上的问题 比如我使用ROS驱动包来启动bluefox摄像头 xff0c 如果没有任何关于权限上的处理就会提示权限问题导致无法正常启动该摄像头 xff0c 如下图 xff1a

随机推荐

  • 三.卡尔曼滤波器(EKF)开发实践之三: 基于三个传感器的海拔高度数据融合

    本系列文章主要介绍如何在工程实践中使用卡尔曼滤波器 分七个小节介绍 一 卡尔曼滤波器开发实践之一 五大公式 二 卡尔曼滤波器开发实践之二 一个简单的位置估计卡尔曼滤波器 三 卡尔曼滤波器 EKF 开发实践之三 基于三个传感器的海拔高度数据融
  • 树莓派 - 1 安装与配置 - a 系统安装(Raspbian)

    xff08 1 xff09 软件 Raspbian operating system https www raspberrypi org downloads raspbian Etcher SD card writing tool http
  • 分享一个Linux的录屏工具script

    在使用该命令后 xff0c 直接录屏 xff0c 会记录终端在命令行的所有动作 想让别人帮你操作 xff0c 但你的思路跟不上对方敲命令的速度 xff0c 可以先录下来 xff0c 然后回去慢慢琢磨 我的是centos7系统 span cl
  • 最佳Linux防病毒软件推荐!

    看到标题或许你会疑问 xff0c linux如此安全 xff0c 为什么我们还需要安装防病毒软件呢 确实 xff0c linux为全球超过70 的web服务器提供支持 xff0c 黑客极有动机来制造强大的病毒来渗透这些服务器安全系统 xff
  • NvidiaAGXXavier刷机Jetpack5.0.2报错记录(已解决,非搬运)

    网上有很多教程 xff0c 很详细的讲了这个板子刷机应该怎么去做 xff0c 正常的话就按照那个步骤走就可以了 xff0c 这里就不再赘述了 xff0c 但是我在给自己的NvidiaAgxXavier刷Jetpack5 0 2的时候 xff
  • Atmel Cortex-A5跑Nuttx是如此酸爽

    开源RTOS Nuttx已经支持Atmel SAMA5系列MPU xff0c 而且看到Nuttx还支持Graphic API xff0c 决定尝试在Ateml SAMA5D3 Xplained上跑下Nuttx Nuttx是一款开源RTOS
  • Using NuttX OS as a library on Atmel Studio 7

    This document explains how to add NuttX OS to your application on Atmel Studio 7 using NuttX OS as a library With Atmel
  • 【开发备忘】QGroundControl编译

    本文记录在windows下编译最新版QGC的过程 Qt版本为5 15 2 xff0c 编译器为MSVC2015 1 Qt环境配置 尽管目前已有Qt6 xff0c 但是QGC官网明确强调了仅可使用Qt 5 15 2 xff0c 因此首先需要安
  • Linux都应用在哪些领域?发展如何?

    与Windows操作系统软件一样 xff0c Linux也是一个操作系统软件 但与Windows不同的是 xff0c Linux是一套开放源代码程序的 xff0c 并可以自由传播的类UNIX操作系统软件 xff0c 随着信息技术的更新变化
  • opensuse 11.1 在线安装虚拟机 VirtualBox-2.2.4

    有些喜欢的windows软件可以用wine虚拟出来了 xff0c 比如酷狗 xff0c 但是有些就比较麻烦了 xff0c 比如中国特色的在线电影 xff0c 网银 xff0c 或许只有用虚拟机解决起来比较方面 xff0c 说句实在话 xff
  • Linux下CMakeLists.txt编译C++程序笔记

    在Linux下运用ROS系统可免去很多构建框架的步骤 xff0c 所以一般只要按照官网给的教程逐步进行即可 但是ROS自身有许多的毛病 xff0c 比如其稳定性和实时性差 xff0c 有时候数据传输会发现丢失的现象 xff0c 因此其性能不
  • px4: actuators control, control group 和 mixer科普

    原文链接 xff1a https pixhawk org dev mixing Control Mixing This page discusses the general purpose control mixing architectu
  • 如何用开源飞控PIXHAWK进行二次开发?

    著作权归作者所有 商业转载请联系作者获得授权 xff0c 非商业转载请注明出处 作者 xff1a 我是肉包子 链接 xff1a http www zhihu com question 38874663 answer 84239995 来源
  • px4的模式与状态

    一 模式 PX4 native flight stack String Description and notes MANUAL ACRO ALTCTL POSCTL OFFBOARD STABILIZED RATTITUDE in mas
  • ESP8266开发实战之(一)-开发环境配置

    最近买了一块ESP8266的小板子 xff0c 上面自带WIFI功能 xff0c 可以进行一些好玩的物联网开发 因此 xff0c 我打算将对整个板子的的熟悉过程通过一系列的文档记录下来 我拿到的板子型号是NodeMUC 1 0 ESP 12
  • ESP8266开发实战之(4)-连接路由器的wifi

    概述 ESP8266支持连接到wifi xff0c 从而使得我们能够通过网络访问 xff0c 做出一些简单而有趣的功能 因此 xff0c 第一步工作便是连接到wifi网络 一般情况下 xff0c 我们要连接wifi xff0c 在手机上的操
  • 怎样用一行代码判断系统的大小端?

    最近在设计自己的TCP IP协议栈 xff0c 代码完成的差不多了 xff0c 已经能够跑在嵌入式STM32开发板上 闲来无事 xff0c 想着优化一下问题的解决方案 这个问题据说是很常见的面试问题 xff1a 如何判断当前系统的大小端 x
  • 在操作系统开发中选bochs还是qemu

    最近有同学问我 xff1a 为什么你在写 0写x86 Linux操作系统时选择了bochs xff0c 而不是qemu xff1f 他认为bochs更加好用 xff0c 很多资料上都写了用该软件 其实我也是经过不断地对比和尝试后 xff0c
  • 网络编程中的大小端

    最近在录制一门手写TCP IP协议栈的课程 不得不说 xff0c TCP IP这个东西是真难 xff0c 写代码费了我半天劲 xff0c 然后又要用课程的方式给讲出现 这其中涉及到大小端的转换 xff0c 所以这里总结一下 在计算机领域 x
  • RTOS系统延时与普通软延时的特点与区别

    我们知道 xff0c 在RTOS中会提供若干延时函数的API 对于没有仔细了解过RTOS的同学而言 xff0c 可能会产生这样疑惑 xff1a 这些API与普通自写的延时函数相比究竟有何优势呢 xff1f 为什么要额外提供这些API xff