Skip to content

[Beta] Jump to system memory boot from user application #710

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 15 commits into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions boards.txt
Original file line number Diff line number Diff line change
@@ -181,6 +181,7 @@ Nucleo_144.menu.upload_method.serialMethod.upload.tool=stm32CubeProg
Nucleo_144.menu.upload_method.dfuMethod=STM32CubeProgrammer (DFU)
Nucleo_144.menu.upload_method.dfuMethod.upload.protocol=2
Nucleo_144.menu.upload_method.dfuMethod.upload.options=-g
Nucleo_144.menu.upload_method.dfuMethod.upload.use_1200bps_touch=true
Nucleo_144.menu.upload_method.dfuMethod.upload.tool=stm32CubeProg

################################################################################
@@ -466,6 +467,7 @@ Nucleo_64.menu.upload_method.serialMethod.upload.tool=stm32CubeProg
Nucleo_64.menu.upload_method.dfuMethod=STM32CubeProgrammer (DFU)
Nucleo_64.menu.upload_method.dfuMethod.upload.protocol=2
Nucleo_64.menu.upload_method.dfuMethod.upload.options=-g
Nucleo_64.menu.upload_method.dfuMethod.upload.use_1200bps_touch=true
Nucleo_64.menu.upload_method.dfuMethod.upload.tool=stm32CubeProg

################################################################################
@@ -571,6 +573,7 @@ Nucleo_32.menu.upload_method.serialMethod.upload.tool=stm32CubeProg
Nucleo_32.menu.upload_method.dfuMethod=STM32CubeProgrammer (DFU)
Nucleo_32.menu.upload_method.dfuMethod.upload.protocol=2
Nucleo_32.menu.upload_method.dfuMethod.upload.options=-g
Nucleo_32.menu.upload_method.dfuMethod.upload.use_1200bps_touch=true
Nucleo_32.menu.upload_method.dfuMethod.upload.tool=stm32CubeProg

################################################################################
@@ -727,6 +730,7 @@ Disco.menu.upload_method.serialMethod.upload.tool=stm32CubeProg
Disco.menu.upload_method.dfuMethod=STM32CubeProgrammer (DFU)
Disco.menu.upload_method.dfuMethod.upload.protocol=2
Disco.menu.upload_method.dfuMethod.upload.options=-g
Disco.menu.upload_method.dfuMethod.upload.use_1200bps_touch=true
Disco.menu.upload_method.dfuMethod.upload.tool=stm32CubeProg

################################################################################
@@ -759,6 +763,7 @@ Eval.menu.upload_method.swdMethod.upload.tool=stm32CubeProg
Eval.menu.upload_method.dfuMethod=STM32CubeProgrammer (DFU)
Eval.menu.upload_method.dfuMethod.upload.protocol=2
Eval.menu.upload_method.dfuMethod.upload.options=-g
Eval.menu.upload_method.dfuMethod.upload.use_1200bps_touch=true
Eval.menu.upload_method.dfuMethod.upload.tool=stm32CubeProg

################################################################################
@@ -847,6 +852,7 @@ GenF0.menu.upload_method.serialMethod.upload.tool=stm32CubeProg
GenF0.menu.upload_method.dfuMethod=STM32CubeProgrammer (DFU)
GenF0.menu.upload_method.dfuMethod.upload.protocol=2
GenF0.menu.upload_method.dfuMethod.upload.options=-g
GenF0.menu.upload_method.dfuMethod.upload.use_1200bps_touch=true
GenF0.menu.upload_method.dfuMethod.upload.tool=stm32CubeProg

################################################################################
@@ -1152,6 +1158,7 @@ GenF1.menu.upload_method.serialMethod.upload.tool=stm32CubeProg
GenF1.menu.upload_method.dfuMethod=STM32CubeProgrammer (DFU)
GenF1.menu.upload_method.dfuMethod.upload.protocol=2
GenF1.menu.upload_method.dfuMethod.upload.options=-g
GenF1.menu.upload_method.dfuMethod.upload.use_1200bps_touch=true
GenF1.menu.upload_method.dfuMethod.upload.tool=stm32CubeProg

GenF1.menu.upload_method.bmpMethod=BMP (Black Magic Probe)
@@ -1215,6 +1222,7 @@ GenF3.menu.upload_method.serialMethod.upload.tool=stm32CubeProg
GenF3.menu.upload_method.dfuMethod=STM32CubeProgrammer (DFU)
GenF3.menu.upload_method.dfuMethod.upload.protocol=2
GenF3.menu.upload_method.dfuMethod.upload.options=-g
GenF3.menu.upload_method.dfuMethod.upload.use_1200bps_touch=true
GenF3.menu.upload_method.dfuMethod.upload.tool=stm32CubeProg

GenF3.menu.upload_method.bmpMethod=BMP (Black Magic Probe)
@@ -1623,6 +1631,7 @@ GenF4.menu.upload_method.serialMethod.upload.tool=stm32CubeProg
GenF4.menu.upload_method.dfuMethod=STM32CubeProgrammer (DFU)
GenF4.menu.upload_method.dfuMethod.upload.protocol=2
GenF4.menu.upload_method.dfuMethod.upload.options=-g
GenF4.menu.upload_method.dfuMethod.upload.use_1200bps_touch=true
GenF4.menu.upload_method.dfuMethod.upload.tool=stm32CubeProg

GenF4.menu.upload_method.bmpMethod=BMP (Black Magic Probe)
@@ -1712,6 +1721,7 @@ GenL0.menu.upload_method.serialMethod.upload.tool=stm32CubeProg
GenL0.menu.upload_method.dfuMethod=STM32CubeProgrammer (DFU)
GenL0.menu.upload_method.dfuMethod.upload.protocol=2
GenL0.menu.upload_method.dfuMethod.upload.options=-g
GenL0.menu.upload_method.dfuMethod.upload.use_1200bps_touch=true
GenL0.menu.upload_method.dfuMethod.upload.tool=stm32CubeProg

GenL0.menu.upload_method.bmpMethod=BMP (Black Magic Probe)
@@ -1752,6 +1762,7 @@ ESC_board.menu.upload_method.serialMethod.upload.tool=stm32CubeProg
ESC_board.menu.upload_method.dfuMethod=STM32CubeProgrammer (DFU)
ESC_board.menu.upload_method.dfuMethod.upload.protocol=2
ESC_board.menu.upload_method.dfuMethod.upload.options=-g
ESC_board.menu.upload_method.dfuMethod.upload.use_1200bps_touch=true
ESC_board.menu.upload_method.dfuMethod.upload.tool=stm32CubeProg

################################################################################
@@ -1834,6 +1845,7 @@ LoRa.menu.upload_method.serialMethod.upload.tool=stm32CubeProg
LoRa.menu.upload_method.dfuMethod=STM32CubeProgrammer (DFU)
LoRa.menu.upload_method.dfuMethod.upload.protocol=2
LoRa.menu.upload_method.dfuMethod.upload.options=-g
LoRa.menu.upload_method.dfuMethod.upload.use_1200bps_touch=true
LoRa.menu.upload_method.dfuMethod.upload.tool=stm32CubeProg

###############################
@@ -2010,6 +2022,7 @@ LoRa.menu.upload_method.dfuMethod.upload.tool=stm32CubeProg
3dprinter.menu.upload_method.dfuMethod=STM32CubeProgrammer (DFU)
3dprinter.menu.upload_method.dfuMethod.upload.protocol=2
3dprinter.menu.upload_method.dfuMethod.upload.options=-g
3dprinter.menu.upload_method.dfuMethod.upload.use_1200bps_touch=true
3dprinter.menu.upload_method.dfuMethod.upload.tool=stm32CubeProg


@@ -2069,6 +2082,7 @@ Genericflight.menu.upload_method.serialMethod.upload.tool=stm32CubeProg
Genericflight.menu.upload_method.dfuMethod=STM32CubeProgrammer (DFU)
Genericflight.menu.upload_method.dfuMethod.upload.protocol=2
Genericflight.menu.upload_method.dfuMethod.upload.options=-g
Genericflight.menu.upload_method.dfuMethod.upload.use_1200bps_touch=true
Genericflight.menu.upload_method.dfuMethod.upload.tool=stm32CubeProg

Genericflight.menu.upload_method.bmpMethod=BMP (Black Magic Probe)
@@ -2199,6 +2213,7 @@ Midatronics.menu.upload_method.serialMethod.upload.tool=stm32CubeProg
Midatronics.menu.upload_method.dfuMethod=STM32CubeProgrammer (DFU)
Midatronics.menu.upload_method.dfuMethod.upload.protocol=2
Midatronics.menu.upload_method.dfuMethod.upload.options=-g
Midatronics.menu.upload_method.dfuMethod.upload.use_1200bps_touch=true
Midatronics.menu.upload_method.dfuMethod.upload.tool=stm32CubeProg

################################################################################
17 changes: 17 additions & 0 deletions cores/arduino/stm32/bootloader.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef _BOOTLOADER_H_
#define _BOOTLOADER_H_

#include <stdint.h>

/* Ensure DTR_TOGGLING_SEQ enabled */
#if defined(BL_LEGACY_LEAF) || defined(BL_HID)
#ifndef DTR_TOGGLING_SEQ
@@ -12,6 +14,21 @@
extern "C" {
#endif /* __cplusplus */

void scheduleBootloaderReset();
void cancelBootloaderReset();
void bootloaderSystickHandler();

/* Request to jump to system memory boot */
void jumpToBootloaderRequested(void);

/* Jump to system memory boot from user application */
void jumpToBootloaderIfRequested(void);

#ifdef DTR_TOGGLING_SEQ
/* DTR toggling sequence management */
void dtr_togglingHook(uint8_t *buf, uint32_t *len);
#endif

#ifdef __cplusplus
}
#endif /* __cplusplus */
5 changes: 5 additions & 0 deletions cores/arduino/stm32/startup_stm32yyxx.S
Original file line number Diff line number Diff line change
@@ -3,3 +3,8 @@
#if defined(CMSIS_STARTUP_FILE)
#include CMSIS_STARTUP_FILE
#endif

# Expose Reset_Handler under a different name, to allow overriding it
# with a strong symbol and then calling the original.
.global Original_Reset_Handler
.thumb_set Original_Reset_Handler,Reset_Handler
81 changes: 74 additions & 7 deletions cores/arduino/stm32/usb/cdc/usbd_cdc.c
Original file line number Diff line number Diff line change
@@ -158,13 +158,26 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_CfgHSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */
0x00,
0x02, /* bNumInterfaces: 2 interface */
0x03, /* bNumInterfaces: 3 interface */
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
0xC0, /* bmAttributes: self powered */
0x32, /* MaxPower 0 mA */

/*---------------------------------------------------------------------------*/
/*Interface Association Descriptor*/
0x08, /* bLength: Descriptor length */
0x0B, /* bDescriptorType: IAD */
0x00, /* bFirstInterface */
0x02, /* bInterfaceCount */
0x02, /* bFunctionClass (class of subdevice, should match first interface) */
0x02, /* bFunctionSubclass (subclass of subdevice, should match first interface) */
0x00, /* bFunctionProtocol (protocol of subdevice, should match first interface) */
/* TODO: Put a meaningful string here, which shows up in the Windows */
/* device manager when no driver is installed yet. */
0x00, /* iFunction */

/*---------------------------------------------------------------------------*/
/* Interface Descriptor */
0x09, /* bLength: Interface Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
@@ -233,7 +246,9 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_CfgHSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN
0x02, /* bmAttributes: Bulk */
LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
0x00 /* bInterval: ignore for Bulk transfer */
0x00, /* bInterval: ignore for Bulk transfer */

DFU_RT_IFACE_DESC,
};


@@ -244,11 +259,25 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_CfgFSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */
0x00,
0x02, /* bNumInterfaces: 2 interface */
0x03, /* bNumInterfaces: 3 interface */
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
0xC0, /* bmAttributes: self powered */
0x32, /* MaxPower 0 mA */

/*---------------------------------------------------------------------------*/
/*Interface Association Descriptor*/
0x08, /* bLength: Descriptor length */
0x0B, /* bDescriptorType: IAD */
0x00, /* bFirstInterface */
0x02, /* bInterfaceCount */
0x02, /* bFunctionClass (class of subdevice, should match first interface) */
0x02, /* bFunctionSubclass (subclass of subdevice, should match first interface) */
0x00, /* bFunctionProtocol (protocol of subdevice, should match first interface) */
/* TODO: Put a meaningful string here, which shows up in the Windows */
/* device manager when no driver is installed yet. */
0x00, /* iFunction */

/*---------------------------------------------------------------------------*/
/* Interface Descriptor */
0x09, /* bLength: Interface Descriptor size */
@@ -318,19 +347,36 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_CfgFSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN
0x02, /* bmAttributes: Bulk */
LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
0x00 /* bInterval: ignore for Bulk transfer */
0x00, /* bInterval: ignore for Bulk transfer */

DFU_RT_IFACE_DESC,
};

__ALIGN_BEGIN static uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = {
0x09, /* bLength: Configuation Descriptor size */
USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION,
USB_CDC_CONFIG_DESC_SIZ,
0x00,
0x02, /* bNumInterfaces: 2 interfaces */
0x03, /* bNumInterfaces: 3 interfaces */
0x01, /* bConfigurationValue: */
0x04, /* iConfiguration: */
0xC0, /* bmAttributes: */
0x32, /* MaxPower 100 mA */

/*---------------------------------------------------------------------------*/
/*Interface Association Descriptor*/
0x08, /* bLength: Descriptor length */
0x0B, /* bDescriptorType: IAD */
0x00, /* bFirstInterface */
0x02, /* bInterfaceCount */
0x02, /* bFunctionClass (class of subdevice, should match first interface) */
0x02, /* bFunctionSubclass (subclass of subdevice, should match first interface) */
0x00, /* bFunctionProtocol (protocol of subdevice, should match first interface) */
/* TODO: Put a meaningful string here, which shows up in the Windows */
/* device manager when no driver is installed yet. */
0x00, /* iFunction */

/*---------------------------------------------------------------------------*/
/*Interface Descriptor */
0x09, /* bLength: Interface Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
@@ -399,7 +445,9 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ]
0x02, /* bmAttributes: Bulk */
0x40, /* wMaxPacketSize: */
0x00,
0x00 /* bInterval */
0x00, /* bInterval */

DFU_RT_IFACE_DESC,
};

/**
@@ -539,7 +587,26 @@ static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev,

switch (req->bmRequest & USB_REQ_TYPE_MASK) {
case USB_REQ_TYPE_CLASS:
if (req->wLength != 0U) {
if ((req->bmRequest & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_INTERFACE
&& req->wIndex == DFU_RT_IFACE_NUM) {
// Handle requests to the DFU interface separately
int device_to_host = (req->bmRequest & 0x80U);

if (!device_to_host && req->wLength > 0) {
// When data is sent, return an error, since the data receiving
// machinery will forget the target interface and handle as a CDC
// request instead.
ret = USBD_FAIL;
} else {
ret = USBD_DFU_Runtime_Control(req->bRequest, req->wValue, (uint8_t *)(void *)hcdc->data, req->wLength);
}

if (ret == USBD_FAIL) {
USBD_CtlError(pdev, req);
} else if (device_to_host && req->wLength > 0) {
USBD_CtlSendData(pdev, (uint8_t *)(void *)hcdc->data, req->wLength);
}
} else if (req->wLength != 0U) {
if ((req->bmRequest & 0x80U) != 0U) {
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
(uint8_t *)hcdc->data,
3 changes: 2 additions & 1 deletion cores/arduino/stm32/usb/cdc/usbd_cdc.h
Original file line number Diff line number Diff line change
@@ -28,6 +28,7 @@ extern "C" {
/* Includes ------------------------------------------------------------------*/
#include "usbd_ioreq.h"
#include "usbd_ep_conf.h"
#include "dfu_runtime.h"

/** @addtogroup STM32_USB_DEVICE_LIBRARY
* @{
@@ -51,7 +52,7 @@ extern "C" {

/* CDC Endpoints parameters */

#define USB_CDC_CONFIG_DESC_SIZ 67U
#define USB_CDC_CONFIG_DESC_SIZ 67U + /* IAD */ 8 + DFU_RT_IFACE_DESC_SIZE
#define CDC_DATA_HS_IN_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE
#define CDC_DATA_HS_OUT_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE

19 changes: 17 additions & 2 deletions cores/arduino/stm32/usb/cdc/usbd_cdc_if.c
Original file line number Diff line number Diff line change
@@ -33,6 +33,9 @@
#define CDC_MAX_PACKET_SIZE USB_MAX_EP0_SIZE
#endif

// TODO: Put this elsewhere
#define BOOTLOADER_RESET_1200_BAUD

/*
* The value USB_CDC_TRANSMIT_TIMEOUT is defined in terms of HAL_GetTick() units.
* Typically it is 1ms value. The timeout determines when we would consider the
@@ -56,8 +59,7 @@ __IO bool receivePended = true;
static uint32_t transmitStart = 0;

#ifdef DTR_TOGGLING_SEQ
/* DTR toggling sequence management */
extern void dtr_togglingHook(uint8_t *buf, uint32_t *len);

uint8_t dtr_toggling = 0;
#endif

@@ -201,6 +203,19 @@ static int8_t USBD_CDC_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length)
break;
}

#ifdef BOOTLOADER_RESET_1200_BAUD
if (cmd == CDC_SET_LINE_CODING || cmd == CDC_SET_CONTROL_LINE_STATE) {
// Auto-reset into the bootloader is triggered when the port, already
// open at 1200 bps, is closed. Cancel the reset when the port is
// opened again.
if (linecoding.bitrate == 1200 && !lineState) {
scheduleBootloaderReset();
} else {
cancelBootloaderReset();
}
}
#endif /* BOOTLOADER_RESET_1200_BAUD */

return ((int8_t)USBD_OK);
}

Loading
Oops, something went wrong.