DFU: fix transitions between runtime and DFU mode

we now always go through a processor reset to avoid any state that might
be persistent/left-over during the switch.
This commit is contained in:
Harald Welte
2017-03-03 00:34:17 +01:00
parent db17e83960
commit d1e963479e
5 changed files with 27 additions and 13 deletions

View File

@@ -1163,10 +1163,20 @@ void USBD_IrqHandler(void)
TRACE_INFO_WP("EoBRes ");
#if defined(BOARD_USB_DFU) && defined(APPLICATION_dfu)
#if defined(BOARD_USB_DFU)
#if defined(APPLICATION_dfu)
/* 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)
USBDFU_SwitchToApp();
#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)
DFURT_SwitchToDFU();
#endif /* APPLICATION_dfu */
#endif /* BOARD_USB_DFU */
/* Flush and enable the Suspend interrupt */
UDP->UDP_ICR = UDP_ICR_WAKEUP | UDP_ICR_RXRSM | UDP_ICR_RXSUSP;

View File

@@ -86,12 +86,11 @@ extern const USBDDriverDescriptors dfu_descriptors;
/* magic value we use during boot to detect if we should start in DFU
* mode or runtime mode */
#define USB_DFU_MAGIC 0xDFDFDFDF
/* RAM address for this magic value above */
#define USB_DFU_MAGIC_ADDR IRAM_ADDR
/* The API between the core DFU handler and the board/soc specific code */
struct dfudata {
uint32_t magic;
uint8_t status;
uint32_t state;
int past_manifest;

View File

@@ -457,7 +457,7 @@ void USBDFU_Initialize(const USBDDriverDescriptors *pDescriptors)
void USBDFU_SwitchToApp(void)
{
/* make sure the MAGIC is not set to enter DFU again */
*(unsigned int *)USB_DFU_MAGIC_ADDR = 0;
g_dfu->magic = 0;
printf("switching to app\r\n");
@@ -468,7 +468,6 @@ void USBDFU_SwitchToApp(void)
__disable_irq();
/* Tell the hybrid to execute FTL JUMP! */
//BootIntoApp();
NVIC_SystemReset();
}

View File

@@ -178,15 +178,17 @@ out:
void DFURT_SwitchToDFU(void)
{
unsigned int *dfu_except_tbl = (unsigned int *)IFLASH_ADDR;
void (*toDFU)(void) = (void *)dfu_except_tbl[1];
*(unsigned int *)USB_DFU_MAGIC_ADDR = USB_DFU_MAGIC;
/* store the magic value that the DFU loader can detect and
* activate itself, rather than boot into the application */
g_dfu->magic = USB_DFU_MAGIC;
/* Disconnect the USB by remoting the pull-up */
USBD_Disconnect();
__disable_irq();
toDFU();
/* reset the processor, we will start execution with the
* ResetVector of the bootloader */
NVIC_SystemReset();
}
void USBDCallbacks_RequestReceived(const USBGenericRequest *request)

View File

@@ -125,6 +125,7 @@ IntFunc exception_table[] = {
};
#if defined(BOARD_USB_DFU) && defined(APPLICATION_dfu)
#include "usb/device/dfu/dfu.h"
static void BootIntoApp(void)
{
unsigned int *pSrc;
@@ -134,7 +135,7 @@ static void BootIntoApp(void)
SCB->VTOR = ((unsigned int)(pSrc)) | (0x0 << 7);
appReset = pSrc[1];
printf("Booting into App from %p, PC=%p\r\n", pSrc, appReset);
g_dfu->state = DFU_STATE_appIDLE;
appReset();
}
@@ -153,8 +154,11 @@ void ResetException( void )
#if defined(BOARD_USB_DFU) && defined(APPLICATION_dfu)
if (*(unsigned long *)IRAM_ADDR != 0xDFDFDFDF)
if (g_dfu->magic != USB_DFU_MAGIC) {
BootIntoApp();
/* Infinite loop */
while ( 1 ) ;
}
#endif
/* Initialize the relocate segment */