Change in osmo-asf4-dfu[master]: start application if valid at boot

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/.

Kévin Redon gerrit-no-reply at lists.osmocom.org
Wed Jan 16 17:42:25 UTC 2019


Kévin Redon has uploaded this change for review. ( https://gerrit.osmocom.org/12592


Change subject: start application if valid at boot
......................................................................

start application if valid at boot

if the application is not valid, check and start the bootloader

Change-Id: I323f2b3a1828d3e40a02c7fc755d07009fb43a85
---
M usb_dfu_main.c
M usb_start.c
2 files changed, 85 insertions(+), 42 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-asf4-dfu refs/changes/92/12592/1

diff --git a/usb_dfu_main.c b/usb_dfu_main.c
index 2535475..91748a5 100644
--- a/usb_dfu_main.c
+++ b/usb_dfu_main.c
@@ -1,45 +1,95 @@
 /**
  * \file
+ * \brief USB DFU bootloader implementation (DFU mode)
  *
- * \brief Application implement
+ * Copyright (c) 2018-2019 sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon at sysmocom.de>
  *
- * Copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries.
- * Copyright (c) 2018 sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon at sysmocom.de>
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
  *
- * \asf_license_start
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
  *
- * \page License
- *
- * Subject to your compliance with these terms, you may use Microchip
- * software and any derivatives exclusively with Microchip products.
- * It is your responsibility to comply with third party license terms applicable
- * to your use of third party software (including open source software) that
- * may accompany Microchip software.
- *
- * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS".  NO WARRANTIES,
- * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
- * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
- * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
- * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
- * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
- * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
- * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE.  TO THE FULLEST EXTENT
- * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
- * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
- * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
- *
- * \asf_license_stop
- *
- */
-/*
- * Support and FAQ: visit <a href="https://www.microchip.com/support/">Microchip Support</a>
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
 #include "atmel_start.h"
 #include "atmel_start_pins.h"
 
+/** Start address of the application in flash
+ *  \remark must be initialized by check_bootloader
+ */
+static uint32_t* application_start_address;
+
+/** Check if the bootloader is valid
+ *  \return true if the bootloader is valid and can be run
+ *  \remark initializes application_start_address
+ */
+static bool check_bootloader(void)
+{
+	if (hri_nvmctrl_read_STATUS_BOOTPROT_bf(FLASH_0.dev.hw) > 15) { // ensure BOOTPROT setting is valid
+		return false;
+	}
+	application_start_address = (uint32_t*)((15 - hri_nvmctrl_read_STATUS_BOOTPROT_bf(FLASH_0.dev.hw)) * 8192); // calculate bootloader size to know start address of the application (e.g. after the bootloader)
+	if (0 == application_start_address) { // no space has been reserved for the bootloader
+		return false;
+	}
+	return true;
+}
+
+/** Check if starting the bootloader is forced
+ *  \return true of the DFU bootloader should be started
+ */
+static bool check_force_dfu(void)
+{
+}
+
+/** Check if the application is valid
+ *  \return true if the application is valid and can be started
+ *  \warning application_start_address must be initialized
+ */
+static bool check_application(void)
+{
+	/* the application starts with the vector table
+	 * the first entry in the vector table is the initial stack pointer (SP) address
+	 * the stack will be placed in RAM which begins at 0x2000 0000, and there is up to 256 KB of RAM (0x40000).
+	 * if the SP is not in this range (e.g. flash has been erased) there is no valid application
+	 * the second entry in the vector table is the reset address, corresponding to the application start
+	 */
+	return (0x20000000 == ((*application_start_address) & 0xFFF80000));
+}
+
+/** Start the application
+ *  \warning application_start_address must be initialized
+ */
+static void start_application(void)
+{
+	__set_MSP(*application_start_address); // re-base the Stack Pointer
+	SCB->VTOR = ((uint32_t) application_start_address & SCB_VTOR_TBLOFF_Msk); // re-base the vector table base address
+	asm("bx %0"::"r"(*(application_start_address + 1))); // jump to application Reset Handler in the application */
+}
+
 int main(void)
 {
-	atmel_start_init();
-	usb_dfu();
+	atmel_start_init(); // initialise system
+	if (!check_bootloader()) { // check bootloader
+		// blink the LED to tell the user we don't know where the application starts
+		while (true) {
+			gpio_set_pin_level(LED_SYSTEM, false);
+			delay_ms(500);
+			gpio_set_pin_level(LED_SYSTEM, true);
+			delay_ms(500);
+		}
+	}
+	if (check_application()) { // application is valid
+		start_application(); // start application
+	} else {
+		usb_dfu(); // start DFU bootloader
+	}
 }
diff --git a/usb_start.c b/usb_start.c
index 7503094..ad91840 100644
--- a/usb_start.c
+++ b/usb_start.c
@@ -82,23 +82,16 @@
 	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);
-	}
+	ASSERT(hri_nvmctrl_read_STATUS_BOOTPROT_bf(FLASH_0.dev.hw) <= 15);
+	uint32_t application_start_address = (15 - hri_nvmctrl_read_STATUS_BOOTPROT_bf(FLASH_0.dev.hw)) * 8192; // calculate bootloader size to know where we should write the application firmware
+	ASSERT(application_start_address > 0);
 
 	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_start + dfu_download_offset, dfu_download_data, dfu_download_length); // write downloaded data chunk to flash
+				int32_t rc = flash_write(&FLASH_0, application_start_address + 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

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

Gerrit-Project: osmo-asf4-dfu
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I323f2b3a1828d3e40a02c7fc755d07009fb43a85
Gerrit-Change-Number: 12592
Gerrit-PatchSet: 1
Gerrit-Owner: Kévin Redon <kredon at sysmocom.de>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20190116/d8a07929/attachment.htm>


More information about the gerrit-log mailing list