Parcourir la source

Add boot command to jump to the bootloader

After much poking around, I finally figured out how to make this work!
The problem was that the ChibiOS initialization code had disabled
interrupts before the __early_init function was run, making the
bootloader not work despite my best intentions.  This was fixed by
enabling interrupts just before jumping to the bootloader.  This in turn
required changing to GNU-flavored C11 to include an inline assembly
instruction.
Clara Hobbs il y a 6 ans
Parent
révision
dcb00f4f39

+ 1
- 1
Makefile Voir le fichier

@@ -10,7 +10,7 @@ endif
10 10
 
11 11
 # C specific options here (added to USE_OPT).
12 12
 ifeq ($(USE_COPT),)
13
-  USE_COPT = -std=c11
13
+  USE_COPT = -std=gnu11
14 14
 endif
15 15
 
16 16
 # C++ specific options here (added to USE_OPT).

+ 11
- 0
boards/PD_BUDDY_SINK/board.c Voir le fichier

@@ -37,6 +37,7 @@
37 37
  * generator plugin. Do not edit manually.
38 38
  */
39 39
 
40
+#include "stm32f072_bootloader.h"
40 41
 #include "hal.h"
41 42
 
42 43
 #if HAL_USE_PAL || defined(__DOXYGEN__)
@@ -93,6 +94,16 @@ const PALConfig pal_default_config = {
93 94
 void __early_init(void) {
94 95
 
95 96
   stm32_clock_init();
97
+  /* Jump to the bootloader if the magic value is set in
98
+   * dfu_reset_to_bootloader_magic. */
99
+  if (dfu_reset_to_bootloader_magic == RESET_TO_BOOTLOADER_MAGIC_CODE) {
100
+    asm("cpsie i");
101
+    void (*bootloader)(void) = (void (*)(void)) (*((uint32_t *) SYSMEM_RESET_VECTOR));
102
+    dfu_reset_to_bootloader_magic = 0;
103
+    __set_MSP(BOOTLOADER_STACK_POINTER);
104
+    bootloader();
105
+    while (42);
106
+  }
96 107
 }
97 108
 
98 109
 #if HAL_USE_MMC_SPI || defined(__DOXYGEN__)

+ 1
- 1
boards/PD_BUDDY_SINK/board.h Voir le fichier

@@ -1,6 +1,6 @@
1 1
 /*
2 2
  * PD Buddy - USB Power Delivery for everyone
3
- * Copyright (C) 2017 Clayton G. Hobbs <clay@lakeserv.net>
3
+ * Copyright (C) 2017-2018 Clayton G. Hobbs <clay@lakeserv.net>
4 4
  *
5 5
  * This program is free software: you can redistribute it and/or modify
6 6
  * it under the terms of the GNU General Public License as published by

+ 1
- 1
boards/PD_BUDDY_SINK/board.mk Voir le fichier

@@ -2,4 +2,4 @@
2 2
 BOARDSRC = $(CHIBIOS)/../boards/PD_BUDDY_SINK/board.c
3 3
 
4 4
 # Required include directories
5
-BOARDINC = $(CHIBIOS)/../boards/PD_BUDDY_SINK
5
+BOARDINC = $(CHIBIOS)/../boards/PD_BUDDY_SINK $(CHIBIOS)/../src

+ 13
- 1
boards/PD_BUDDY_SINK/cfg/board.chcfg Voir le fichier

@@ -10,7 +10,19 @@
10 10
   </configuration_settings>
11 11
   <board_name>PD Buddy Sink</board_name>
12 12
   <board_id>PD_BUDDY_SINK</board_id>
13
-  <board_functions></board_functions>
13
+  <board_functions>
14
+  	<__early_init>/* Jump to the bootloader if the magic value is set in
15
+   * dfu_reset_to_bootloader_magic. */
16
+  if (dfu_reset_to_bootloader_magic == RESET_TO_BOOTLOADER_MAGIC_CODE) {
17
+    asm("cpsie i");
18
+    void (*bootloader)(void) = (void (*)(void)) (*((uint32_t *) SYSMEM_RESET_VECTOR));
19
+    dfu_reset_to_bootloader_magic = 0;
20
+    __set_MSP(BOOTLOADER_STACK_POINTER);
21
+    bootloader();
22
+    while (42);
23
+  }</__early_init></board_functions>
24
+  <headers>
25
+  	<header>stm32f072_bootloader.h</header></headers>
14 26
   <subtype>STM32F072xB</subtype>
15 27
   <clocks HSEFrequency="0" HSEBypass="true" LSEFrequency="0"
16 28
   	LSEBypass="false" LSEDrive="3 High Drive (default)" ></clocks>

+ 15
- 0
src/shell.c Voir le fichier

@@ -45,6 +45,7 @@
45 45
 #include "config.h"
46 46
 #include "led.h"
47 47
 #include "device_policy_manager.h"
48
+#include "stm32f072_bootloader.h"
48 49
 
49 50
 
50 51
 /* Buffer for unwritten configuration */
@@ -192,6 +193,19 @@ static void cmd_identify(BaseSequentialStream *chp, int argc, char *argv[])
192 193
     chEvtSignal(pdbs_led_thread, PDBS_EVT_LED_IDENTIFY);
193 194
 }
194 195
 
196
+static void cmd_boot(BaseSequentialStream *chp, int argc, char *argv[])
197
+{
198
+    (void) argv;
199
+    if (argc > 0) {
200
+        chprintf(chp, "Usage: boot\r\n");
201
+        return;
202
+    }
203
+
204
+    sduStop(&SDU1);
205
+    usbDisconnectBus(serusbcfg.usbp);
206
+    dfu_run_bootloader();
207
+}
208
+
195 209
 static void cmd_get_cfg(BaseSequentialStream *chp, int argc, char *argv[])
196 210
 {
197 211
     struct pdbs_config *cfg = NULL;
@@ -493,6 +507,7 @@ static void cmd_get_source_cap(BaseSequentialStream *chp, int argc, char *argv[]
493 507
 static const struct pdbs_shell_cmd commands[] = {
494 508
     {"license", cmd_license, "Show copyright and license information"},
495 509
     {"identify", cmd_identify, "Blink the LED to identify the device"},
510
+    {"boot", cmd_boot, "Run the DfuSe bootloader"},
496 511
     {"get_cfg", cmd_get_cfg, "Print the stored configuration"},
497 512
     {"load", cmd_load, "Load the stored configuration into the buffer"},
498 513
     {"write", cmd_write, "Store the configuration buffer"},

+ 29
- 0
src/stm32f072_bootloader.c Voir le fichier

@@ -0,0 +1,29 @@
1
+/*
2
+ * PD Buddy - USB Power Delivery for everyone
3
+ * Copyright (C) 2017-2018 Clayton G. Hobbs <clay@lakeserv.net>
4
+ *
5
+ * This program is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * This program is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+#include "stm32f072_bootloader.h"
20
+
21
+
22
+uint32_t dfu_reset_to_bootloader_magic;
23
+
24
+
25
+void dfu_run_bootloader(void)
26
+{
27
+    dfu_reset_to_bootloader_magic = RESET_TO_BOOTLOADER_MAGIC_CODE;
28
+    NVIC_SystemReset();
29
+}

+ 40
- 0
src/stm32f072_bootloader.h Voir le fichier

@@ -0,0 +1,40 @@
1
+/*
2
+ * PD Buddy - USB Power Delivery for everyone
3
+ * Copyright (C) 2017-2018 Clayton G. Hobbs <clay@lakeserv.net>
4
+ *
5
+ * This program is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * This program is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+#ifndef PDB_STM32F072_BOOTLOADER_H
20
+#define PDB_STM32F072_BOOTLOADER_H
21
+
22
+#include <stdint.h>
23
+
24
+#include <ch.h>
25
+
26
+/*
27
+ * Code to jump to the STM32F072 bootloader, based on
28
+ * https://stackoverflow.com/a/36793779
29
+ */
30
+
31
+#define SYSMEM_RESET_VECTOR 0x1FFFC804
32
+#define RESET_TO_BOOTLOADER_MAGIC_CODE 0xDEADBEEF
33
+#define BOOTLOADER_STACK_POINTER 0x20002250
34
+
35
+
36
+/* Magic value used for jumping to the STM32F072 bootloader */
37
+extern uint32_t dfu_reset_to_bootloader_magic;
38
+
39
+
40
+#endif /* PDB_STM32F072_BOOTLOADER_H */

Chargement…
Annuler
Enregistrer