1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #14119 from benpicco/cpu/stm32_usb_bootloader

cpu/stm32: implement reset to bootloader
This commit is contained in:
benpicco 2020-06-10 23:13:50 +02:00 committed by GitHub
commit f75c971297
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 340 additions and 1 deletions

View File

@ -1,5 +1,5 @@
MODULE = cpu
DIRS = $(RIOTCPU)/cortexm_common periph stmclk vectors
DIRS = $(RIOTCPU)/cortexm_common periph stmclk vectors bootloader
include $(RIOTBASE)/Makefile.base

View File

@ -8,4 +8,8 @@ ifneq (,$(filter periph_usbdev,$(FEATURES_USED)))
USEMODULE += xtimer
endif
ifneq (,$(filter bootloader_stm32,$(FEATURES_USED)))
USEMODULE += bootloader_stm32
endif
include $(RIOTCPU)/cortexm_common/Makefile.dep

View File

@ -1,5 +1,6 @@
include $(RIOTCPU)/stm32/stm32_info.mk
FEATURES_PROVIDED += bootloader_stm32
FEATURES_PROVIDED += cpu_stm32$(CPU_FAM)
FEATURES_PROVIDED += periph_cpuid
FEATURES_PROVIDED += periph_gpio periph_gpio_irq

View File

@ -0,0 +1,3 @@
MODULE = bootloader_stm32
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1,77 @@
/*
* Copyright (C) 2020 Benjamin Valentin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup cpu_stm32
* @{
*
* @file
* @brief Trigger reset to the bootloader stored in the internal boot ROM
* memory.
*
* This will start the DFU/UART/SPI bootloader.
* See application note AN2606 for which options are available on
* your individual MCU.
*
* @author Benjamin Valentin <benpicco@googlemail.com>
* @author Marian Buschsieweke <marian.buschsieweke@ovgu.de>
*
* @}
*/
#include "cpu.h"
#include "periph_cpu.h"
#include "sched.h"
/* repurpose the sched_context_switch_request variable to signal
* jump to bootloader after reset */
#define MAGIC sched_context_switch_request
#define BOOTLOADER_MAGIC 0xB007AFFE
/* called by reset_handler_default() before memory is initialized */
void pre_startup(void)
{
if (MAGIC != BOOTLOADER_MAGIC) {
return;
}
/* clear magic */
MAGIC = 0;
/* enable SYSCFG clock */
#if defined(RCC_APB2ENR_SYSCFGEN)
RCC->APB2ENR = RCC_APB2ENR_SYSCFGEN;
#elif defined(RCC_APB2ENR_SYSCFGCOMPEN)
RCC->APB2ENR = RCC_APB2ENR_SYSCFGCOMPEN
#endif
/* remap ROM at zero */
#if defined(SYSCFG_MEMRMP_MEM_MODE_0)
SYSCFG->MEMRMP = SYSCFG_MEMRMP_MEM_MODE_0;
#elif defined(SYSCFG_CFGR1_MEM_MODE_0)
SYSCFG->CFGR1 = SYSCFG_CFGR1_MEM_MODE_0;
#endif
/* jump to the bootloader */
__asm__ volatile(
"ldr r0, [%[btldr]] \n"
"mov sp, r0 \n"
"ldr r0, [%[btldr], #4] \n"
"mov pc, r0 \n"
: /* no outputs */
: [btldr] "r" ((uintptr_t)STM32_BOOTLOADER_ADDR)
: "r0", "memory"
);
}
void __attribute__((weak)) usb_board_reset_in_bootloader(void)
{
irq_disable();
MAGIC = BOOTLOADER_MAGIC;
NVIC_SystemReset();
}

View File

@ -24,6 +24,23 @@ extern "C" {
#endif
#ifndef DOXYGEN
/**
* @brief Starting address of the ROM bootloader
* see application note AN2606
*/
#if defined(CPU_LINE_STM32F030x4) || defined(CPU_LINE_STM32F030x6) || \
defined(CPU_LINE_STM32F030x8) || defined(CPU_LINE_STM32F031x6) || \
defined(CPU_LINE_STM32F051x8)
#define STM32_BOOTLOADER_ADDR (0x1FFFEC00)
#elif defined(CPU_LINE_STM32F072xB) || defined(CPU_LINE_STM32F070xB)
#define STM32_BOOTLOADER_ADDR (0x1FFFC800)
#elif defined(CPU_LINE_STM32F030xC) || defined(CPU_LINE_STM32F091xC)
#define STM32_BOOTLOADER_ADDR (0x1FFFD800)
#elif defined(CPU_LINE_STM32F042x6)
#define STM32_BOOTLOADER_ADDR (0x1FFFC400)
#endif
/**
* @brief Override ADC resolution values
* @{

View File

@ -23,6 +23,18 @@
extern "C" {
#endif
#ifndef DOXYGEN
/**
* @brief Starting address of the ROM bootloader
* see application note AN2606
*/
#if defined(CPU_LINE_STM32F103xB) || defined(CPU_LINE_STM32F103xE)
#define STM32_BOOTLOADER_ADDR (0x1FFFF000)
#endif
#endif /* ndef DOXYGEN */
/**
* @name Real time counter configuration
* @{

View File

@ -31,6 +31,13 @@ extern "C" {
#define ADC_DEVS (2U)
#ifndef DOXYGEN
/**
* @brief Starting address of the ROM bootloader
* see application note AN2606
*/
#define STM32_BOOTLOADER_ADDR (0x1FFF0000)
/**
* @brief Override the ADC resolution configuration
* @{

View File

@ -0,0 +1,41 @@
/*
* Copyright (C) 2015-2016 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup cpu_stm32
* @{
*
* @file
* @brief STM32F3 CPU specific definitions for internal peripheral handling
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef PERIPH_F3_PERIPH_CPU_H
#define PERIPH_F3_PERIPH_CPU_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef DOXYGEN
/**
* @brief Starting address of the ROM bootloader
* see application note AN2606
*/
#define STM32_BOOTLOADER_ADDR (0x1FFFD800)
#endif /* ndef DOXYGEN */
#ifdef __cplusplus
}
#endif
#endif /* PERIPH_F3_PERIPH_CPU_H */
/** @} */

View File

@ -37,6 +37,17 @@ extern "C" {
#endif
#ifndef DOXYGEN
/**
* @brief Starting address of the ROM bootloader
* see application note AN2606
*/
#if defined(CPU_LINE_STM32F423xx)
#define STM32_BOOTLOADER_ADDR (0x1FF00000)
#else
#define STM32_BOOTLOADER_ADDR (0x1FFF0000)
#endif
/**
* @brief Override the ADC resolution configuration
* @{

View File

@ -0,0 +1,42 @@
/*
* Copyright (C) 2017 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup cpu_stm32
* @{
*
* @file
* @brief STM32F7 CPU specific definitions for internal peripheral handling
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*
*/
#ifndef PERIPH_F7_PERIPH_CPU_H
#define PERIPH_F7_PERIPH_CPU_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef DOXYGEN
/**
* @brief Starting address of the ROM bootloader
* see application note AN2606
*/
#define STM32_BOOTLOADER_ADDR (0x1FF00000)
#endif /* ndef DOXYGEN */
#ifdef __cplusplus
}
#endif
#endif /* PERIPH_F7_PERIPH_CPU_H */
/** @} */

View File

@ -27,6 +27,13 @@ extern "C" {
#endif
#ifndef DOXYGEN
/**
* @brief Starting address of the ROM bootloader
* see application note AN2606
*/
#define STM32_BOOTLOADER_ADDR (0x1FF00000)
/**
* @brief Override ADC resolution values
* @{

View File

@ -26,6 +26,13 @@ extern "C" {
#endif
#ifndef DOXYGEN
/**
* @brief Starting address of the ROM bootloader
* see application note AN2606
*/
#define STM32_BOOTLOADER_ADDR (0x1FF00000)
/**
* @brief Override the ADC resolution configuration
* @{

View File

@ -42,6 +42,13 @@ extern "C" {
#endif
#ifndef DOXYGEN
/**
* @brief Starting address of the ROM bootloader
* see application note AN2606
*/
#define STM32_BOOTLOADER_ADDR (0x1FFF0000)
/**
* @brief Override ADC resolution values
* @{

View File

@ -0,0 +1,42 @@
/*
* Copyright (C) 2019 Inria
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup cpu_stm32
* @{
*
* @file
* @brief STM32WB CPU specific definitions for internal peripheral handling
*
* @author Francisco Molina <francois-xavier.molina@inria.fr>
*
*/
#ifndef PERIPH_WB_PERIPH_CPU_H
#define PERIPH_WB_PERIPH_CPU_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef DOXYGEN
/**
* @brief Starting address of the ROM bootloader
* see application note AN2606
*/
#define STM32_BOOTLOADER_ADDR (0x1FFF0000)
#endif /* ndef DOXYGEN */
#ifdef __cplusplus
}
#endif
#endif /* PERIPH_WB_PERIPH_CPU_H */
/** @} */

View File

@ -29,14 +29,20 @@
#include "periph/f1/periph_cpu.h"
#elif defined(CPU_FAM_STM32F2)
#include "periph/f2/periph_cpu.h"
#elif defined(CPU_FAM_STM32F3)
#include "periph/f3/periph_cpu.h"
#elif defined(CPU_FAM_STM32F4)
#include "periph/f4/periph_cpu.h"
#elif defined(CPU_FAM_STM32F7)
#include "periph/f7/periph_cpu.h"
#elif defined(CPU_FAM_STM32L0)
#include "periph/l0/periph_cpu.h"
#elif defined(CPU_FAM_STM32L1)
#include "periph/l1/periph_cpu.h"
#elif defined(CPU_FAM_STM32L4)
#include "periph/l4/periph_cpu.h"
#elif defined(CPU_FAM_STM32WB)
#include "periph/wb/periph_cpu.h"
#endif
#ifdef __cplusplus
@ -59,6 +65,14 @@ extern "C" {
#error "error: LSI clock speed not defined for your target CPU"
#endif
#ifdef Doxygen
/**
* @brief Starting address of the ROM bootloader
* see application note AN2606
*/
#define STM32_BOOTLOADER_ADDR
#endif
/**
* @brief Length of the CPU_ID in octets
*

View File

@ -0,0 +1,10 @@
BOARD ?= nucleo-f411re
include ../Makefile.tests_common
FEATURES_REQUIRED = bootloader_stm32
USEMODULE += shell
USEMODULE += shell_commands
USEMODULE += usb_board_reset
include $(RIOTBASE)/Makefile.include

View File

@ -0,0 +1,37 @@
/*
* Copyright (C) 2020 Benjamin Valentin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup tests
* @{
*
* @file
* @brief Test application to activate the STM32 bootloader mode.
*
* @author Benjamin Valentin <benpicco@googlemail.com>
*
* @}
*/
#include <stdio.h>
#include <string.h>
#include "shell.h"
#include "shell_commands.h"
int main(void)
{
char line_buf[SHELL_DEFAULT_BUFSIZE];
puts("STM32 bootloader test application.");
/* bootloader command is provided by default */
shell_run(NULL, line_buf, SHELL_DEFAULT_BUFSIZE);
return 0;
}