aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKévin Redon <kredon@sysmocom.de>2019-01-09 14:48:20 +0100
committerKévin Redon <kredon@sysmocom.de>2019-01-16 18:41:23 +0100
commitdfa652604c82320e719113c66c9fd4979d50d217 (patch)
treec98bdbc8b194db3ba1d130fae1e40ca3ebbf6545
parent37409534d7c8165853b4e673aa95d8bda8377806 (diff)
use reserved bootloader get application start
the reserved bootloader size is set in the NVM user configuration and allows to know the application start address (e.g. after the bootloader) Change-Id: I9dda27d6401caabb4a6470aa3fe9691f63097136
-rw-r--r--usb/class/dfu/device/dfudf.c6
-rw-r--r--usb/class/dfu/device/dfudf.h4
-rw-r--r--usb_start.c22
3 files changed, 18 insertions, 14 deletions
diff --git a/usb/class/dfu/device/dfudf.c b/usb/class/dfu/device/dfudf.c
index 41e235b..8232979 100644
--- a/usb/class/dfu/device/dfudf.c
+++ b/usb/class/dfu/device/dfudf.c
@@ -44,7 +44,7 @@ enum usb_dfu_status dfu_status = USB_DFU_STATUS_OK;
uint8_t dfu_download_data[512];
uint16_t dfu_download_length = 0;
-size_t dfu_download_progress = 0;
+size_t dfu_download_offset = 0;
bool dfu_manifestation_complete = false;
/**
@@ -215,7 +215,7 @@ static int32_t dfudf_out_req(uint8_t ep, struct usb_req *req, enum usb_ctrl_stag
to_return = usbdc_xfer(ep, NULL, 0, false); // send ACK
break;
case USB_DFU_ABORT: // abort current operation
- dfu_download_progress = 0; // reset download progress
+ dfu_download_offset = 0; // reset download progress
dfu_state = USB_DFU_STATE_DFU_IDLE; // put back in idle state (nothing else to do)
to_return = usbdc_xfer(ep, NULL, 0, false); // send ACK
break;
@@ -246,7 +246,7 @@ static int32_t dfudf_out_req(uint8_t ep, struct usb_req *req, enum usb_ctrl_stag
if (USB_SETUP_STAGE == stage) { // there will be data to be flash
to_return = usbdc_xfer(ep, dfu_download_data, req->wLength, false); // send ack to the setup request to get the data
} else { // now there is data to be flashed
- dfu_download_progress = req->wValue * sizeof(dfu_download_data); // remember which block to flash
+ dfu_download_offset = req->wValue * sizeof(dfu_download_data); // remember which block to flash
dfu_download_length = req->wLength; // remember the data size to be flash
dfu_state = USB_DFU_STATE_DFU_DNLOAD_SYNC; // go to sync state
to_return = usbdc_xfer(ep, NULL, 0, false); // ACK the data
diff --git a/usb/class/dfu/device/dfudf.h b/usb/class/dfu/device/dfudf.h
index a19b569..cee5845 100644
--- a/usb/class/dfu/device/dfudf.h
+++ b/usb/class/dfu/device/dfudf.h
@@ -49,8 +49,8 @@ extern enum usb_dfu_status dfu_status;
extern uint8_t dfu_download_data[512];
/** Length of downloaded data in bytes */
extern uint16_t dfu_download_length;
-/** Progress of the already downloaded data in bytes */
-extern size_t dfu_download_progress;
+/** Offset of where the downloaded data should be flashed in bytes */
+extern size_t dfu_download_offset;
/** If manifestation (firmware flash and check) is complete */
extern bool dfu_manifestation_complete;
diff --git a/usb_start.c b/usb_start.c
index 0ce8aba..7503094 100644
--- a/usb_start.c
+++ b/usb_start.c
@@ -45,14 +45,6 @@ static const usb_dfu_func_desc_t* usb_dfu_func_desc = (usb_dfu_func_desc_t*)&usb
/** Ctrl endpoint buffer */
static uint8_t ctrl_buffer[64];
-/** Application address in the flash
- (
- * It comes after the bootloader.
- * The NVMCTRL allows to reserve space at the beginning of the flash for the bootloader, but only in multiples of 8192 bytes.
- * The binary just with the USB stack already uses 8 kB, we reserve 16 kB for the bootloader (giving use a bit of margin for future fixes).
- */
-#define APPLICATION_ADDR (8192*2)
-
/**
* \brief USB DFU Init
*/
@@ -89,12 +81,24 @@ void usb_dfu(void)
{
while (!dfudf_is_enabled()); // wait for DFU to be installed
gpio_set_pin_level(LED_SYSTEM, false); // switch LED on to indicate USB DFU stack is ready
+
+ uint32_t application_start = hri_nvmctrl_read_STATUS_BOOTPROT_bf(FLASH_0.dev.hw); // read BOOTPROT setting to get the bootloader size
+ ASSERT(application_start <= 15);
+ application_start = (15 - application_start) * 8192; // calculate bootloader size to know where we should write the application firmware
+ while (0 == application_start) { // no space has been reserved for the bootloader
+ // blink the LED to tell the user we don't know where the application starts
+ gpio_set_pin_level(LED_SYSTEM, false);
+ delay_ms(500);
+ gpio_set_pin_level(LED_SYSTEM, true);
+ delay_ms(500);
+ }
+
while (true) { // main DFU infinite loop
// run the second part of the USB DFU state machine handling non-USB aspects
if (USB_DFU_STATE_DFU_DNLOAD_SYNC == dfu_state || USB_DFU_STATE_DFU_DNBUSY == dfu_state) { // there is some data to be flashed
gpio_set_pin_level(LED_SYSTEM, true); // switch LED off to indicate we are flashing
if (dfu_download_length > 0) { // there is some data to be flashed
- int32_t rc = flash_write(&FLASH_0, APPLICATION_ADDR + dfu_download_progress, dfu_download_data, dfu_download_length); // write downloaded data chunk to flash
+ int32_t rc = flash_write(&FLASH_0, application_start + dfu_download_offset, dfu_download_data, dfu_download_length); // write downloaded data chunk to flash
if (ERR_NONE == rc) {
dfu_state = USB_DFU_STATE_DFU_DNLOAD_IDLE; // indicate flashing this block has been completed
} else { // there has been a programming error