没有 while(1) 为什么 MPLAB 中的这段代码持续运行

问题描述

在这代码中,我没有使用 while(1),只有当它进入 'if' 条件时,它才会调用 TIMER_ISR 函数,该函数每 250 毫秒初始化一次。但是当它进入 else 条件时,没有任何计时器功能或任何东西,但为什么它会持续运行。

dbutils.fs.cp("file:/tmp/my-image.png",graph_path)

解决方法

如果问题是:在裸机 MCU 应用程序上从 main() 返回是否有意义,那么 TL;DR:没有意义,因为没有人可以返回。没有操作系统可以握住您的手 - 您的应用就是全部。

详细说明:

所有现代 MCU 都有一个称为“重置中断”的入口点。当您上电时,或者看门狗电路重置 MCU 之后,或者因为您在 MCU 复位引脚上有外部 /reset 信号时,您可能会在哪里结束。

然后程序计数器通过进入上电复位的中断服务程序(有时称为复位向量)来启动程序。从这里开始,设置 MCU 上最基本的东西,然后通常会调用“C 运行时”(CRT),这是特定于编译器的启动代码,用于初始化所有内存区域以启用标准 C 环境,例如初始化变量等。当 CRT 完成所有这些后,它会调用 main()

或者,如果您用汇编程序编写了所有内容,您就不必为 CRT 而烦恼,而是可以从重置 ISR 中调用您喜欢的任何函数。通常这是通过直接跳转而不是函数调用来完成的,不需要堆叠任何参数,因为您不希望永远返回。你只会不必要地浪费堆栈空间。

这就是为什么嵌入式系统中最常见的 main() 形式是 void main (void),而不是严格符合 C 的 int main (void) - 由于调用约定,后者可能会不必要地浪费堆栈空间。 (在 gcc 编译器上,始终使用 -ffreestanding 选择嵌入式“独立”系统作为目标。)

现在,如果您用 C 编写程序并从 main() 返回,您充其量会崩溃回到 CRT 代码中,如果幸运的话,某个好心人写了一个 for(;;){}在那里循环以捕获程序计数器。这在新手友好的环境中很常见。或者,您可以一路崩溃回到上电复位 ISR。

或者更有可能的是,如果 main() 被称为上述汇编方式(来自 CRT 或来自您的自定义代码),您会直接跳转到未知地址,因为没有保存返回地址。

从那里,程序计数器将在随机内存位置用完,开始执行它最终在内存中接下来遇到的任何内容,将这些单元格的内容解释为 OP 代码,无论它们是否如此 - 您获取“失控代码”,这是一种严重且危险的错误情况。它会一直这样做,直到它偶然发现导致硬件异常的东西,比如访问受保护的内存,或者直到看门狗重置所有东西,以防看门狗被启用。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...