This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Protect bootloader from overwrite/erase

I am using Nordics sample bootloader and I really want to make sure that given a freak accident in sending it the firmware or in the firmware code itself that the bootloader is never erased or overwritten. In its current state, is the bootloader protected against that or are there measures I can take to accomplish it?

I have also noticed the call sd_flash_protect, but I am not sure if that is the proper approach and if so how to use it.

Thanks,

  • You can use the registers PROTENSETx to protect you bootloader. If you have enabled the softdevice these registers are accessed through the sd_flash_protect call. PROTENSETx enables you to protect 64 different blocks of the memory. For the nRF51x22 these blocks are 4 k big.

    Update: main.c I edited the standard .../nRF6310/S110/bla_app_hrs example. The main file is above here. I added code to set the PROTENSET and protect the upper half of flash and then try to write to that area. It fails and gives me an error code.

    UPDATE 2: Always make sure that you are using nRF51 of second revision if you are using sd_flash_protect() or PROTENSET. On nRF51 revision 1 this functionality is not available.

  • I added in the call sd_flash_protect(0,0xFFFFFFFF); to the bootloader after the softdevice is enabled just to verify that it will hardfault(per spec) instead of completing its process. I know the bootloader is not only erasing that area, but my firmware is getting written to that area as it is almost 100K in size. Using this to test, I not only have been able to successfully write firmware every time, but I have been able to erase the bootloader.

    I have tested this with and without a debugger connected.

  • I added an attachment to my initial reply here. Please have a look at that main.c file.

    If I understand you correctly you also set sd_flash_protect(0,0xFFFFFFFF) but are still allowed to write to that upper half of the memory? Any chance you could share the flash write routine that you use?

  • The flash write and erase routines are pstorage as it is the setup in the DFU/bootloader examples.

    The store is done in dfu_dual_bank:

    uint32_t dfu_data_pkt_handle(dfu_update_packet_t * p_packet) {
         switch(m_dfu_state) {
              case DFU_STATE_RX_DATA_PKT:
                   err_code = pstorage_raw_store(&m_storage_handle_app, (uint8_t*) p_data, data_length, m_app_data_received);
         }
    }
    

    Erase is done in dfu_dual_bank:

    uint32_t dfu_image_size_set(uint32_t image_size) {
         switch (m_dfu_state)   {
              case DFU_STATE_IDLE: 
                    err_code = pstorage_raw_clear(&m_storage_handle_app, image_size);
          }
    }
    

    And the setup is in main {

    // Initialize.
        timers_init();
        gpiote_init();
        ble_stack_init();
        scheduler_init();
        sd_flash_protect((uint32_t)0,(uint32_t)0xFFFFFFFF);
    }
    

    where

    static void ble_stack_init(void)
    {
        uint32_t err_code;
        
        SOFTDEVICE_HANDLER_INIT(NRF_CLOCK_LFCLKSRC_XTAL_250_PPM, true);
    
        err_code = softdevice_sys_evt_handler_set(sys_evt_dispatch);
        APP_ERROR_CHECK(err_code);
    }
    

    Note: It is very hard to write and edit this comment in the 3 line editor window this forum gives me.

  • I finally was able to see the behavior you are describing and I had to change the chip and use a nRF51822 revision 1. It's marked with N51822, QFAACA, 1230AA. The second line is the important one here, on revision 1 of the nrf51822 it will say QFAACx, where x can be A or 0. I do suspect that the chip you are working on are marked with CA or C0 and hence a revision 1 chip.

    I've been testing this on revision 2 of the chip QFAAGx and this is the first version where the flash protect was implemented and hence I have not be able to recreate the behavior you see as expected.

Related