嵌入式C编程语言中的“Super Loop”是什么?

5

嵌入式C编程语言中的Super Loop是什么?


服务所有请求的无限循环。 - Haris
这是一个无限循环,任务按顺序调用。 - LPs
首先,C编程语言就是C编程语言。无论你的目标是小型嵌入式系统还是大型超级计算机,都没有特殊的“嵌入式C编程语言”,只有纯粹的C语言。至于“超级循环”这个术语,你从哪里听说的?在哪里读到的?在C语言中并不常见。你尝试过搜索它吗? - Some programmer dude
10
不必对原帖进行“跟风抱怨”,对于那些具有领域知识的人来说,该术语是众所周知的,因此不需要澄清。如果您没有听说过它,那可能是因为您没有足够的领域知识来回答标记为嵌入式系统的问题。去寻找其他标签吧。参考链接:https://en.wikibooks.org/wiki/Embedded_Systems/Super_Loop_Architecture. - Lundin
1
@Someprogrammerdude,C语言有一个技术报告(ISO/IEC TR 18037:2008),用于支持嵌入式处理器的扩展。 - user7881131
5个回答

14

这指的是通常位于“裸机”系统(没有操作系统)的main()函数中的无限循环,因为这样的系统永远无法从主函数返回。一个典型的裸机嵌入式系统看起来像这样:

void main (void)
{
  // various initializations

  for(;;) // "super loop" or "main loop"
  {
    // do stuff
  }
}

8

MCU是一种设备,当电源开启时会持续运行或执行指令(通常情况下)。

因此,使用while循环可以强制MCU执行某些操作,即使循环为空,它也会一直循环执行。

但是它必须做一些事情,因为它不同于PC程序,在主函数末尾有“return”语句。

如果没有“超级循环”,那么MCU可能会从FLASH/RAM(随便哪个..)获取指令并执行一些愚蠢的操作,因为MCU不知道它正在执行什么。它只会执行您提供给它的代码。

通过使用超级循环,您可以确保MCU不会无法控制地执行一些指令,可能会进入故障安全区域。当然,即使您有超级循环,这种情况也可能发生,但这是另一个话题。

int main() {
    //Init if you have something
    while (1) {
        //DO stuff always
    }
    return 0; //This should never happen!
}

循环可能是为什么int main()对于大多数编译器来说是不正确的形式的原因。大多数编译器(例如gcc)在编译自由系统时使用void main(void) - Lundin
它并不是错误的,只是看起来有点奇怪。但这并不意味着它不正确。 - ringbuffer_peek
当从“CRT”启动代码调用main()时,它将生成错误的调用约定,无意中消耗额外的堆栈内存。所以是的,在我知道的任何独立系统上都是不正确的。 - Lundin
我有点相信静态代码分析工具,认为使用 int main 不是错误的做法。大多数编译器都知道(即使 gcc 也很聪明),如果你在没有返回语句的情况下使用 int main,它不会给出警告。 - ringbuffer_peek
@Lundin 当我使用 void main 时,在GCC中会收到警告*Return type of main is not int [-Wmain]*。 - ringbuffer_peek
GCC默认使用托管系统编译器。您需要为独立系统进行编译,使用-ffreestanding选项。总的来说,在主函数格式方面,对程序员进行了大量洗脑。就标准而言,该格式实际上非常灵活。https://dev59.com/7HVC5IYBdhLWcg3wtzkQ#31263079 - Lundin

0

超级循环是一个无限循环,仅适用于嵌入式C编程,因为您必须长时间运行代码,并希望在机器人或其他设备的行为发生变化时明确终止。

超级循环就像这样

while(1){

// Your code

// exit condition

}

for(;;) {

}

1
你的 'while' 循环看起来像一个超级循环,除了没有退出。在你的示例中奇怪的 'for' 循环捕获超级循环退出后的控制流是不必要的,因为嵌入式设备中的超级循环通常不会退出。 - Tammi

0

超级循环(或超级循环)是嵌入式实时固件开发人员经常选择的设计模式,特别适用于非常小的系统(尤其是“裸机”系统),其中简单性是重要的设计目标。

超级循环(“超级”在拉丁语中意为“以上”)是程序的顶层循环。一个特别简单的实现可能看起来像这样:

int main() {
    initializeGlobalState();
    while (1) {
        sampleInputs();
        updateGlobalStateBasedOnNewInputs();
        updateOutputs();
    }

    // can't ever get here but the compiler may require a `return` statement.
    return 0;
}

简单是目标,但模式允许小的复杂性。例如,可以实现一个基本的优先级方案:

initializeGlobalState();
while (1) {
    sampleHighPriorityInputs();
    if (updateStateBasedOnNewHighPriorityInputs()) {
        updateOutputs();
        continue;
    }
    sampleOtherInputs();
    updateGlobalStateBasedOnNewOtherInputs();
    updateOutputs();
}

可以进行调度:

initializeGlobalState();
while (1) {
    timeNow=readFreeRunningTimer();
    sampleInputs();
    updateGlobalState();
    if (timeNow > task1_dueDate) {
        doTask1();
        task1_dueDate += task1_fixedPeriod;
    }
    if (timeNow > task2_dueDate) {
        doTask2();
        task2_dueDate = computeTask2DueDateBasedOnGlobalStateOrInputs();
    }
    ...
    updateOutputs();
}

可以通过减缓速度来节省电力:

initializeGlobalState();
enableHeartbeatInterrupt();
while (1) {
    ...
    WAIT_FOR_INTERRUPT;
}

还有可能出现其他的复杂情况,但超级循环的缺点是,如果您尝试添加太多的超级循环,它会变得笨重而脆弱。当这种情况发生时,开发人员可能会希望他们已经在实时操作系统和/或应用程序框架上构建了该项目。


0
超级循环:它可以说是一个无限循环,使得架构固件代码变得更简单。主要包括读取输入、处理输入数据和设置输出。
  • 它不运行在RTOS或操作系统上,即没有调度或异步代码任务的机会。
代码片段: if ((uint8_t)(cur_tick_ms - last_print_time_ms) >= 100) { printf("Print time! curr_tick_ms = %i\n", cur_tick_ms); last_print_time_ms = cur_tick_ms;}``

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接