aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKévin Redon <kredon@sysmocom.de>2018-07-07 15:22:16 +0200
committerKévin Redon <kredon@sysmocom.de>2018-07-11 20:48:24 +0200
commit9918c2840e4c0ff18a9441b1e0371d244e891ac1 (patch)
tree938a6aa8a4cf7ac538085254ee5c40f4475e01d3
parentd24e9bde26230f5364fbea8fc8a5052a693b7790 (diff)
DFU: use central DFU override check
TRACE_INFO will also provide the DFU start reason, but TRACE_INFO (TRACE_LEVEL >= 4) should only be used for debugging. WARNING: With TRACE_LEVEL >= 4 the DFU binary is over the maximum of 16 kiB allocated for the DFU bootloader. Thus make combined will not boot the main application because its start if after the expecte 16 kiB address; and flashing using DFU will overwrite the DFU bootloader itself. Change-Id: I82323e0f76c03f67df7dc8f2b6783166cc25f3aa
-rw-r--r--firmware/apps/dfu/main.c53
-rw-r--r--firmware/libboard/common/source/board_cstartup_gnu.c26
2 files changed, 51 insertions, 28 deletions
diff --git a/firmware/apps/dfu/main.c b/firmware/apps/dfu/main.c
index 26cbb8c..467b7dd 100644
--- a/firmware/apps/dfu/main.c
+++ b/firmware/apps/dfu/main.c
@@ -159,22 +159,30 @@ WEAK int board_override_enter_dfu(void)
int USBDFU_OverrideEnterDFU(void)
{
uint32_t *app_part = (uint32_t *)FLASH_ADDR(0);
+ /* at the first call we are before the text segment has been relocated,
+ * so g_dfu is not initialized yet */
+ g_dfu = &_g_dfu;
+ if (USB_DFU_MAGIC == g_dfu->magic) {
+ return 1;
+ }
/* If the loopback jumper is set, we enter DFU mode */
- if (board_override_enter_dfu())
- return 1;
+ if (board_override_enter_dfu()) {
+ return 2;
+ }
/* if the first word of the application partition doesn't look
* like a stack pointer (i.e. point to RAM), enter DFU mode */
- if ((app_part[0] < IRAM_ADDR) ||
- ((uint8_t *)app_part[0] > IRAM_END))
- return 1;
+ if ((app_part[0] < IRAM_ADDR) || ((uint8_t *)app_part[0] > IRAM_END)) {
+ return 3;
+ }
/* if the second word of the application partition doesn't look
* like a function from flash (reset vector), enter DFU mode */
if (((uint32_t *)app_part[1] < app_part) ||
- ((uint8_t *)app_part[1] > IFLASH_END))
- return 1;
+ ((uint8_t *)app_part[1] > IFLASH_END)) {
+ return 4;
+ }
return 0;
}
@@ -218,7 +226,7 @@ extern int main(void)
EEFC_ReadUniqueID(g_unique_id);
- printf("\n\r\n\r"
+ printf("\n\r\n\r"
"=============================================================================\n\r"
"DFU bootloader %s for board %s (C) 2010-2017 by Harald Welte\n\r"
"=============================================================================\n\r",
@@ -230,6 +238,35 @@ extern int main(void)
g_unique_id[2], g_unique_id[3]);
TRACE_INFO("Reset Cause: 0x%x\n\r", reset_cause);
+#if (TRACE_LEVEL >= TRACE_LEVEL_INFO)
+ /* Find out why we are in the DFU bootloader, and not the main application */
+ TRACE_INFO("DFU bootloader start reason: ");
+ switch (USBDFU_OverrideEnterDFU()) {
+ case 0:
+ /* 0 normally means that there is no override, but we are in the bootloader,
+ * thus the first check in board_cstartup_gnu did return something else than 0.
+ * this can only be g_dfu->magic which is erased when the segment are
+ * relocated, which happens in board_cstartup_gnu just after USBDFU_OverrideEnterDFU.
+ * no static variable can be used to store this case since this will also be overwritten
+ */
+ case 1:
+ TRACE_INFO_WP("DFU switch requested by main application\n\r");
+ break;
+ case 2:
+ TRACE_INFO_WP("bootloader forced (button pressed or jumper set)\n\r");
+ break;
+ case 3:
+ TRACE_INFO_WP("stack pointer (first application word) does no point in RAM\n\r");
+ break;
+ case 4: // the is no reason
+ TRACE_INFO_WP("reset vector (second application word) does no point in flash\n\r");
+ break;
+ default:
+ TRACE_INFO_WP("unknown\n\r");
+ break;
+ }
+#endif
+
/* clear g_dfu on power-up reset */
if (reset_cause == 0)
memset(g_dfu, 0, sizeof(*g_dfu));
diff --git a/firmware/libboard/common/source/board_cstartup_gnu.c b/firmware/libboard/common/source/board_cstartup_gnu.c
index 42231fb..bfe59ad 100644
--- a/firmware/libboard/common/source/board_cstartup_gnu.c
+++ b/firmware/libboard/common/source/board_cstartup_gnu.c
@@ -159,26 +159,12 @@ void ResetException( void )
#if defined(BOARD_USB_DFU) && defined(APPLICATION_dfu)
- /* we are before the text segment has been relocated, so g_dfu is
- * not initialized yet */
- g_dfu = &_g_dfu;
- if ((g_dfu->magic != USB_DFU_MAGIC) && !USBDFU_OverrideEnterDFU()) {
- /* start application if valid
- * the application starts with the vector table
- * the first entry in the vector table is the initial stack pointer (SP) address
- * the stack will be placed in RAM, which begins at 0x2000 0000
- * there is up to 48 KB of RAM (0xc000)
- * since the stack grown "downwards" it should start at the end of the RAM: max 0x2000 c000
- * if the SP is not in this range (e.g. flash has been erased) there is no valid application
- * the second entry in the vector table is the reset address, corresponding to the application start
- */
- if (((*((uint32_t*)(IFLASH_ADDR+BOARD_DFU_BOOT_SIZE)))&0xFFFF0000)==0x20000000) {
- UART_Exit();
- __disable_irq();
- BootIntoApp();
- /* Infinite loop */
- while ( 1 ) ;
- }
+ if (!USBDFU_OverrideEnterDFU()) {
+ UART_Exit();
+ __disable_irq();
+ BootIntoApp();
+ /* Infinite loop */
+ while ( 1 ) ;
}
#endif