Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 5e194bd

Browse files
committed
[AVR] Discover newer bootloader at runtime
Replaces #4280, only checks for the bootloader once Tested with Hoodloader2, should work with every LUFA-derived bootloader released after 2014 (.apitable_signatures section must be placed at end of the flash) BootloaderAPITable.S : .global BootloaderAPI_Signatures BootloaderAPI_Signatures: .long BOOT_START_ADDR ; Start address of the bootloader .word 0xDF00 ; Signature for the CDC class bootloader .word 0xDCFB ; Signature for a LUFA class bootloader makefile: BOOT_API_LD_FLAGS += $(call BOOT_SECTION_LD_FLAG, .apitable_signatures, BootloaderAPI_Signatures, 8)
1 parent 71b87bf commit 5e194bd

File tree

3 files changed

+54
-14
lines changed

3 files changed

+54
-14
lines changed

‎cores/arduino/CDC.cpp‎

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ typedef struct
3434
static volatile LineInfo _usbLineInfo = { 57600, 0x00, 0x00, 0x00, 0x00 };
3535
static volatile int32_t breakValue = -1;
3636

37+
bool _updatedLUFAbootloader = false;
38+
3739
#define WEAK __attribute__ ((weak))
3840

3941
extern const CDCDescriptor _cdcInterface PROGMEM;
@@ -99,24 +101,32 @@ bool CDC_Setup(USBSetup& setup)
99101
// with a relatively long period so it can finish housekeeping tasks
100102
// like servicing endpoints before the sketch ends
101103

102-
#ifndef MAGIC_KEY
103-
#define MAGIC_KEY 0x7777
104-
#endif
105-
#ifndef MAGIC_KEY_POS
106-
#define MAGIC_KEY_POS 0x0800
104+
uint16_t magic_key_pos = MAGIC_KEY_POS;
105+
106+
// If we don't use the new RAMEND directly, check manually if we have a newer bootloader.
107+
// This is used to keep compatible with the old leonardo bootloaders.
108+
// You are still able to set the magic key position manually to RAMEND-1 to save a few bytes for this check.
109+
#if MAGIC_KEY_POS != (RAMEND-1)
110+
// For future boards save the key in the inproblematic RAMEND
111+
// Which is reserved for the main() return value (which will never return)
112+
if (_updatedLUFAbootloader) {
113+
// horray, we got a new bootloader!
114+
magic_key_pos = (RAMEND-1);
115+
}
107116
#endif
108117

109118
// We check DTR state to determine if host port is open (bit 0 of lineState).
110119
if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0)
111120
{
112121
#if MAGIC_KEY_POS != (RAMEND-1)
113-
*(uint16_t *)(RAMEND-1) = *(uint16_t *)MAGIC_KEY_POS;
114-
*(uint16_t *)MAGIC_KEY_POS = MAGIC_KEY;
115-
#else
116-
// for future boards save the key in the inproblematic RAMEND
117-
// which is reserved for the main() return value (which will never return)
118-
*(uint16_t *)MAGIC_KEY_POS = MAGIC_KEY;
122+
// Backup ram value if its not a newer bootloader.
123+
// This should avoid memory corruption at least a bit, not fully
124+
if (magic_key_pos != (RAMEND-1)) {
125+
*(uint16_t *)(RAMEND-1) = *(uint16_t *)magic_key_pos;
126+
}
119127
#endif
128+
// Store boot key
129+
*(uint16_t *)magic_key_pos = MAGIC_KEY;
120130
wdt_enable(WDTO_120MS);
121131
}
122132
else
@@ -129,10 +139,15 @@ bool CDC_Setup(USBSetup& setup)
129139
wdt_disable();
130140
wdt_reset();
131141
#if MAGIC_KEY_POS != (RAMEND-1)
132-
*(uint16_t *)MAGIC_KEY_POS = *(uint16_t *)(RAMEND-1);
133-
#else
134-
*(uint16_t *)MAGIC_KEY_POS = 0x0000;
142+
// Restore backed up (old bootloader) magic key data
143+
if (magic_key_pos != (RAMEND-1)) {
144+
*(uint16_t *)magic_key_pos = *(uint16_t *)(RAMEND-1);
145+
} else
135146
#endif
147+
{
148+
// Clean up RAMEND key
149+
*(uint16_t *)magic_key_pos = 0x0000;
150+
}
136151
}
137152
}
138153
return true;

‎cores/arduino/USBCore.cpp‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ extern const u8 STRING_PRODUCT[] PROGMEM;
3535
extern const u8 STRING_MANUFACTURER[] PROGMEM;
3636
extern const DeviceDescriptor USB_DeviceDescriptor PROGMEM;
3737
extern const DeviceDescriptor USB_DeviceDescriptorB PROGMEM;
38+
extern bool _updatedLUFAbootloader;
3839

3940
const u16 STRING_LANGUAGE[2] = {
4041
(3<<8) | (2+2),
@@ -806,6 +807,12 @@ void USBDevice_::attach()
806807
UDIEN = (1<<EORSTE) | (1<<SOFE) | (1<<SUSPE); // Enable interrupts for EOR (End of Reset), SOF (start of frame) and SUSPEND
807808

808809
TX_RX_LED_INIT;
810+
811+
#if MAGIC_KEY_POS != (RAMEND-1)
812+
if (pgm_read_word(FLASHEND - 1) == NEW_LUFA_SIGNATURE) {
813+
_updatedLUFAbootloader = true;
814+
}
815+
#endif
809816
}
810817

811818
void USBDevice_::detach()

‎variants/leonardo/pins_arduino.h‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,4 +366,22 @@ const uint8_t PROGMEM analog_pin_to_channel_PGM[] = {
366366
// Alias SerialUSB to Serial
367367
#define SerialUSB SERIAL_PORT_USBVIRTUAL
368368

369+
// Bootloader related fields
370+
// Old Caterian bootloader places the MAGIC key into unsafe RAM locations (it can be rewritten
371+
// by the running sketch before to actual reboot).
372+
// Newer bootloaders, recognizable by the LUFA "signature" at the end of the flash, can handle both
373+
// the usafe and the safe location. Check once (in USBCore.cpp) if the bootloader in new, then set the global
374+
// _updatedLUFAbootloader variable to true/false and place the magic key consequently
375+
#ifndef MAGIC_KEY
376+
#define MAGIC_KEY 0x7777
377+
#endif
378+
379+
#ifndef MAGIC_KEY_POS
380+
#define MAGIC_KEY_POS 0x0800
381+
#endif
382+
383+
#ifndef NEW_LUFA_SIGNATURE
384+
#define NEW_LUFA_SIGNATURE 0xDCFB
385+
#endif
386+
369387
#endif /* Pins_Arduino_h */

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /