arduino / arduino/ArduinoCore-avr

mega bootloader watchdog sporadic hang

Open
#263 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
C
Stars
1.5k
Forks
1.1k
PR merge metrics
No merged PRs in 30d

Description

If the restart was caused by the watchdog, the bootloader currently exits with

```
void (*app_start)(void) = 0x0000;
...
app_start();
```

In any other case, the bootloader exits with

```
// exit the bootloader in an orderly fashion

asm volatile ("nop"); // No operation. Do nothing for one clock cycle. Probably not necessary, but doesn't harm either. Copy and pasted from code snippet.
UART_STATUS_REG &= 0xfd; //for the mega2560, this is the register UCSR0A. We clear bit 1 to zero here. 0xfd = 0b1111 1101 . Bit 1 - U2Xn: Double the USART Transmission Speed This bit only has effect for the asynchronous operation. Write this bit to zero when using synchronous operation.
boot_rww_enable(); // from : Bootloader Support Utilities. Enable the Read-While-Write memory section. enable application section

// the next instruction is more complicated than necessary for the mega2560. asm jmp 0 would do the job as well, but the jmp command is not available on all processors

/* Indirect jump to the address pointed to by the Z (16 bits) pointer register in the register file.
The Z pointer register is 16 bits wide and allows jump within the lowest 64K words (128K bytes) section of program memory. This instruction is not available in all devices. Refer to the device specific instruction set summary.
*/

// Z pointer is at registers 30 and 31

asm volatile //the volatile keyword tells the compiler to disable certain optimizations. These optimizations would attempt to make the code smaller, but break it in the process.
(
"clr r30 \n\t" // clear register 30. The new line and tab characters are only there so the assembler file will look nice and human readable.
"clr r31 \n\t"
"ijmp \n\t" // indirect jump
);

/*
* Never return (stay in an endless loop) to stop GCC to generate exit return code
* Actually we will never reach this point, because we jumped away earlier, but the compiler doesn't
* understand this.
*/
for(;;); // endless loop
```

If the code for the orderly exit is used also for the watchdog, then the sporadic hang after watchdog reset disappears.
See also [http://forum.arduino.cc/index.php?topic=378288.0](url)

Contributor guide

No contributing guide indexed for this repository

Research direction

Locate the bootloader code that handles watchdog resets and compare its exit path with the orderly exit sequence shown in the issue. Reproduce or inspect the Mega2560 watchdog-reset behavior, then verify that using the orderly path removes the sporadic hang without breaking other bootloader exits.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
embedded-iot
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.