From 7e25c1e98ee6942e60a3584616b3801d0898b1fb Mon Sep 17 00:00:00 2001 From: Devan Lai Date: Sat, 11 Sep 2021 13:12:20 -0700 Subject: [PATCH] Replace target_manifest_app with target_pre_detach Provide a target-specific hook to run just before detaching/rebooting. The manifested parameter can be used to distinguish between resetting to run existing vs new firmware. --- src/dfu.c | 24 ++++++++++++++++-------- src/dummy.c | 15 ++++++++++----- src/target.h | 2 +- 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/dfu.c b/src/dfu.c index 8923130..b8fa42f 100644 --- a/src/dfu.c +++ b/src/dfu.c @@ -101,6 +101,9 @@ static void dfu_on_detach_complete(usbd_device* usbd_dev, struct usb_setup_data* (void)usbd_dev; (void)req; + /* Run the target-specific pre-detach hook before resetting */ + target_pre_detach(manifestation_complete); + /* Reset and maybe launch the application */ scb_reset_system(); } @@ -149,13 +152,17 @@ static void dfu_on_manifest_request(usbd_device* usbd_dev, struct usb_setup_data if (dfu_manifest_request_callback) { /* The manifestation callback returns a boolean indicating if it succeeded */ - if (dfu_manifest_request_callback()) { - manifestation_complete = true; - dfu_set_state(STATE_DFU_MANIFEST_SYNC); - } else { - dfu_set_status(DFU_STATUS_ERR_FIRMWARE); - return; /* Avoid resetting on error */ - } + manifestation_complete = dfu_manifest_request_callback(); + } else { + /* Assume manifestation success */ + manifestation_complete = true; + } + + if (manifestation_complete) { + dfu_set_state(STATE_DFU_MANIFEST_SYNC); + } else { + dfu_set_status(DFU_STATUS_ERR_FIRMWARE); + return; /* Avoid resetting on error */ } #if DFU_WILL_DETACH @@ -202,7 +209,6 @@ dfu_control_class_request(usbd_device *usbd_dev, * the device is manifestation tolerant (DFU_WILL_DETACH == 0) */ if (manifestation_complete) { /* Only enter idle state after manifestation has completed successfully */ - manifestation_complete = false; dfu_set_state(STATE_DFU_IDLE); } else { /* Perform manifestation after download as described in the @@ -239,6 +245,8 @@ dfu_control_class_request(usbd_device *usbd_dev, dfu_download_size = req->wLength; memcpy(dfu_download_buffer, *buf, dfu_download_size); dfu_set_state(STATE_DFU_DNLOAD_SYNC); + /* Reset manifestation progress on new download */ + manifestation_complete = false; } else { dfu_set_status(DFU_STATUS_ERR_STALLEDPKT); usbd_ep_stall_set(usbd_dev, 0x00, 1); diff --git a/src/dummy.c b/src/dummy.c index 6589e57..b10df11 100644 --- a/src/dummy.c +++ b/src/dummy.c @@ -24,8 +24,8 @@ void target_get_serial_number(char* dest, size_t max_chars) __attribute__((weak)); void target_log(const char* str) __attribute__((weak)); -void target_manifest_app(void) __attribute__((weak)); void target_pre_main(void) __attribute__((weak)); +void target_pre_detach(bool manifested) __attribute__((weak)); size_t target_get_timeout(void) __attribute__((weak)); void target_get_serial_number(char* dest, size_t max_chars) { @@ -39,15 +39,20 @@ void target_log(const char* str) { (void)str; } -void target_manifest_app(void) { - scb_reset_system(); -} - void target_pre_main(void) { } +void target_pre_detach(bool manifested) { + /* This runs just before executing a reboot in response to a USB bus reset + or a detach request. + If new firmware was successfully downloaded, manifested is set to true. + This can be used to set flags or blink LEDs before rebooting. + */ + (void)manifested; +} + size_t target_get_timeout(void) { return 100; diff --git a/src/target.h b/src/target.h index 7e671cf..2f748d0 100644 --- a/src/target.h +++ b/src/target.h @@ -31,12 +31,12 @@ extern void target_get_serial_number(char* dest, size_t max_chars); extern size_t target_get_max_firmware_size(void); extern void target_log(const char* str); extern void target_relocate_vector_table(void); -extern void target_manifest_app(void); extern void target_flash_unlock(void); extern void target_flash_lock(void); extern bool target_flash_program_array(uint16_t* dest, const uint16_t* data, size_t half_word_count); extern void target_pre_main(void); +extern void target_pre_detach(bool manifested); extern size_t target_get_timeout(void); #endif