Go Down

Topic: while(1){} - whaaaaaaat??? (Read 6139 times) previous topic - next topic

wossname

I've seen things like while(1){} used at the end of the loop() function.  Doesn't that just hold the CPU at 100% usage and make it waste battery power?

Or does the compiler notice what is going on and just do something sane instead? I need to know because I'll lose sleep otherwise.

maniacbug

I think the CPU is always using the same amount of power, unless you put it in sleep mode, which is rarely done.

Stylistically, "while(1){}" at the end of loop is a little silly.  The stuff before it should just be in setup() and then loop() should be empty.

wossname

#2
Mar 10, 2011, 08:54 pm Last Edit: Mar 10, 2011, 08:56 pm by wossname Reason: 1
But hang on, if the compiler tells the chip to repeatedly run the contents of loop() once it's finished running setup() then doesn't the same problem exist?  Doesn't the chip just run loop() as fast as it can while not actually getting anywhere?

Let me put it another way... an empty loop() function is basically supposed to represent some dormant state where the CPU is not executing instructions, is that right?  Or will it still be spinning it's wheels relentlessly running while(1) {loop();}?  Lets not forget that it takes energy to do things like increment the instruction pointer and check registers and so forth.

That seems like a "busy wait" to me, which I've always been taught (in my experience as a windows/linux programmer) is a VERY bad thing indeed.  I doubt the Arduino developers would allow this.  So something else must be happening -- a special case for "loop(){}" perhaps -- that I've not seen in the documentation anywhere.

I could be making too many parallels with Intel x86 programming here so my understanding of such things is limited, just trying to fill in the gaps :)

maniacbug

#3
Mar 10, 2011, 09:03 pm Last Edit: Mar 10, 2011, 09:27 pm by maniacbug Reason: 1
In Linux and Windows, we have to think about the other processes running, and interact with them in a nice way.  On Arduino, there's nothing else for the processor to do, other than what we tell it to do.  (Leaving interrupts out of the picture for the moment.)

From my understanding, a "while(1);" loop doesn't take any more or less energy than anything else the AtMega could be doing.  It's not like it has active power management or things like that.

If you want to actually consume less power when doing nothing, I believe you have to put it to sleep.  And from what I've read, that's pointless on a stock Arduino board because the voltage regulator continues to take a ton of power.

nickgammon

Yes, either way the CPU is madly "doing nothing". But you could argue that testing a button for a press is 99.99% of the time "doing nothing".

Since this is a not a multi-processing system there is no particular harm, apart from using the battery (if battery powered). And as maniacbug said, there are ways of putting it to sleep (to wake after time elapses, or an interrupt).

But the thing is, whereas in Windows or Linux this is a Very Bad Thing, it doesn't apply here. The reason being that you aren't trying to run other processes at the same time. For example, if writing a game in Windows, you don't pause the game by looping in a CPU loop for a second, because during that time you can't respond to keypresses, move things around on the screen etc.

But with a microprocessor? Unless there is something else you want to do, it may as well loop in a tight loop as do anything else.
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

nickgammon


  And from what I've read, that's pointless on a stock Arduino board because the voltage regulator continues to take a ton of power.


Good point. On another thread I think we tested the difference between a sleeping and running Arduino, and it only reduced power consumption from about 55 ma to 42 ma. The difference was the LED, the voltage regulator, the USB management chip etc.

If you were doing something "in the field" where battery consumption was important you would probably use a "bare bones" processor (eg. no USB chip) and make it sleep as much as possible (eg. wake every minute to take a measurement).
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

gardner

#6
Mar 10, 2011, 09:18 pm Last Edit: Mar 11, 2011, 09:39 pm by gardner Reason: 1
Yes, loop() is called over and over, with no condition, wait or other intervening code.
There are a couple of good reasons to halt the CPU: to reduce digital noise during A2D, to reduce power.  I often throw in a halt at the end of my main loop:

Code: [Select]
#include <avr/sleep.h>

setup()
{
  :

 /* enable subsequent sleep operations
  */
 set_sleep_mode(SLEEP_MODE_IDLE);

  :
}


loop()
{
  :
  :

 cli();
 if (my_wakeup_condition_is_not_true) {
      sleep_enable();
      sei();
      sleep_cpu();
      sleep_disable();
 } else
       sei();
}


This is bound to be woken up at least by the millis() timer, so it doesn't change how the sketch runs for the most part.  Mine tend to be interrupt driven, so it makes no difference at all.   It's not really all that useful, but it makes me feel better to know that I am not wasting all the CPU power.

Please note that I had omitted the sei() that re-enables interrupts when I first posted this -- I failed to copy it from the source program.

cmiyc

Quote
Doesn't that just hold the CPU at 100% usage and make it waste battery power?


As others have noted, microcontrollers just run in a loop.  In fact, unless you explicitly tell them to go to sleep, they just keep doing whatever you tell them to do.

The reason I am posting is because you have made an assumption in your statement which may not hold true for code you are looking at.  The comment "waste battery power."   That is an assumption, which can be dangerous.

Just because you might intend to use battery power in your application, do not assume that code you are looking at from others are going to as well.  (Obviously, this applies to more than just while(1); loops.)
Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.com

hobbified

On a semi-related note, does anyone know if there's any reason why the Arduino IDE prevents loop() from being declared inline? Done right, it should save several microseconds per loop (function call overhead, and stack-manip overhead if loop uses no non-static vars), which could make a real difference on tight loops. As it is, people who want this have to write their own while(1) loop inside of loop().

cmiyc

You might be interested in this excellent analysis done by westfw:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1283329855
Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.com

mowcius

Quote
On a semi-related note, does anyone know if there's any reason why the Arduino IDE prevents loop() from being declared inline? Done right, it should save several microseconds per loop (function call overhead, and stack-manip overhead if loop uses no non-static vars), which could make a real difference on tight loops. As it is, people who want this have to write their own while(1) loop inside of loop().

Well setup{} and loop{} are defined within the standard main{} and if I remember correctly, loop{} is within a while(1){} function. You could go modify this if you wanted. I am tempted to just start using main{} again rather than setup{} and loop{}.

wossname


The reason I am posting is because you have made an assumption in your statement which may not hold true for code you are looking at.  The comment "waste battery power."   That is an assumption, which can be dangerous.

Just because you might intend to use battery power in your application, do not assume that code you are looking at from others are going to as well.  (Obviously, this applies to more than just while(1); loops.)


Bad code will still be bad code regardless of it's power source.  It just seemed easier to describe my question in terms of batteries that's all.  Thanks for your input.



Anyways, if it's generally not considered a bad thing to let the chip sit there keeping itself nice and warm then that's fine by me. :)  However, I'll certainly be using the "halt" method kindly outlined by Gardner above, thanks for that tip :)

cmiyc

Quote
if it's generally not considered a bad thing to let the chip sit there keeping itself nice and warm then that's fine by me.


It comes from history.  Microcontrollers are typically controlling things which require continuous input, output, or actions.  So historically, you don't find many microcontrollers halted.  Generally, there is something they could be doing.

Keep in mind I'm talking about the fine line between a Microcontroller (such as the ATmega328 which the Arduino is based on) and a Microprocessor. 
Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.com

Go Up