嵌入式软件实现中经常出现的一个有趣问题是弄清楚如何延迟代码执行。有时,嵌入式开发人员可能只希望有 10 微秒的延迟,以允许 I/O 线在读取之前稳定下来,或者可能希望在读取之间有一个指定的时间段来消除它的抖动。在这篇文章中,我们将探讨五种延迟代码执行的技术。

技术 #1 – 条件循环

第一种可能是最常用和最简单的技术是使用条件循环。条件循环延迟通常会使用 for、while 或 do while 循环来重复执行无操作 (NOP) 指令。例如:

有条件的延迟在紧要关头可能很有用,但它几乎不准确或有效。如果开发人员要针对不同的操作模式(例如低功耗操作)调整时钟频率,则延迟时间将完全不同。另外,总是有一个问题,那就是延迟到底有多少?有人可能认为它有 100,000 条指令,但每次循环都会有额外的指令来检查循环变量并增加 i。这些时序循环太难以预测,无法在任何生产代码中使用。

技巧 #2 – 使用计时器

可以使用的第二种技术是利用内置在微控制器中的硬件定时器。通常有几种不同的硬件定时器可用于跟踪系统时间、生成波形、捕获输入和通用目的。如果嵌入式开发人员需要延迟,例如 10 微秒,硬件计时器可以加载表示 10 微秒的计数值。在这种情况下,定时器将被设置为一次性定时器。代码将启动计时器并等待设置计时器溢出标志,这将指示时间已过。

此代码的抽象版本可能如下所示:

这种技术比我们之前看到的条件循环要强大得多。它也更便携,可以更容易地调整到所需的延迟时间。事实上,API 可以在整个代码中重复使用,以允许将单个计时器用于所需的任意数量的延迟。

技术 #3 – 使用系统记号(HAL 示例)

可能存在专用硬件计时器不可用或不希望设置一次性计时器的情况。在这些情况下,开发人员可以利用板载系统滴答声来产生延迟。即使是裸机系统通常也有一个后台定时器,它充当系统滴答声,以便软件从微控制器启动的那一刻起就有一个时间参考。通常,这些系统滴答声在典型系统中设置为每 1 或 10 毫秒发生一次。

系统通常使用一些 API 允许开发人员访问当前系统时钟,例如 SysTick_Get()。开发人员可以利用它来创建类似于以下内容的延迟:

开发人员只需要确保如果他们做这样的事情,他们不会遇到计算问题或其他潜在问题,因此应该检查边界条件。

技巧 #4 – 使用 RTOS 屈服函数

在使用实时操作系统 (RTOS) 的更高级系统中,嵌入式开发人员可以利用内置的 RTOS API 调用来生成任务以产生延迟。例如,如果开发人员正在使用 FreeRTOS,他们可以在他们的任务中使用如下代码:

此延迟功能将导致任务在一个 RTOS 滴答声中产生当前任务。根据配置,RTOS 滴答声可以设置为 1 毫秒或 10 毫秒。使用这样的延迟机制可能会出现问题,因为该任务将在该时间段内产生 CPU,但不能保证一旦系统滴答期到期,该任务将成为最高优先级的任务!如果任务是准备好运行的最高优先级任务,则该任务只会在延迟后立即运行,因此延迟时间可能会有一些抖动。

技巧 #5 – 使用 RTOS 对象

我们今天要讨论的最后一个技术是使用其他 RTOS 对象来延迟时间。如果你仔细查看你最喜欢的 RTOS 中的信号量、互斥体和队列等对象的 API,你会注意到大多数等待的 API 调用也包含延迟时间。此延迟时间也可用于导致应用程序延迟。

与 RTOS 对象相关的是大多数 RTOS 还包括软定时器。这些是基于软件的定时器,由正在运行的硬件定时器触发。然后可以将与技术#2 和技术#3 中所示的技术类似的技术与这些软计时器一起使用,以在代码执行中产生延迟。

结语

有几种不同的技术可供想要延迟代码执行的开发人员使用,所使用的技术将取决于系统中可用的软件和硬件资源。然后,嵌入式开发人员可以决定他们想要使用的解决方案有多复杂。不过,归根结底,肯定有几种机制可以帮助将代码执行延迟定义的时间段。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信小程序

微信扫一扫体验

立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部