This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

NVMC does not work in bootloader

Hi,

I am trying to write my own bootloader. I gather new image via serial and store it in flash in my application at 0x30000 then invoke reset and in bootloader I want to copy image to application space. I used secure DFU as start point for this. I rewritten main and now it looks like this:

int main()
{
    nrf_nvmc_page_erase(0x1f000);
    nrf_nvmc_page_erase(0x20000);
    nrf_nvmc_page_erase(0x21000);
    nrf_nvmc_page_erase(0x22000);
    uint8_t * src = (uint8_t *)0x30000;
    uint32_t dst = 0x1F000;
    uint32_t buf;
    for (uint32_t i = 0; i < 0x4000; i += 4)
    {
        memcpy(&buf, src + i, 4);
        nrf_nvmc_write_word((dst + i), buf);  
    } 
    NRF_LOG_INFO("Jumping to: 0x%08x\r\n", dst);
    nrf_bootloader_app_start(dst);
}

I use S132 hence 0x1f000 as start address. Before enetring bootloader I check with nrfjprog that under 0x30000 I have my application prepared. When run this I end up with erased memory at 0x1f000 like nothing was copied.

What am I missing?

EDIT: I found that i bootloader was restarting before jump to application and was able to execute page erases but not the writes again.

  • I ran the following snippet in the bootloader_secure_ble example

    uint8_t  data_buffer[1024] __attribute__((at(0x30000))) __attribute__((used)) = {/* Filled with random values*/}
    int main(void)
    {
        nrf_nvmc_page_erase(0x1F000);
      
        uint8_t * src = (uint8_t *)0x30000;
        uint32_t dst = 0x1F000;
        uint32_t buf;
        
        for (uint32_t i = 0; i < 0x1000; i += 4)
        {
            memcpy(&buf, src + i, 4);
            nrf_nvmc_write_word((dst + i), buf);  
        } 
        
        while(1){};
    }
    

    And the data was correctly copied to 0x1F000 and upwards.

Related