Skip to content

Commit

Permalink
cpu/atmega_common: Fix pm_reboot with LTO
Browse files Browse the repository at this point in the history
The reboot process for ATmegas is to enable the watchdog timer and loop until
the wdt reboots this MCU. However, this reboot will keep the wdt configuration,
so that the wdt needs to be disabled during boot. This is done in get_mcusr,
but without the attribute "used" it will be optimized out in LTO builds. This
commits adds the attribute "used" to get_mcusr.

Also simplified the backward compatibility with older ATmegas (currently not
supported by RIOT) on outdated versions of avrlibc.
  • Loading branch information
maribu committed Feb 10, 2020
1 parent b5bb846 commit 60ee8cd
Showing 1 changed file with 10 additions and 8 deletions.
18 changes: 10 additions & 8 deletions cpu/atmega_common/cpu.c
Expand Up @@ -36,6 +36,13 @@
#define ENABLE_DEBUG (0)
#include "debug.h"

#ifndef MCUSR
/* In older ATmegas the MCUSR register was still named MCUCSR. Current avrlibc
* versions provide the MCUSR macro for those as well, but adding a fallback
* here doesn't hurt*/
#define MCUSR MCUCSR
#endif /* !MCUSR */

/*
* Since atmega MCUs do not feature a software reset, the watchdog timer
* is being used. It will be set to the shortest time and then force a
Expand All @@ -51,7 +58,7 @@
*/
uint8_t mcusr_mirror __attribute__((section(".noinit")));
uint8_t soft_rst __attribute__((section(".noinit")));
void get_mcusr(void) __attribute__((naked)) __attribute__((section(".init0")));
void get_mcusr(void) __attribute__((naked, section(".init0"), used));

void get_mcusr(void)
{
Expand All @@ -62,13 +69,8 @@ void get_mcusr(void)
__asm__ __volatile__("mov %0, r2\n" : "=r" (mcusr_mirror) :);
#else
/* save the reset flags */
#ifdef MCUCSR
mcusr_mirror = MCUCSR;
MCUSR = 0;
#else
mcusr_mirror = MCUSR;
MCUSR = 0;
#endif
mcusr_mirror = MCUSR;
MCUSR = 0;
wdt_disable();
#endif
}
Expand Down

0 comments on commit 60ee8cd

Please sign in to comment.