<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>MBR jumps to application not bootloader</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/56437/mbr-jumps-to-application-not-bootloader</link><description>We have problems with the restart which the application does after receiving the DFU attribute is written. 
 Startup should work like this as I understand it: the reset vector resides at addr 4, and points to 0x8e9 in MBR. MBR checks if there is any copy</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Mon, 13 Jan 2020 10:47:31 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/56437/mbr-jumps-to-application-not-bootloader" /><item><title>RE: MBR jumps to application not bootloader</title><link>https://devzone.nordicsemi.com/thread/228763?ContentTypeID=1</link><pubDate>Mon, 13 Jan 2020 10:47:31 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:6f4e1c20-20fa-4156-8196-7ceecff6d167</guid><dc:creator>bjorn-spockeli</dc:creator><description>&lt;p&gt;Hi Sven,&amp;nbsp;&lt;/p&gt;
&lt;p&gt;in SDK v15.3.0 and later we introduced a change in the way the MBR fetches the bootloader start address, i.e. the location of the bootloaders vector table. The MBR will now first try to fetch the bootloader and the MBR parameter page addresses from a specific location inside the MBR region(0x0000 to 0x1000), if these locations are blank( i.e. 0xFFFFFFFF) then it will check the UICR registers (i.e. 0x10001014 and 0x10001018) for the&amp;nbsp;&lt;span&gt;bootloader&amp;nbsp; and&amp;nbsp;&lt;/span&gt;&lt;span&gt;MBR parameter page addresses. The bootloader project will place the bootloader&amp;nbsp; and&amp;nbsp;MBR parameter page addresses at 0xFFC and 0xFF8 respectivly. However, this will lead to some IDEs ( like Keil and IAR) to erase the flash page that the MBR is programmed to in order to write the two addresses to&amp;nbsp;0xFFC and 0xFF8.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;If you flash the SoftDevice and MBR first and then the bootloader, then the MBR will be erased and the bootloader&amp;nbsp; and&amp;nbsp;MBR parameter page addresses at 0xFFC and 0xFF8. If the bootloader is flashed first and then the SoftDevice and MBR is flashed, then the addresses&amp;nbsp;at 0xFFC and 0xFF8 will be 0xFFFFFFFF and the&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;We solved this in SDK v16.0.0, were the bootloader will write the&amp;nbsp;the&amp;nbsp;bootloader&amp;nbsp; and&amp;nbsp;MBR parameter page addresses to 0xFFC and 0xFF8 at first boot, instead of placing the addresses there in the compiled binary see nrf_bootloader_mbr_addrs_populate() in main.c in the bootloader project.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;I also made a patch for Keil and SES in SDK v15.3.0, see&amp;nbsp;&lt;a href="https://devzone.nordicsemi.com/f/nordic-q-a/47823/sd_mbr_command_copy_sd-returns-nrf_error_internal-sdk-14-0"&gt;https://devzone.nordicsemi.com/f/nordic-q-a/47823/sd_mbr_command_copy_sd-returns-nrf_error_internal-sdk-14-0#&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;// In nrf_mbr.h
/** @brief Location (in the flash memory) of the bootloader address. */
#define MBR_BOOTLOADER_ADDR      (0xFF8)

/** @brief Location (in UICR) of the bootloader address. */
#define MBR_UICR_BOOTLOADER_ADDR  (0x10001014) // (&amp;amp;(NRF_UICR-&amp;gt;NRFFW[0]))

/** @brief Location (in the flash memory) of the address of the MBR parameter page. */
#define MBR_PARAM_PAGE_ADDR      (0xFFC)

/** @brief Location (in UICR) of the address of the MBR parameter page. */
#define MBR_UICR_PARAM_PAGE_ADDR  (0x10001018)// (&amp;amp;(NRF_UICR-&amp;gt;NRFFW[1]))

//In app_util.h

#if defined(MBR_PRESENT) || defined(SOFTDEVICE_PRESENT)
#include &amp;quot;nrf_mbr.h&amp;quot;

#define BOOTLOADER_ADDRESS      ((*(uint32_t *)MBR_BOOTLOADER_ADDR) == 0xFFFFFFFF ? MBR_UICR_BOOTLOADER_ADDR : MBR_BOOTLOADER_ADDR) /**&amp;lt; The currently configured start address of the bootloader. If 0xFFFFFFFF, no bootloader start address is configured. */
#define MBR_PARAMS_PAGE_ADDRESS ((*(uint32_t *)MBR_PARAM_PAGE_ADDR) == 0xFFFFFFFF ? MBR_UICR_PARAM_PAGE_ADDR : MBR_PARAM_PAGE_ADDR) /**&amp;lt; The currently configured address of the MBR params page. If 0xFFFFFFFF, no MBR params page address is configured. */

//#define BOOTLOADER_ADDRESS      ((*(uint32_t *)MBR_BOOTLOADER_ADDR) == 0xFFFFFFFF ? *MBR_UICR_BOOTLOADER_ADDR : *(uint32_t *)MBR_BOOTLOADER_ADDR) /**&amp;lt; The currently configured start address of the bootloader. If 0xFFFFFFFF, no bootloader start address is configured. */
//#define MBR_PARAMS_PAGE_ADDRESS ((*(uint32_t *)MBR_PARAM_PAGE_ADDR) == 0xFFFFFFFF ? *MBR_UICR_PARAM_PAGE_ADDR : *(uint32_t *)MBR_PARAM_PAGE_ADDR) /**&amp;lt; The currently configured address of the MBR params page. If 0xFFFFFFFF, no MBR params page address is configured. */

#else
#define BOOTLOADER_ADDRESS      (NRF_UICR-&amp;gt;NRFFW[0]) /**&amp;lt; Check UICR, just in case. */
#define MBR_PARAMS_PAGE_ADDRESS (NRF_UICR-&amp;gt;NRFFW[1]) /**&amp;lt; Check UICR, just in case. */
#endif

//In nrf_dfu_types.h 
#define NRF_UICR_MBR_PARAMS_PAGE_ADDRESS    MBR_UICR_PARAM_PAGE_ADDR //(MBR_PARAM_PAGE_ADDR)

// In nrf_bootoader_info.h
#define NRF_UICR_BOOTLOADER_START_ADDRESS   MBR_UICR_BOOTLOADER_ADDR //(MBR_BOOTLOADER_ADDR)


//in main.c 
ret_code_t nrf_bootloader_write_bl_addr_to_mbr(void){

    if( (*(volatile uint32_t *)MBR_BOOTLOADER_ADDR != BOOTLOADER_START_ADDR) || 
     (*(volatile uint32_t *)MBR_PARAM_PAGE_ADDR != NRF_MBR_PARAMS_PAGE_ADDRESS))
     {
          // Enable Write with the NVMC
          NRF_NVMC-&amp;gt;CONFIG = NVMC_CONFIG_WEN_Wen &amp;lt;&amp;lt; NVMC_CONFIG_WEN_Pos;
          while (NRF_NVMC-&amp;gt;READY == NVMC_READY_READY_Busy){}

          // Write Bootloader start address to MBR 
          *(volatile uint32_t *)MBR_BOOTLOADER_ADDR = BOOTLOADER_START_ADDR;
          // Write MBR parameter page address to MBR
          *(volatile uint32_t *)MBR_PARAM_PAGE_ADDR = NRF_MBR_PARAMS_PAGE_ADDRESS;
          // Revert NVMC to read-only
          NRF_NVMC-&amp;gt;CONFIG = NVMC_CONFIG_WEN_Ren &amp;lt;&amp;lt; NVMC_CONFIG_WEN_Pos;
          while (NRF_NVMC-&amp;gt;READY == NVMC_READY_READY_Busy){}
      }

    return NRF_SUCCESS;
}&lt;/pre&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Best regards&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Bjørn&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>