Does the AVR chip on Arduino Uno constantly run instructions?

Go To Last Post
67 posts / 0 new

Pages

Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Lets say I write my own code and not use the `C` template Arduino provides, I won't have a loop in mine and just return:


int main(){
 return 0;

}

 

In this case, does atmega328p come to a halt or there are other instructions it's executing? if so what are they?

Last Edited: Wed. Jul 1, 2020 - 05:16 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It depends on your crt0.  I use gcc+avr-libc which executes _exit after main.

_exit seems to disable interrupts and then spin:

 

000002bc <_exit>:
 2bc:   f8 94           cli

000002be <__stop_program>:
 2be:   ff cf           rjmp    .-2             ; 0x2be <__stop_program>

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Unless you remove power or put them into a "sleep" mode, all microcontrollers are always executing instructions.

 

EDIT

 

See the 2nd point in this post: https://www.avrfreaks.net/commen...

 

EDIT 2

 

I guess 3 other ways to stop a microcontroller executing instructions (when powered-up & not asleep) would be:

  1. Keep RESET asserted;
  2. Remove the clock;
  3. Halt the processor using a debugger.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Wed. Jul 1, 2020 - 04:44 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:

Unless you remove power or put them into a "sleep" mode, all microcontrollers are always executing instructions.

 

 

What sort of instruction would it be running, another loop?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Any instructions it can find!

 

Whatever the PC (Program Counter)  is pointing to

 

EDIT

 

For example, in compilers which don't have the "catcher" at the end of main(), it could just run off through the entire Flash space fetching whatever it finds and executing that as instructions ...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Wed. Jul 1, 2020 - 04:48 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is not specific to AVR or Arduino - it applies to any microcontroller.

 

(in fact, not even just to microcontrollers - any computer at all!)

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:
This is not specific to AVR or Arduino - it applies to any microcontroller

(in fact, not even just to microcontrollers - any computer at all!).

 

I thought in a computer OS there are always programs running, else the OS would go into a halt until an interrupt occurs?

 

So on MCUs it just fetches random instructions?

Last Edited: Wed. Jul 1, 2020 - 05:09 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avruser1523 wrote:
go into a halt

which means either some sort of "sleep" state, or just a spin loop.

 

So on MCUs it just fetches random instructions?

No, not "random";  the CPU always behaves deterministically - it fetches whatever the PC is pointing at.

 

The CPU neither knows nor cares anything about "main()" - it just fetches from memory, and executes.

 

Again, not specific to microcontrollers.

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Wed. Jul 1, 2020 - 05:10 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avruser1523 wrote:

I thought in a computer OS there are always programs running, else the OS would go into a halt until an interrupt occurs?

 

So on MCUs it just fetches random instructions?

 

What do you mean, "go into a halt"? Some architectures do have "halt" or "sleep" instructions that will stop execution in a number of ways that are architecture or even implementation specific. But often it will just be a wait loop.

 

And yes, it will fetch whatever the PC is pointing to. On a MCU this will probably be uninitialized flash 0xFF 0xFF ...

This may either be a valid opcode, wich will be executed, or invalid, which may do a number of things. On the AVR I think invalid opcodes just execute as NOP, on more complex architectures it will probably generate some kind of exception interrupt.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Right but, what drives the address in PC, i.e who changes what PC is looking at? that should be driven from something.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 2

avruser1523 wrote:

Right but, what drives the address in PC, i.e who changes what PC is looking at? that should be driven from something.

 

Its automatically incremented by the main CPU clock, or it may be changed by branch instructions. This is a basic way most (all?) CPUs operate.

See https://en.wikipedia.org/wiki/Program_counter

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


 

avruser1523 wrote:
what drives the address in PC

For the AVR, this is documented for each instruction in the Instruction Set Manual:

 

http://ww1.microchip.com/downloads/en/devicedoc/atmel-0856-avr-instruction-set-manual.pdf

 

Similarly for other processors

 

EDIT

 

Example of a branch:

 

 

and a CALL:

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Wed. Jul 1, 2020 - 05:42 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


there's also info in the Datasheet; eg,

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Not sure if this is what you're asking but Arduino has hidden code that runs behind your back.

// the "int main()" below is implicit in Arduino
// but is shown here EXPLICITLY by UnoArduSim
int main()
 {
   setup();
   while(true)
    {
       loop();
       serialEventRun();
     }
   return 0; // never reached
 }

I believe this keeps calling the  loop()  and serial() check.  The code explanation is from a simulator I found online. Is it valid?... IDK.

https://www.sites.google.com/site/unoardusim/services

The sim is updated periodically.

 

I reserve my right to assemble!
Brawndo's got what plants crave... It's got electrolytes!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The CPU neither knows nor cares anything about "main()" - it just fetches from memory, and executes.

 

Back in the very early 80's, in science, we had a computer that came with optional $$$ roms for extra features like statistical commands, math functions, tape drive (!) control, etc.  You could not enter, or even load a program using these things unless the required optional roms were installed.  Of course, we'd try the opposite...we'd load our running programs and then yank out the roms to see what would happen.  Usually some form of mayhem!  I'm surprised we didn't destroy the whole system.   Some other student got detention just for printing out bad words.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Thu. Jul 2, 2020 - 07:27 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The fact that a microcontroller is always running is one of the reasons that Arduino implemented the "loop()" function instead of just using "main()"...

 

With avr-gcc, if main() returns, the processor will go into another loop as shown in reply #2.

I suppose it could go into a deep sleep mode, but that would require more code, be chip-specific, and be equally unlikely to be what the programmer had in mind.

 

What do you think you WANT to do on a microcontroller, if main() returns?  What should happen to the state of any output pins, for example?

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

westfw wrote:

 

What do you think you WANT to do on a microcontroller, if main() returns?  What should happen to the state of any output pins, for example?

 

 

I would assume it either goes to sleep or an infinite loop until and interrupt occurs.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avruser1523 wrote:
I would assume it either goes to sleep or an infinite loop until and interrupt occurs.

 

That would require configuration - what wakes it from sleep? What interrupt source is configured? What would happen if the PC got corrupted? 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avruser1523 wrote:
...  until and interrupt occurs.

and what would you expect to happen when that interrupt occurs ?

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As pointed out above, the point of a microcontroller in particular but any processor in general is that there is always an outermost

while (true);

or equivalent. You should _never_ return from a top level program on a microcontroller (except perhaps to a debugger, and in development). Anywhere it looks like a program finishes, it almost always means that the said program has handed control back to another supervising program - whether that's e.g. an RTOS or Windows or Linux operating system. The operating system never returns anywhere...

 

Neil

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

By a complete coincidence someone asked something almost identical yesterday so my explanation of what happens (but only in avr-gcc) for AVR if you return from main() is at:

 

https://www.avrfreaks.net/comment/2949281#comment-2949281 (his 3rd question)

 

and, no, as others have said it does not "SLEEP". If it were going to SLEEP there'd have to be some mechanism to wake it up, one requirement of that is that interrupts are enabled but as you'll see in my link the very first thing that happens after you leave main() is CLI. Anyway if it were to SLEEP and have some potential wakeup mechanism hat would be the point? Once you have left main() the show is over. Apart from a CPU reset there's no coming back from the deep hole you just jumped into.

 

As I stated in that other thread my graphic signature (only visible in PC browser not mobile/tablet) has a "FAQ#2 entry" for this very reason - when a program is not being run from an operating system (like in Windows or Linux etc) then if you return from main() there's nowhere for it to go to. Nothing is going to take back control and consider running the "next program" as in Win/Linux. All you have is a "loop: RJMP loop" to prevent it running off through flash interpreting all the rubbish bytes as opcodes.

Last Edited: Thu. Jul 2, 2020 - 09:18 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
Anyway if it were to SLEEP and have some potential wakeup mechanism hat would be the point

 

It would be not to waste power executing an infinite loop like "while(1)"?

 

on x86 bases Operating systems this usually happens with the "HLT" instructions, sleep until interrupted. So Microcontrollers usually don't have this capability? hence the only thing to do is go in an infinite loop?

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avruser1523 wrote:
It would be not to waste power executing an infinite loop like "while(1)"?
But an Arduino is connected to a PC to get power. Exactly how much difference in power consumption do you think a few mA in an Arduino matters compared to the consumption of your average PC?

 

Sure, if AVRs are battery powered and especially when they are powered from low capacity batteries then consumption is a "thing" but i such cases the system designer will have designed the hardware and the software from the ground up as power sensitive and the main() code they write will inevitably have been designed to spend as much of its time as possible SLEEPing to conserve power. One thing it most definitely will not be doing (like all good embedded apps) will be returning from main(). The sleep() support will be inside the while(1) loop of main() - with ISR()s adjacent to act as the infrequent wake up soource.

avruser1523 wrote:
on x86 bases Operating systems this usually happens with the "HLT" instructions,
Apart from closing the lid on your laptop when do you think it ever fully "sleeps" ??

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If one wants to reduce power, then putting the processor to sleep within the main() function (and generally within the while(1) loop) would be how that is handled. However, as has been emphasized upon exit from main the processor just sits in an infinite loop and the only thing that might cause it to do something else would be if the watchdog timer was enabled and initiated a watchdog reset.

David

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

Apart from closing the lid on your laptop when do you think it ever fully "sleeps"

Really never, there are always things to run but the capability is there:

https://en.wikipedia.org/wiki/Idle_(CPU)

 

So i'm assuming if manage to remove the outermost "while(1)" and return from main, PC will start interpreting Flash data as opcodes (as you said) and crash and restart perhaps?

Last Edited: Thu. Jul 2, 2020 - 02:07 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avruser1523 wrote:
So i'm assuming if manage to remove the outermost
Easy to do, just check -nostdlib to prevent linking in the startup & default libs.

But why would you want to

avruser1523 wrote:
crash and restart
???

David

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

frog_jr wrote:

???

 

On a regular OS you would a get an "illegal instruction" and program would be killed. I thought on an MCU chip would just reset/restart upon getting an illegal instruction?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avruser1523 wrote:
PC will start interpreting Flash data

PCs don't run from flash!

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:

PC

Here PC was referring to the Program Counter on the MCU.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avruser1523 wrote:
On a regular OS you would a get an "illegal instruction" and program would be killed.

No, in the microcontroller world, its a much kinder, gentler reforms for such offensive behavior!  it just sits in the corner and twiddles it thumbs until bed time.

 

 

FF = PI > S.E.T

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avruser1523 wrote:
I thought on an MCU chip would just reset/restart upon getting an illegal instruction?

What made you think that?

 

It would depend on the particular MCU in question.

 

On very small MCUs (eg, 8-bitters), there are often no gaps in the instructions set - so there is no such thing as an "illegal instruction" per se.

 

On Cortex-M, an illegal instruction will cause a Hard Fault, which gets handled by the Hard Fault Handler - which is just more code.

 

eg, see:  https://interrupt.memfault.com/blog/cortex-m-fault-debug - look for "UNDEFINSTR"

 

Summary:

 

 you have to RTFM for the specific controller(s) in question.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Thu. Jul 2, 2020 - 02:34 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:

avruser1523 wrote:
PC will start interpreting Flash data

PCs don't run from flash!

 

avruser1523 wrote:
Here PC was referring to the Program Counter

That still makes no sense.

 

The Program Counter - as its name suggests - is just a counter; it does not interpret anything.

 

It just tells the CPU where to do the next instruction fetch.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:
It just tells the CPU where to do the next instruction fetch.

That's what I meant.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

but it's not what you said!

 

if you want to get into these fine details, then you need to learn to describe things clearly and precisely.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:
PCs don't run from flash!

 

Well, actually the BIOS code does.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avruser1523 wrote:
on x86 bases Operating systems this usually happens with the "HLT" instructions, sleep until interrupted. So Microcontrollers usually don't have this capability? hence the only thing to do is go in an infinite loop?

No one said that.  Search your thread replies for " SLEEP".

 

awneil wrote:
Unless you remove power or put them into a "sleep" mode,

awneil wrote:
which means either some sort of "sleep" state

El Tangas wrote:
What do you mean, "go into a halt"? Some architectures do have "halt" or "sleep" instructions that will stop execution in a number of ways

westfw wrote:
I suppose it could go into a deep sleep mode,

 

So what does an AVR SLEEP node do?  Maybe -- stop until interrupted?

 

It seems some datasheet work would be helpful.

 

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There is a lot of nibbling around the edges, here. Lets lay it on the line, so to speak:

 

(1) Normally (that is, if a C compiler is involved), the micro will spin in a loop on returning from main().

 

(2) You COULD put it to terminal sleep, but few programmers try to do that; not much point that I can see.

 

(3) You COULD put it to interruptible sleep, but many programs do that as a normal part of operation and you don't have to fall off the end of main() to do that.

 

(4) What a C program does in desktop environments is not relevant. 

 

(5) Microcontrollers, at least of the modern kind, generally do not have a HALT (or equivalent). 

 

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avruser1523 wrote:

It would be not to waste power executing an infinite loop like "while(1)"?

on x86 bases Operating systems this usually happens with the "HLT" instructions, sleep until interrupted.

So Microcontrollers usually don't have this capability? hence the only thing to do is go in an infinite loop?

You seem to assume/expect  a MCU is clairvoyant, yet you say a x86 needs an explicit instruction ?

 

MCUs are the same, they need to be told by user, who wants them to go into a lower power mode, exactly what to do.

 

MCUs do have many choices for lower power, but you need to decide which to use  :

  •  They can slow down the SysCLK, which keeps SW alive, but running slower - that saves power.
  •  They can cease opcode fetch,  but wait for an interrupt. Here, all enabled peripheral CLKs are usually active.
  •  They can cease opcode fetch, and shut down peripherals, running just a low power wake-up timer, or a Real Time Clock peripheral
  •  They can cease opcode fetch, and shut down peripherals, and all timers, ie totally halted until the user or something external intervenes

 

ka7ehk wrote:
(5) Microcontrollers, at least of the modern kind, generally do not have a HALT (or equivalent). 

Even that varies, plenty of MCUs have a setting that completely stops all clocks, until a pin changes (can be RESET pin, or some can wake on pin change). I'd call that a HALT.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I guess what he is arguing for is that the catching spin-loop should always setup to and then invoke SLEEP rather than just "loop: rjmp loop"ing ?

 

My argument would be that not everyone who wants to build a C program for an AVR necessarily wants the added code required to do this eating their flash. There is the most minimal catch (in avr-gcc) possible. Two opcodes, a CLI and an RJMP. If a particular user wants more it's up to them to provide it. The obvious would be:

int main(void) {
    //stuff
    
    //not sure why I'm doing this but I'll let it fall-through...
}

changed to:

#include <avr/sleep.h>

int main(void) {
    //stuff
    
    //if I get here I'm all done so...
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    cli(); // will never wake up
    sleep_mode();
}

So it's up to a user to do this if they want.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ka7ehk wrote:
(1) Normally (sic?)  (that is, if a C compiler is involved), the micro will spin in a loop on returning from main().

Is that true?

 

(Genuine question - I haven't done a study, so I don't know)

 

As Cliff has already mentioned, there was a point at which that was removed from GCC - was that to make it more "normal", or did that make it "unusual" ... ?

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:
As Cliff has already mentioned, there was a point at which that was removed from GCC - was that to make it more "normal", or did that make it "unusual" ... ?
It was an accident as someone didn't think through the consequences. I am pretty sure all the AVR compilers now provide a "catch" after main() though I'm not so sure about weird things like MikroC.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
I am pretty sure all the AVR compilers now provide a "catch" after main()

It does seem the reasonable thing to do.

 

Also wondering about non-AVR compilers ...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just to be pedantic but it's not exactly the "compiler" or even the "linker" that does this but the C RuntTime library from the C lib. (for example I think ARM has choices for C lib so with the same compiler it might be possible for there to be different behaviours in fact)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

And now I guess we arrive at the actual answer to the OP question...

Where does main() return to when it finishes? It returns to where it was called from. On avr-gcc, this is the C runtime library (unless you specify the -nostartfiles option during build).

The source for this file is here:

 

http://svn.savannah.gnu.org/viewvc/*checkout*/avr-libc/trunk/avr-libc/crt1/gcrt1.S?revision=2519

 

Notice this part:

	.section .init9,"ax",@progbits
#ifdef __AVR_ASM_ONLY__
	XJMP	main
#else	/* !__AVR_ASM_ONLY__ */
	XCALL	main
	XJMP	exit
#endif	/* __AVR_ASM_ONLY__ */

 

The crt calls main(), then it calls exit() which is a function from the C standard library.

We can continue and find the source for exit()  http://svn.savannah.gnu.org/viewvc/*checkout*/avr-libc/trunk/avr-libc/libc/stdlib/exit.S?revision=1944

Basicaly it's this:

 

_U(exit):
	cli
	XJMP	_U(_exit)

 

This is where the infinite loop after main() comes from. Actually you can include stdlib.h and call exit() at any time.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

El Tangas wrote:
And now I guess we arrive at the actual answer to the OP question...
Or "revisit" what I already gave in the link in #21 perhaps? cheeky

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

El Tangas wrote:
And now I guess we arrive at the actual answer to the OP question...
Or "revisit" what I already gave in the link in #21 perhaps? cheeky

 

Or revisit #2 perhaps.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

El Tangas wrote:
It returns to where it was called from.

But not all embedded implementations actually call main() - some just jump to it ...

 

cheeky

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:
some just jump to it ...
Really? Then what happens at:

    ...
}

???

 

If closing brace means "end of function, do epilogue then RET" then where does it RET to if it was JMP not a CALL? Or are you suggesting those that JMP do some clever stack manipulation first to get a return address onto the stack? (in which case wouldn't CALL have been easier??)

Last Edited: Fri. Jul 3, 2020 - 03:44 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Of course, if it's treating the entry to main() as a special case, then it would also have to recognise the end of main() as a special case.

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But main() is "just another function". In fact it can be called recursively so it has to have the normal epilogue.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MattRW wrote:

clawson wrote:

El Tangas wrote:
And now I guess we arrive at the actual answer to the OP question...
Or "revisit" what I already gave in the link in #21 perhaps? cheeky

 

Or revisit #2 perhaps.

 

Yeah, well, I guess we are running in circles now, meaning there is not much more to say about this subject...

Pages