cancel
Showing results for 
Search instead for 
Did you mean: 

Does main() require an infinite loop?

The BOOM
Associate III

This page says:

"With a custom main() on Arduino, do not return from main(). As there is no operating system running on a standard Arduino, there is no where to return to. If you do return, abort() is called, then exit(). On the AVR-8 MCU ( Uno, Mega ) this results in global interrupts being disabled and execution enters an infinite loop. To overcome the eventual return, you can utilize an infinite loop of your own, which is not unlike what the Arduino core does itself."

Does this same rule apply to the STM32 MCUs?"

thx

21 REPLIES 21
Uwe Bonnes
Principal III

What should the processor do after main? So yes, there should be an infinit loop.

chaaalyy
Senior II

Well... Indeed, that´s a very good question: Imagine an application, using the "main" just once for initializing everything and the rest is completely driven by interrupts. Absolutely no code in an infinite loop then...

The BOOM
Associate III

Exactly. i want only interrupts. How can i ensure interrupts will work, without using an infinite loop?

KnarfB
Principal III

The loop doesn't hurt. For power saving, you can put a __WFI() in the loop. In addition, there is a sleep-on-exit feature. The MCU then goes back to sleep after a interrupt handler exits.

Ok, but is the loop required for interrupts and other features to work, as it is on Arduino?

If you put the sequence (using HAL)

HAL_PWR_EnableSleepOnExit();
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);

in your code, this shall be the last line excuted. So no loop needed afterwards. Interrupt handlers are still running, no issue here.

But, there are exceptions: if you are using a debugger and press pause/break, you may well end up after that statement.

So, enclosing these statements in a while(1) {} loop adds 1 (!) machine instruction, an unconditional branch, to your code and you are on the safe side.

Great info!

"this shall be the last line excuted. But if you are using a debugger and press pause/break, you may well end up after that statement."

- i need to understand how a break can stop after the last line executed.

(Btw, which debugger works with STM32? I read that VSCode is a virtual debugger -- doesn't actually run on the device.)

"enclosing these statements in a while(1) {} loop adds 1 (!) machine instruction, an unconditional branch"

- You mean, the loop won't continue after the first iteration?

> i need to understand how a break can stop after the last line executed.

The MCU sleeps in the middle of the HAL_PWR_EnterSLEEPMode function and continues with the next machine instruction.

> (Btw, which debugger works with STM32?

I use STM32CubeIDE which integrates everything you need. The wiki has more info: https://wiki.st.com/stm32mcu/wiki/Main_Page.

> You mean, the loop won't continue after the first iteration?

No, the branch goes backwards (up in the source code) so it goes on and on...

I really recommend trying it out.

"No, the branch goes backwards (up in the source code) so it goes on and on..."

- So, your `HAL_PWR_` code will not stop the while loop from iterating?

If that's true, then why is the `HAL_PWR_` needed? To prevent breaking on the wrong line? i thought that's only a risk if we don't have the while loop.

If i'm understanding (i prolly don't), if we're going to use a while loop, then there's no benefit from the `HAL_PWR_` code.