nop optimized away

Go To Last Post
6 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi!

I have an unresponsive LPC flash BIOS chip which I want to program via an ATmega168. Since adding nops has resolved a timing problem before, I tried to add blocks of 4 nops, but they got optimized away, I guess.

For instance the example from
http://www.nongnu.org/avr-libc/u... produces no nop instead of 4:

void main(void) {

asm volatile("nop\n\t"
             "nop\n\t"
             "nop\n\t"
             "nop\n\t"
             ::);

}

Same thing with more than 3

asm volatile("nop"::);

It seems that any sequence of 4 or more nops produces no nops if it is an even number and one nop if it is odd.

This now explains how avr-gcc magically only included the original nops as it was then the 5th with the 4 nop block added.

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

I tried it on all optimization levels (-O0, -O1, -O2, -O3, -Os), and it produced 4 NOPs each time.

Regards,
Steve A.

The Board helps those that help themselves.

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

You need to use the new builtin function for delaying a specific number of cycles:

extern void __builtin_avr_delay_cycles(unsigned long __n);

Specify the exact number of cycles that you need as the parameter. The compiler will generate the do-nothing code for you, and it won't be optimized away.

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

what versions software do you use?

what happens if you do:

asm volatile("nop\n\t"::); 
asm volatile("nop\n\t"::); 
asm volatile("nop\n\t"::); 
asm volatile("nop\n\t"::); 

regards

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

Hi,

Or use my library here:

https://www.avrfreaks.net/index.p...

Thanks,

Alan

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

Hi,

Or you can use the builtin function that EW mentions. Here are some defines that help with that:

#define Delay_ns(__ns) \
    if((unsigned long) (F_CPU/1000000000.0 * __ns) != F_CPU/1000000000.0 * __ns)\
          __builtin_avr_delay_cycles((unsigned long) ( F_CPU/1000000000.0 * __ns)+1);\
    else __builtin_avr_delay_cycles((unsigned long) ( F_CPU/1000000000.0 * __ns))
#define Delay_us(__us) \
    if((unsigned long) (F_CPU/1000000.0 * __us) != F_CPU/1000000.0 * __us)\
          __builtin_avr_delay_cycles((unsigned long) ( F_CPU/1000000.0 * __us)+1);\
    else __builtin_avr_delay_cycles((unsigned long) ( F_CPU/1000000.0 * __us))
#define Delay_ms(__ms) \
    if((unsigned long) (F_CPU/1000.0 * __ms) != F_CPU/1000.0 * __ms)\
          __builtin_avr_delay_cycles((unsigned long) ( F_CPU/1000.0 * __ms)+1);\
    else __builtin_avr_delay_cycles((unsigned long) ( F_CPU/1000.0 * __ms))
#define Delay_s(__s) \
    if((unsigned long) (F_CPU/1.0 * __s) != F_CPU/1.0 * __s)\
          __builtin_avr_delay_cycles((unsigned long) ( F_CPU/1.0 * __s)+1);\
    else __builtin_avr_delay_cycles((unsigned long) ( F_CPU/1.0 * __s))

Good luck,

Alan