leo25 / arduino

Automatically exported from code.google.com/p/arduino
0 stars 0 forks source link

wiring.h round macro causes error with avr-libc-1.7.1 fix #604

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
I am debugging routines in the Linux avr-gcc compiler. 

I found and corrected a bug in the avr-libc-1.7.1 delay.h file, but the 
solution caused a problem with the round() function in math.h. Here is the 
report to Savannah on the delay.h bug.
https://savannah.nongnu.org/bugs/?34047

Here is a section of a post to the Arduino forum, so I don't have to retype it. 
Bug #2 is the bug affecting the Arduino library. Past versions of avr-libc may 
need that round macro, but not 1.7.1. It generates an error with that version.

Bug #1
avrlibc-1.7.1/include/util/delay.h.in

At line 44, add this:
Code:

#include <math.h>

This is required due to the calls to fabs() and ceil() in the delay.h file.

If you are using a precompiled version from a repository or download from 
Atmel, you can "retro" this fix by adding the same line to your current delay.h 
file.
/usr/../avr/include/util/delay.h
My repository installed it in "/usr/avr/include/util/delay.h", but that could 
vary by version of Linux and the repository. Some may be "/usr/local/".

Bug #2
arduino-0022/hardware/arduino/cores/arduino/wiring.h
Remark out line 79 (round macro). This causes a problem with the avr-gcc math.h 
library when you add the include to delay.h.
Code:

// #define round(x)     ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))

Original issue reported on code.google.com by t...@prolectron.com on 28 Aug 2011 at 5:03

GoogleCodeExporter commented 9 years ago
I'm confused.  Does Arduino include a version of avr-libc with this problem?  
If so, what's the best way to fix it?

Original comment by dmel...@gmail.com on 28 Aug 2011 at 6:16

GoogleCodeExporter commented 9 years ago
Don't be confused. The bug fix in the avr-libc 1.7.1 threw an error when I 
added the math.h include to the delay.h file. The "#define round ..." statement 
in the wiring.h file caused the avr-libc math.h file to generate an error. The 
define replaced the "round" in the math.h file with the macro. Oops!

The challenge was a major redo of the delay.h file from avr-libc 1.7.0 to 
1.7.1. The delay timing was off, so the new redo included a call to fabs() and 
a call to ceil(). Both are functions declared in math.h. But the include was 
not added to the finished product.

If you know a better way to resolve that issue, I am always open to suggestion.

Original comment by t...@prolectron.com on 28 Aug 2011 at 8:22

GoogleCodeExporter commented 9 years ago
So you're saying I need to comment out the Arduino version of round() to avoid 
breaking math.h in avr-libc 1.7.1?  Is that the version we're using now?  

Either way, is the new built-in round() a suitable replacement for the previous 
Arduino-specific one?

Original comment by dmel...@gmail.com on 31 Aug 2011 at 7:25

GoogleCodeExporter commented 9 years ago
Yes, the version of round in the math.h file does fine with the new version. 
But that may not be the case with previous versions of the run time library.

I think Arduino is using avr-libc 1.6.7 or the like with the Windows version. I 
have upgraded to the latest releases of all I could find. I am using avr-libc 
1.7.1. That is apparently what is included with the Atmel 8-bit toolkit 3.2.3 
on their site. It comes with avr-gcc v4.5.1. That is what I am running. I think 
I am still the only one running any of these versions. When I downloaded it 
from the Atmel site, it would not even compile the "blink" example.

I do not want to break any previous avr-libc versions by remarking out that 
macro without checking the version. The round macro may be needed in those 
older versions. Is there a define that allows you to determine the avr-libc 
version in wiring.h?

The version included in my repository was buggy, so I was trying to get a 
current version running. And now I have one.

Original comment by t...@prolectron.com on 31 Aug 2011 at 7:56

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
I found the correct define to check the version. Instead of remarking out the 
round macro, use this:

#if __AVR_LIBC_VERSION__ < 10701UL
#define round(x)     ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
#endif

It works with version 1.7.1. You might want to check this with earlier versions.

Original comment by t...@prolectron.com on 1 Sep 2011 at 11:15

GoogleCodeExporter commented 9 years ago
Linux distributions just upgraded their gcc-avr to 1.7.1 too. 
Debian/Ubuntu/Mint's version of arduino has this patch:
http://patch-tracker.debian.org/patch/series/view/arduino/0022+dfsg-4/libc_1.7.1
.patch

Bug-Debian: http://bugs.debian.org/633659
--- arduino-0022+dfsg.orig/hardware/arduino/cores/arduino/wiring.h
+++ arduino-0022+dfsg/hardware/arduino/cores/arduino/wiring.h
@@ -76,7 +76,7 @@ extern "C"{
 #define max(a,b) ((a)>(b)?(a):(b))
 #define abs(x) ((x)>0?(x):-(x))
 #define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
-#define round(x)     ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
+//#define round(x)     ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
 #define radians(deg) ((deg)*DEG_TO_RAD)
 #define degrees(rad) ((rad)*RAD_TO_DEG)
 #define sq(x) ((x)*(x))

Original comment by showard...@gmail.com on 16 Oct 2011 at 10:27

GoogleCodeExporter commented 9 years ago
I think the __AVR_LIBC_VERSION__ ifdef is the superior solution.

Original comment by craigle...@gmail.com on 17 Mar 2012 at 6:14

GoogleCodeExporter commented 9 years ago
Still not fixed in whatever version of arduino is in Ubuntu 12.04. It's such an 
easy fix too!

Original comment by tdh...@gmail.com on 22 Jul 2012 at 4:35

GoogleCodeExporter commented 9 years ago
No wait, it actually is fixed, as far as I can tell. I was using an old version 
of the code.

Original comment by tdh...@gmail.com on 22 Jul 2012 at 4:48