Skip to content

Commit

Permalink
avr/bootloader.c: Now compatible with bootloaders which always run fi…
Browse files Browse the repository at this point in the history
…rst.

The boot loader now knows when to go into bootstrap mode by
looking for a specific EEPROM value. Also updated code style
to match Contiki code style guidelines.
darconeous committed May 19, 2013
1 parent 5df586e commit 9c17a54
Showing 2 changed files with 71 additions and 39 deletions.
108 changes: 69 additions & 39 deletions cpu/avr/bootloader.c
Original file line number Diff line number Diff line change
@@ -5,69 +5,99 @@
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include "dev/usb/usb_drv.h"
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>

//Not all AVR toolchains alias MCUSR to the older MSUSCR name
//#if defined (__AVR_ATmega8__) || defined (__AVR_ATmega8515__) || defined (__AVR_ATmega16__)
/* Not all AVR toolchains alias MCUSR to the older MSUSCR name */
#if !defined (MCUSR) && defined (MCUCSR)
#warning *** MCUSR not defined, using MCUCSR instead ***
#define MCUSR MCUCSR
#endif

#ifndef EEPROM_MAGIC_BYTE_ADDR
#define EEPROM_MAGIC_BYTE_ADDR (uint8_t*)(E2END-3)
#endif

volatile uint32_t Boot_Key ATTR_NO_INIT;

extern void Bootloader_Jump_Check(void) ATTR_INIT_SECTION(3);

bool
bootloader_is_present(void) {
#if defined(RAMPZ)
return pgm_read_word_far(BOOTLOADER_START_ADDRESS)!=0xFFFF;
bootloader_is_present(void)
{
#if defined(BOOTLOADER_START_ADDRESS)
return pgm_read_word_far(BOOTLOADER_START_ADDRESS) != 0xFFFF;
#else
/* Probably can just return false when < 64K flash */
// return pgm_read_word_near(BOOTLOADER_START_ADDRESS)!=0xFFFF;
return false;
return false;
#endif
}

void
Jump_To_Bootloader(void)
{
uint8_t i;

/* Disable all interrupts */
cli();

#ifdef UDCON
// If USB is used, detach from the bus
Usb_detach();
/* If USB is used, detach from the bus */
Usb_detach();

uint8_t i;

/* Wait two seconds for the USB detachment to register on the host */
for(i = 0; i < 200; i++) {
_delay_ms(10);
watchdog_periodic();
}
#endif

// Disable all interrupts
cli();
/* Set the bootloader key to the magic value and force a reset */
Boot_Key = MAGIC_BOOT_KEY;

// Set the bootloader key to the magic value and force a reset
Boot_Key = MAGIC_BOOT_KEY;
eeprom_write_byte(EEPROM_MAGIC_BYTE_ADDR, 0xFF);

// Wait two seconds for the USB detachment to register on the host
for (i = 0; i < 128; i++)
_delay_ms(16);
/* Enable interrupts */
sei();

// Set the bootloader key to the magic value and force a reset
Boot_Key = MAGIC_BOOT_KEY;

watchdog_reboot();
watchdog_reboot();
}

extern void Bootloader_Jump_Check(void) ATTR_INIT_SECTION(3);

void
Bootloader_Jump_Check(void)
{
// If the reset source was the bootloader and the key is correct, clear it and jump to the bootloader
if(MCUSR & (1<<WDRF)) {
MCUSR = 0;
if(Boot_Key == MAGIC_BOOT_KEY) {
Boot_Key = 0;
wdt_disable();

((void (*)(void))BOOTLOADER_START_ADDRESS)();
} else {
Boot_Key++;
}
} else {
Boot_Key = MAGIC_BOOT_KEY-4;
}
/* If the reset source was the bootloader and the key is correct,
* clear it and jump to the bootloader
*/
if(MCUSR & (1 << WDRF)) {
MCUSR = 0;
if(Boot_Key == MAGIC_BOOT_KEY) {
Boot_Key = 0;
wdt_disable();

/* Disable all interrupts */
cli();

eeprom_write_byte(EEPROM_MAGIC_BYTE_ADDR, 0xFF);

/* Enable interrupts */
sei();

((void (*)(void))(BOOTLOADER_START_ADDRESS)) ();
} else {
/* The watchdog fired. Probably means we
* crashed. Wait two seconds before continuing.
*/

Boot_Key++;
uint8_t i;

for(i = 0; i < 200; i++) {
_delay_ms(10);
watchdog_periodic();
}
}
} else {
Boot_Key = MAGIC_BOOT_KEY - 4;
}
}
2 changes: 2 additions & 0 deletions platform/avr-ravenusb/Makefile.avr-ravenusb
Original file line number Diff line number Diff line change
@@ -2,6 +2,8 @@ CONTIKI_TARGET_DIRS = . apps net loader dev/usb dev/serial
CONTIKI_CORE=contiki-raven-main
CONTIKI_TARGET_MAIN = ${CONTIKI_CORE}.o

BOOTLOADER_START = 0x1F000

#USB Ethernet Interface + USB Serial Port TX Only
USB = uart_usb_lib.c \
cdc_task.c \

0 comments on commit 9c17a54

Please sign in to comment.