Discussion:
[avr-gcc-list] [bug] uint16_t optimization error for 8-bit AVRs.
Lv Zheng
2012-02-28 03:16:37 UTC
Permalink
Hi, all

I'm new to this mailing list to report an old version avr-gcc bug which
might be a known bug and wonder if someone here can kindly give me hints if
there are any solutions.

We found this bug when we compile our project (sdfirm.sourceforge.net) using
avr-gcc-4.5.2 or avr-gcc-3.4.4.

C source codes are attached hereafter:
==================================================
#define MAKEWORD(a, b) ((uint16_t)(((uint16_t)(a)) | \
((uint16_t)(b)) << 8))

#define PN53X_LEN 3
#define PN53X_LCS 4
#define PN53X_TFI 5
#define PN53X_CMD 6
#define PN53X_PD(n) (PN53X_CMD+(n))

/* XXX: Workaround for an AVR-GCC Bug
* This function should be put into a seperate file to avoid a GCC bug when
* optimizations are performed on uint16_t operations for 8-bit AVR chips.
*/
boolean pn53x_is_ciu_register(uint16_t reg)
{
return (reg >= PN53X_REG_CIU_BASE) &&
(reg < (PN53X_REG_CIU_BASE + PN53X_REG_CIU_SIZE));
}

void pn53x_response_ReadRegister(void)
{
uint8_t i, j;
uint16_t reg;
uint8_t val;

for (i = 0, j = 0;
i < (pn53x_stub_cmd[PN53X_LEN]-2);
i += 2, j++) {
reg = MAKEWORD(pn53x_stub_cmd[PN53X_PD(2)+i],
pn53x_stub_cmd[PN53X_PD(1)+i]);
if (!pn53x_is_ciu_register(reg)) {
if (reg == PN53X_REG_Control_switch_rng) {
val = pn53x_ctrl_reg_switch_rng;
} else {
pn53x_response_error(PN53X_ERR_CMD);
return;
}
} else {
uint8_t mask;
uint8_t index = PN53X_CIU_REG2INDEX(reg);
mask = pn53x_ciu_readables[index];
val = (pn53x_ciu_read_register(reg) & mask);
}
pn53x_stub_resp[PN53X_PD(1)+j] = val;
}
pn53x_build_frame(j+2);
}
==================================================
The bug is occurred between the following codes:
==================================================
reg = MAKEWORD(pn53x_stub_cmd[PN53X_PD(2)+i],
pn53x_stub_cmd[PN53X_PD(1)+i]);
if (!pn53x_is_ciu_register(reg)) {
==================================================
Assembly generations are incorrect:
00004e60 <pn53x_response_ReadRegister>:
4e60: ef 92 push r14
4e62: ff 92 push r15
4e64: 0f 93 push r16
4e66: 1f 93 push r17
4e68: cf 93 push r28
4e6a: df 93 push r29
-----
4e6c: 10 e0 ldi r17, 0x00 ; 0
4e6e: 26 c0 rjmp .+76 ; 0x4ebc
<pn53x_response_ReadRegister+0x5c>
-----
loop:
j is assigned to r17
-----
4e70: fa 01 movw r30, r20
4e72: e5 53 subi r30, 0x35 ; 53
4e74: f7 4f sbci r31, 0xF7 ; 247
4e76: 80 e0 ldi r24, 0x00 ; 0
4e78: ec 01 movw r28, r24
4e7a: 80 85 ldd r24, Z+8 ; 0x08
-----
now r24 is pn53x_stub_cmd[PN53X_PD(2)+i]
but we couldn't find any codes related to the pn53x_stub_cmd[PN53X_PD(1)+i]
hereafter...
-----
4e7c: 90 e0 ldi r25, 0x00 ; 0
4e7e: 8c 2b or r24, r28
4e80: 9d 2b or r25, r29
4e82: 9c 01 movw r18, r24
4e84: 20 50 subi r18, 0x00 ; 0
4e86: 33 46 sbci r19, 0x63 ; 99
4e88: 20 34 cpi r18, 0x40 ; 64
4e8a: 31 05 cpc r19, r1
4e8c: 50 f0 brcs .+20 ; 0x4ea2
<pn53x_response_ReadRegister+0x42>
4e8e: 21 e6 ldi r18, 0x61 ; 97
4e90: 86 30 cpi r24, 0x06 ; 6
4e92: 92 07 cpc r25, r18
4e94: 19 f4 brne .+6 ; 0x4e9c
<pn53x_response_ReadRegister+0x3c>
4e96: 80 91 a0 06 lds r24, 0x06A0
4e9a: 0a c0 rjmp .+20 ; 0x4eb0
<pn53x_response_ReadRegister+0x50>
4e9c: 87 e2 ldi r24, 0x27 ; 39
4e9e: 16 df rcall .-468 ; 0x4ccc <pn53x_response_error>
4ea0: 1b c0 rjmp .+54 ; 0x4ed8
<pn53x_response_ReadRegister+0x78>
4ea2: e8 2f mov r30, r24
4ea4: f0 e0 ldi r31, 0x00 ; 0
4ea6: ec 53 subi r30, 0x3C ; 60
4ea8: fd 4f sbci r31, 0xFD ; 253
4eaa: 00 81 ld r16, Z
4eac: c5 df rcall .-118 ; 0x4e38 <pn53x_ciu_read_register>
4eae: 80 23 and r24, r16
4eb0: e1 2f mov r30, r17
4eb2: f0 e0 ldi r31, 0x00 ; 0
4eb4: ea 56 subi r30, 0x6A ; 106
4eb6: f8 4f sbci r31, 0xF8 ; 248
4eb8: 87 83 std Z+7, r24 ; 0x07
4eba: 1f 5f subi r17, 0xFF ; 255
-----
4ebc: 41 2f mov r20, r17
4ebe: 44 0f add r20, r20
4ec0: 50 e0 ldi r21, 0x00 ; 0
4ec2: 20 91 ce 08 lds r18, 0x08CE
4ec6: 30 e0 ldi r19, 0x00 ; 0
4ec8: 22 50 subi r18, 0x02 ; 2
4eca: 30 40 sbci r19, 0x00 ; 0
4ecc: 42 17 cp r20, r18
4ece: 53 07 cpc r21, r19
4ed0: 7c f2 brlt .-98 ; 0x4e70
<pn53x_response_ReadRegister+0x10>
-----
loop:
i is assigned to r20
pn53x_stub_cmd[PN53X_LEN]-2 is assigned to r18,r19
-----

4ed2: 81 2f mov r24, r17
4ed4: 8e 5f subi r24, 0xFE ; 254
4ed6: d2 de rcall .-604 ; 0x4c7c <pn53x_build_frame>
4ed8: df 91 pop r29
4eda: cf 91 pop r28
4edc: 1f 91 pop r17
4ede: 0f 91 pop r16
4ee0: ff 90 pop r15
4ee2: ef 90 pop r14
4ee4: 08 95 ret
==================================================
Assembly generations are vary if we put a simple uart print code between the
two lines as:
==================================================
reg = MAKEWORD(pn53x_stub_cmd[PN53X_PD(2)+i],
pn53x_stub_cmd[PN53X_PD(1)+i]);
uart_putchar(0x00);
if (!pn53x_is_ciu_register(reg)) {
==================================================
Assembly generations are correct:
00002a5a <pn53x_response_ReadRegister>:
2a5a: ef 92 push r14
2a5c: ff 92 push r15
2a5e: 0f 93 push r16
2a60: 1f 93 push r17
2a62: cf 93 push r28
2a64: df 93 push r29
2a66: ff 24 eor r15, r15
2a68: 2a c0 rjmp .+84 ; 0x2abe
<pn53x_response_ReadRegister+0x64>
-----
2a6a: fa 01 movw r30, r20
2a6c: e0 57 subi r30, 0x70 ; 112
2a6e: f7 4f sbci r31, 0xF7 ; 247
2a70: 17 81 ldd r17, Z+7 ; 0x07
2a72: 00 e0 ldi r16, 0x00 ; 0
-----
now r16,r17 is pn53x_stub_cmd[PN53X_PD(1)+i]
-----
2a74: 80 85 ldd r24, Z+8 ; 0x08
-----
now r24 is pn53x_stub_cmd[PN53X_PD(1)+i]
-----
2a76: c8 2f mov r28, r24
2a78: d0 e0 ldi r29, 0x00 ; 0
2a7a: c0 2b or r28, r16
2a7c: d1 2b or r29, r17
-----
now r28,r29 containe the MAKEWORD result
-----
2a7e: 80 e0 ldi r24, 0x00 ; 0
2a80: 24 d4 rcall .+2120 ; 0x32ca <uart_hw_write_byte>
2a82: ce 01 movw r24, r28
2a84: 80 50 subi r24, 0x00 ; 0
2a86: 93 46 sbci r25, 0x63 ; 99
2a88: 80 34 cpi r24, 0x40 ; 64
2a8a: 91 05 cpc r25, r1
2a8c: 50 f0 brcs .+20 ; 0x2aa2
<pn53x_response_ReadRegister+0x48>
2a8e: 81 e6 ldi r24, 0x61 ; 97
2a90: c6 30 cpi r28, 0x06 ; 6
2a92: d8 07 cpc r29, r24
2a94: 19 f4 brne .+6 ; 0x2a9c
<pn53x_response_ReadRegister+0x42>
2a96: 80 91 c4 04 lds r24, 0x04C4
2a9a: 0b c0 rjmp .+22 ; 0x2ab2
<pn53x_response_ReadRegister+0x58>
2a9c: 87 e2 ldi r24, 0x27 ; 39
2a9e: 16 df rcall .-468 ; 0x28cc <pn53x_response_error>
2aa0: 1c c0 rjmp .+56 ; 0x2ada
<pn53x_response_ReadRegister+0x80>
2aa2: ce 01 movw r24, r28
2aa4: ec 2f mov r30, r28
2aa6: f0 e0 ldi r31, 0x00 ; 0
2aa8: e5 50 subi r30, 0x05 ; 5
2aaa: fe 4f sbci r31, 0xFE ; 254
2aac: e0 80 ld r14, Z
2aae: c2 df rcall .-124 ; 0x2a34 <pn53x_ciu_read_register>
2ab0: 8e 21 and r24, r14
2ab2: ef 2d mov r30, r15
2ab4: f0 e0 ldi r31, 0x00 ; 0
2ab6: e5 5a subi r30, 0xA5 ; 165
2ab8: f8 4f sbci r31, 0xF8 ; 248
2aba: 87 83 std Z+7, r24 ; 0x07
2abc: f3 94 inc r15
2abe: 4f 2d mov r20, r15
2ac0: 44 0f add r20, r20
2ac2: 50 e0 ldi r21, 0x00 ; 0
2ac4: 20 91 93 08 lds r18, 0x0893
2ac8: 30 e0 ldi r19, 0x00 ; 0
2aca: 22 50 subi r18, 0x02 ; 2
2acc: 30 40 sbci r19, 0x00 ; 0
2ace: 42 17 cp r20, r18
2ad0: 53 07 cpc r21, r19
2ad2: 5c f2 brlt .-106 ; 0x2a6a
<pn53x_response_ReadRegister+0x10>
2ad4: 8f 2d mov r24, r15
2ad6: 8e 5f subi r24, 0xFE ; 254
2ad8: d1 de rcall .-606 ; 0x287c <pn53x_build_frame>
2ada: df 91 pop r29
2adc: cf 91 pop r28
2ade: 1f 91 pop r17
2ae0: 0f 91 pop r16
2ae2: ff 90 pop r15
2ae4: ef 90 pop r14
2ae6: 08 95 ret
==================================================
The cc command line is listed as the following:

avr-gcc -Wp,-MD,drivers/scs/.pn53x_stub.rel.d
-nostdinc -nostdlib -D__KERNEL__ -Iinclude
-Wall -DKBUILD_CONF -Iinclude
-D__AVR__
-ffunction-sections -fsigned-char -mmcu=avr51
-D__AVR_ENHANCED__ -D__AVR_MEGA__ -D__AVR_2_BYTE_PC__
-Os -fomit-frame-pointer
-o drivers/scs/pn53x_stub.rel -c drivers/scs/pn53x_stub.c

Best regards/Lv ZETALOG Zheng
Georg-Johann Lay
2012-02-28 07:58:33 UTC
Permalink
Post by Lv Zheng
Hi, all
I'm new to this mailing list to report an old version avr-gcc bug which
might be a known bug and wonder if someone here can kindly give me hints
if there are any solutions.
If you see a bug: The last GCC version supported is 4.3

The last avr-gcc version supported is 4.6 (because of developer shortage)

If it's only a missed optimization, it might be fixed for 4.8 provided a
proper bug report is made.
Post by Lv Zheng
We found this bug when we compile our project (sdfirm.sourceforge.net)
using avr-gcc-4.5.2 or avr-gcc-3.4.4.
Obviously, not

* undefined: uint16_t
* undefined: boolean
* undefined: PN53X_REG_CIU_BASE
* undefined: PN53X_REG_CIU_SIZE

No crystal ball at this side of the cable...
See below for instructions
Post by Lv Zheng
avr-gcc -Wp,-MD,drivers/scs/.pn53x_stub.rel.d
-nostdinc -nostdlib -D__KERNEL__ -Iinclude
-Wall -DKBUILD_CONF -Iinclude
-D__AVR__
-ffunction-sections -fsigned-char -mmcu=avr51
-D__AVR_ENHANCED__ -D__AVR_MEGA__ -D__AVR_2_BYTE_PC__
-Os -fomit-frame-pointer
-o drivers/scs/pn53x_stub.rel -c drivers/scs/pn53x_stub.c
We don't have the files you have.

To enable others to reproduce, do the following:

* compile together with -v -save-temps -dp
* show us the command line output
* show us the generated .i file
* show us what is wring with the generated .s file

If no .s file is produced (there is bug in 3.4) then compile
with -S instead of -save-temps -o file.o -c
Lv Zheng
2012-02-28 11:25:25 UTC
Permalink
Post by Georg-Johann Lay
Obviously, not
* undefined: uint16_t
* undefined: boolean
* undefined: PN53X_REG_CIU_BASE
* undefined: PN53X_REG_CIU_SIZE
No crystal ball at this side of the cable...
See below for instructions
I tried to put only required definitions into a single C file, but the
avr-gcc failed to generate the incorrect result. So I had to copy all of my
includes into one single .c file to regenerate the error result. Sorry for
the large attached .c file.

So please find it in the avr-bug.c.
Post by Georg-Johann Lay
Post by Lv Zheng
avr-gcc -Wp,-MD,drivers/scs/.pn53x_stub.rel.d
-nostdinc -nostdlib -D__KERNEL__ -Iinclude
-Wall -DKBUILD_CONF -Iinclude
-D__AVR__
-ffunction-sections -fsigned-char -mmcu=avr51
-D__AVR_ENHANCED__ -D__AVR_MEGA__ -D__AVR_2_BYTE_PC__
-Os -fomit-frame-pointer
-o drivers/scs/pn53x_stub.rel -c drivers/scs/pn53x_stub.c
We don't have the files you have.
* compile together with -v -save-temps -dp
Please find my command line at the end of the avr-bug.l.
Post by Georg-Johann Lay
* show us the command line output
Please find the output in the avr-bug.l.
Post by Georg-Johann Lay
* show us the generated .i file
Please find the output in the avr-bug.i.
Post by Georg-Johann Lay
* show us what is wring with the generated .s file
Please find the output in the avr-bug.s.

Best regards/Lv Zheng
Georg-Johann Lay
2012-02-28 11:59:45 UTC
Permalink
Post by Lv Zheng
Post by Georg-Johann Lay
Obviously, not
* undefined: uint16_t
* undefined: boolean
* undefined: PN53X_REG_CIU_BASE
* undefined: PN53X_REG_CIU_SIZE
No crystal ball at this side of the cable...
See below for instructions
I tried to put only required definitions into a single C file, but the
avr-gcc failed to generate the incorrect result. So I had to copy all
of my includes into one single .c file to regenerate the error result.
Sorry for the large attached .c file.
You don't need to put anything anywhere ;-)

Just compile with -save-temps and show the i-file
*without* *HTML* *tags*.

And please describe the bug!

Don't expect that anyone will invest days to reverse-engineer your code and
work out what it supposes to do, what it does do, or what it does not do, if
you post thousands of lines.

At your option, work out a minimal test case that can be understood and still
exposes the artefact.

The more information you give, the better you explain the issue, the simpler
your test case is, the more non-needed stuff you omit, the more likely you will
get help.

You can add -dp -save-temps and explain where the bug can be seen in the s-file
and explain *why* the instruction is wrong and *what* is expected instead.

Moreover, you should ensure yourself that the issue is not already known, for
example PR46779 or PR39633.

If you just see a "missed optimization", then switch to a newer version of GCC
and/or try to tweak the command line arguments.
Lv Zheng
2012-02-29 02:08:01 UTC
Permalink
I can dig into details if time allows. Please wait for my next submission.
Before that, could anyone answer me a small question?
Are there any known bugs in avr-gcc related to the
__attribute__((__progmem__))?

Best regards/Lv Zheng
Andreas Höschler
2014-10-08 22:54:48 UTC
Permalink
Hi all,

I have just got my avr tool chain running on Solaris, established communication of avrdude with the USB programmer and am now trying to recompile my first program (one that I wrote years ago on another machine).

It goes like so:

main.c
======
#define F_CPU 16000000UL /* 16 MHz CPU clock */
#include "Global.h"
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>
#include <Serial.h>
#include <AnalogDigital.h>
#include <Timer.h>
#define OUTPUTPORT PORTB
#define OUTPUTPIN PD5

static volatile uint16_t startA;
...

Makefile
==========
# AVR-GCC Makefile
PROJECT=toggle_led
SOURCES=main.c Serial.c Timer.c AnalogDigital.c
HEADERS=Serial.h
CC=avr-gcc
OBJCOPY=avr-objcopy
MMCU=atmega8

CFLAGS=-mmcu=$(MMCU) -Wall -O2

$(PROJECT).hex: $(PROJECT).out
$(OBJCOPY) -j .text -O ihex $(PROJECT).out $(PROJECT).hex

$(PROJECT).out: $(SOURCES)
$(CC) $(CFLAGS) -I./ -o $(PROJECT).out $(SOURCES)

program: $(PROJECT).hex
avrdude -p atmega8 -c avrispmkII -P usb -e -U flash:w:$(PROJECT).hex
clean:
rm -f $(PROJECT).out
rm -f $(PROJECT).hex


When I try to make this I get

-bash-3.2# make
avr-gcc -mmcu=atmega8 -Wall -O2 -I./ -o toggle_led.out main.c Serial.c Timer.c AnalogDigital.c
main.c:3:24: error: util/delay.h: No such file or directory
main.c:4:20: error: avr/io.h: No such file or directory
main.c:5:27: error: avr/interrupt.h: No such file or directory
main.c:6:22: error: inttypes.h: No such file or directory
In file included from main.c:7:
./Serial.h:3: error: expected ')' before 'baud'
./Serial.h:4: error: expected ')' before 'data'

....

It seems avr-gcc is missing something!? Any idea what the problem might be?

Thanks for getting me (re)started (after years)!!

Andreas
Senthil Kumar Selvaraj
2014-10-09 04:18:07 UTC
Permalink
Post by Andreas Höschler
Hi all,
I have just got my avr tool chain running on Solaris, established communication of avrdude with the USB programmer and am now trying to recompile my first program (one that I wrote years ago on another machine).
main.c
======
#define F_CPU 16000000UL /* 16 MHz CPU clock */
#include "Global.h"
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>
#include <Serial.h>
#include <AnalogDigital.h>
#include <Timer.h>
#define OUTPUTPORT PORTB
#define OUTPUTPIN PD5
static volatile uint16_t startA;
...
Makefile
==========
# AVR-GCC Makefile
PROJECT=toggle_led
SOURCES=main.c Serial.c Timer.c AnalogDigital.c
HEADERS=Serial.h
CC=avr-gcc
OBJCOPY=avr-objcopy
MMCU=atmega8
CFLAGS=-mmcu=$(MMCU) -Wall -O2
$(PROJECT).hex: $(PROJECT).out
$(OBJCOPY) -j .text -O ihex $(PROJECT).out $(PROJECT).hex
$(PROJECT).out: $(SOURCES)
$(CC) $(CFLAGS) -I./ -o $(PROJECT).out $(SOURCES)
program: $(PROJECT).hex
avrdude -p atmega8 -c avrispmkII -P usb -e -U flash:w:$(PROJECT).hex
rm -f $(PROJECT).out
rm -f $(PROJECT).hex
When I try to make this I get
-bash-3.2# make
avr-gcc -mmcu=atmega8 -Wall -O2 -I./ -o toggle_led.out main.c Serial.c Timer.c AnalogDigital.c
main.c:3:24: error: util/delay.h: No such file or directory
main.c:4:20: error: avr/io.h: No such file or directory
main.c:5:27: error: avr/interrupt.h: No such file or directory
main.c:6:22: error: inttypes.h: No such file or directory
./Serial.h:3: error: expected ')' before 'baud'
./Serial.h:4: error: expected ')' before 'data'
The compiler is not able to find header files supplied by avr-libc. Did
you build both of them with the same install prefix? Can you paste the
output of running avr-gcc with -v?

Regards
Senthil
Andreas Höschler
2014-10-09 09:16:19 UTC
Permalink
Hi Senthil,
Post by Senthil Kumar Selvaraj
The compiler is not able to find header files supplied by avr-libc. Did
you build both of them with the same install prefix? Can you paste the
output of running avr-gcc with -v?
See below:

-bash-3.2$ avr-gcc -v
Using built-in specs.
Target: avr
Configured with: ../gcc-4.3.3/configure --target=avr --prefix=/usr/local/avr --enable-languages=c --disable-libssp --disable-shared --disable-libada --disable-libssp --disable-nls --with-dwarf2 --with-gmp=/usr/local --with-mpfr=/usr/local --prefix=/usr/local/avr : (reconfigured) ../gcc-4.3.3/configure --target=avr --prefix=/usr/local/avr --enable-languages=c --disable-libssp --disable-shared --disable-libada --disable-libssp --disable-nls --with-dwarf2 --with-gmp=/usr/local --with-mpfr=/usr/local --prefix=/usr/local/avr : (reconfigured) ../gcc-4.3.3/configure --target=avr --prefix=/usr/local/avr --enable-languages=c --disable-libssp --disable-shared --disable-libada --disable-libssp --disable-nls --with-dwarf2 --with-gmp=/usr/local --with-mpfr=/usr/local --prefix=/usr/local/avr
Thread model: single
gcc version 4.3.3 (GCC)


Thanks,

Andreas
Senthil Kumar Selvaraj
2014-10-09 09:34:54 UTC
Permalink
Post by Andreas Höschler
Hi Senthil,
Post by Senthil Kumar Selvaraj
The compiler is not able to find header files supplied by avr-libc. Did
you build both of them with the same install prefix? Can you paste the
output of running avr-gcc with -v?
-bash-3.2$ avr-gcc -v
Using built-in specs.
Target: avr
Configured with: ../gcc-4.3.3/configure --target=avr --prefix=/usr/local/avr --enable-languages=c --disable-libssp --disable-shared --disable-libada --disable-libssp --disable-nls --with-dwarf2 --with-gmp=/usr/local --with-mpfr=/usr/local --prefix=/usr/local/avr : (reconfigured) ../gcc-4.3.3/configure --target=avr --prefix=/usr/local/avr --enable-languages=c --disable-libssp --disable-shared --disable-libada --disable-libssp --disable-nls --with-dwarf2 --with-gmp=/usr/local --with-mpfr=/usr/local --prefix=/usr/local/avr : (reconfigured) ../gcc-4.3.3/configure --target=avr --prefix=/usr/local/avr --enable-languages=c --disable-libssp --disable-shared --disable-libada --disable-libssp --disable-nls --with-dwarf2 --with-gmp=/usr/local --with-mpfr=/usr/local --prefix=/usr/local/avr
Thread model: single
gcc version 4.3.3 (GCC)
Hmm, did you manage to build avr-libc successfully? Atleast from the avr-libc
configure command line you sent in the previous email, it looks like
you're missing --prefix.

Can you try configuring avr-libc with

./configure --host=avr --prefix=/usr/local/avr

and then running make and make install?

Regards
Senthil
Post by Andreas Höschler
Thanks,
Andreas
Andreas Höschler
2014-10-09 10:32:38 UTC
Permalink
Hi Senthil,
Post by Senthil Kumar Selvaraj
Post by Andreas Höschler
-bash-3.2$ avr-gcc -v
Using built-in specs.
Target: avr
Configured with: ../gcc-4.3.3/configure --target=avr --prefix=/usr/local/avr --enable-languages=c --disable-libssp --disable-shared --disable-libada --disable-libssp --disable-nls --with-dwarf2 --with-gmp=/usr/local --with-mpfr=/usr/local --prefix=/usr/local/avr : (reconfigured) ../gcc-4.3.3/configure --target=avr --prefix=/usr/local/avr --enable-languages=c --disable-libssp --disable-shared --disable-libada --disable-libssp --disable-nls --with-dwarf2 --with-gmp=/usr/local --with-mpfr=/usr/local --prefix=/usr/local/avr : (reconfigured) ../gcc-4.3.3/configure --target=avr --prefix=/usr/local/avr --enable-languages=c --disable-libssp --disable-shared --disable-libada --disable-libssp --disable-nls --with-dwarf2 --with-gmp=/usr/local --with-mpfr=/usr/local --prefix=/usr/local/avr
Thread model: single
gcc version 4.3.3 (GCC)
Hmm, did you manage to build avr-libc successfully? Atleast from the avr-libc
configure command line you sent in the previous email, it looks like
you're missing --prefix.
Can you try configuring avr-libc with
./configure --host=avr --prefix=/usr/local/avr
and then running make and make install?
Wow, that fixed it! I can successfully build code now:

-bash-3.2$ make
avr-gcc -mmcu=atmega8 -Wall -O2 -I /usr/local/avr/include -I./ -o toggle_led.out main.c Serial.c Timer.c AnalogDigital.c
avr-objcopy -j .text -O ihex toggle_led.out toggle_led.hex

-rw-r--r-- 1 ahoesch other 5908 Oct 9 12:31 toggle_led.hex

Thanks a lot!!!

Andreas
Andreas Höschler
2014-10-13 21:57:57 UTC
Permalink
Hi all,

doing my first cautious steps in C on an Arduino I try to convert a string read over the serial interface to a uint32_t.

uint32_t getLong_from_serial_rec_buffer()
{
char char_buffer[10];
int i;
for (i = 0 ; i < 10 ; i++)
{
if (bytes_in_serial_rec_buffer() > 0)
{
char current = buffer[buffer_tail];
if (current >= '0' && current <= '9')
{
get_from_serial_rec_buffer(); // we already know the byte :-)
char_buffer[i] = current;
}
else // is a comma or NULL or whatever other character
{
char_buffer[i] = 0;

putString_in_serial_trans_buffer(char_buffer);

return (uint32_t)atol(char_buffer);
}
}
}
return -1;
}

void putLong_in_serial_trans_buffer(uint32_t value)
{
char char_buffer[10];
utoa(value, char_buffer, 10);
int i;
for (i = 0 ; i < 10 ; i++)
{
char current = char_buffer[i];
if (current != 0) TxByte (current);
else break;
}
}

This does not work. The thing receives 500000 as a string but atol seems to be good for 16bit values only!? The value returned by getLong_from_serial_rec_buffer is at least always smaller than 65536. What am I missing? Where would I find the correct function that returns a 32bit value?

Thanks a lot,

Andreas
Georg-Johann Lay
2014-10-14 09:23:48 UTC
Permalink
Post by Andreas Höschler
Hi all,
doing my first cautious steps in C on an Arduino I try to convert a string read over the serial interface to a uint32_t.
So what's wrong with strtoul from stdlib.h ?
Post by Andreas Höschler
[snipped bulk op code]
Johann

p.s.

You started this new thread as an answer to "Building code", presumably of
laziness. This means your mail is filed deep inside the "Building code" thread
and hence is likely to be overlooked when someone is not deeply involved in
that thread. Better start a new thread at top level, i.e. not as an answer to
any other mail.
Andreas Höschler
2014-11-26 19:46:01 UTC
Permalink
HI all,

I have programmed ATMega8 in the past (worked great). I have purchased a ATMega2560 board now and am trying to get my avr gcc tool chain to accept this chip:

Makefile
==================
# AVR-GCC Makefile
PROJECT=toggle_led
SOURCES=main.c
HEADERS=
CC=avr-gcc
OBJCOPY=avr-objcopy
MMCU=atmega2560

CFLAGS=-mmcu=$(MMCU) -Wall -O2 -I /usr/local/avr/include

$(PROJECT).hex: $(PROJECT).out
$(OBJCOPY) -j .text -O ihex $(PROJECT).out $(PROJECT).hex

$(PROJECT).out: $(SOURCES)
$(CC) $(CFLAGS) -I./ -o $(PROJECT).out $(SOURCES)

program: $(PROJECT).hex
avrdude -p $(MMCU) -c avrispmkII -P usb -e -U flash:w:$(PROJECT).hex
clean:
rm -f $(PROJECT).out
rm -f $(PROJECT).hex

main.c
==================
#define F_CPU 16000000UL /* 16 MHz CPU clock */
#include <util/delay.h>
#define OUTPUTPORT PORTB
#define OUTPUTPIN PB7
int main (void)
{
DDRB = 0xff; // all outputs
while (1) /* loop forever */
{
if ((PORTB & _BV(PB7)) > 0) PORTB &= ~_BV(PB7);
else PORTB |= _BV(PB7);
delay_ms(500);
}
return (0);
}

When I try to make this project I get

-bash-3.2$ make
avr-gcc -mmcu=atmega2560 -Wall -O2 -I /usr/local/avr/include -I./ -o toggle_led.out main.c
unknown MCU 'atmega2560' specified
Known MCU names:
avr2
at90s2313
...
attiny12
attiny15
attiny28
main.c:1: error: MCU 'atmega2560' supported for assembler only
main.c: In function 'toggleOutput':
main.c:19: error: 'PORTB' undeclared (first use in this function)
main.c:19: error: (Each undeclared identifier is reported only once
main.c:19: error: for each function it appears in.)
main.c:19: warning: implicit declaration of function '_BV'
main.c:19: error: 'PB7' undeclared (first use in this function)
main.c: In function 'main':
main.c:34: error: 'DDRB' undeclared (first use in this function)
main.c:45: error: 'PORTB' undeclared (first use in this function)
main.c:45: error: 'PB7' undeclared (first use in this function)
make: *** [toggle_led.out] Error 1

The chip atmega2560 indeed is not in the offered list!? I built my tool chain as shown below! What am I missing? How can this be fixed?

Thanks a lot!!!

Andreas

********************************************************************************************************
We download http://ftp.gnu.org/gnu/binutils/binutils-2.24.tar.gz:

PREFIX=/usr/local/avr
export PREFIX
PATH=$PATH:$PREFIX/bin
export PATH

cd /usr/src
mkdir avr
cd avr
scp ***@192.168.1.7:/home/ahoesch/Downloads/binutils-2.24.tar.gz .
gunzip binutils-2.24.tar.gz
gtar xvf binutils-2.24.tar
cd binutils-2.24
./configure --target=avr --program-prefix="avr-" --prefix=$PREFIX
make
make install

We download http://gcc.cybermirror.org/releases/gcc-4.3.3/gcc-4.3.3.tar.bz2:

cd /usr/src/
gtar xvf mpfr-2.4.0.tar
cd mpfr-2.4.0
./configure
make
make install

cd /usr/src/avr
mkdir avrgcc
scp ***@192.168.1.7:/home/ahoesch/Downloads/gcc-4.3.3.tar.bz2 .
bunzip2 gcc-4.3.3.tar.bz2
gtar xvf gcc-4.3.3.tar
cd avrgcc
../gcc-4.3.3/configure --target=avr --prefix=/usr/local/avr --enable-languages=c --disable-libssp --disable-shared --disable-libada --disable-libssp --disable-nls --with-dwarf2 --with-gmp=/usr/local --with-mpfr=/usr/local --prefix=/usr/local/avr
make
make install

pico /etc/default/login
pico /etc/default/su

PATH= ...:/usr/local/avr/bin
SUPATH= ...:/usr/local/avr/bin

Relogin to get the new PATH value.

which avr-gcc

We download http://download.savannah.gnu.org/releases/avr-libc/avr-libc-1.8.1.tar.bz2:

cd /usr/src/avr
scp ***@192.168.1.7:/home/ahoesch/Downloads/avr-libc-1.8.1.tar.bz2 .
bunzip2 avr-libc-1.8.1.tar.bz2
gtar xvf avr-libc-1.8.1.tar
cd avr-libc-1.8.1
./configure --host=avr --prefix=/usr/local/avr
make
make install


We sync avrdude-5.8 and arduino.sh from the 192.168.1.2

rsync -avz -e ssh arduino.sh avrdude-5.8 ***@192.168.1.7:/usr/src/avr

and build as follows:

LIBUSB=/usr/sfw
export CPPFLAGS="-I${LIBUSB}/include"
export LDFLAGS="-L${LIBUSB}/lib"
make
make install

This installs

/usr/local/bin/avrdude
/usr/local/etc/avrdude.conf

We can now do

avrdude -c avrispmkII -P usb -p atmega8
...
Thomas D. Dean
2014-11-26 21:33:17 UTC
Permalink
Post by Andreas Höschler
#define F_CPU 16000000UL /* 16 MHz CPU clock */
#include <util/delay.h>
#define OUTPUTPORT PORTB
#define OUTPUTPIN PB7
int main (void)
{
DDRB = 0xff; // all outputs
while (1) /* loop forever */
{
if ((PORTB & _BV(PB7)) > 0) PORTB &= ~_BV(PB7);
else PORTB |= _BV(PB7);
delay_ms(500);
}
return (0);
}
A couple coding problems.

You need to include avr/io.h to get port definitions.
delay_ms(500) should be _delay_ms(500)

Tom Dean
Andreas Höschler
2014-11-26 22:25:06 UTC
Permalink
Hi Tom,
Post by Thomas D. Dean
Post by Andreas Höschler
#define F_CPU 16000000UL /* 16 MHz CPU clock */
#include <util/delay.h>
#define OUTPUTPORT PORTB
#define OUTPUTPIN PB7
int main (void)
{
DDRB = 0xff; // all outputs
while (1) /* loop forever */
{
if ((PORTB & _BV(PB7)) > 0) PORTB &= ~_BV(PB7);
else PORTB |= _BV(PB7);
delay_ms(500);
}
return (0);
}
A couple coding problems.
You need to include avr/io.h to get port definitions.
I tried with and without. With I get

-bash-3.2$ make
avr-gcc -mmcu=atmega2560 -Wall -O2 -I /usr/local/avr/include -I./ -o toggle_led.out main.c
unknown MCU 'atmega2560' specified
Known MCU names:
avr2
at90s2313
...
attiny15
attiny28
main.c:1: error: MCU 'atmega2560' supported for assembler only
In file included from main.c:4:
/usr/local/avr/include/avr/io.h:530:6: warning: #warning "device type not defined"
main.c: In function 'toggleOutput':
main.c:19: error: 'PORTB' undeclared (first use in this function)
main.c:19: error: (Each undeclared identifier is reported only once
main.c:19: error: for each function it appears in.)
main.c:19: error: 'PB7' undeclared (first use in this function)
main.c: In function 'main':
main.c:34: error: 'DDRB' undeclared (first use in this function)
main.c:45: error: 'PORTB' undeclared (first use in this function)
main.c:45: error: 'PB7' undeclared (first use in this function)
make: *** [toggle_led.out] Error 1

:-(

Thanks,

Andreas
Thomas D. Dean
2014-11-26 22:34:09 UTC
Permalink
On 11/26/14 14:25, Andreas Höschler wrote:


#define F_CPU 16000000UL /* 16 MHz CPU clock */
#include <avr/io.h>
#include <util/delay.h>
#define OUTPUTPORT PORTB
#define OUTPUTPIN PB7
int main (void) {
DDRB = 0xff; // all outputs
while (1) /* loop forever */
{
if ((PORTB & _BV(PB7)) > 0) PORTB &= ~_BV(PB7);
else PORTB |= _BV(PB7);
_delay_ms(500);
}
return (0);
}
avr-gcc -mmcu=atmega2560 -Wall -O2 -I /usr/lib/avr/include/ main.c
No errors.

Tom Dean
Andreas Höschler
2014-11-26 22:57:59 UTC
Permalink
Hi Tom,
Post by Andreas Höschler
#define F_CPU 16000000UL /* 16 MHz CPU clock */
#include <avr/io.h>
#include <util/delay.h>
#define OUTPUTPORT PORTB
#define OUTPUTPIN PB7
int main (void) {
DDRB = 0xff; // all outputs
while (1) /* loop forever */
{
if ((PORTB & _BV(PB7)) > 0) PORTB &= ~_BV(PB7);
else PORTB |= _BV(PB7);
_delay_ms(500);
}
return (0);
}
avr-gcc -mmcu=atmega2560 -Wall -O2 -I /usr/lib/avr/include/ main.c
I get this

-bash-3.2$ avr-gcc -mmcu=atmega2560 -Wall -O2 -I /usr/lib/avr/include/ main.c
unknown MCU 'atmega2560' specified
Known MCU names:
avr2
at90s2313
at90s2323
at90s2333
at90s2343
attiny22
attiny26
at90s4414
at90s4433
at90s4434
at90s8515
at90c8534
at90s8535
avr25
attiny13
attiny2313
attiny24
attiny44
attiny84
attiny25
attiny45
attiny85
attiny261
attiny461
attiny861
attiny43u
attiny48
attiny88
at86rf401
avr3
at43usb320
at43usb355
at76c711
avr31
atmega103
avr35
at90usb82
at90usb162
avr4
atmega8
atmega48
atmega48p
atmega88
atmega88p
atmega8515
atmega8535
atmega8hva
at90pwm1
at90pwm2
at90pwm2b
at90pwm3
at90pwm3b
avr5
atmega16
atmega161
atmega162
atmega163
atmega164p
atmega165
atmega165p
atmega168
atmega168p
atmega169
atmega169p
atmega32
atmega323
atmega324p
atmega325
atmega325p
atmega3250
atmega3250p
atmega328p
atmega329
atmega329p
atmega3290
atmega3290p
atmega32hvb
atmega406
atmega64
atmega640
atmega644
atmega644p
atmega645
atmega6450
atmega649
atmega6490
atmega16hva
at90can32
at90can64
at90pwm216
at90pwm316
at90usb646
at90usb647
at94k
avr51
atmega128
atmega1280
atmega1281
atmega1284p
at90can128
at90usb1286
at90usb1287
avr1
at90s1200
attiny11
attiny12
attiny15
attiny28
main.c:1: error: MCU 'atmega2560' supported for assembler only
In file included from main.c:4:
/usr/local/avr/lib/gcc/avr/4.3.3/../../../../avr/include/avr/io.h:530:6: warning: #warning "device type not defined"
main.c: In function 'toggleOutput':
main.c:19: error: 'PORTB' undeclared (first use in this function)
main.c:19: error: (Each undeclared identifier is reported only once
main.c:19: error: for each function it appears in.)
main.c:19: error: 'PB7' undeclared (first use in this function)
main.c: In function 'main':
main.c:34: error: 'DDRB' undeclared (first use in this function)
main.c:45: error: 'PORTB' undeclared (first use in this function)
main.c:45: error: 'PB7' undeclared (first use in this function)

Have you looked at my tool chain setup receipt (see below)? May be I need another version of one of the ingredients!?? What components contains the chip infos? Is this in avr-libc? I use v1.8.1. Which version do you have?

Thanks a lot,

Andreas


********************************************************************************************************
We download http://ftp.gnu.org/gnu/binutils/binutils-2.24.tar.gz:

PREFIX=/usr/local/avr
export PREFIX
PATH=$PATH:$PREFIX/bin
export PATH

cd /usr/src
mkdir avr
cd avr
scp ***@192.168.1.7:/home/ahoesch/Downloads/binutils-2.24.tar.gz .
gunzip binutils-2.24.tar.gz
gtar xvf binutils-2.24.tar
cd binutils-2.24
./configure --target=avr --program-prefix="avr-" --prefix=$PREFIX
make
make install

We download http://gcc.cybermirror.org/releases/gcc-4.3.3/gcc-4.3.3.tar.bz2:

cd /usr/src/
gtar xvf mpfr-2.4.0.tar
cd mpfr-2.4.0
./configure
make
make install

cd /usr/src/avr
mkdir avrgcc
scp ***@192.168.1.7:/home/ahoesch/Downloads/gcc-4.3.3.tar.bz2 .
bunzip2 gcc-4.3.3.tar.bz2
gtar xvf gcc-4.3.3.tar
cd avrgcc
../gcc-4.3.3/configure --target=avr --prefix=/usr/local/avr --enable-languages=c --disable-libssp --disable-shared --disable-libada --disable-libssp --disable-nls --with-dwarf2 --with-gmp=/usr/local --with-mpfr=/usr/local --prefix=/usr/local/avr
make
make install

pico /etc/default/login
pico /etc/default/su

PATH= ...:/usr/local/avr/bin
SUPATH= ...:/usr/local/avr/bin

Relogin to get the new PATH value.

which avr-gcc

We download http://download.savannah.gnu.org/releases/avr-libc/avr-libc-1.8.1.tar.bz2:

cd /usr/src/avr
scp ***@192.168.1.7:/home/ahoesch/Downloads/avr-libc-1.8.1.tar.bz2 .
bunzip2 avr-libc-1.8.1.tar.bz2
gtar xvf avr-libc-1.8.1.tar
cd avr-libc-1.8.1
./configure --host=avr --prefix=/usr/local/avr
make
make install


We sync avrdude-5.8 and arduino.sh from the 192.168.1.2

rsync -avz -e ssh arduino.sh avrdude-5.8 ***@192.168.1.7:/usr/src/avr

and build as follows:

LIBUSB=/usr/sfw
export CPPFLAGS="-I${LIBUSB}/include"
export LDFLAGS="-L${LIBUSB}/lib"
make
make install

This installs

/usr/local/bin/avrdude
/usr/local/etc/avrdude.conf

We can now do

avrdude -c avrispmkII -P usb -p atmega8
...
Jan Waclawek
2014-11-26 22:38:40 UTC
Permalink
What is your avr-gcc version?

Jan
Andreas Höschler
2014-11-26 22:58:59 UTC
Permalink
Hi Jan,
What is your avr-gcc version?
-bash-3.2$ avr-gcc -v
Using built-in specs.
Target: avr
Configured with: ../gcc-4.3.3/configure --target=avr --prefix=/usr/local/avr --enable-languages=c --disable-libssp --disable-shared --disable-libada --disable-libssp --disable-nls --with-dwarf2 --with-gmp=/usr/local --with-mpfr=/usr/local --prefix=/usr/local/avr : (reconfigured) ../gcc-4.3.3/configure --target=avr --prefix=/usr/local/avr --enable-languages=c --disable-libssp --disable-shared --disable-libada --disable-libssp --disable-nls --with-dwarf2 --with-gmp=/usr/local --with-mpfr=/usr/local --prefix=/usr/local/avr : (reconfigured) ../gcc-4.3.3/configure --target=avr --prefix=/usr/local/avr --enable-languages=c --disable-libssp --disable-shared --disable-libada --disable-libssp --disable-nls --with-dwarf2 --with-gmp=/usr/local --with-mpfr=/usr/local --prefix=/usr/local/avr
Thread model: single
gcc version 4.3.3 (GCC)


Thanks,

Andreas
Wim Lewis
2014-10-14 09:52:08 UTC
Permalink
Post by Andreas Höschler
void putLong_in_serial_trans_buffer(uint32_t value)
{
char char_buffer[10];
utoa(value, char_buffer, 10);
The truncation is probably happening here--- utoa() takes an unsigned
int, which is 16 bits on this architecture. Try using ultoa() instead
and see if that helps. Compiling with the -Wconversion option turned on
might warn about this kind of situation.


Wim.
Andreas Höschler
2014-10-14 17:30:59 UTC
Permalink
Hi all,
Post by Wim Lewis
The truncation is probably happening here--- utoa() takes an unsigned
int, which is 16 bits on this architecture. Try using ultoa() instead
and see if that helps. Compiling with the -Wconversion option turned on
might warn about this kind of situation.
The working set of methods:

uint32_t getLong_from_serial_rec_buffer()
{
char char_buffer[10];
int i;
for (i = 0 ; i < 10 ; i++)
{
if (bytes_in_serial_rec_buffer() > 0)
{
char current = buffer[buffer_tail];
if (current >= '0' && current <= '9')
{
get_from_serial_rec_buffer(); // we already know the byte :-)
char_buffer[i] = current;
}
else // is a comma or NULL or whatever other character
{
char_buffer[i] = 0;
uint32_t ret = (uint32_t)strtoul(char_buffer, NULL, 0);
return ret;
}
}
}
return -1;
}

void putLong_in_serial_trans_buffer(uint32_t value)
{
char char_buffer[10];
ltoa(value, char_buffer, 10);
int i;
for (i = 0 ; i < 10 ; i++)
{
char current = char_buffer[i];
if (current != 0) TxByte (current);
else break;
}
}

Thanks,

Andreas
Lv Zheng
2012-02-29 04:19:38 UTC
Permalink
In the code below, avr-gcc can generate errornous result at Os. It could be
a known bug as PR39633.

$ avr-gcc -Os -v -save-temps -dp -o avr-bug.o -c avr-bug.c
Using built-in specs.
COLLECT_GCC=avr-gcc
COLLECT_LTO_WRAPPER=/usr/local/avr/libexec/gcc/avr/4.5.2/lto-wrapper
Target: avr
Configured with:
../../../gcc-4.5.2/configure --target=avr --prefix=/usr/local/avr --with-gmp=/usr/local/avr
--with-mpfr=/usr/local/avr --with-mpc=/usr/local/avr --with-dwarf2 --disable-nls
--disable-threads --disable-shared --disable-multilib --disable-libada --disable-libssp
--disable-libmudflap --enable-target-optspace --enable-languages=c
Thread model: single
gcc version 4.5.2 (GCC)
COLLECT_GCC_OPTIONS='-Os' '-v' '-save-temps' '-dp' '-o' 'avr-bug.o' '-c'
/usr/local/avr/libexec/gcc/avr/4.5.2/cc1 -E -quiet -v
avr-bug.c -Os -fpch-preprocess -o avr-bug.i
ignoring nonexistent directory
"/usr/local/avr/lib/gcc/avr/4.5.2/../../../../avr/sys-include"
#include "..." search starts here:
#include <...> search starts here:
/usr/local/avr/lib/gcc/avr/4.5.2/include
/usr/local/avr/lib/gcc/avr/4.5.2/include-fixed
/usr/local/avr/lib/gcc/avr/4.5.2/../../../../avr/include
End of search list.
COLLECT_GCC_OPTIONS='-Os' '-v' '-save-temps' '-dp' '-o' 'avr-bug.o' '-c'
/usr/local/avr/libexec/gcc/avr/4.5.2/cc1 -fpreprocessed
avr-bug.i -quiet -dumpbase avr-bug.c -dp -auxbase-strip
avr-bug.o -Os -version -o avr-bug.s
GNU C (GCC) version 4.5.2 (avr)
compiled by GNU C version 4.4.5, GMP version 4.3.2, MPFR version 2.4.2, MPC
version 0.8.2
GGC heuristics: --param ggc-min-expand=99 --param ggc-min-heapsize=129302
GNU C (GCC) version 4.5.2 (avr)
compiled by GNU C version 4.4.5, GMP version 4.3.2, MPFR version 2.4.2, MPC
version 0.8.2
GGC heuristics: --param ggc-min-expand=99 --param ggc-min-heapsize=129302
Compiler executable checksum: 5ab3f29dbbb68c653e4e0a10090c3fc4
COLLECT_GCC_OPTIONS='-Os' '-v' '-save-temps' '-dp' '-o' 'avr-bug.o' '-c'
/usr/local/avr/lib/gcc/avr/4.5.2/../../../../avr/bin/as -o avr-bug.o
avr-bug.s
COMPILER_PATH=/usr/local/avr/libexec/gcc/avr/4.5.2/:/usr/local/avr/libexec/gcc/avr/4.5.2/:/usr/local/avr/libexec/gcc/avr/:/usr/local/avr/lib/gcc/avr/4.5.2/:/usr/local/avr/lib/gcc/avr/:/usr/local/avr/lib/gcc/avr/4.5.2/../../../../avr/bin/
LIBRARY_PATH=/usr/local/avr/lib/gcc/avr/4.5.2/:/usr/local/avr/lib/gcc/avr/4.5.2/../../../../avr/lib/
COLLECT_GCC_OPTIONS='-Os' '-v' '-save-temps' '-dp' '-o' 'avr-bug.o' '-c'

$ cat avr-bug.c
#define MAKEWORD(a, b) ((a) | ((unsigned short)(b) << 8))

unsigned char force_z_ref[200];

static unsigned char casted_range_check_opt(unsigned short reg)
{
return (reg >= 100) && (reg < 200);
}

extern unsigned char avoid_further_opt(void);

void bug_playback(void)
{
unsigned char i;
unsigned short reg;
unsigned char val;

for (i = 0; i < (force_z_ref[3]-2); i += 2) {
reg = MAKEWORD(force_z_ref[8+i],
force_z_ref[7+i]);
if (!casted_range_check_opt(reg)) {
val = avoid_further_opt();
}
}
}

$ cat avr-bug.s
.file "avr-bug.c"
__SREG__ = 0x3f
__SP_H__ = 0x3e
__SP_L__ = 0x3d
__tmp_reg__ = 0
__zero_reg__ = 1
.global __do_copy_data
.global __do_clear_bss
.text
.global bug_playback
.type bug_playback, @function
bug_playback:
push r14 ; 67 *pushqi/1 [length = 1]
push r15 ; 68 *pushqi/1 [length = 1]
push r17 ; 69 *pushqi/1 [length = 1]
push r28 ; 70 *pushqi/1 [length = 1]
push r29 ; 71 *pushqi/1 [length = 1]
/* prologue: function */
/* frame size = 0 */
/* stack size = 5 */
.L__stack_usage = 5
ldi r17,lo8(0) ; 6 *movqi/1 [length = 1]
rjmp .L2 ; 82 jump [length = 1]
.L4:
mov r30,r18 ; 56 *movhi/1 [length = 2]
mov r31,r19
subi r30,lo8(-(force_z_ref)) ; 13 *addhi3/4 [length = 2]
sbci r31,hi8(-(force_z_ref))
ldi r24,lo8(0) ; 50 *movqi/1 [length = 1]
mov r28,r24 ; 60 *movhi/1 [length = 2]
mov r29,r25
ldd r24,Z+8 ; 21 *movqi/4 [length = 1]
ldi r25,lo8(0) ; 66 *movqi/1 [length = 1]
or r24,r28 ; 23 iorhi3/1 [length = 2]
or r25,r29
subi r24,lo8(-(-100)) ; 24 *addhi3/4 [length = 2]
sbci r25,hi8(-(-100))
cpi r24,100 ; 25 *cmphi/4 [length = 2]
cpc r25,__zero_reg__
brlo .L3 ; 26 branch [length = 1]
rcall avoid_further_opt ; 29 call_value_insn/3 [length = 1]
.L3:
subi r17,lo8(-(2)) ; 32 addqi3/2 [length = 1]
.L2:
mov r18,r17 ; 61 *movqi/1 [length = 1]
ldi r19,lo8(0) ; 62 *movqi/1 [length = 1]
lds r24,force_z_ref+3 ; 38 *movqi/4 [length = 2]
ldi r25,lo8(0) ; 64 *movqi/1 [length = 1]
sbiw r24,2 ; 40 *addhi3/3 [length = 1]
cp r18,r24 ; 41 *cmphi/3 [length = 2]
cpc r19,r25
brlt .L4 ; 42 branch [length = 1]
/* epilogue start */
pop r29 ; 74 popqi [length = 1]
pop r28 ; 75 popqi [length = 1]
pop r17 ; 76 popqi [length = 1]
pop r15 ; 77 popqi [length = 1]
pop r14 ; 78 popqi [length = 1]
ret ; 79 return_from_epilogue [length = 1]
.size bug_playback, .-bug_playback
.comm force_z_ref,200,1

Best regards/Lv ZETALOG Zheng
Georg-Johann Lay
2012-02-29 21:38:28 UTC
Permalink
Thanks for your suggestions.
We noticed the bug is fixed in the gcc-4.6.
PR46779 is fixed in 4.6.2
We'll upgrade our AVR toolchains and contact you again if any further
bugs can be found.
Please don't write me private mails, thanks.
Best Regards/Lv ZETALOG Zheng
Szikra István
2014-11-08 00:32:52 UTC
Permalink
Hi everyone!

My problem in sort: I’m getting
in r24, 0x18
ldi r25, 0x00
andi r24, 0xEF
out 0x18, r24
instead of
cbi 0x18, 4
.

I’m trying to write efficient modern C/C++ code for multiple platforms
including AVR 8 bit controllers.

Unfortunately GCC support for AVR (among other things) is not always
flawless. And it changes from versions to version (and not always for
the better).
Since I’m a long time AVR developer I have a lot of compiler versions
installed (WinAVR 2006-2010, and Atmel Studio 6.2 with GCC 4.8.1), but I
could test my code with only one (the latest).

I run into some trouble with clearing port bits not translating from C
into cbi in assembler. It is caused by my bits template, but I do not
know why. It seems to me like a bug in GCC. Maybe someone here can shed
some light on the reason, or suggest a fix.

Here is the code:

#include <avr/io.h>
//#include <bits.hpp>

template<typename T>
constexpr unsigned int bits(T idx1)
{
return (1<<idx1);
}
template <typename T, typename... Rest>
constexpr unsigned int bits(T idx1, Rest... r)
{
return (1<<idx1) | bits(r...);
}

int main(void)
{
DDRB = 0x0f;
for(;;) {
PORTB |= bits(4);
PORTB &=~bits(4);

PORTB |= (1<<4);
PORTB &=~(1<<4);
}
}

It’s compiled with avr-gcc (AVR_8_bit_GNU_Toolchain_3.4.4_1229) 4.8.1
(Atmel Studio 6.2):
avr-gcc -c -mmcu=attiny13 -I. -x c++ -gdwarf-2 -DF_CPU=9600000UL -Os
-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
-fno-exceptions -Wall -Wundef -fno-strict-aliasing -Winline
-fno-inline-small-functions -fno-default-inline -save-temps
-Wa,-adhlns=./test.lst -ID:/Lib/ -std=gnu++11 -MMD -MP -MF .dep/test.o.d
test.cpp -o test.o

My older compiler versions do not support -std=gnu++11. By the way,
does anyone know when Atmel is coming out with GCC 4.8.3 version for AVR?

----
Here is the preproc output:
template<typename T>
constexpr unsigned int bits(T idx1)
{
return (1<<idx1);
}
template <typename T, typename... Rest>
constexpr unsigned int bits(T idx1, Rest... r)
{
return (1<<idx1) | bits(r...);
}

int main(void)
{
(*(volatile uint8_t *)((0x17) + 0x20)) = 0x0f;
for(;;) {
(*(volatile uint8_t *)((0x18) + 0x20)) |= bits(4);
(*(volatile uint8_t *)((0x18) + 0x20)) &=~bits(4);

(*(volatile uint8_t *)((0x18) + 0x20)) |= (1<<4);
(*(volatile uint8_t *)((0x18) + 0x20)) &=~(1<<4);
}
}

----
Assembly list file (relevant part only):
19:test.cpp **** for(;;) {
20:test.cpp **** PORTB |= bits(4);
26 .loc 1 20 0 discriminator 1
27 0004 C49A sbi 0x18,4
28 .LVL1:
21:test.cpp **** PORTB &=~bits(4);
29 .loc 1 21 0 discriminator 1
30 0006 88B3 in r24,0x18
31 0008 90E0 ldi r25,0
32 000a 8F7E andi r24,239
33 000c 88BB out 0x18,r24
22:test.cpp ****
23:test.cpp **** PORTB |= (1<<4);
34 .loc 1 23 0 discriminator 1
35 000e C49A sbi 0x18,4
24:test.cpp **** PORTB &=~(1<<4);
36 .loc 1 24 0 discriminator 1
37 0010 C498 cbi 0x18,4


and the objdump (in case someone likes it better, like me)
for(;;) {
PORTB |= bits(4);
26: c4 9a sbi 0x18, 4 ; 24
PORTB &=~bits(4);
28: 88 b3 in r24, 0x18 ; 24
2a: 90 e0 ldi r25, 0x00 ; 0 <---WTF?
2c: 8f 7e andi r24, 0xEF ; 239
2e: 88 bb out 0x18, r24 ; 24

PORTB |= (1<<4);
30: c4 9a sbi 0x18, 4 ; 24
PORTB &=~(1<<4);
32: c4 98 cbi 0x18, 4 ; 24
34: f8 cf rjmp .-16 ; 0x26 <main+0x4>


Regards,
Steven
David Brown
2014-11-08 12:48:30 UTC
Permalink
Post by Szikra István
Hi everyone!
My problem in sort: I’m getting
in r24, 0x18
ldi r25, 0x00
andi r24, 0xEF
out 0x18, r24
instead of
cbi 0x18, 4
.
I’m trying to write efficient modern C/C++ code for multiple platforms
including AVR 8 bit controllers.
Unfortunately GCC support for AVR (among other things) is not always
flawless. And it changes from versions to version (and not always for
the better).
Since I’m a long time AVR developer I have a lot of compiler versions
installed (WinAVR 2006-2010, and Atmel Studio 6.2 with GCC 4.8.1), but I
could test my code with only one (the latest).
I run into some trouble with clearing port bits not translating from C
into cbi in assembler. It is caused by my bits template, but I do not
know why. It seems to me like a bug in GCC. Maybe someone here can shed
some light on the reason, or suggest a fix.
#include <avr/io.h>
//#include <bits.hpp>
template<typename T>
constexpr unsigned int bits(T idx1)
{
return (1<<idx1);
}
template <typename T, typename... Rest>
constexpr unsigned int bits(T idx1, Rest... r)
{
return (1<<idx1) | bits(r...);
}
Just an idea that might be worth trying - try replacing the "unsigned
int" return type with "uint8_t" (/always/ use <stdint.h> types with
defined bit sizes!). AVR gcc has quite a number of optimisations and
special case patterns for dealing with 8-bit types, especially uint8_t,
and it often gives tighter code if you've used uint8_t even if uint16_t
gives the same actual values.

Secondly, consider making your templates based on the value of idx1
rather than the type - the type will always be an int (or promoted to an
int in the shift expression). Alternatively, drop the template entirely.
Szikra István
2014-11-08 20:42:34 UTC
Permalink
Post by David Brown
Post by Szikra István
Hi everyone!
My problem in sort: I’m getting
in r24, 0x18
ldi r25, 0x00
andi r24, 0xEF
out 0x18, r24
instead of
cbi 0x18, 4
.
I’m trying to write efficient modern C/C++ code for multiple platforms
including AVR 8 bit controllers.
Unfortunately GCC support for AVR (among other things) is not always
flawless. And it changes from versions to version (and not always for
the better).
Since I’m a long time AVR developer I have a lot of compiler versions
installed (WinAVR 2006-2010, and Atmel Studio 6.2 with GCC 4.8.1), but I
could test my code with only one (the latest).
I run into some trouble with clearing port bits not translating from C
into cbi in assembler. It is caused by my bits template, but I do not
know why. It seems to me like a bug in GCC. Maybe someone here can shed
some light on the reason, or suggest a fix.
#include <avr/io.h>
//#include <bits.hpp>
template<typename T>
constexpr unsigned int bits(T idx1)
{
return (1<<idx1);
}
template <typename T, typename... Rest>
constexpr unsigned int bits(T idx1, Rest... r)
{
return (1<<idx1) | bits(r...);
}
Just an idea that might be worth trying - try replacing the "unsigned
int" return type with "uint8_t" (/always/ use <stdint.h> types with
defined bit sizes!). AVR gcc has quite a number of optimisations and
special case patterns for dealing with 8-bit types, especially uint8_t,
and it often gives tighter code if you've used uint8_t even if uint16_t
gives the same actual values.
Thanks, I have already tried using unsigned char return type, and also
casting it. It did not help.
PORTB &=~ (uint8_t)bits(4);
28: 88 b3 in r24, 0x18 ; 24
2a: 90 e0 ldi r25, 0x00 ; 0
2c: 8f 7e andi r24, 0xEF ; 239
2e: 88 bb out 0x18, r24 ; 24

But, what helped was casting the result of ~:
PORTB &= (uint8_t)~bits(4);
28: c4 98 cbi 0x18, 4 ; 24
Post by David Brown
Secondly, consider making your templates based on the value of idx1
rather than the type - the type will always be an int (or promoted to an
int in the shift expression). Alternatively, drop the template entirely.
Yeah, I just replaced the bits(idx) with (1<<idx) in my code, till the
bug is fixed. Now I'm changing it to casting...
_port &= (unsigned char)~bits(_index);

What do you mean by basing the template on the value of idx1?
I'm still new to templates. Actually I don't need T at all.

constexpr unsigned int bits(int idx1)
{
return (1<<idx1);
}
template <typename... Rest>
constexpr unsigned int bits(int idx1, Rest... r)
{
return (1<<idx1) | bits(r...);
}


Regards,
Steven
David Brown
2014-11-10 10:18:25 UTC
Permalink
Post by Szikra István
Post by David Brown
Post by Szikra István
Hi everyone!
My problem in sort: I’m getting
in r24, 0x18
ldi r25, 0x00
andi r24, 0xEF
out 0x18, r24
instead of
cbi 0x18, 4
.
I’m trying to write efficient modern C/C++ code for multiple platforms
including AVR 8 bit controllers.
Unfortunately GCC support for AVR (among other things) is not always
flawless. And it changes from versions to version (and not always for
the better).
Since I’m a long time AVR developer I have a lot of compiler versions
installed (WinAVR 2006-2010, and Atmel Studio 6.2 with GCC 4.8.1), but I
could test my code with only one (the latest).
I run into some trouble with clearing port bits not translating from C
into cbi in assembler. It is caused by my bits template, but I do not
know why. It seems to me like a bug in GCC. Maybe someone here can shed
some light on the reason, or suggest a fix.
#include <avr/io.h>
//#include <bits.hpp>
template<typename T>
constexpr unsigned int bits(T idx1)
{
return (1<<idx1);
}
template <typename T, typename... Rest>
constexpr unsigned int bits(T idx1, Rest... r)
{
return (1<<idx1) | bits(r...);
}
Just an idea that might be worth trying - try replacing the "unsigned
int" return type with "uint8_t" (/always/ use <stdint.h> types with
defined bit sizes!). AVR gcc has quite a number of optimisations and
special case patterns for dealing with 8-bit types, especially uint8_t,
and it often gives tighter code if you've used uint8_t even if uint16_t
gives the same actual values.
Thanks, I have already tried using unsigned char return type, and also
casting it. It did not help.
PORTB &=~ (uint8_t)bits(4);
28: 88 b3 in r24, 0x18 ; 24
2a: 90 e0 ldi r25, 0x00 ; 0
2c: 8f 7e andi r24, 0xEF ; 239
2e: 88 bb out 0x18, r24 ; 24
PORTB &= (uint8_t)~bits(4);
28: c4 98 cbi 0x18, 4 ; 24
Post by David Brown
Secondly, consider making your templates based on the value of idx1
rather than the type - the type will always be an int (or promoted to an
int in the shift expression). Alternatively, drop the template entirely.
Yeah, I just replaced the bits(idx) with (1<<idx) in my code, till the
bug is fixed. Now I'm changing it to casting...
_port &= (unsigned char)~bits(_index);
What do you mean by basing the template on the value of idx1?
I'm still new to templates. Actually I don't need T at all.
constexpr unsigned int bits(int idx1)
{
return (1<<idx1);
}
template <typename... Rest>
constexpr unsigned int bits(int idx1, Rest... r)
{
return (1<<idx1) | bits(r...);
}
Regards,
Steven
You can make templates based on constant values, with the syntax:

template<int N>
...

where N is a compile-time constant.

But in this case, it would make the source code uglier (using
"bits<4>()" instead of "bits(4)"), and would not help code generation at
all.

You only actually need templates here to get the variable number of
arguments (without using C-style varadic functions, which are horrible).
So you can drop the templating on T:

constexpr uint8_t bits(int i) {
return 1 << i;
}

template<typename... Rest>
constexpr uint8_t bits(int i, Rest... r) {
return (1 << i) | bits(r...);
}


None of this affects the generated code.


At the moment, the only version of avrgcc I have convenient is avr-gcc
4.5.1 - I don't do much AVR development, and haven't updated for a
while. But this version generates optimal object code for your
templates (after I replace "constexpr" by "const", since gcc 4.5 doesn't
support "constexpr"). So this looks like a regression to me. I seem to
remember the same issue having come up before in the past, but I can't
remember the details.
Joern Rennecke
2014-11-09 16:35:59 UTC
Permalink
Post by Szikra István
Unfortunately GCC support for AVR (among other things) is not always
flawless. And it changes from versions to version (and not always for the
better).
regression tests can help to catch instances where the compiler looses
functionality.

I'm trying to make gcc 5.0 do the right thing. As a matter of fact, I
get a preprocessor failure and an ICE (Internal Compiler Error) there.
Post by Szikra István
Since I’m a long time AVR developer I have a lot of compiler versions
installed (WinAVR 2006-2010, and Atmel Studio 6.2 with GCC 4.8.1), but I
could test my code with only one (the latest).
I run into some trouble with clearing port bits not translating from C into
cbi in assembler. It is caused by my bits template, but I do not know why.
It seems to me like a bug in GCC. Maybe someone here can shed some light on
the reason, or suggest a fix.
May I include that as a test case in the gcc.target/avr testsuite?
Georg-Johann Lay
2014-11-17 09:44:09 UTC
Permalink
Post by Joern Rennecke
Post by Szikra István
Unfortunately GCC support for AVR (among other things) is not always
flawless. And it changes from versions to version (and not always for the
better).
regression tests can help to catch instances where the compiler looses
functionality.
I'm trying to make gcc 5.0 do the right thing. As a matter of fact, I
get a preprocessor failure and an ICE (Internal Compiler Error) there.
There is a typo in predicates.md:low_io_address_operand.

The constant should read 0x20, not 020.

Johann
Joern Rennecke
2014-11-09 21:00:11 UTC
Permalink
Post by Szikra István
Hi everyone!
My problem in sort: I’m getting
in r24, 0x18
ldi r25, 0x00
andi r24, 0xEF
out 0x18, r24
instead of
cbi 0x18, 4
.
I’m trying to write efficient modern C/C++ code for multiple platforms
including AVR 8 bit controllers.
Unfortunately GCC support for AVR (among other things) is not always
flawless. And it changes from versions to version (and not always for the
better).
Since I’m a long time AVR developer I have a lot of compiler versions
installed (WinAVR 2006-2010, and Atmel Studio 6.2 with GCC 4.8.1), but I
could test my code with only one (the latest).
I run into some trouble with clearing port bits not translating from C into
cbi in assembler. It is caused by my bits template, but I do not know why.
It seems to me like a bug in GCC. Maybe someone here can shed some light on
the reason, or suggest a fix.
The transformation would seem prima facia best suited for the combine pass.
When we see the store, we know it's only 8 bit wide, thus we can perform the
arithmetic in 8 bit. However, the store is to a volatile (actually,
I/O) address.
Now, gcc is not very good at optimizing code involving volatile (the
target-independent
code would likely already have simplified the arithmetic if these
weren't in the way -
buy you'd really need a completely different test case without
volatile to keep the
computation relevant).
These memory / I/O accesses require extra ordering constraints, so
large parts of the optimizers just punt when they encounter a volatile
reference.
There is some scope to tweak this - I've attached at proof of concept
patch to optimize
your code (based on gcc 5.0). However, this opens the possibility
that it'll break something with respect to volatile ordering now - or
even later down the line.

ISTR we have some more detailed dependency checks at least in some places. in
fact, if there weren't, we should already see the existing cbi pattern
misbehaving.
consider:
typedef unsigned char uint8_t;

main ()
{
int i = (*(volatile uint8_t *)((0x18) + 0x20)) ;
(*(volatile uint8_t *)((0x17) + 0x20)) = 0x0f;
(*(volatile uint8_t *)((0x18) + 0x20)) = i & ~4;
}
if the complier was oblivious to the intervening write it could
generate a cbi here -
but it doesn't - well, at least not at -O2 ...

Another possible approach would be to use a peephole2 pattern or a
target-specific
optimization pass to do the 16->8 bit arithmetic transformation.
However, if you work after combine (as is definitely the case with peephole2),
you need to
Georg-Johann Lay
2014-11-17 17:17:42 UTC
Permalink
Post by Joern Rennecke
Post by Szikra István
Hi everyone!
My problem in sort: I’m getting
in r24, 0x18
ldi r25, 0x00
andi r24, 0xEF
out 0x18, r24
instead of
cbi 0x18, 4
.
I’m trying to write efficient modern C/C++ code for multiple platforms
including AVR 8 bit controllers.
Unfortunately GCC support for AVR (among other things) is not always
flawless. And it changes from versions to version (and not always for the
better).
Since I’m a long time AVR developer I have a lot of compiler versions
installed (WinAVR 2006-2010, and Atmel Studio 6.2 with GCC 4.8.1), but I
could test my code with only one (the latest).
I run into some trouble with clearing port bits not translating from C into
cbi in assembler. It is caused by my bits template, but I do not know why.
It seems to me like a bug in GCC. Maybe someone here can shed some light on
the reason, or suggest a fix.
The transformation would seem prima facia best suited for the combine pass.
For the code in question it's already differently emit by C vs. C++ front end.

Consider


#define RR (*(unsigned char volatile*) (0x18 + __AVR_SFR_OFFSET__))

static unsigned bits (int n)
{
return 1u << n;
}

void fun (void)
{
RR &= ~bits(4);
}


as a test case which works both for C and C++. The C++ front fails in applying
a similar type demotion like the C front, and no tree pass performs such type
demotion, either.
Post by Joern Rennecke
When we see the store, we know it's only 8 bit wide, thus we can perform the
arithmetic in 8 bit. However, the store is to a volatile (actually,
I/O) address.
Now, gcc is not very good at optimizing code involving volatile (the
target-independent
code would likely already have simplified the arithmetic if these
weren't in the way -
buy you'd really need a completely different test case without
volatile to keep the
computation relevant).
These memory / I/O accesses require extra ordering constraints, so
large parts of the optimizers just punt when they encounter a volatile
reference.
There is some scope to tweak this - I've attached at proof of concept
patch to optimize
Is there a solution that is more reliable than combine? Currently combine
appears to be the best candidate. However there are many constraints that must
be satisfied for such non-matching split to apply. Optimization must be turned
on (it's not only an optimization issue because CBI/SBI are atomic whereas
IN/OP/OUT sequences are not), combine must have a scratch handy, the single-set
must have been cooked up by combine and from 3 insns, etc. And a matching
split is not possible for obvious reasons.

It actually boils down to supplying combine with a split point it fails to find
itself -- for whatever reason...
Post by Joern Rennecke
your code (based on gcc 5.0). However, this opens the possibility
that it'll break something with respect to volatile ordering now - or
even later down the line.
ISTR we have some more detailed dependency checks at least in some places. in
fact, if there weren't, we should already see the existing cbi pattern
misbehaving.
typedef unsigned char uint8_t;
main ()
{
int i = (*(volatile uint8_t *)((0x18) + 0x20)) ;
(*(volatile uint8_t *)((0x17) + 0x20)) = 0x0f;
(*(volatile uint8_t *)((0x18) + 0x20)) = i & ~4;
}
if the complier was oblivious to the intervening write it could
generate a cbi here -
but it doesn't - well, at least not at -O2 ...
The combiner must not come up with a CBI-like pattern for this; it would mean
combine drags a volatile access over an other, and that would be incorrect for
the same reasons like for why PR51374 was a combine bug.
Post by Joern Rennecke
Another possible approach would be to use a peephole2 pattern or a
target-specific
peephole2 is even less reliable than combine here :-( because it's rather about
data flow than about code flow. A single (move) insn that has nothing to do
with the operation and peep2 fails... And in the test case there are also
moves involved so that it's almost impossible to recover from that.
Post by Joern Rennecke
optimization pass to do the 16->8 bit arithmetic transformation.
However, if you work after combine (as is definitely the case with peephole2),
you need to
diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index cc85b79..6e7e353 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -679,8 +679,8 @@ (define_expand "mov<mode>"
;; "movqi_insn"
;; "movqq_insn" "movuqq_insn"
(define_insn "mov<mode>_insn"
- [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r ,d ,Qm ,r ,q,r,*r")
- (match_operand:ALL1 1 "nox_general_operand" "r Y00,n Ynn,r Y00,Qm,r,q,i"))]
+ [(set (match_operand:ALL1 0 "movdst_operand" "=r ,d ,Qm ,r ,q,r,*r")
+ (match_operand:ALL1 1 "nox_general_operand" "r Y00,n Ynn,r Y00,Qm,r,q,i"))]
"(register_operand (operands[0], <MODE>mode)
|| reg_or_0_operand (operands[1], <MODE>mode)) &&
/* skip if operands are out of lds/sts memory access range(0x40..0xbf)
@@ -3086,6 +3086,20 @@ (define_peephole2 ; andi
operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));
})
+; standard promotion can get us a 16 bit int where only an 8 bit value
+; is required. combine-split extend-binop-store to binop-store.
+
+(define_split
+ [(set (match_operand:QI 0 "any_qi_mem_operand")
+ (match_operator 3 "avr_binary_operator"
+ [(match_operand 1 "nonmemory_operand")
+ (match_operand 2 "nonmemory_operand")]))
+ (clobber (match_operand:QI 4 "register_operand"))]
This would work for all 8-bit modes, something like

(define_code_iterator some_binop [xor ior and plus minus mult ashift])

(define_split
[(set (mem:ALL1 (match_operand:ALL1 0 "any_qi_mem_operand" ""))
(some_binop:ALL1 (match_operand:ALL1 1 "nonmemory_operand" "")
(match_operand:ALL1 2 "nonmemory_operand" "")))
(clobber (match_operand:ALL1 3 "register_operand"))]
""
[(set (match_dup 3)
(some_binop:ALL1 (match_dup 1)
(match_dup 2)))
(set (match_dup 0)
(match_dup 3))]

and then something like 1 == GET_MODE_SIZE (mode) in the predicate.
Post by Joern Rennecke
+ ""
+ [(set (match_dup 4) (match_dup 3))
+ (set (match_dup 0) (match_dup 4))]
+ "");
+
;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
;; ior
diff --git a/gcc/config/avr/predicates.md b/gcc/config/avr/predicates.md
index 4b456a5..ea8e095 100644
--- a/gcc/config/avr/predicates.md
+++ b/gcc/config/avr/predicates.md
@@ -69,6 +69,24 @@ (define_predicate "nop_general_operand"
(and (match_operand 0 "general_operand")
(match_test "!avr_mem_flash_p (op)")))
+; allow a QImode memory operand, including volatile / I/O.
+(define_predicate "any_qi_mem_operand"
+ (and (match_code "mem")
+ (match_test "address_operand (XEXP (op, 0), Pmode)")
+ (match_test "mode == QImode")))
+
+;; We also allow volatile memory here, so that the combiner can work with
+;; stores for I/O accesses as combiner-splitter results.
+;; As this is for a destination location, that should generally be safe
+;; for combine, as we should he handling the last insn then, which stays
+;; in place.
+;; ??? Could this ever match for a two-destination combination?
+;; ??? Should we make sure this predicate can't match I/O for transformations
+;; with a wider scope, like store sinking?
Unfortunately there is no easy going way to query GCC for the current pass,
e.g. something like combine_in_progress or combine_completed...

May it be the case that some pass changes the access width or split one HI
access to 2*QI, e.g. subreg lowering? Using a different predicate (or
otherwise hacking around volatile_ok) is inevitable to make this solution work
with combine, hence it would be highly appreciated to forge the new predicate
in such a way that it is the same like the original one except for insn combiner.
Post by Joern Rennecke
+(define_predicate "movdst_operand"
+ (ior (match_operand 0 "nonimmediate_operand")
+ (match_operand 0 "any_qi_mem_operand")))
+
;; Return 1 if OP is an "ordinary" general operand, i.e. a general
;; operand whose load is not handled by a libgcc call or ELPM.
(define_predicate "nox_general_operand"
@@ -180,6 +198,10 @@ (define_predicate "simple_comparison_operator"
(and (match_operand 0 "comparison_operator")
(not (match_code "gt,gtu,le,leu"))))
+; A binary operator that the avr can perform in a single insn.
+(define_predicate "avr_binary_operator"
+ (match_code "and,ior,xor,plus,minus"))
+
;; Return true if OP is a valid call operand.
(define_predicate "call_insn_operand"
(and (match_code "mem")
Joern Rennecke
2014-11-17 18:49:21 UTC
Permalink
Post by Georg-Johann Lay
as a test case which works both for C and C++. The C++ front fails in
applying a similar type demotion like the C front,
Well, duh, that's because it's a different language.
Post by Georg-Johann Lay
Is there a solution that is more reliable than combine? Currently combine
appears to be the best candidate. However there are many constraints that
must be satisfied for such non-matching split to apply. Optimization must
be turned on (it's not only an optimization issue because CBI/SBI are atomic
whereas IN/OP/OUT sequences are not),
The only way you can get these atomic operations without optimizations is
to request them in the first place, e.g. by adding & using a built-in
function for cbi.
Post by Georg-Johann Lay
The combiner must not come up with a CBI-like pattern for this; it would
mean combine drags a volatile access over an other, and that would be
incorrect for the same reasons like for why PR51374 was a combine bug.
The fact that combine.c uses init_recog_no_volatile clearly shows that
combine was not designed with operating on volatile operations in mind.
If combine was all fixed up and audited to be volatile safe, we should be
able to use init_recog instead.
The avr port recognizing volatile irrespective of volatile_ok is
playing with fire.
Post by Georg-Johann Lay
Post by Joern Rennecke
Another possible approach would be to use a peephole2 pattern or a
target-specific
peephole2 is even less reliable than combine here :-( because it's rather
peephole2 is more specific, thus it can be used more safely, i.e. not easier to
avoid unwanted transformations. But by the same token, the desired
transformation
is only performed when the instructions are layed out in an anticipated pattern.
Post by Georg-Johann Lay
about data flow than about code flow. A single (move) insn that has nothing
to do with the operation and peep2 fails...
You can make peephole2 patterns that anticipate a fixed number and placement of
unrelated instructions.
Post by Georg-Johann Lay
This would work for all 8-bit modes, something like
(define_code_iterator some_binop [xor ior and plus minus mult ashift])
(define_split
[(set (mem:ALL1 (match_operand:ALL1 0 "any_qi_mem_operand" ""))
(some_binop:ALL1 (match_operand:ALL1 1 "nonmemory_operand" "")
(match_operand:ALL1 2 "nonmemory_operand" "")))
(clobber (match_operand:ALL1 3 "register_operand"))]
""
[(set (match_dup 3)
(some_binop:ALL1 (match_dup 1)
(match_dup 2)))
(set (match_dup 0)
(match_dup 3))]
and then something like 1 == GET_MODE_SIZE (mode) in the predicate.
We started with the premise that the patterns we want to optimize come from
C integer promotion rules. So we have to watch out for integer modes.
Does the optimization problem also arise frequently enough with non-integer
modes that we'd care to make our code more complicated for that?
Oh, and as mentioned above, we're playing with fire, now you want a bigger
conflagration...
Post by Georg-Johann Lay
Unfortunately there is no easy going way to query GCC for the current pass,
e.g. something like combine_in_progress or combine_completed...
How about (strcmp (current_pass->name, "combine") == 0) ?

If you want to know if the combine pass has run, you can insert
a new pass after it that sets a flag.
Andreas Höschler
2014-11-27 11:43:59 UTC
Permalink
Date: November 27, 2014 8:40:36 AM GMT+01:00
Subject: Re: [avr-gcc-list] Programming ATMega2560
That's strange as by 4.3.3 the avr6 (subfamily/group where both ATMega256x
belong) support was certainly already established. I use 4.2.2 for my
daily work with ATMega2560.
But it is known to be tricky to build a working package. Your "free" way is
too suspicious.
Post by Andreas Höschler
What components contains the chip infos?
All of them, in some way - that's part of why it's tricky.
You better stick to tried proven packages; and better to go for 4.8+,
benefiting from accessing FLASH through the named address space features.
One of them might be the Atmel builds,
http://www.atmel.com/tools/atmelavrtoolchainforlinux.aspx
Other may be built using Bingo's scripts, see
http://www.avrfreaks.net/forum/script-building-avr-gcc-451-linux
JW
----- Original Message ---------------
Post by Andreas Höschler
Hi Jan,
What is your avr-gcc version?
-bash-3.2$ avr-gcc -v
Using built-in specs.
Target: avr
Configured with: ../gcc-4.3.3/configure --target=avr --prefix=/usr/local/avr --enable-languages=c --disable-libssp --disable-shared --disable-libada --disable-libssp --disable-nls --with-dwarf2 --with-gmp=/usr/local --with-mpfr=/usr/local --prefix=/usr/local/avr : (reconfigured) ../gcc-4.3.3/configure --target=avr --prefix=/usr/local/avr --enable-languages=c --disable-libssp --disable-shared --disable-libada --disable-libssp --disable-nls --with-dwarf2 --with-gmp=/usr/local --with-mpfr=/usr/local --prefix=/usr/local/avr : (reconfigured) ../gcc-4.3.3/configure --target=avr --prefix=/usr/local/avr --enable-languages=c --disable-libssp --disable-shared --disable-libada --disable-libssp --disable-nls --with-dwarf2 --with-gmp=/usr/local --with-mpfr=/usr/local --prefix=/usr/local/avr
Thread model: single
gcc version 4.3.3 (GCC)
Thanks,
Andreas
Andreas Höschler
2014-11-27 11:54:26 UTC
Permalink
Hi Jan,
That's strange as by 4.3.3 the avr6 (subfamily/group where both ATMega256x
belong) support was certainly already established. I use 4.2.2 for my
daily work with ATMega2560.
avr6 definitely does not show up in my "Known MCU names:" list. It ends at avr5!? :-(

And my gcc is

Configured with: ../gcc-4.3.3/configure --target=avr --prefix=/usr/local/avr --enable-languages=c --disable-libssp --disable-shared --disable-libada --disable-libssp --disable-nls --with-dwarf2 --with-gmp=/usr/local --with-mpfr=/usr/local --prefix=/usr/local/avr : (reconfigured) ../gcc-4.3.3/configure --target=avr --prefix=/usr/local/avr --enable-languages=c --disable-libssp --disable-shared --disable-libada --disable-libssp --disable-nls --with-dwarf2 --with-gmp=/usr/local --with-mpfr=/usr/local --prefix=/usr/local/avr : (reconfigured) ../gcc-4.3.3/configure --target=avr --prefix=/usr/local/avr --enable-languages=c --disable-libssp --disable-shared --disable-libada --disable-libssp --disable-nls --with-dwarf2 --with-gmp=/usr/local --with-mpfr=/usr/local --prefix=/usr/local/avr
Thread model: single
gcc version 4.3.3 (GCC)
But it is known to be tricky to build a working package. Your "free" way is
too suspicious.
You better stick to tried proven packages; and better to go for 4.8+,
I need this on Sun Solaris and doubt anyone is offering ready-to-use packages for this platform. So I have to build from sources.

Anyone had success building the chain from sources and got avr6 support?

Thanks,

Andreas
Jan Waclawek
2014-11-27 12:11:25 UTC
Permalink
Post by Andreas Höschler
Post by Jan Waclawek
What is your avr-gcc version?
Configured with: ../gcc-4.3.3/
That's strange as by 4.3.3 the avr6 (subfamily/group where both ATMega256x
belong) support was certainly already established. I use 4.2.2 for my
daily work with ATMega2560.

But it is known to be tricky to build a working package. Your "free" way is
too suspicious.
Post by Andreas Höschler
What components contains the chip infos?
All of them, in some way - that's part of why it's tricky.

You better stick to tried proven packages; and better to go for 4.8+,
benefiting from accessing FLASH through the named address space features.

One of them might be the Atmel builds,
http://www.atmel.com/tools/atmelavrtoolchainforlinux.aspx

Other may be built using Bingo's scripts, see
http://www.avrfreaks.net/forum/script-building-avr-gcc-451-linux


JW
Andreas Höschler
2014-11-27 21:56:21 UTC
Permalink
Hi Jan and all,
That's strange as by 4.3.3 the avr6 (subfamily/group where both ATMega256x
belong) support was certainly already established. I use 4.2.2 for my
daily work with ATMega2560.
But it is known to be tricky to build a working package. Your "free" way is
too suspicious.
I googled a lot on this problem and this time tried to build the chain on MacOSX (recipe below). I still hit the same problem. It simply won't build code for the atmega2560 chip! :-(

avr-gcc -v

Using built-in specs.
Target: avr
Configured with: ../gcc-4.2.4/configure --target=avr --prefix=/usr/local/avr --enable-languages=c --disable-libssp : (reconfigured) ../gcc-4.2.4/configure --target=avr --prefix=/usr/local/avr --enable-languages=c --disable-libssp
Thread model: single
gcc version 4.2.4


avr-gcc -mmcu=atmega2560 main.c

unknown MCU 'atmega2560' specified
Known MCU names:
...
main.c:1: error: MCU ‘atmega2560’ supported for assembler only

When configuring avr-libc (as shown below) I get

checking if avr-gcc has support for atmega2560... no
checking if avr-gcc has support for atmega2561... no

No wonder it does not work. But gcc-4.2.4 is supposed to have atmega2560 support, isn't it?

I am clueless! :-( Any hints are greatly appreciated. See below for my tool chain cook recipe. I also tried avrfreaks but no response so far!

Thanks,

Andreas

**************************************************************************************
PREFIX=/usr/local/avr
export PREFIX
PATH=$PATH:$PREFIX/bin
export PATH

su -
cd /usr/src
mkdir avr
cd avr
gunzip binutils-2.24.tar.gz
gnutar xvf binutils-2.24.tar
cd binutils-2.24
./configure --target=avr --program-prefix="avr-" --prefix=$PREFIX
make
make install

We download https://gmplib.org/download/gmp/gmp-6.0.0a.tar.bz2 from https://gmplib.org/#DOWNLOAD

cd /usr/src
bunzip2 gmp-6.0.0a.tar.bz2
tar xvf gmp-6.0.0a.tar
cd gmp-6.0.0
./configure
make
make check
make install

We downlaod mpfr from http://www.mpfr.org:

cd /usr/src/
bunzip2 mpfr-3.1.2.tar.bz2
tar xvf mpfr-3.1.2.tar
cd mpfr-3.1.2
./configure
make
make check
make install

We download http://gcc.cybermirror.org/releases/gcc-4.2.0/gcc-4.2.0.tar.bz2:

cd /usr/src/avr
mkdir avrgcc
bunzip2 gcc-4.2.4.tar.bz2
tar xvf gcc-4.2.4.tar
cd avrgcc
../gcc-4.2.4/configure --target=avr --prefix=$PREFIX --enable-languages=c --disable-libssp
make
make install

We download http://download.savannah.gnu.org/releases/avr-libc/avr-libc-1.8.1.tar.bz2:

cd /usr/src/avr
bunzip2 avr-libc-1.8.1.tar.bz2
gtar xvf avr-libc-1.8.1.tar
cd avr-libc-1.8.1
./configure --host=avr --prefix=$PREFIX
make
make install
Jan Waclawek
2014-11-27 22:56:20 UTC
Permalink
Post by Andreas Höschler
I googled a lot on this problem and this time tried to build the chain on MacOSX (recipe below). I still hit the same problem. It simply won't build code for the atmega2560 chip! :-(
The device list in gcc is in gcc/config/avr/avr-devices.c - can you see
atmega2560/2561 there?

JW
Andreas Höschler
2014-11-27 23:24:20 UTC
Permalink
Hi Jan,
Post by Jan Waclawek
Post by Andreas Höschler
I googled a lot on this problem and this time tried to build the chain on MacOSX (recipe below). I still hit the same problem. It simply won't build code for the atmega2560 chip! :-(
The device list in gcc is in gcc/config/avr/avr-devices.c - can you see
atmega2560/2561 there?
I do not even have this file in my gcc tree! :-(

pwd
/usr/src/avr/gcc-4.2.4

ls ./gcc/config/avr
avr-protos.h avr.h avr.opt libgcc.S rtems.h t-rtems
avr.c avr.md constraints.md predicates.md t-avr

Andreas
Andreas Höschler
2014-11-28 13:02:43 UTC
Permalink
Hi Jan,

I checked the Linux scripts you pointed to and tried to apply what they have therein. They patch the gcc 4.5.1 sources. Part of the patch is bringing the avr-devices.c file into the gcc source tree.

I could run all the patches on my gcc 4.5.1 tree. Unfortunately building the gcc fails then (see below for details)!
Post by Jan Waclawek
Post by Andreas Höschler
I googled a lot on this problem and this time tried to build the chain on MacOSX (recipe below). I still hit the same problem. It simply won't build code for the atmega2560 chip! :-(
The device list in gcc is in gcc/config/avr/avr-devices.c - can you see
atmega2560/2561 there?
I then tried to copy avr-devices.c from the patched gcc 4.5.1 tree over to the gcc 4.2.4 tree. I can build the 4.2.4 tree but configuring avr-libc still says that gcc does not support atmega2560.

./configure --host=avr --prefix=$PREFIX | grep 2560

checking if avr-gcc has support for atmega2560... no
config.status: creating avr/lib/avr6/atmega2560/Makefile

And making my project afterwards still brings the same error message:

unknown MCU 'atmega2560' specified
main.c:1: error: MCU ‘atmega2560’ supported for assembler only
make: *** [toggle_led.out] Error 1

It seems you have a working gcc 4.2.4 source tree on your machine!? Would you be willing to tar your tree and send it over to me? This is indeed tricky stuff.

Any other ideas?

Thanks a lot,

Andreas


**************************************************************
Running configure in multilib subdir avrtiny10
pwd: /usr/src/avr/avrgcc/avr
mkdir avrtiny10
configure: creating cache ./config.cache
checking for --enable-version-specific-runtime-libs... no
checking for a BSD-compatible install... /usr/bin/install -c
checking for gawk... awk
checking build system type... x86_64-apple-darwin10.8.0
checking host system type... avr-unknown-none
checking for avr-ar... /usr/local/avr/avr/bin/ar
checking for avr-lipo... avr-lipo
checking for avr-nm... /usr/src/avr/avrgcc/./gcc/nm
checking for avr-ranlib... /usr/local/avr/avr/bin/ranlib
checking for avr-strip... /usr/local/avr/avr/bin/strip
checking whether ln -s works... yes
checking for avr-gcc... /usr/src/avr/avrgcc/./gcc/xgcc -B/usr/src/avr/avrgcc/./gcc/ -B/usr/local/avr/avr/bin/ -B/usr/local/avr/avr/lib/ -isystem /usr/local/avr/avr/include -isystem /usr/local/avr/avr/sys-include -mmcu=avrtiny10
checking for suffix of object files... configure: error: in `/usr/src/avr/avrgcc/avr/avrtiny10/libgcc':
configure: error: cannot compute suffix of object files: cannot compile
See `config.log' for more details.
make[1]: *** [configure-target-libgcc] Error 1
make: *** [all] Error 2
admins-Mac-mini-2:avrgcc root#
cfo
2014-11-28 17:12:17 UTC
Permalink
Hi Jan,
I checked the Linux scripts you pointed to and tried to apply what they
have therein. They patch the gcc 4.5.1 sources. Part of the patch is
bringing the avr-devices.c file into the gcc source tree.
You do know that you'd have to apply the included binutils patches to
binutils also ??

Some of the avr device def's usually have to be made in both binutils &
gcc

/Bingo
Andreas Höschler
2014-11-28 22:58:10 UTC
Permalink
Hi all,
Post by cfo
Post by Andreas Höschler
I checked the Linux scripts you pointed to and tried to apply what they
have therein. They patch the gcc 4.5.1 sources. Part of the patch is
bringing the avr-devices.c file into the gcc source tree.
You do know that you'd have to apply the included binutils patches to
binutils also ??
Some of the avr device def's usually have to be made in both binutils &
gcc
Thanks a lot for this hint. I indeed had not patched binutils. Doing so solved a lot of problems. However, the gcc build still does not go through completely. It stops in one avr subdir:

Running configure in multilib subdir avrtiny10
pwd: /usr/src/avr/avrgcc/avr
mkdir avrtiny10
configure: creating cache ./config.cache
checking for --enable-version-specific-runtime-libs... no
checking for a BSD-compatible install... /usr/bin/install -c
checking for gawk... awk
checking build system type... x86_64-apple-darwin10.8.0
checking host system type... avr-unknown-none
checking for avr-ar... /usr/local/avr/avr/bin/ar
checking for avr-lipo... avr-lipo
checking for avr-nm... /usr/src/avr/avrgcc/./gcc/nm
checking for avr-ranlib... /usr/local/avr/avr/bin/ranlib
checking for avr-strip... /usr/local/avr/avr/bin/strip
checking whether ln -s works... yes
checking for avr-gcc... /usr/src/avr/avrgcc/./gcc/xgcc -B/usr/src/avr/avrgcc/./gcc/ -B/usr/local/avr/avr/bin/ -B/usr/local/avr/avr/lib/ -isystem /usr/local/avr/avr/include -isystem /usr/local/avr/avr/sys-include -mmcu=avrtiny10
checking for suffix of object files... configure: error: in `/usr/src/avr/avrgcc/avr/avrtiny10/libgcc':
configure: error: cannot compute suffix of object files: cannot compile
See `config.log' for more details.
make[1]: *** [configure-target-libgcc] Error 1
make: *** [all] Error 2

When I move avrtiny10 away

mv avrtiny10 avrtiny10_

the gcc build succeeds. But this gets me into trouble when building avr-libc! :-( So I guess I have to figure out what the problem is with this avrtiny10 subdir! The config.log says

...
localstatedir='${prefix}/var'
mandir='${datarootdir}/man'
oldincludedir='/usr/include'
pdfdir='${docdir}'
prefix='/usr/local/avr'
program_transform_name='s&^&avr-&'
psdir='${docdir}'
sbindir='${exec_prefix}/sbin'
set_have_cc_tls=''
set_use_emutls=''
sharedstatedir='${prefix}/com'
slibdir='$(exec_prefix)/$(host_noncanonical)/lib'
sysconfdir='${prefix}/etc'
target_alias='avr'
target_subdir='avr'
tmake_file=''
vis_hide=''

## ----------- ##
## confdefs.h. ##
## ----------- ##

/* confdefs.h */
#define PACKAGE_NAME "GNU C Runtime Library"
#define PACKAGE_TARNAME "libgcc"
#define PACKAGE_VERSION "1.0"
#define PACKAGE_STRING "GNU C Runtime Library 1.0"
#define PACKAGE_BUGREPORT ""
#define PACKAGE_URL "http://www.gnu.org/software/libgcc/"

configure: exit 1

I have no idea what this means and how this can be fixed. I applied all 20 gcc patches one after the other and all went through without error messages (see below). Still the tree does not build. I am rather clueless here! :-(

Hints still greatly appreciated!!

Thanks a lot,

Andreas

****************************************************************************************

cd /usr/src/avr
mkdir avrgcc
bunzip2 gcc-4.5.1.tar.bz2
tar xvf gcc-4.5.1.tar
cd gcc-4.5.1

patch -p0 < /usr/src/gcc-4.5.1-patches/patch-200-gcc-4.5.1-libiberty-Makefile.in
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-300-gcc-4.5.1-fixedpoint-3-4-2010
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-301-gcc-4.5.1-xmega-v14
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-302-gcc-4.5.1-avrtiny10
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-303-gcc-4.5.1-osmain
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-304-gcc-4.5.1-builtins-v6
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-305-gcc-4.5.1-avrtiny10-non-fixedpoint
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-306-gcc-4.5.1-option-list-devices
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-400-gcc-4.5.1-new-devices
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-401-gcc-4.5.1-atmega32_5_50_90_pa
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-402-gcc-4.5.1-attiny1634
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-403-gcc-4.5.1-atmega48pa
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-500-gcc-4.5.1-bug13473
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-501-gcc-4.5.1-bug13579
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-502-gcc-4.5.1-bug-18145-v4
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-503-gcc-4.5.1-avrtiny10-bug-12510
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-504-gcc-4.5.1-bug12915
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-505-gcc-4.5.1-bug13932
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-506-gcc-4.5.1-bug13789
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-599-gcc-4.5.1-bug46779
cd ..
cd avrgcc
../gcc-4.5.1/configure --target=avr --prefix=$PREFIX --with-gnu-ld --with-gnu-as --enable-languages="c,c++" --disable-libssp --with-dwarf2 --with-gmp=/usr/local --with-mpfr=/usr/local
make
Andreas Höschler
2014-12-01 19:49:16 UTC
Permalink
Hi,

I would like to thank you all for helping me out while setting up the tool chain on MacOSX. I finally got it working!! For whomever is interested here is the list of required steps:

Thanks a lot,

Andreas

************************************************************************************************************************

PREFIX=/usr/local/avr
export PREFIX
PATH=$PATH:$PREFIX/bin
export PATH

We download http://ftp.gnu.org/gnu/binutils/binutils-2.20.1.tar.gz:
We download http://www.smartsoft.de/Downloads/binutils-2.20.1-patches.tar.gz

cd /usr/src
gunzip binutils-2.20.1-patches.tar.gz
tar xvf binutils-2.20.1-patches.tar

mkdir avr
cd avr
bunzip2 binutils-2.20.1.tar.bz2
gnutar xvf binutils-2.20.1.tar
cd binutils-2.20.1

patch -p0 < /usr/src/binutils-2.20.1-patches/patch-300-binutils-2.20.1-avr-size
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-301-binutils-2.20.1-avr-coff
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-302-binutils-2.20.1-new-sections
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-303-binutils-2.20.1-as-dwarf
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-304-binutils-2.20.1-dwarf2-AVRStudio-workaround
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-305-binutils-2.20.1-assembler-options
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-400-binutils-2.20.1-xmega
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-401-binutils-2.20.1-new-devices
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-402-binutils-2.20.1-avrtiny10
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-403-binutils-2.20.1-xmega128a1u-64a1u
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-404-binutils-2.20.1-atxmega16x1-32x1
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-405-binutils-2.20.1-atxmega128b1
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-406-binutils-2.20.1-atxmega256a3bu
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-407-binutils-2.20.1-at90pwm161
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-408-binutils-2.20.1-atmega16hvb-32hvb
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-409-binutils-2.20.1-atmega32_5_50_90_pa
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-410-binutils-2.20.1-attiny1634
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-411-binutils-2.20.1-atmega48pa
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-500-binutils-2.20.1-bug13789
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-Makefile.in

CFLAGS="-Wno-error -g -O2" ./configure --target=avr --program-prefix="avr-" --prefix=$PREFIX --disable-nls
make
make install

We download https://gmplib.org/download/gmp/gmp-6.0.0a.tar.bz2 from https://gmplib.org/#DOWNLOAD

cd /usr/src
bunzip2 gmp-6.0.0a.tar.bz2
tar xvf gmp-6.0.0a.tar
cd gmp-6.0.0
./configure
make
make check
make install

We download mpfr from http://www.mpfr.org!
We download http://www.smartsoft.de/Downloads/mpfr-3.1.2-patches.tar.gz!

cd /usr/src/
gunzip mpfr-3.1.2-patches.tar.gz
tar xvf mpfr-3.1.2-patches.tar

bunzip2 mpfr-3.1.2.tar.bz2
tar xvf mpfr-3.1.2.tar
cd mpfr-3.1.2
patch -N -Z -p1 < /usr/src/mpfr-3.1.2-patches/allpatches
./configure
make
make check
make install

We download mpc from http://www.multiprecision.org/?prog=mpc&page=download.

cd /usr/src/
gunzip mpc-1.0.2.tar.gz
tar xvf mpc-1.0.2.tar
cd mpc-1.0.2
./configure
make
make install

We download http://gcc.cybermirror.org/releases/gcc-4.5.1/gcc-4.5.1.tar.bz2:
We download http://www.smartsoft.de/Downloads/gcc-4.5.1-patches.tar.gz

cd /usr/src/
gunzip gcc-4.5.1-patches.tar.gz
tar xvf gcc-4.5.1-patches.tar

cd /usr/src/avr
mkdir avrgcc
bunzip2 gcc-4.5.1.tar.bz2
tar xvf gcc-4.5.1.tar
cd gcc-4.5.1

patch -p0 < /usr/src/gcc-4.5.1-patches/patch-200-gcc-4.5.1-libiberty-Makefile.in
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-300-gcc-4.5.1-fixedpoint-3-4-2010
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-301-gcc-4.5.1-xmega-v14
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-302-gcc-4.5.1-avrtiny10
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-303-gcc-4.5.1-osmain
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-304-gcc-4.5.1-builtins-v6
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-305-gcc-4.5.1-avrtiny10-non-fixedpoint
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-306-gcc-4.5.1-option-list-devices
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-400-gcc-4.5.1-new-devices
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-401-gcc-4.5.1-atmega32_5_50_90_pa
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-402-gcc-4.5.1-attiny1634
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-403-gcc-4.5.1-atmega48pa
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-500-gcc-4.5.1-bug13473
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-501-gcc-4.5.1-bug13579
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-502-gcc-4.5.1-bug-18145-v4
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-503-gcc-4.5.1-avrtiny10-bug-12510
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-504-gcc-4.5.1-bug12915
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-505-gcc-4.5.1-bug13932
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-506-gcc-4.5.1-bug13789
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-599-gcc-4.5.1-bug46779
cd ..
cd avrgcc
../gcc-4.5.1/configure --target=avr --prefix=$PREFIX --with-gnu-ld --with-gnu-as --enable-languages="c,c++" --with-gmp=/usr/local --with-mpfr=/usr/local --disable-nls --disable-libssp --with-dwarf2
make
make install

We download http://download.savannah.gnu.org/releases/avr-libc/avr-libc-1.8.1.tar.bz2:

cd /usr/src/avr
bunzip2 avr-libc-1.8.1.tar.bz2
tar xvf avr-libc-1.8.1.tar
cd avr-libc-1.8.1
./configure --host=avr --prefix=$PREFIX --build=`./config.guess`
make
make install
David Gustavson
2014-12-01 20:01:31 UTC
Permalink
Wow, what a process!
Thank you so much for documenting the whole thing so the rest of us
don't have to piece it together for ourselves!

DaveGadgeteer
Post by Andreas Höschler
Hi,
I would like to thank you all for helping me out while setting up the
tool chain on MacOSX. I finally got it working!! For whomever is
Thanks a lot,
Andreas
************************************************************************************************************************
PREFIX=/usr/local/avr
export PREFIX
PATH=$PATH:$PREFIX/bin
export PATH
We download
http://www.smartsoft.de/Downloads/binutils-2.20.1-patches.tar.gz
cd /usr/src
gunzip binutils-2.20.1-patches.tar.gz
tar xvf binutils-2.20.1-patches.tar
mkdir avr
cd avr
bunzip2 binutils-2.20.1.tar.bz2
gnutar xvf binutils-2.20.1.tar
cd binutils-2.20.1
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-300-binutils-2.20.1-avr-size
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-301-binutils-2.20.1-avr-coff
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-302-binutils-2.20.1-new-sections
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-303-binutils-2.20.1-as-dwarf
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-304-binutils-2.20.1-dwarf2-AVRStudio-workaround
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-305-binutils-2.20.1-assembler-options
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-400-binutils-2.20.1-xmega
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-401-binutils-2.20.1-new-devices
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-402-binutils-2.20.1-avrtiny10
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-403-binutils-2.20.1-xmega128a1u-64a1u
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-404-binutils-2.20.1-atxmega16x1-32x1
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-405-binutils-2.20.1-atxmega128b1
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-406-binutils-2.20.1-atxmega256a3bu
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-407-binutils-2.20.1-at90pwm161
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-408-binutils-2.20.1-atmega16hvb-32hvb
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-409-binutils-2.20.1-atmega32_5_50_90_pa
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-410-binutils-2.20.1-attiny1634
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-411-binutils-2.20.1-atmega48pa
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-500-binutils-2.20.1-bug13789
patch -p0 < /usr/src/binutils-2.20.1-patches/patch-Makefile.in
CFLAGS="-Wno-error -g -O2" ./configure --target=avr --program-prefix="avr-" --prefix=$PREFIX --disable-nls
make
make install
We download https://gmplib.org/download/gmp/gmp-6.0.0a.tar.bz2 from
https://gmplib.org/#DOWNLOAD
cd /usr/src
bunzip2 gmp-6.0.0a.tar.bz2
tar xvf gmp-6.0.0a.tar
cd gmp-6.0.0
./configure
make
make check
make install
We download mpfr from http://www.mpfr.org!
We download http://www.smartsoft.de/Downloads/mpfr-3.1.2-patches.tar.gz!
cd /usr/src/
gunzip mpfr-3.1.2-patches.tar.gz
tar xvf mpfr-3.1.2-patches.tar
bunzip2 mpfr-3.1.2.tar.bz2
tar xvf mpfr-3.1.2.tar
cd mpfr-3.1.2
patch -N -Z -p1 < /usr/src/mpfr-3.1.2-patches/allpatches
./configure
make
make check
make install
We download mpc from
http://www.multiprecision.org/?prog=mpc&page=download.
cd /usr/src/
gunzip mpc-1.0.2.tar.gz
tar xvf mpc-1.0.2.tar
cd mpc-1.0.2
./configure
make
make install
We download
We download http://www.smartsoft.de/Downloads/gcc-4.5.1-patches.tar.gz
cd /usr/src/
gunzip gcc-4.5.1-patches.tar.gz
tar xvf gcc-4.5.1-patches.tar
cd /usr/src/avr
mkdir avrgcc
bunzip2 gcc-4.5.1.tar.bz2
tar xvf gcc-4.5.1.tar
cd gcc-4.5.1
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-200-gcc-4.5.1-libiberty-Makefile.in
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-300-gcc-4.5.1-fixedpoint-3-4-2010
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-301-gcc-4.5.1-xmega-v14
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-302-gcc-4.5.1-avrtiny10
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-303-gcc-4.5.1-osmain
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-304-gcc-4.5.1-builtins-v6
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-305-gcc-4.5.1-avrtiny10-non-fixedpoint
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-306-gcc-4.5.1-option-list-devices
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-400-gcc-4.5.1-new-devices
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-401-gcc-4.5.1-atmega32_5_50_90_pa
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-402-gcc-4.5.1-attiny1634
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-403-gcc-4.5.1-atmega48pa
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-500-gcc-4.5.1-bug13473
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-501-gcc-4.5.1-bug13579
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-502-gcc-4.5.1-bug-18145-v4
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-503-gcc-4.5.1-avrtiny10-bug-12510
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-504-gcc-4.5.1-bug12915
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-505-gcc-4.5.1-bug13932
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-506-gcc-4.5.1-bug13789
patch -p0 < /usr/src/gcc-4.5.1-patches/patch-599-gcc-4.5.1-bug46779
cd ..
cd avrgcc
../gcc-4.5.1/configure --target=avr --prefix=$PREFIX --with-gnu-ld --with-gnu-as --enable-languages="c,c++" --with-gmp=/usr/local --with-mpfr=/usr/local --disable-nls --disable-libssp --with-dwarf2
make
make install
We download
cd /usr/src/avr
bunzip2 avr-libc-1.8.1.tar.bz2
tar xvf avr-libc-1.8.1.tar
cd avr-libc-1.8.1
./configure --host=avr --prefix=$PREFIX --build=`./config.guess`
make
make install
_______________________________________________
AVR-GCC-list mailing list
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Andreas Höschler
2014-12-01 21:50:08 UTC
Permalink
Hi all,
Post by David Gustavson
Wow, what a process!
Thank you so much for documenting the whole thing so the rest of us
don't have to piece it together for ourselves!
Just for the record, the following chain of commands works on Sun Solaris (10 Intel)! :-)

Best wishes,

Andreas

*********************************************************************************************

PREFIX=/usr/local/avr
export PREFIX
PATH=$PATH:$PREFIX/bin
export PATH

We download http://ftp.gnu.org/gnu/binutils/binutils-2.20.1.tar.gz:
We download http://www.smartsoft.de/Downloads/binutils-2.20.1-patches.tar.gz

cd /usr/src
gunzip binutils-2.20.1-patches.tar.gz
tar xvf binutils-2.20.1-patches.tar

mkdir avr
cd avr
bunzip2 binutils-2.20.1.tar.bz2
tar xvf binutils-2.20.1.tar
cd binutils-2.20.1

gpatch -p0 < /usr/src/binutils-2.20.1-patches/patch-300-binutils-2.20.1-avr-size
gpatch -p0 < /usr/src/binutils-2.20.1-patches/patch-301-binutils-2.20.1-avr-coff
gpatch -p0 < /usr/src/binutils-2.20.1-patches/patch-302-binutils-2.20.1-new-sections
gpatch -p0 < /usr/src/binutils-2.20.1-patches/patch-303-binutils-2.20.1-as-dwarf
gpatch -p0 < /usr/src/binutils-2.20.1-patches/patch-304-binutils-2.20.1-dwarf2-AVRStudio-workaround
gpatch -p0 < /usr/src/binutils-2.20.1-patches/patch-305-binutils-2.20.1-assembler-options
gpatch -p0 < /usr/src/binutils-2.20.1-patches/patch-400-binutils-2.20.1-xmega
gpatch -p0 < /usr/src/binutils-2.20.1-patches/patch-401-binutils-2.20.1-new-devices
gpatch -p0 < /usr/src/binutils-2.20.1-patches/patch-402-binutils-2.20.1-avrtiny10
gpatch -p0 < /usr/src/binutils-2.20.1-patches/patch-403-binutils-2.20.1-xmega128a1u-64a1u
gpatch -p0 < /usr/src/binutils-2.20.1-patches/patch-404-binutils-2.20.1-atxmega16x1-32x1
gpatch -p0 < /usr/src/binutils-2.20.1-patches/patch-405-binutils-2.20.1-atxmega128b1
gpatch -p0 < /usr/src/binutils-2.20.1-patches/patch-406-binutils-2.20.1-atxmega256a3bu
gpatch -p0 < /usr/src/binutils-2.20.1-patches/patch-407-binutils-2.20.1-at90pwm161
gpatch -p0 < /usr/src/binutils-2.20.1-patches/patch-408-binutils-2.20.1-atmega16hvb-32hvb
gpatch -p0 < /usr/src/binutils-2.20.1-patches/patch-409-binutils-2.20.1-atmega32_5_50_90_pa
gpatch -p0 < /usr/src/binutils-2.20.1-patches/patch-410-binutils-2.20.1-attiny1634
gpatch -p0 < /usr/src/binutils-2.20.1-patches/patch-411-binutils-2.20.1-atmega48pa
gpatch -p0 < /usr/src/binutils-2.20.1-patches/patch-500-binutils-2.20.1-bug13789
gpatch -p0 < /usr/src/binutils-2.20.1-patches/patch-Makefile.in

CFLAGS="-Wno-error -g -O2" ./configure --target=avr --program-prefix="avr-" --prefix=$PREFIX --disable-nls
make
make install

We download https://gmplib.org/download/gmp/gmp-6.0.0a.tar.bz2 from https://gmplib.org/#DOWNLOAD

cd /usr/src
wget --no-check-certificate https://gmplib.org/download/gmp/gmp-6.0.0a.tar.bz2
bunzip2 gmp-6.0.0a.tar.bz2
tar xvf gmp-6.0.0a.tar
cd gmp-6.0.0
./configure ABI=32 --build=k6-pc-solaris2.11
make
make check
make install

We download mpfr from http://www.mpfr.org!
We download http://www.smartsoft.de/Downloads/mpfr-3.1.2-patches.tar.gz!

cd /usr/src/
wget http://www.smartsoft.de/Downloads/mpfr-3.1.2-patches.tar.gz
gunzip mpfr-3.1.2-patches.tar.gz
tar xvf mpfr-3.1.2-patches.tar

bunzip2 mpfr-3.1.2.tar.bz2
tar xvf mpfr-3.1.2.tar
cd mpfr-3.1.2
gpatch -N -Z -p1 < /usr/src/mpfr-3.1.2-patches/allpatches
./configure
make
make check
make install

We download mpc from http://www.multiprecision.org/?prog=mpc&page=download.

cd /usr/src/
gunzip mpc-1.0.2.tar.gz
tar xvf mpc-1.0.2.tar
cd mpc-1.0.2
./configure
make
make install

We download http://gcc.cybermirror.org/releases/gcc-4.5.1/gcc-4.5.1.tar.bz2:
We download http://www.smartsoft.de/Downloads/gcc-4.5.1-patches.tar.gz

cd /usr/src/
wget http://www.smartsoft.de/Downloads/gcc-4.5.1-patches.tar.gz
gunzip gcc-4.5.1-patches.tar.gz
tar xvf gcc-4.5.1-patches.tar

cd /usr/src/avr
mkdir avrgcc
bunzip2 gcc-4.5.1.tar.bz2
gtar xvf gcc-4.5.1.tar
cd gcc-4.5.1

gpatch -p0 < /usr/src/gcc-4.5.1-patches/patch-200-gcc-4.5.1-libiberty-Makefile.in
gpatch -p0 < /usr/src/gcc-4.5.1-patches/patch-300-gcc-4.5.1-fixedpoint-3-4-2010
gpatch -p0 < /usr/src/gcc-4.5.1-patches/patch-301-gcc-4.5.1-xmega-v14
gpatch -p0 < /usr/src/gcc-4.5.1-patches/patch-302-gcc-4.5.1-avrtiny10
gpatch -p0 < /usr/src/gcc-4.5.1-patches/patch-303-gcc-4.5.1-osmain
gpatch -p0 < /usr/src/gcc-4.5.1-patches/patch-304-gcc-4.5.1-builtins-v6
gpatch -p0 < /usr/src/gcc-4.5.1-patches/patch-305-gcc-4.5.1-avrtiny10-non-fixedpoint
gpatch -p0 < /usr/src/gcc-4.5.1-patches/patch-306-gcc-4.5.1-option-list-devices
gpatch -p0 < /usr/src/gcc-4.5.1-patches/patch-400-gcc-4.5.1-new-devices
gpatch -p0 < /usr/src/gcc-4.5.1-patches/patch-401-gcc-4.5.1-atmega32_5_50_90_pa
gpatch -p0 < /usr/src/gcc-4.5.1-patches/patch-402-gcc-4.5.1-attiny1634
gpatch -p0 < /usr/src/gcc-4.5.1-patches/patch-403-gcc-4.5.1-atmega48pa
gpatch -p0 < /usr/src/gcc-4.5.1-patches/patch-500-gcc-4.5.1-bug13473
gpatch -p0 < /usr/src/gcc-4.5.1-patches/patch-501-gcc-4.5.1-bug13579
gpatch -p0 < /usr/src/gcc-4.5.1-patches/patch-502-gcc-4.5.1-bug-18145-v4
gpatch -p0 < /usr/src/gcc-4.5.1-patches/patch-503-gcc-4.5.1-avrtiny10-bug-12510
gpatch -p0 < /usr/src/gcc-4.5.1-patches/patch-504-gcc-4.5.1-bug12915
gpatch -p0 < /usr/src/gcc-4.5.1-patches/patch-505-gcc-4.5.1-bug13932
gpatch -p0 < /usr/src/gcc-4.5.1-patches/patch-506-gcc-4.5.1-bug13789
gpatch -p0 < /usr/src/gcc-4.5.1-patches/patch-599-gcc-4.5.1-bug46779
cd ..
cd avrgcc
../gcc-4.5.1/configure --target=avr --prefix=$PREFIX --with-gnu-ld --with-gnu-as --enable-languages="c,c++" --with-gmp=/usr/local --with-mpfr=/usr/local --disable-nls --disable-libssp --with-dwarf2
make
make install

We download http://download.savannah.gnu.org/releases/avr-libc/avr-libc-1.8.1.tar.bz2:

cd /usr/src/avr
bunzip2 avr-libc-1.8.1.tar.bz2
tar xvf avr-libc-1.8.1.tar
cd avr-libc-1.8.1
./configure --host=avr --prefix=$PREFIX --build=`./config.guess`
make
make install

We download http://download.savannah.gnu.org/releases/avrdude/avrdude-5.2.tar.gz:

cd /usr/src/avr
gunzip avrdude-5.2.tar.gz
gnutar xvf avrdude-5.2.tar
cd avrdude-5.2
./configure --prefix=$PREFIX
make
make install
Joerg Wunsch
2015-01-14 08:04:40 UTC
Permalink
Post by Andreas Höschler
We download http://www.smartsoft.de/Downloads/binutils-2.20.1-patches.tar.gz
Note that with recent GNU tools, you don't need any patches in order
to get started.

If you look at the list of your patches, you'll notice that they are
simply a collection of many many tweak Atmel applies to their version,
yet they didn't push it upstream (by that time). Some of them is just
new device support, others (like avr-size) are crude hacks, others
(like avr-coff and dwarf2-AVRStudio-workaround) are simply not needed.
I wouldn't recommend using such an old version. You'll lack a lot of
useful features, in particular the named address space support
(__flash qualifier).

I'd recommend you simply use the latest released GNU tools as a base
to start, without any AVR-specific patches. They should give you a
pretty well working AVR environment.
Likewise, AVRDUDE is already at version 6.1 meanwhile.
--
cheers, Joerg .-.-. --... ...-- -.. . DL8DTL

http://www.sax.de/~joerg/
Never trust an operating system you don't have sources for. ;-)
Andreas Höschler
2014-12-03 21:11:26 UTC
Permalink
Hi all,

I am close to tearing my hair out. After having established the avr tool chain I tried out a very simple C-program (see below) on an SainSmart Mega2560 board programmed into the chip by making use of /Applications/Arduino.app//Contents/Resources/Java/hardware/tools/avr/bin/avrdude:

#define F_CPU 16000000UL /* 16 MHz CPU clock */
#include "Global.h"
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>

char String[] = "Hello world!!";

void USARTInit0(uint16_t baud)
{
// Set Baud rate
int value = (F_CPU / 16 / baud) - 1;
UBRR0H = (uint8_t)(value>>8);
UBRR0L = (uint8_t)value;

// 8N1
UCSR0C = 0x06; // (3<<UCSZ00);

// Enable receiver and transmitter
UCSR0B = (1<<RXEN0) | (1<<TXEN0);
}

void TxByte0 (uint8_t data)
{
// Wait for empty transmit buffer
while ( !(UCSR0A & (1 << UDRE0)) );
// Putting data into the buffer, forces transmission
UDR0 = data;
}

int main (void)
{
DDRB = 0xff; // all outputs

USARTInit0(38400); // 9600 19200 38400

while (1)
{
TxByte0('A');
TxByte0('B');
TxByte0('C');
TxByte0('\n');

char *s = String;
while (*s != 0)
{
TxByte0(*s);
s++;
}

_delay_ms(500);
}
return (0);
}

This program produces the following output

...
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿABC
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿABC
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿABC
...

telling me that sending single chars works but sending strings fails (does not seem to have anything to do with the serial communication but rather be some kind of memory management problem!??).

To be sure the problem is not caused by my own gcc build I changed my Makefile to

# AVR-GCC Makefile
PROJECT=toggle_led
SOURCES=main.c
HEADERS=
CC=/Applications/Arduino.app//Contents/Resources/Java/hardware/tools/avr/bin/avr-gcc
OBJCOPY=avr-objcopy
MMCU=atmega2560

CFLAGS=-mmcu=$(MMCU) -Wall -O2 -I /usr/local/avr/include

$(PROJECT).hex: $(PROJECT).out
$(OBJCOPY) -j .text -O ihex $(PROJECT).out $(PROJECT).hex

$(PROJECT).out: $(SOURCES)
$(CC) $(CFLAGS) -I./ -o $(PROJECT).out $(SOURCES)

program: $(PROJECT).hex
avrdude -p $(MMCU) -c avrispmkII -P usb -e -U flash:w:$(PROJECT).hex
clean:
rm -f $(PROJECT).out
rm -f $(PROJECT).hex



and thus built the program with a gcc from a respected source (avr-gcc coming with Arduino.app). But the problem persists!? I already discussed this problem on avrfreaks forum. All agree that the above code should work but it does not!?? :-()

Could this be a problem of the board/chip? I am using a SainSmart Mega2560 board (which seems to be a clone of the original Arduino product)! Or am I doing anything wrong??

Clueless!?? :-( Hints are greatly appreciated!!

Thanks a lot,

Andreas
Wouter van Gulik
2014-12-03 21:21:42 UTC
Permalink
Could you post the assembler output? IIRC --save-temps or -S should be
added to the gcc command line.

Wouter
Post by Andreas Höschler
Hi all,
I am close to tearing my hair out. After having established the avr tool
chain I tried out a very simple C-program (see below) on an SainSmart
Mega2560 board programmed into the chip by making use
#define F_CPU 16000000UL /* 16 MHz CPU clock */
#include "Global.h"
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>
char String[] = "Hello world!!";
void USARTInit0(uint16_t baud)
{
// Set Baud rate
int value = (F_CPU / 16 / baud) - 1;
UBRR0H = (uint8_t)(value>>8);
UBRR0L = (uint8_t)value;
// 8N1
UCSR0C = 0x06; // (3<<UCSZ00);
// Enable receiver and transmitter
UCSR0B = (1<<RXEN0) | (1<<TXEN0);
}
void TxByte0 (uint8_t data)
{
// Wait for empty transmit buffer
while ( !(UCSR0A & (1 << UDRE0)) );
// Putting data into the buffer, forces transmission
UDR0 = data;
}
int main (void)
{
DDRB = 0xff; // all outputs
USARTInit0(38400); // 9600 19200 38400
while (1)
{
TxByte0('A');
TxByte0('B');
TxByte0('C');
TxByte0('\n');
char *s = String;
while (*s != 0)
{
TxByte0(*s);
s++;
}
_delay_ms(500);
}
return (0);
}
This program produces the following output
...
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿABC
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿABC
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿABC
...
telling me that sending single chars works but sending strings fails (does
not seem to have anything to do with the serial communication but rather be
some kind of memory management problem!??).
To be sure the problem is not caused by my own gcc build I changed my Makefile to
# AVR-GCC Makefile
PROJECT=toggle_led
SOURCES=main.c
HEADERS=
CC=/Applications/Arduino.app//Contents/Resources/Java/hardware/tools/avr/bin/avr-gcc
OBJCOPY=avr-objcopy
MMCU=atmega2560
CFLAGS=-mmcu=$(MMCU) -Wall -O2 -I /usr/local/avr/include
$(PROJECT).hex: $(PROJECT).out
$(OBJCOPY) -j .text -O ihex $(PROJECT).out $(PROJECT).hex
$(PROJECT).out: $(SOURCES)
$(CC) $(CFLAGS) -I./ -o $(PROJECT).out $(SOURCES)
program: $(PROJECT).hex
avrdude -p $(MMCU) -c avrispmkII -P usb -e -U flash:w:$(PROJECT).hex
rm -f $(PROJECT).out
rm -f $(PROJECT).hex
and thus built the program with a gcc from a respected source (avr-gcc
coming with Arduino.app). But the problem persists!? I already discussed
this problem on avrfreaks forum. All agree that the above code should work
but it does not!?? :-()
Could this be a problem of the board/chip? I am using a SainSmart Mega2560
board (which seems to be a clone of the original Arduino product)! Or am I
doing anything wrong??
Clueless!?? :-( Hints are greatly appreciated!!
Thanks a lot,
Andreas
_______________________________________________
AVR-GCC-list mailing list
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Andreas Höschler
2014-12-03 22:15:20 UTC
Permalink
Hi Wouter,

here is the assembler file generated with

avr-gcc -mmcu=atmega2560 -Wall -O2 -S -I /usr/local/avr/include -I./ -o toggle_led.out main.c



Thanks!!

Andreas
+
Could you post the assembler output? IIRC --save-temps or -S should be added to the gcc command line.
Wouter
Hi all,
#define F_CPU 16000000UL /* 16 MHz CPU clock */
#include "Global.h"
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>
char String[] = "Hello world!!";
void USARTInit0(uint16_t baud)
{
// Set Baud rate
int value = (F_CPU / 16 / baud) - 1;
UBRR0H = (uint8_t)(value>>8);
UBRR0L = (uint8_t)value;
// 8N1
UCSR0C = 0x06; // (3<<UCSZ00);
// Enable receiver and transmitter
UCSR0B = (1<<RXEN0) | (1<<TXEN0);
}
void TxByte0 (uint8_t data)
{
// Wait for empty transmit buffer
while ( !(UCSR0A & (1 << UDRE0)) );
// Putting data into the buffer, forces transmission
UDR0 = data;
}
int main (void)
{
DDRB = 0xff; // all outputs
USARTInit0(38400); // 9600 19200 38400
while (1)
{
TxByte0('A');
TxByte0('B');
TxByte0('C');
TxByte0('\n');
char *s = String;
while (*s != 0)
{
TxByte0(*s);
s++;
}
_delay_ms(500);
}
return (0);
}
This program produces the following output
...
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿABC
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿABC
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿABC
...
telling me that sending single chars works but sending strings fails (does not seem to have anything to do with the serial communication but rather be some kind of memory management problem!??).
To be sure the problem is not caused by my own gcc build I changed my Makefile to
# AVR-GCC Makefile
PROJECT=toggle_led
SOURCES=main.c
HEADERS=
CC=/Applications/Arduino.app//Contents/Resources/Java/hardware/tools/avr/bin/avr-gcc
OBJCOPY=avr-objcopy
MMCU=atmega2560
CFLAGS=-mmcu=$(MMCU) -Wall -O2 -I /usr/local/avr/include
$(PROJECT).hex: $(PROJECT).out
$(OBJCOPY) -j .text -O ihex $(PROJECT).out $(PROJECT).hex
$(PROJECT).out: $(SOURCES)
$(CC) $(CFLAGS) -I./ -o $(PROJECT).out $(SOURCES)
program: $(PROJECT).hex
avrdude -p $(MMCU) -c avrispmkII -P usb -e -U flash:w:$(PROJECT).hex
rm -f $(PROJECT).out
rm -f $(PROJECT).hex
and thus built the program with a gcc from a respected source (avr-gcc coming with Arduino.app). But the problem persists!? I already discussed this problem on avrfreaks forum. All agree that the above code should work but it does not!?? :-()
Could this be a problem of the board/chip? I am using a SainSmart Mega2560 board (which seems to be a clone of the original Arduino product)! Or am I doing anything wrong??
Clueless!?? :-( Hints are greatly appreciated!!
Thanks a lot,
Andreas
_______________________________________________
AVR-GCC-list mailing list
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Senthil Kumar Selvaraj
2014-12-04 04:24:14 UTC
Permalink
Post by Andreas Höschler
Hi Wouter,
here is the assembler file generated with
avr-gcc -mmcu=atmega2560 -Wall -O2 -S -I /usr/local/avr/include -I./ -o toggle_led.out main.c
Thanks!!
Andreas
+
Could you post the assembler output? IIRC --save-temps or -S should be added to the gcc command line.
Wouter
Hi all,
#define F_CPU 16000000UL /* 16 MHz CPU clock */
#include "Global.h"
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>
char String[] = "Hello world!!";
void USARTInit0(uint16_t baud)
{
// Set Baud rate
int value = (F_CPU / 16 / baud) - 1;
UBRR0H = (uint8_t)(value>>8);
UBRR0L = (uint8_t)value;
// 8N1
UCSR0C = 0x06; // (3<<UCSZ00);
// Enable receiver and transmitter
UCSR0B = (1<<RXEN0) | (1<<TXEN0);
}
void TxByte0 (uint8_t data)
{
// Wait for empty transmit buffer
while ( !(UCSR0A & (1 << UDRE0)) );
// Putting data into the buffer, forces transmission
UDR0 = data;
}
int main (void)
{
DDRB = 0xff; // all outputs
USARTInit0(38400); // 9600 19200 38400
while (1)
{
TxByte0('A');
TxByte0('B');
TxByte0('C');
TxByte0('\n');
char *s = String;
while (*s != 0)
{
TxByte0(*s);
s++;
}
_delay_ms(500);
}
return (0);
}
This program produces the following output
...
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿABC
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿABC
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿABC
...
telling me that sending single chars works but sending strings fails (does not seem to have anything to do with the serial communication but rather be some kind of memory management problem!??).
Older versions of the toolchain did not tell the linker where to place
globals in data memory (i.e. did not pass -Tdata) - that would obviously
break globals.

Can you try making String local and see if that helps? Can you also send
the output ELF (or atleast disassembly (objdump -S) and sections
(objdump -h))?

Regards
Senthil
Post by Andreas Höschler
To be sure the problem is not caused by my own gcc build I changed my Makefile to
# AVR-GCC Makefile
PROJECT=toggle_led
SOURCES=main.c
HEADERS=
CC=/Applications/Arduino.app//Contents/Resources/Java/hardware/tools/avr/bin/avr-gcc
OBJCOPY=avr-objcopy
MMCU=atmega2560
CFLAGS=-mmcu=$(MMCU) -Wall -O2 -I /usr/local/avr/include
$(PROJECT).hex: $(PROJECT).out
$(OBJCOPY) -j .text -O ihex $(PROJECT).out $(PROJECT).hex
$(PROJECT).out: $(SOURCES)
$(CC) $(CFLAGS) -I./ -o $(PROJECT).out $(SOURCES)
program: $(PROJECT).hex
avrdude -p $(MMCU) -c avrispmkII -P usb -e -U flash:w:$(PROJECT).hex
rm -f $(PROJECT).out
rm -f $(PROJECT).hex
and thus built the program with a gcc from a respected source (avr-gcc coming with Arduino.app). But the problem persists!? I already discussed this problem on avrfreaks forum. All agree that the above code should work but it does not!?? :-()
Could this be a problem of the board/chip? I am using a SainSmart Mega2560 board (which seems to be a clone of the original Arduino product)! Or am I doing anything wrong??
Clueless!?? :-( Hints are greatly appreciated!!
Thanks a lot,
Andreas
_______________________________________________
AVR-GCC-list mailing list
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Paweł Si
2014-12-03 23:13:26 UTC
Permalink
Post by Andreas Höschler
$(PROJECT).hex: $(PROJECT).out
$(OBJCOPY) -j .text -O ihex $(PROJECT).out $(PROJECT).hex
I would say that here is the problem, change this to:
$(OBJCOPY) -R .eeprom -O ihex $(PROJECT).out $(PROJECT).hex
Andreas Höschler
2014-12-04 11:36:56 UTC
Permalink
Hi Paweł,
Post by Andreas Höschler
$(PROJECT).hex: $(PROJECT).out
$(OBJCOPY) -j .text -O ihex $(PROJECT).out $(PROJECT).hex
$(OBJCOPY) -R .eeprom -O ihex $(PROJECT).out $(PROJECT).hex
That was it!!!!

Thanks so much! You probably can't imagine how happy I am that this problem is finally resolved.

I would love to understand the difference between "-j .text" and "-R .eeprom". I googled for avr-objcopy and all I found was

-j sectionname
--only-section=sectionname
Copy only the named section from the input file to the output file.
This option may be given more than once. Note that using this
[-R sectionname|--remove-section=sectionname
This does not really explains it to me! :-( Can I always use "-R .eeprom" and am done or should I understand what these options mean and use them from case to case?
Thanks,
Andreas
Richard Weickelt
2014-12-04 12:04:07 UTC
Permalink
Post by Andreas Höschler
I would love to understand the difference between "-j .text" and "-R
.eeprom". I googled for avr-objcopy and all I found was
-j sectionname --only-section=sectionname Copy only the named section
from the input file to the output file. This option may be given
more than once. Note that using this [-R
sectionname|--remove-section=sectionname This does not really explains it
to me! :-( Can I always use "-R .eeprom" and am done or should I
understand what these options mean and use them from case to case?
Thanks, Andreas
You might want to read
http://www.nongnu.org/avr-libc/user-manual/mem_sections.html and about the
ELF format, sections and segments in general. I can recommend the book
"Linkers and Loaders" by John Levine but there is various other information
in the web.

Your global string array is not located in the .text section but .data. This
section gets flashed into the AVR as well (hint: PROGBITS, see avr-readelf
-S <EXECUTABLE>) but has to be "loaded" into the RAM during application
startup.

If You throw away the .data section with "objdump -j .text", then Your
program will of course copy data from an empty flash region into the RAM.
Andreas Höschler
2014-12-04 12:31:01 UTC
Permalink
Hi Richarf, Simon and Senthil,

thanks a lot for your additional hints, explanations and links. This starts to make sense now for me!

Back to coding the beast! :-)

Best wishes,

Andreas
Simon Cook
2014-12-04 12:12:48 UTC
Permalink
HI Andreas,

Using "-j .text" would only keep the .text section, as your string is in
the .data section, the actual contents would have been removed and you
would expect your string to be just noise (as you saw). "-R .eeprom" would
copy all sections apart from .eeprom which would mean that your .text and
.data would remain intact and your program work as expected. Judging by
your assembly file I don't see any section change to .eeprom so this may
have actually done anything.

In general, I would expect using neither -j nor -R would in most cases
produce a working file, but there may be some cases where it is useful to
know which of these to use. When you need them, -j is for when only a list
of known sections are needed, and -R is for keeping everything except a
given section.

Hope this helps,
Simon
Post by Andreas Höschler
Hi Paweł,
$(PROJECT).hex: $(PROJECT).out
Post by Andreas Höschler
$(OBJCOPY) -j .text -O ihex $(PROJECT).out $(PROJECT).hex
$(OBJCOPY) -R .eeprom -O ihex $(PROJECT).out $(PROJECT).hex
That was it!!!!
Thanks so much! You probably can't imagine how happy I am that this
problem is finally resolved.
I would love to understand the difference between "-j .text" and "-R
.eeprom". I googled for avr-objcopy and all I found was
*-j* *sectionname*
*--only-section=**sectionname*
Copy only the named section from the input file to the output file.
This option may be given more than once. Note that using this
[*-R* *sectionname*|*--remove-section=**sectionname*
This does not really explains it to me! :-( Can I always use "-R .eeprom" and am done or should I understand what these options mean and use them from case to case?
Thanks,
Andreas
_______________________________________________
AVR-GCC-list mailing list
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Paweł Si
2014-12-04 13:57:10 UTC
Permalink
Post by Simon Cook
In general, I would expect using neither -j nor -R would in most cases
produce a working file, but there may be some cases where it is useful to
know which of these to use. When you need them, -j is for when only a list
of known sections are needed, and -R is for keeping everything except a
given section.
Yes, probably:
$(OBJCOPY) -O ihex $(PROJECT).out $(PROJECT).hex
is good enough, I just copied "-R .eeprom" from one of my projects,
where I use the eeprom but don't want to have it in my hex file.
(I'm just lazy ;) )

You should also look what's the difference between these two files (with a
simple editor):
$(OBJCOPY) -O binary $(PROJECT).out $(PROJECT).bin
and
$(OBJCOPY) -j .text -O binary $(PROJECT).out
$(PROJECT).text_section_only.bin

and of course you should look at:
avr-objdump -D $(PROJECT).out > $(PROJECT).asm
the "__do_copy_data" part is the most interesting one.

Best Regards,
Paweł
Georg-Johann Lay
2014-12-15 18:58:52 UTC
Permalink
Post by Andreas Höschler
Hi all,
[code using .[ro]data]
This program produces the following output
...
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿABC
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿABC
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿABC
...
telling me that sending single chars works but sending strings fails (does not seem to have anything to do with the serial communication but rather be some kind of memory management problem!??).
To be sure the problem is not caused by my own gcc build I changed my Makefile to
FYI, What counts are the command options that are passed to the compiler in the
and; just Makefile variables / snippets might not be enough for others to help
you (except you are having problems with make).
Post by Andreas Höschler
# AVR-GCC Makefile
PROJECT=toggle_led
SOURCES=main.c
HEADERS=
CC=/Applications/Arduino.app//Contents/Resources/Java/hardware/tools/avr/bin/avr-gcc
OBJCOPY=avr-objcopy
MMCU=atmega2560
CFLAGS=-mmcu=$(MMCU) -Wall -O2 -I /usr/local/avr/include
Adding this include path should never ever be needed. If you toolchain
installation does not work without it, that installation is broken and the
right approach is to get a working distribution of the toolchain.

You can even mess up you builds by specifying include path or library path that
appear correct to you but actually are not. The compiler(driver) always knows
its own paths. Sometimes tools like Code::Blocks that try to be smarter than
they actually are and will add such paths. Make sure you IDE or whatever
generated this Makefile is sane in this respect.
Post by Andreas Höschler
$(PROJECT).hex: $(PROJECT).out
$(OBJCOPY) -j .text -O ihex $(PROJECT).out $(PROJECT).hex
You are using data from input section .data* resp. .rodata* (namely by string
literal "Hello world!!") which in turn is initialized at startup time from
flash. Hence you may also include .data when building your executable.


Johann
Loading...