微控制器与现代 CPU 的无限循环

电器工程 Arduino 微控制器 avr 中央处理器
2022-01-07 22:19:02

在微控制器上(更具体地说,在使用 ATmega 328P 微控制器的 Arduino Uno 板上)我通常会使用无限循环来检查输入等(在 Arduino 领域,这通常是loop()功能)。但是,如果我将此功能留空,则不会引起任何问题。

在具有 Intel i7 CPU 等的台式机/笔记本电脑上,如果我运行类似的无限循环(无事可做或几乎无事可做),它会将 CPU 固定在 ~100% 并且通常会启动风扇等(延迟可能例如添加以防止这种情况)。

为什么这在微控制器上看起来不错,但在微处理器上通常不需要?我认为 ATmega 实际上以 100% 的速度运行,并且因为它的功率如此之低,它不会引起任何明显的热问题,我是否正确?

4个回答

为什么这在微控制器上看起来不错,但在微处理器上通常不需要?

出于同样的原因,它在微控制器上也是不需要的:它浪费电力。

我认为 ATmega 实际上在 100% 运行是对的吗

正确的。

那是因为它的功率很低,不会引起任何明显的热量问题吗?

正确的。但是,如果您使用电池运行微控制器,那么您必须认真考虑不浪费电力。在像 AtMega328P 这样的微型 CPU 上,它不会引起发热问题,但肯定会缩短电池寿命。

所有的 CPU,无论是台式机还是微型微控制器,都使用相同的方法:

1-降低时钟速度或电压。

2-关闭不需要的硬件。

3-进入睡眠并在事件中唤醒(这是关闭不需要的硬件的特殊情况,在这种情况下,cpu 已关闭)。

在 AtMega328P 中,您也可以实现这一点。如果您不需要 8 位内核的所有强大功能,您可以使用较慢的时钟,您可以关闭不需要的外围设备……最重要的是睡眠模式。

您应该阅读手册了解详细信息,因为有几种睡眠模式在唤醒延迟、哪些外围设备保持在线并能够唤醒 cpu、RAM 数据是保存还是丢失等方面有所不同。但基本上这个想法是:当在睡眠模式下,cpu 会停止,因此它使用的电量要少得多。当发生中断时,这会唤醒 CPU 并处理中断。

当然,您必须使用正确的睡眠模式并对其进行正确配置,以便需要唤醒 cpu 的外围设备(例如,定时器或 GPIO 中断)不会关闭。如果一切都关闭了,您将不得不使用 NMI 甚至重置来唤醒它,在后一种情况下,通过重新启动它。

如果您的应用程序所做的只是等待中断,例如:

  • 引脚更改中断 (PCI) 以检测按钮按下或传入信号

  • 定时器

  • UART 或 USB 接收数据

  • 等等

然后你不需要旋转主循环。在启动时配置完所有内容后,您将使用“进入睡眠”指令启动主循环。下一条指令将在 cpu 唤醒后执行,处理所有挂起的中断,并返回主循环。然后,如果需要,主循环可以对接收到的事件做一些事情,如果它们没有完全由中断代码处理......然后回到睡眠状态。

即使您不使用电池,具有低待机电流的电源也可以为开关电源供电以跳过周期并浪费更少的电力。

在微控制器上(更具体地说,在使用 ATmega 328P 微控制器的 Arduino Uno 板上)我通常会使用无限循环来检查输入等(在 Arduino 领域,这通常是 loop() 函数)。但是,如果我将此功能留空,则不会引起任何问题。

经典的编程模式,有一个主循环......

在具有 Intel i7 CPU 等的台式机/笔记本电脑上,如果我运行类似的无限循环(无事可做或几乎无事可做),它会将 CPU 固定在 ~100% 并且通常会启动风扇等(延迟可能例如添加以防止这种情况)。

…我们可能正在编写不同的主循环。

同样的主循环在微控制器上也是不好的做法,因为这也会在满负载下运行 CPU ——这会消耗电力。不要那样做,尤其是在你使用电池的情况下。

现代 CPU 内核具有同步机制。这允许人们实现类似“让这个循环的执行休眠直到 1 毫秒过去,或者直到这个条件改变”之类的东西。

这基本上是任何多任务操作系统的核心——基本上所有配得上这个名字的操作系统现在都是。在微控制器上,您经常会发现所谓的 RTOS(实时操作系统),它可以保证您在多少纳秒后开始执行某项操作,因为这是典型的用例微控制器,而在台式机和服务器 CPU 上,您通常会发现成熟的同时多处理操作系统,它们对时间的保证较少,但提供了更大的功能集以及硬件和软件环境抽象。

我对 Arduino 执行环境的了解还不够好,无法对其做出合格的陈述,我正在研究这一点,因为我写道:Arduino 似乎不是为此而设计的——它真的希望你只是忙着旋转。由于它没有“yield”功能,因此当您使用内置函数loop时,无法调用它在调用之间所做的“家务管理” 。delay啊! 糟糕的设计。

你会在功耗和/或延迟感知设计中做什么,你会为你的微控制器使用 RTOS——FreeRTOS 非常流行,对于 ARM Cortex-M 系列,mbed 有很大的吸引力,我个人喜欢 ChibiOS (但我认为从 Arduino 草图切换时这不是一个好的选择),Linux 基金会正在推动 Zephyr(我对此很矛盾);确实,有很多选择,您的微控制器制造商通常通过他们的 IDE 支持一个或多个。

为什么这在微控制器上看起来不错,但在微处理器上通常不需要?

这不是真的,这是一种不寻常的设计模式,事实上,对于微控制器来说,它通常会定期做事或对外部刺激做出反应。您通常不希望在微控制器上连续“使用尽可能多的 CPU”。

这种模式也有例外,它们既存在于 MC​​U 中,也存在于服务器/桌面处理器世界中;当您知道您实际上总是有例如网络数据要在交换机设备中处理,或者当您知道您的游戏总是可以预先计算一些您可能需要或可能不需要的世界时,那么您会发现这些自旋循环。在某些硬件驱动程序中,您会发现“自旋锁”,这意味着 CPU 会不断查询一个值,直到它发生变化(例如,硬件已完成设置并且现在可以使用),但它通常只是一种紧急解决方案,并且例如,在尝试将此类代码导入 Linux 时,您必须解释为什么要这样做。

我认为 ATmega 实际上以 100% 的速度运行,并且因为它的功率如此之低,它不会引起任何明显的热问题,我是否正确?

是的。按照现代标准,ATMega 并不是低功耗的,但它的低功耗足以让热量不会成为问题。

我认为 ATmega 实际上以 100% 的速度运行,并且因为它的功率如此之低,它不会引起任何明显的热问题,我是否正确?

是的,它通常一直以 100% 的速度运行,但功率太低,不会显着升温。

在具有 Intel i7 CPU 等的台式机/笔记本电脑上,如果我运行类似的无限循环(无事可做或几乎无事可做),它会将 CPU 固定在 ~100% 并且通常会启动风扇等

CPU 的时钟速度越快,它消耗的功率就越多,因为每次逻辑电平发生变化时,它都必须为栅极中晶体管的电容充电。现代 CPU 旨在尽可能快地运行 - 实际上比可能的更快即使在使晶体管尽可能小、使用尽可能低的电压并应用巨大的散热器之后,它们仍然无法以足够快的速度运行以满足 PC 用户的“速度需求”。因此,他们依赖于操作系统和应用程序花费大部分时间等待事情发生(用户输入、外围硬件等)的事实。

如果您尝试以最大频率连续运行 i7 中的所有内核,它会崩溃。为了防止这种未使用的核心被关闭,当不需要最大速度时(即大部分时间),活动核心以较低的频率运行。空闲时,操作系统不仅会运行一个繁忙的循环来连续执行指令,而且还会在等待中断等时使 CPU 进入减速或停止状态。CPU 的各个部分也可以在不使用时关闭。

ATmega 还可以进入低功耗模式,并在不需要时关闭各个外围设备。如果将系统时钟更改为较低的频率(例如 32.678 kHz)并关闭所有不必要的外围设备,则它可以(缓慢地)以几微安的电流运行 - 不是为了降低温度,而是在小电池上持续更长时间。

也可以“超频”许多 Atmega 芯片。我在 30MHz 下运行了一个 ATmega1284p(在 5V 时最大额定 20MHz),它工作得很好,但是很热。

取决于您的 ATmega 系统是使用交流壁式电源还是小型电池。

关闭交流电(通过壁式电源),100% CPU 使用自旋回路消耗的功率低于水电费变化的本底噪声。除非在超级绝缘的环境中,否则散热很可能太小以至于不需要散热器或风扇。可以用红外温度计测量。

使用小型电池,Arduino 旋转回路将对您更换或充电这些电池的频率产生重大影响。也许是几个小时而不是几个月。如果访问您的嵌入式系统很困难,这是一个严重的问题。一种常见的解决方案是在无限循环内使用某种定时的低功耗睡眠模式,或睡眠模式加上来自某个外部源的唤醒中断。