avr-libc-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: can't reproduce documented overflow behavior of _delay_ms()


From: Georg-Johann Lay
Subject: Re: can't reproduce documented overflow behavior of _delay_ms()
Date: Fri, 24 Jan 2020 09:18:16 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.9.0

Am 23.01.20 um 23:57 schrieb Britton Kerin:
On a 16 MHz Arduino Mega 256, this code:

   __builtin_avr_delay_cycles (100.0);   // Compiles, so we apparently have it
   debug_led_on ();
   _delay_ms (290000.0);
   debug_led_off ();
   assert (0);

leaves the debug led on for about 269 s.  Same for larger arguments to
_delay_ms (e.g. 350000.0).  This is different from what this
documentation implies will happen:

   If the avr-gcc toolchain has __builtin_avr_delay_cycles() support,
maximal possible delay is
   4294967.295 ms/ F_CPU in MHz. For values greater than the maximal
possible delay,
   overflows results in no delay i.e., 0ms.

It looks like the result is now the maximum delay, rather than 0ms.
Perhaps __builtin_avr_delay_cycles() has changed?

No, the code is still from the initial commit

https://gcc.gnu.org/r172416

The code is still the same today:

https://gcc.gnu.org/viewcvs/gcc/trunk/gcc/config/avr/avr.md?annotate=280000
https://gcc.gnu.org/viewcvs/gcc/trunk/gcc/config/avr/avr.c?annotate=280000

That's from just prior to the SVN->GIT transition.
(I found no way for a similar neat view with gitweb. The transition was 3 weeks ago, and since then that code did not change either.)

https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;a=tree;f=gcc/config/avr;hb=HEAD

Johann


Also, the documentation for _delay_us() also contains this:

   If the user requests a delay greater than the maximal possible one,
_delay_us() will
   automatically call _delay_ms() instead. The user will not be
informed about this case.

   If the avr-gcc toolchain has __builtin_avr_delay_cycles() support,
maximal possible delay is
   4294967.295 us/ F_CPU in MHz. For values greater than the maximal
possible delay, overflow
   results in no delay i.e., 0us.

This looks suspicious because if _delay_us() calls _delay_ms() for
longer delays, one would
expect the same maximum low-resolution delay as for _delay_ms().  And
in fact this code
behaves as expected (gives 10 seconds with LED on):

   __builtin_avr_delay_cycles (100.0);   // Compiles, so we apparently have it
   debug_led_on ();
   _delay_us (10000000.0);   // 10 s in us
   debug_led_off ();
   assert (0);

but this code delays for only 269s:

   __builtin_avr_delay_cycles (100.0);   // Compiles, so we apparently have it
   debug_led_on ();
   _delay_us (290000000.0);   // 290 s in us
   debug_led_off ();
   assert (0);

So it looks like with recent avr gcc at least my suspicion is correct.

If it would get applied I could prepare a documentation patch for
these issues, but I don't know when the __builtin_avr_delay_cycles()
behavior changed (assuming that's the cause of the above problem).

Britton






reply via email to

[Prev in Thread] Current Thread [Next in Thread]