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

Shifting Bootloader area using BLE DFU

Hello

I have a firmware with Softdevice S132 for NRF52 consists of main application (0x1F000 len:0x56000 ) and Bootloader  (0x75000 len:0x9000). What I'm trying to do is adding more space for the existing App using a page from the Bootloader, So I will do the following shift: main application (0x1F000 len:0x57000 ) and Bootloader  (0x76000 len:0x8000).

When I flash the project using the wires (erasing and flashing firmware + softdevice) It works without any problem, but when I upgrade the bootloader using BLE with the shifted one the device becomes dead. I think this is mentioned clearly in this post Relocating Bootloader by DFU .

According to the explanation, this is because the wired programming erase every thing including the UICR registers (NRFFW[0] which has the start address of bootloader) and flash new firmware while the BLE DFU approach will not do that. However, I made a bridge bootloader that erase the UICR area and update the NRF_UICR->NRFFW[0] to the new Bootloader address after it finishes uploading the new bootloader, but I still get the same thing. I also tried to set the vector table using manually in that step     sd_softdevice_vector_table_base_set(NRF_UICR->NRFFW[0]).

    sd_softdevice_disable();
    if (NRF_UICR->NRFFW[0] != 0x76000)  
    {
        //enable reading 
        NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
        while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
        
        // backup other data in UICR before erasing
        uint32_t * uicr_area_ptr = (uint32_t *)NRF_UICR_BASE ;
        uint32_t uicr_area_buffer[67];
        for (int reg_num=0;reg_num < 67 ; reg_num++)
        {
            uicr_area_buffer[reg_num] = *uicr_area_ptr;
            uicr_area_ptr++;
        }
        
        //erase the UICR
        NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Een << NVMC_CONFIG_WEN_Pos;
        while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
        NRF_NVMC->ERASEUICR = 1;
        while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
        
        //enable writing
        NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen<< NVMC_CONFIG_WEN_Pos;
        while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
        
        // restore other data in UICR after erasing
        uicr_area_ptr = (uint32_t *)NRF_UICR_BASE ;
        for (int reg_num=0;reg_num < 67 ; reg_num++)
        {
            *uicr_area_ptr = uicr_area_buffer[reg_num];
            uicr_area_ptr++;
            while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
        }
        //write the bootloader start address
        NRF_UICR->NRFFW[0] = 0x76000;
        
        //enable reading 
        NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
        while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
    }

    sd_softdevice_vector_table_base_set(NRF_UICR->NRFFW[0]);

    reset_device();
    }

So am I miss something, for example the MBR in Softdevice uses the old bootloader address, or what? BTW from where the MBR knows the Address the Bootloader ? and is there any detailed documentation/code for MBR ?

Best

Related