Change in simtrace2[master]: DFU: add DFU application

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

laforge gerrit-no-reply at lists.osmocom.org
Thu Jan 16 20:35:04 UTC 2020


laforge has submitted this change. ( https://gerrit.osmocom.org/c/simtrace2/+/16558 )

Change subject: DFU: add DFU application
......................................................................

DFU: add DFU application

this adds the DFU as application, allowing to flash the bootloader.
a USB DFU alternative is added to flash the bootloader partition.

when the DFU is started as bootloader, the partition/alternative
to flash the bootloader is marked as "not available", and
ineffective.
the same happens for the application partition when DFU is started
as application.

this distinction is make at compile time, not at runtime, because
of size restrictions (the bootloader was already close to the
16 kB limit).
*_dfu_flash.bin should not be mixed with *_dfu_dfu.bin.
*_dfu_dfu.bin should be flashed as application using the already
existing DFU bootloader.
once this images is started (as application), the *_dfu_flash.bin
should be flashed as bootloader using the DFU application.

once the DFU bootloader has been flashed, soft resetting
(not re-powering) will cause the bootloader to start, allowing to
flash the application with a normal image (e.g. not DFU),
replacing the DFU application.
this switch to DFU only happens after downloading (e.g. flashing).

it is planned to have the DFU application erase itself after
flashing, but this is currently not implemented.

Change-Id: Ic273bb593a7669111b0219fe301d7897419167c8
---
M firmware/Makefile
M firmware/apps/dfu/main.c
M firmware/apps/dfu/usb_strings.txt
M firmware/atmel_softpack_libraries/libchip_sam3s/source/USBD_HAL.c
M firmware/atmel_softpack_libraries/usb/device/dfu/dfu.h
M firmware/atmel_softpack_libraries/usb/device/dfu/dfu_desc.c
M firmware/atmel_softpack_libraries/usb/device/dfu/dfu_driver.c
M firmware/libboard/common/include/board_common.h
M firmware/libboard/common/source/board_cstartup_gnu.c
9 files changed, 92 insertions(+), 20 deletions(-)

Approvals:
  laforge: Looks good to me, approved
  Jenkins Builder: Verified



diff --git a/firmware/Makefile b/firmware/Makefile
index 5c7aa92..bdca6e5 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -41,7 +41,7 @@
 
 # Defines which are the available memory targets for the SAM3S-EK board.
 ifeq ($(APP), dfu)
-MEMORIES ?= flash
+MEMORIES ?= flash dfu
 else
 MEMORIES ?= dfu
 endif
diff --git a/firmware/apps/dfu/main.c b/firmware/apps/dfu/main.c
index 5aafc7c..2e80884 100644
--- a/firmware/apps/dfu/main.c
+++ b/firmware/apps/dfu/main.c
@@ -26,8 +26,15 @@
 
 #include <osmocom/core/timer.h>
 
+/* USB alternate interface index used to identify which partition to flash */
+/** USB alternate interface index indicating RAM partition */
 #define ALTIF_RAM 0
+/** USB alternate interface index indicating flash partition */
+#if defined(ENVIRONMENT_flash)
 #define ALTIF_FLASH 1
+#elif defined(ENVIRONMENT_dfu)
+#define ALTIF_FLASH 2
+#endif
 
 unsigned int g_unique_id[4];
 /* remember if the watchdog has been configured in the main loop so we can kick it in the ISR */
@@ -44,10 +51,18 @@
  *----------------------------------------------------------------------------*/
 
 #define RAM_ADDR(offset) (IRAM_ADDR + BOARD_DFU_RAM_SIZE + offset)
+#if defined(ENVIRONMENT_flash)
 #define FLASH_ADDR(offset) (IFLASH_ADDR + BOARD_DFU_BOOT_SIZE + offset)
+#elif defined(ENVIRONMENT_dfu)
+#define FLASH_ADDR(offset) (IFLASH_ADDR + offset)
+#endif
 
-#define IFLASH_END	((uint8_t *)IFLASH_ADDR + IFLASH_SIZE)
-#define IRAM_END	((uint8_t *)IRAM_ADDR + IRAM_SIZE)
+#define IRAM_END ((uint8_t *)IRAM_ADDR + IRAM_SIZE)
+#if defined(ENVIRONMENT_flash)
+#define IFLASH_END ((uint8_t *)IFLASH_ADDR + IFLASH_SIZE)
+#elif defined(ENVIRONMENT_dfu)
+#define IFLASH_END ((uint8_t *)IFLASH_ADDR + BOARD_DFU_BOOT_SIZE)
+#endif
 
 /* incoming call-back: Host has transferred 'len' bytes (stored at
  * 'data'), which we shall write to 'offset' into the partition
@@ -90,7 +105,11 @@
 		break;
 	case ALTIF_FLASH:
 		addr = FLASH_ADDR(offset);
+#if defined(ENVIRONMENT_flash)
 		if (addr < IFLASH_ADDR || addr + len >= IFLASH_ADDR + IFLASH_SIZE) {
+#elif defined(ENVIRONMENT_dfu)
+		if (addr < IFLASH_ADDR || addr + len >= IFLASH_ADDR + BOARD_DFU_BOOT_SIZE) {
+#endif
 			g_dfu->state = DFU_STATE_dfuERROR;
 			g_dfu->status = DFU_STATUS_errADDRESS;
 			rc = DFU_RET_STALL;
@@ -281,12 +300,12 @@
 	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
-		 */
+		if (SCB->VTOR < IFLASH_ADDR + BOARD_DFU_BOOT_SIZE) {
+			TRACE_INFO_WP("unknown\n\r");
+		} else {
+			TRACE_INFO_WP("DFU is the main application\n\r");
+		}
+		break;
 	case 1:
 		TRACE_INFO_WP("DFU switch requested by main application\n\r");
 		break;
diff --git a/firmware/apps/dfu/usb_strings.txt b/firmware/apps/dfu/usb_strings.txt
index f1c79bc..4a58cb8 100644
--- a/firmware/apps/dfu/usb_strings.txt
+++ b/firmware/apps/dfu/usb_strings.txt
@@ -3,3 +3,4 @@
 DFU (Device Firmware Upgrade)
 RAM
 Flash (Application Partition)
+Flash (Bootloader Partition)
diff --git a/firmware/atmel_softpack_libraries/libchip_sam3s/source/USBD_HAL.c b/firmware/atmel_softpack_libraries/libchip_sam3s/source/USBD_HAL.c
index ac2595c..1ebab5b 100644
--- a/firmware/atmel_softpack_libraries/libchip_sam3s/source/USBD_HAL.c
+++ b/firmware/atmel_softpack_libraries/libchip_sam3s/source/USBD_HAL.c
@@ -1171,12 +1171,19 @@
 	/* if we are currently in the DFU bootloader, and we are beyond
 	 * the MANIFEST stage, we shall switch to the normal
 	 * application */
-	if (g_dfu->past_manifest)
+	if (g_dfu->past_manifest) {
+#if defined(ENVIRONMENT_flash)
 		USBDFU_SwitchToApp();
+#elif defined(ENVIRONMENT_dfu)
+		USBDFU_SwitchToDFU();
+#endif
+	}
+
 #else
 	/* if we are currently in the main application, and we are in
-	 * appDETACH state, switch into the DFU bootloader */
-	if (g_dfu->state == DFU_STATE_appDETACH)
+	 * appDETACH state or past downloading, switch into the DFU bootloader.
+	 */
+	if (g_dfu->state == DFU_STATE_appDETACH || g_dfu->state == DFU_STATE_dfuMANIFEST)
 		DFURT_SwitchToDFU();
 #endif /* APPLICATION_dfu */
 #endif /* BOARD_USB_DFU */
diff --git a/firmware/atmel_softpack_libraries/usb/device/dfu/dfu.h b/firmware/atmel_softpack_libraries/usb/device/dfu/dfu.h
index 7354696..5bd8684 100644
--- a/firmware/atmel_softpack_libraries/usb/device/dfu/dfu.h
+++ b/firmware/atmel_softpack_libraries/usb/device/dfu/dfu.h
@@ -124,6 +124,9 @@
 /* USBD tells us to switch from DFU mode to application mode */
 void USBDFU_SwitchToApp(void);
 
+/* USBD tells us to switch from to DFU mode */
+void USBDFU_SwitchToDFU(void);
+
 /* Return values to be used by USBDFU_handle_{dn,up}load */
 #define DFU_RET_NOTHING	0
 #define DFU_RET_ZLP	1
diff --git a/firmware/atmel_softpack_libraries/usb/device/dfu/dfu_desc.c b/firmware/atmel_softpack_libraries/usb/device/dfu/dfu_desc.c
index ebbe070..faebc13 100644
--- a/firmware/atmel_softpack_libraries/usb/device/dfu/dfu_desc.c
+++ b/firmware/atmel_softpack_libraries/usb/device/dfu/dfu_desc.c
@@ -19,9 +19,10 @@
 	STR_MANUF	= 1,
 	STR_PROD,
 	STR_CONFIG,
+	// strings for the first alternate interface (e.g. DFU)
 	_STR_FIRST_ALT,
 	// serial string
-	STR_SERIAL	= (_STR_FIRST_ALT+BOARD_DFU_NUM_IF),
+	STR_SERIAL	= (_STR_FIRST_ALT + BOARD_DFU_NUM_IF),
 	// version string (on additional interface)
 	VERSION_CONF_STR,
 	VERSION_STR,
@@ -29,6 +30,25 @@
 	STRING_DESC_CNT,
 };
 
+/* string used to replace one of both DFU flash partition atlsettings */
+static const unsigned char usb_string_notavailable[] = {
+	USBStringDescriptor_LENGTH(13),
+	USBGenericDescriptor_STRING,
+	USBStringDescriptor_UNICODE('n'),
+	USBStringDescriptor_UNICODE('o'),
+	USBStringDescriptor_UNICODE('t'),
+	USBStringDescriptor_UNICODE(' '),
+	USBStringDescriptor_UNICODE('a'),
+	USBStringDescriptor_UNICODE('v'),
+	USBStringDescriptor_UNICODE('a'),
+	USBStringDescriptor_UNICODE('i'),
+	USBStringDescriptor_UNICODE('l'),
+	USBStringDescriptor_UNICODE('a'),
+	USBStringDescriptor_UNICODE('b'),
+	USBStringDescriptor_UNICODE('l'),
+	USBStringDescriptor_UNICODE('e'),
+};
+
 /* USB string for the serial (using 128-bit device ID) */
 static unsigned char usb_string_serial[] = {
 	USBStringDescriptor_LENGTH(32),
@@ -121,7 +141,7 @@
 		.bNumEndpoints =	0,					\
 		.bInterfaceClass =	0xfe,					\
 		.bInterfaceSubClass =	1,					\
-		.iInterface =		(_STR_FIRST_ALT+ALT),			\
+		.iInterface =		(_STR_FIRST_ALT + ALT),			\
 		.bInterfaceProtocol =	2,					\
 	}
 
@@ -180,6 +200,11 @@
 	for (i = 0; i < ARRAY_SIZE(usb_strings) && i < ARRAY_SIZE(usb_strings_extended); i++) {
 		usb_strings_extended[i] = usb_strings[i];
 	}
+#if defined(ENVIRONMENT_dfu)
+	usb_strings_extended[_STR_FIRST_ALT + 1] = usb_string_notavailable;
+#elif defined(ENVIRONMENT_flash)
+	usb_strings_extended[_STR_FIRST_ALT + 2] = usb_string_notavailable;
+#endif
 	usb_strings_extended[STR_SERIAL] = usb_string_serial;
 	usb_strings_extended[VERSION_CONF_STR] = usb_string_version_conf;
 	usb_strings_extended[VERSION_STR] = usb_string_version;
diff --git a/firmware/atmel_softpack_libraries/usb/device/dfu/dfu_driver.c b/firmware/atmel_softpack_libraries/usb/device/dfu/dfu_driver.c
index 1cca7ab..cfb9f63 100644
--- a/firmware/atmel_softpack_libraries/usb/device/dfu/dfu_driver.c
+++ b/firmware/atmel_softpack_libraries/usb/device/dfu/dfu_driver.c
@@ -43,7 +43,7 @@
 
 /** structure containing the DFU state and magic value to know if DFU or application should be started */
 __dfudata struct dfudata _g_dfu = {
-  	.state = DFU_STATE_appIDLE,
+	.state = DFU_STATE_dfuIDLE,
 	.past_manifest = 0,
 	.total_bytes = 0,
 };
@@ -463,7 +463,20 @@
 	/* make sure the MAGIC is not set to enter DFU again */
 	g_dfu->magic = 0;
 
-	printf("switching to app\r\n");
+	/* disconnect from USB to ensure re-enumeration */
+	USBD_Disconnect();
+
+	/* disable any interrupts during transition */
+	__disable_irq();
+
+	/* Tell the hybrid to execute FTL JUMP! */
+	NVIC_SystemReset();
+}
+
+void USBDFU_SwitchToDFU(void)
+{
+	/* make sure the MAGIC is not set to enter DFU again */
+	g_dfu->magic = USB_DFU_MAGIC;
 
 	/* disconnect from USB to ensure re-enumeration */
 	USBD_Disconnect();
diff --git a/firmware/libboard/common/include/board_common.h b/firmware/libboard/common/include/board_common.h
index dd21e4b..7c4b908 100644
--- a/firmware/libboard/common/include/board_common.h
+++ b/firmware/libboard/common/include/board_common.h
@@ -112,10 +112,13 @@
 #define BOARD_USB_UDP
 
 #define BOARD_USB_DFU
+
+
 #define BOARD_DFU_BOOT_SIZE	(16 * 1024)
 #define BOARD_DFU_RAM_SIZE	(2 * 1024)
 #define BOARD_DFU_PAGE_SIZE	512
-#define BOARD_DFU_NUM_IF	2
+/** number of DFU interfaces (used to flash specific partitions) */
+#define BOARD_DFU_NUM_IF	3
 
 extern void board_exec_dbg_cmd(int ch);
 extern void board_main_top(void);
diff --git a/firmware/libboard/common/source/board_cstartup_gnu.c b/firmware/libboard/common/source/board_cstartup_gnu.c
index e82a2fb..d548a30 100644
--- a/firmware/libboard/common/source/board_cstartup_gnu.c
+++ b/firmware/libboard/common/source/board_cstartup_gnu.c
@@ -126,7 +126,7 @@
 	IrqHandlerNotUsed   /* 35 not used */
 };
 
-#if defined(BOARD_USB_DFU) && defined(APPLICATION_dfu)
+#if defined(BOARD_USB_DFU) && defined(APPLICATION_dfu) && defined(ENVIRONMENT_flash)
 #include "usb/device/dfu/dfu.h"
 static void BootIntoApp(void)
 {
@@ -159,8 +159,9 @@
 	LowLevelInit() ;
 
 
-#if defined(BOARD_USB_DFU) && defined(APPLICATION_dfu)
-	if (!USBDFU_OverrideEnterDFU()) {
+#if defined(BOARD_USB_DFU) && defined(APPLICATION_dfu) && defined(ENVIRONMENT_flash)
+	// boot application if there is not DFU override
+	if (!USBDFU_OverrideEnterDFU() && SCB->VTOR < IFLASH_ADDR + BOARD_DFU_BOOT_SIZE) {
 		UART_Exit();
 		__disable_irq();
 		BootIntoApp();

-- 
To view, visit https://gerrit.osmocom.org/c/simtrace2/+/16558
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: simtrace2
Gerrit-Branch: master
Gerrit-Change-Id: Ic273bb593a7669111b0219fe301d7897419167c8
Gerrit-Change-Number: 16558
Gerrit-PatchSet: 3
Gerrit-Owner: tsaitgaist <kredon at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-Reviewer: tsaitgaist <kredon at sysmocom.de>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20200116/a1c366a9/attachment.htm>


More information about the gerrit-log mailing list