<p>Harald Welte <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/12592">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Jenkins Builder: Verified
  Harald Welte: Looks good to me, approved

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

<div style="display:none"> Gerrit-Project: osmo-asf4-dfu </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: I323f2b3a1828d3e40a02c7fc755d07009fb43a85 </div>
<div style="display:none"> Gerrit-Change-Number: 12592 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Kévin Redon <kredon@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder (1000002) </div>