Просмотр исходного кода

Fixing device bricking bug

- When loading a garbage image onto the device, the chip hangs
  and refuses to jump to the bootloader and start dfu

Fix
- Check if chip was in locked state and jump to dfu
- Check if watchdog timer fired and jump to dfu
simple
Jacob Alexander 9 лет назад
Родитель
Сommit
2c7542e2e7
3 измененных файлов: 38 добавлений и 18 удалений
  1. 17
    2
      Bootloader/CMakeLists.txt
  2. 0
    1
      Bootloader/flash.c
  3. 21
    15
      Lib/mk20dx.c

+ 17
- 2
Bootloader/CMakeLists.txt Просмотреть файл

#| You _MUST_ clean the build directory if you change this value #| You _MUST_ clean the build directory if you change this value
#| #|
set( CHIP set( CHIP
"mk20dx128vlf5" # McHCK mk20dx128vlf5
# "mk20dx256vlh7" # Kiibohd-dfu
"mk20dx128vlf5" # McHCK mk20dx128vlf5
# "mk20dx256vlh7" # Kiibohd-dfu mk20dx256vlh7
) )





###
# Compiler Selection
#

#| *** EXPERIMENTAL ***
#| Stick with gcc unless you know what you're doing
#| Currently only arm is supported with clang
set( COMPILER
"gcc" # arm-none-eabi-gcc / avr-gcc - Default
# "clang" # arm-none-eabi
CACHE STRING "Compiler Type" )



### ###
# Bootloader Configuration # Bootloader Configuration
# #

+ 0
- 1
Bootloader/flash.c Просмотреть файл



int flash_program_section(uintptr_t addr, size_t num_words) int flash_program_section(uintptr_t addr, size_t num_words)
{ {
GPIOA_PSOR |= (1<<19);
FTFL.fccob.program_section.fcmd = FTFL_FCMD_PROGRAM_SECTION; FTFL.fccob.program_section.fcmd = FTFL_FCMD_PROGRAM_SECTION;
FTFL.fccob.program_section.addr = addr; FTFL.fccob.program_section.addr = addr;
FTFL.fccob.program_section.num_words = num_words; FTFL.fccob.program_section.num_words = num_words;

+ 21
- 15
Lib/mk20dx.c Просмотреть файл

/* Teensyduino Core Library /* Teensyduino Core Library
* http://www.pjrc.com/teensy/ * http://www.pjrc.com/teensy/
* Copyright (c) 2013 PJRC.COM, LLC. * Copyright (c) 2013 PJRC.COM, LLC.
* Modifications by Jacob Alexander 2014
* Modifications by Jacob Alexander 2014-2015
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* SOFTWARE. * SOFTWARE.
*/ */


// ----- Includes -----

// Local Includes // Local Includes
#include "mk20dx.h" #include "mk20dx.h"


portd_isr, // 59 Pin detect (Port D) portd_isr, // 59 Pin detect (Port D)
porte_isr, // 60 Pin detect (Port E) porte_isr, // 60 Pin detect (Port E)
software_isr, // 61 Software interrupt software_isr, // 61 Software interrupt
#elif defined(_mk20dx256_)
#elif defined(_mk20dx256_) || defined(_mk20dx256vlh7_)
dma_ch0_isr, // 16 DMA channel 0 transfer complete dma_ch0_isr, // 16 DMA channel 0 transfer complete
dma_ch1_isr, // 17 DMA channel 1 transfer complete dma_ch1_isr, // 17 DMA channel 1 transfer complete
dma_ch2_isr, // 18 DMA channel 2 transfer complete dma_ch2_isr, // 18 DMA channel 2 transfer complete


// ----- Functions ----- // ----- Functions -----


#if defined(_mk20dx128vlf5_) && defined(_bootloader_) // Bootloader Section
#if ( defined(_mk20dx128vlf5_) || defined(_mk20dx256vlh7_) ) && defined(_bootloader_) // Bootloader Section
__attribute__((noreturn)) __attribute__((noreturn))
static inline void jump_to_app( uintptr_t addr ) static inline void jump_to_app( uintptr_t addr )
{ {
__attribute__ ((section(".startup"))) __attribute__ ((section(".startup")))
void ResetHandler() void ResetHandler()
{ {
// Disable Watchdog
WDOG_UNLOCK = WDOG_UNLOCK_SEQ1;
WDOG_UNLOCK = WDOG_UNLOCK_SEQ2;
WDOG_STCTRLH = WDOG_STCTRLH_ALLOWUPDATE;

#if defined(_mk20dx128vlf5_) && defined(_bootloader_) // Bootloader Section
#if ( defined(_mk20dx128vlf5_) || defined(_mk20dx256vlh7_) ) && defined(_bootloader_) // Bootloader Section
extern uint32_t _app_rom; extern uint32_t _app_rom;


// We treat _app_rom as pointer to directly read the stack // We treat _app_rom as pointer to directly read the stack
// pointer and check for valid app code. This is no fool // pointer and check for valid app code. This is no fool
// proof method, but it should help for the first flash. // proof method, but it should help for the first flash.
if ( RCM_SRS0 & 0x40 || _app_rom == 0xffffffff ||
//
// Purposefully disabling the watchdog *after* the reset check this way
// if the chip goes into an odd state we'll reset to the bootloader (invalid firmware image)
// RCM_SRS0 & 0x20
//
// Also checking for ARM lock-up signal (invalid firmware image)
// RCM_SRS1 & 0x02
if ( RCM_SRS0 & 0x40 || RCM_SRS0 & 0x20 || RCM_SRS1 & 0x02 || _app_rom == 0xffffffff ||
memcmp( (uint8_t*)&VBAT, sys_reset_to_loader_magic, sizeof(sys_reset_to_loader_magic) ) == 0 ) // Check for soft reload memcmp( (uint8_t*)&VBAT, sys_reset_to_loader_magic, sizeof(sys_reset_to_loader_magic) ) == 0 ) // Check for soft reload
{ {
memset( (uint8_t*)&VBAT, 0, sizeof(VBAT) ); memset( (uint8_t*)&VBAT, 0, sizeof(VBAT) );
jump_to_app( addr ); jump_to_app( addr );
} }
#endif #endif
// Disable Watchdog
WDOG_UNLOCK = WDOG_UNLOCK_SEQ1;
WDOG_UNLOCK = WDOG_UNLOCK_SEQ2;
WDOG_STCTRLH = WDOG_STCTRLH_ALLOWUPDATE;


uint32_t *src = (uint32_t*)&_etext; uint32_t *src = (uint32_t*)&_etext;
uint32_t *dest = (uint32_t*)&_sdata; uint32_t *dest = (uint32_t*)&_sdata;
dest = (uint32_t*)&_sbss; dest = (uint32_t*)&_sbss;
while ( dest < (uint32_t*)&_ebss ) *dest++ = 0; while ( dest < (uint32_t*)&_ebss ) *dest++ = 0;


// MCHCK
// MCHCK / Kiibohd-dfu
#if defined(_mk20dx128vlf5_) #if defined(_mk20dx128vlf5_)
// Default all interrupts to medium priority level // Default all interrupts to medium priority level
for ( unsigned int i = 0; i < NVIC_NUM_INTERRUPTS; i++ ) for ( unsigned int i = 0; i < NVIC_NUM_INTERRUPTS; i++ )
// USB Clock and FLL select // USB Clock and FLL select
SIM_SOPT2 = SIM_SOPT2_USBSRC | SIM_SOPT2_TRACECLKSEL; SIM_SOPT2 = SIM_SOPT2_USBSRC | SIM_SOPT2_TRACECLKSEL;


// Teensy 3.0 and 3.1
// Teensy 3.0 and 3.1 and Kiibohd-dfu (mk20dx256vlh7)
#else #else
unsigned int i;

SCB_VTOR = 0; // use vector table in flash SCB_VTOR = 0; // use vector table in flash


// default all interrupts to medium priority level // default all interrupts to medium priority level
for ( i = 0; i < NVIC_NUM_INTERRUPTS; i++ )
for ( unsigned int i = 0; i < NVIC_NUM_INTERRUPTS; i++ )
{ {
NVIC_SET_PRIORITY( i, 128 ); NVIC_SET_PRIORITY( i, 128 );
} }