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
This commit is contained in:
parent
37409534d7
commit
dfa652604c
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
22
usb_start.c
22
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
|
||||
|
|
Loading…
Reference in New Issue