Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nrf52832 custom simple bootloader implementation.

Hi everybody.
I know that it is complete standart question, which has many asks and solutions here.
I'm quite new to bootloader management stuff.
So asking about some targeting recommendations and solutions, some custom examples to start with.

My goal is to implement kind of bootloader (no need of heavy original one with DFU, encryption and a lot of extra bloating stuff)
I only need such functionality:
 - Have some kind of extra program (actually bootloader), starts from different memory address from original app.
 - Ability to boot to this program on some event from main app. and only thing to do is copy new FW from some flash area to main program area.
Inside of a boot program can implement simple progress of copying like LED blink stuff or so
 - After that restart app and boot to main app.

Encryption of FW doesn't needed. Let has it also on a point that FW on flash has already verified and only ready for copying to main program area.

Does it possible to make it based on some simple example, not using Softdevice and a lot of extra original bootloader implementation?
Even more, does this procedure described above actually possible at all?

King regards.
Ivan.
 

Parents
  • Hi,

    there's no need for bootloader in your case. Assuming you're not concerned about troubles while updating (otherwise there should be full-featured bootloader with DFU), just write a short piece of code that can be copied to RAM and started by main firmware after disabling softdevice and interrupts. This code will copy firmware (using NVMC registers) and reboot device.

  • So, you mean that I can handle this from one app.?
    Just on some trigger, start some other program in RAM with ability to FLASH to FLASH memory copying to main app start address, and after completing this procedure just reset and start main app again based on new FW now.

    Maybe you can give some advices how to place some extra app. copying code to RAM and tell program to start execution from that address?

  • I 've tried all this together.
    Now I can wriite to some other king of 'program' 0x0 flash address without any problem.
    But when I write to 0x0 then I got device bricked.

  • Here is my final code.

    //execute FW update 
    void execute_fw_update(uint8_t* fwData, uint32_t fwSize) { 
    update_fw_proc updater = (update_fw_proc) (RAM_START + 1);
    uint32_t src = (uint32_t)fw_copy_flash;
    
    memcpy((void*)RAM_START, (void *)(src & ~1), FW_FLASH_FUNC_SIZE); */
    __dsb(0xf);
    __isb(0xf);
    (updater)(FW_FLASH_START, fwData, fwSize);
    
    }
    
    //ram function code to update flash
    
    static void fw_copy_flash(uint32_t dest, uint8_t *src, uint32_t size)
    {
    int i;
    int pagesNum = FW_DATA_MAX_SIZE / NRF_FICR->CODEPAGESIZE;
    
    __disable_irq();
    
    //erase number of pages needed
    for (i = 0; i < pagesNum; i++) {
    // Enable erase.
    NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Een;
    __ISB();
    __DSB();
    
    // Erase the page
    NRF_NVMC->ERASEPAGE = i * NRF_FICR->CODEPAGESIZE; 
    
    while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {;}
    
    NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
    __ISB();
    __DSB();
    }
    
    for (i = 0; i < size; i++)
    {
    uint32_t byte_shift = (dest + i) & (uint32_t)0x03;
    uint32_t address32 = (dest + i) & ~byte_shift; // Address to the word this byte is in.
    uint32_t value32 = (*(uint32_t*)address32 & ~((uint32_t)0xFF << (byte_shift << (uint32_t)3)));
    value32 = value32 + ((uint32_t)src[i] << (byte_shift << 3));
    
    // Enable write.
    NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos);
    __ISB();
    __DSB();
    
    *(uint32_t*)address32 = value32;
    while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {;}
    
    NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos);
    __ISB();
    __DSB();
    }
    
    //reset board
    //NVIC_SystemReset();
    __DSB(); /* Ensure all outstanding memory accesses included
    buffered write are completed before reset */
    SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
    (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
    SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */
    __DSB(); /* Ensure completion of memory access */
    
    for(;;) /* wait until reset */
    {
    __NOP();
    }
    }

  • all seems without some flash functions.

    But still get device bricked after usiing it for 0x0 program flash rewrite.
    Flash write working proper way, cause I 've tested it on other region.

  • Hi,

    I didn't understood meaning of this: 

    uint32_t byte_shift = (dest + i) & (uint32_t)0x03;
    uint32_t address32 = (dest + i) & ~byte_shift; // Address to the word this byte is in.
    uint32_t value32 = (*(uint32_t*)address32 & ~((uint32_t)0xFF << (byte_shift << (uint32_t)3)));
    value32 = value32 + ((uint32_t)src[i] << (byte_shift << 3));

    The right way is to program flash word by word:

    *(uint32_t*)dest = value;
    dest += 4;


    You can look in debugger what's actually written at address 0.

  • I 've taken this from standart implementation.
    Flash copy body is ok, cause as I said I 've tested write to 0x5000.
    I get proper write and sw reset, and after reset I get same image to 0x0 at 0x5000.

Reply Children
No Data
Related