Arduino UNO infinite reboot problem

Hi, all!

I have the strange problem with the next program:

#include <avr/io.h>
#include <util/delay.h>

void
pin_write(void)
{
}

void
main(void)
{
	DDRD |= 1 << 2;

	while (1) {
		PORTD |= 1 << 2;
		_delay_ms(200);
		PORTD &= ~(1 << 2);
		_delay_ms(200);
	}
}

If i compile and flash it to the arduino, then it constantly reboot(builtin LED blink 3 times and so on).

But! If i remove pin_write() function, everything works as needed :-). What’s the mystic :-)?

compile command:

avr-gcc -Wall -Wno-main -DF_CPU=16000000 -mmcu=atmega328p -c test.c -o test.o

flash command:

avrdude -carduino -P/dev/ttyACM0 -b115200 -patmega328p -U flash:w:test.hex:i

gcc 7.3.0
binutils 2.30
avr-libc 2.0.0

Do you have a bootloader? Looks like execution starts not from main() but from the first command. In case of pin_write() present ret commands set IP to an unspecified location an causing reset at some point later.

Do you have a bootloader?

Yes. I have the default bootloader. I flash arduino with usual usb cable.

In case of pin_write() present ret commands set IP to an unspecified location an causing reset at some point later.

If i place pin_write() after main(), the behaviour is the same.

Ну, тогда загадка.

Не-не-не. Нафиг загадки.

The diff output of test.wo.s (test.c without pin_write()) vs test.s (test.c with pin_write()):

--- test.wo.s   2019-02-02 09:41:05.975979913 +0300
+++ test.s      2019-02-02 09:41:30.247979382 +0300
@@ -5,6 +5,16 @@
 __tmp_reg__ = 0
 __zero_reg__ = 1
        .text
+.global        pin_write
+       .type   pin_write, @function
+pin_write:
+/* prologue: function */
+/* frame size = 0 */
+/* stack size = 0 */
+.L__stack_usage = 0
+/* epilogue start */
+       ret
+       .size   pin_write, .-pin_write
        .section        .text.startup,"ax",@progbits
 .global        main
        .type   main, @function
@@ -14,7 +24,7 @@
 /* stack size = 0 */
 .L__stack_usage = 0
        sbi 0xa,2
-.L2:
+.L3:
        sbi 0xb,2
        ldi r18,lo8(639999)
        ldi r24,hi8(639999)
@@ -35,6 +45,6 @@
        brne 1b
        rjmp .
        nop
-       rjmp .L2
+       rjmp .L3
        .size   main, .-main
        .ident  "GCC: (GNU) 7.3.0"

I use -Os option to generate smaller code and smaller diff(with -Os the problem stay the same).

test.wo.s:

        .file   "test.c"
__SP_H__ = 0x3e
__SP_L__ = 0x3d
__SREG__ = 0x3f
__tmp_reg__ = 0
__zero_reg__ = 1
        .text
        .section        .text.startup,"ax",@progbits
.global main
        .type   main, @function
main:
/* prologue: function */
/* frame size = 0 */
/* stack size = 0 */
.L__stack_usage = 0
        sbi 0xa,2
.L2:
        sbi 0xb,2
        ldi r18,lo8(639999)
        ldi r24,hi8(639999)
        ldi r25,hlo8(639999)
1:      subi r18,1
        sbci r24,0
        sbci r25,0
        brne 1b
        rjmp .
        nop
        cbi 0xb,2
        ldi r18,lo8(639999)
        ldi r24,hi8(639999)
        ldi r25,hlo8(639999)
1:      subi r18,1
        sbci r24,0
        sbci r25,0
        brne 1b
        rjmp .
        nop
        rjmp .L2
        .size   main, .-main
        .ident  "GCC: (GNU) 7.3.0"

How did you get from test.o to test.hex?
The link and objcopy could have been wrong. Particularly if you skipped the link step...

westfw:
How did you get from test.o to test.hex?
The link and objcopy could have been wrong. Particularly if you skipped the link step...

Oops. Forgot to say:

avr-gcc -o test.elf test.o
avr-objcopy -j .text -j .data -O ihex test.elf test.hex

Actually the gcc command looks like this:

avr-gcc -o test.o test.c -larduino

But arduino lib isn't used in test.c, so AFAIK this doesn't matter.

I've tried:

binutils 3.31
gcc 8.2.0
avr-libc 2.0.0

But this don't help.

I've got an answer on avrfreaks.net. Adding -mmcu=atmega328p to linker solve the problem.