Egor Skriptunoff suggestion is almost exactly right: the SRAM variable is mapped to the wrong memory address. The latchingFlag
variable is not at 0x0100
address, which is the first valid SRAM address, but is mapped to 0x060
, overlapping the WDTCSR
register. This can be seen in the disassembly lines like the following one:
lds r24, 0x0060
THis line is supposed to load the value of latchingFlag
from SRAM, and we can see that location 0x060
is used instead of 0x100
.
The problem has to with a bug in the binutils which two conditions are met:
- The linker is invoked with
--gc-sections
flag (compiler options:-Wl,--gc-sections
) to save code space - None of your SRAM variables are initialized (i.e. initialized to non-zero values)
When both of these conditions are met, the .data
section gets removed. When the .data
section is missing, the SRAM variables start at address 0x060
instead of 0x100
.
One solution is to reinstall binutils: the current versions have this bug fixed. Another solution is to edit your linker scripts: on Ubuntu this is probably in /usr/lib/ldscripts
. For ATmega168/328 the script that needs to be edited is avr5.x
, but you should really edit all them, otherwise you could run into this bug on other AVR platforms. The change that needs to be made is the following one:
.data : AT (ADDR (.text) + SIZEOF (.text))
{
PROVIDE (__data_start = .) ;
- *(.data)
+ KEEP(*(.data))
So replace the line *(.data)
with KEEP(*(.data))
. This ensures that the .data
section is not discarded, and consequently the SRAM variable addresses start at 0x0100