Go Down

Topic: noreturn? (Read 2209 times) previous topic - next topic

Coding Badly


Is there any reason not to mark setup and loop as "noreturn"...

void setup( void ) __attribute__ ((noreturn));
void loop( void ) __attribute__ ((noreturn));

Doing that shaved 80 bytes off the code size of a sketch.  As far as I can tell, the unnecessary register preserving epilogue / prologue was the only thing removed.

CrossRoads

Would that help with the jitter seen on signals too?
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Coding Badly


It may.  Do you have an example?

sixeyes

I don't understand, setup() and loop() do return. They're not like exit() or abort(). Calling them does not terminate code execution which is what the attribute is for.

CrossRoads

An example - every once in a while someone asks how fast can a frequency be created (not using PWM).
The times I've played with a scope looking at signals using digitalWrite to take an output Hi & Lo, the output seems to jitter back & forth some amount, which I assumed had to do with stuff dealing with the end of loop and going back to the start. This was before I knew about the behind the scenes void Main, and now this extra return stuff.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Coding Badly

I don't understand, setup() and loop() do return. They're not like exit() or abort(). Calling them does not terminate code execution which is what the attribute is for.


The attribute name is a misnomer.  While it is intended to be used for "terminating" functions, in the GCC-AVR world, as far as I can tell, it only alters the behaviour of the optimizer.  "noreturn" tells the compiler that: certain registers do not need to be preserved; certain optimizations can be performed that can others cause problems.  Because there is essentially trivial code in the 0022 version of main (three calls and a jump), calling a "noreturn" function should not cause any problems.

Coding Badly

An example - every once in a while someone asks how fast can a frequency be created (not using PWM).
The times I've played with a scope looking at signals using digitalWrite to take an output Hi & Lo, the output seems to jitter back & forth some amount,


The most likely culprit is the millis interrupt service routine.  Try turning off the timer 0 interrupt and using the AVR-Libc delay functions...
http://www.nongnu.org/avr-libc/user-manual/group__util__delay.html

Quote
which I assumed had to do with stuff dealing with the end of loop and going back to the start


I don't think that can be the culprit with Arduino 0022.  For a given sketch, the main / prologue / epilogue code path is always the same.  This creates a constant dead-time but does not add jitter.

CrossRoads

"Try turning off the timer 0 interrupt and using the AVR-Libc delay functions..."

That's a bit too deep in the software for me ...
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Coding Badly


It's a bit crude but...

Code: [Select]
TCCR0B = 0;
TCCR0A = 0;


...turns off timer 0.


The delay functions are similar to the Arduino delay...

Code: [Select]
#include <util/delay.h>

void loop( void )
{
 digitalWrite( 7, HIGH );
 _delay_us( 10 );
 digitalWrite( 7, LOW );
 _delay_us( 1 );
}


...should be very close to a 10 us high / 1 us low pulse with no jitter.

CrossRoads

Well, I'll keep that in mind for something.  I'm kinda leery of messing with the timers when they seem tied into so many other things.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

westfw

Quote
void loop() {
  cli(); // Turn off interrupts to prevent glitching of fast loop
  while (1) {
    digitalWriteFast(13, 1);
    digitalWriteFast(13, 0);
  }
}

millis() and Serial will break with interrupts turned off, but if all you're doing is demonostrating max pin write speed, that shouldn't matter...

Go Up