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

Protect program pages in flash

Hi

I am using NRF52 with 512KB flash, and with SDK15.2

I am not using DFU

I tried to protect the program flash pages using "sd_flash_protect".

I tried to protect pages:

      1. START page/address- from FLASH_START=0x19000 (which I took from the linker_section_placement_macros in the solution). This is page 0x19

       2.END page/address - fstorage.end_addr-3 pages, which I am using for event log. This is page 0x7A.

when I call to sd_flash_protect(l_iConfigReg[0], l_iConfigReg[1], l_iConfigReg[2], l_iConfigReg[3])

where the parameters to the function are: R0-FF000000, R1-FFFFFFFF, R2-FFFFFFFF, R3-7FFFFFFF

I receive status code NRF_ERROR_NOT_SUPPORTED (6)

If I set l_iConfigReg[2] and l_iConfigReg[3] to 0, the function return with status code NRF_SUCCESS.

If I set l_iConfigReg[2] to 0x1 l_iConfigReg[3] to 0, the function return with status code NRF_ERROR_NOT_SUPPORTED .

So it seems that I can protect only half of the flash

Is there any reason why, and how can I protect the program's flash pages?

Thanks

  • Hello,

    so you are trying to protect: 

    R3                          | R2                        | R1                        | R0
    7FFF FFFF                   | FFFF FFFF                 | FFFF FFFF                 | FF00 0000
    
    0x007E FFFF - 0x0060 0000   | 0x005F FFFF - 0x0040 0000 | 0x003F FFFF - 0x0020 0000 | 0x001F FFFF - 0x0001 8000
    
    
    So basically, 0x0001 8000 -> 0x007E FFFF

    Does your application use the flash for anything else? Do you use the BLE? The peer manager? FDS? Fstorage? Or any other modules that would require to write to flash in any way?

     

    If I set l_iConfigReg[2] and l_iConfigReg[3] to 0, the function return with status code NRF_SUCCESS.

    If I set l_iConfigReg[2] to 0x1 l_iConfigReg[3] to 0, the function return with status code NRF_ERROR_NOT_SUPPORTED .

    So there is something in R2 that it doesn't like. Have you tried any other values than 0xFFFFFFFF and 0x00000001? Perhaps it is one specific area in R1 that it doesn't allow you to protect, possibly because the softdevice has set this area to e.g. fstorage or FDS?

    Best regards,

    Edvin

  • Hi

    We are using: NFC, BLE, FDS is enabled
    How can I tell which page I can protect and which I can't?

    Trial and error is not a good practice

    Arik

  • Hello,

    But the FDS pages are the pages that are not flash protected, right? 

    "END page/address - fstorage.end_addr-3 pages, which I am using for event log. This is page 0x7A."

    Perhaps you can try something like this:

        uint32_t block_cfg[4] = {0x00000000};
        NRF_LOG_INFO("START;");
        
        ret_code_t err_code = NRF_SUCCESS;
        
        for (uint8_t i=0; i<4; i++)
        {
            for (uint8_t j=0; j<32; j++)
            {
                uint32_t test_value = 0x000000000;
                test_value = 0x01 << j;
                block_cfg[i] = test_value;
                
                err_code = sd_flash_protect(block_cfg[0], block_cfg[1], block_cfg[2], block_cfg[3]);
                
                if (err_code != NRF_SUCCESS)
                {
                    NRF_LOG_INFO("failed i=%d, j=%d", i, j);
                }
            }
            block_cfg[i] = 0x00000000;
        }
        NRF_LOG_INFO("DONE");

    NB: If many of the checks fail, you may lose some logs, but you can use it to get an idea of what areas you are not able to protect. 

    Another approach is to force this through, like it is done in the bootloader projects in the SDK. The flash is protected before the softdevice is enabled using the function nrf_bootloader_flash_protect(). Check it out in the example:

    SDK\examples\dfu\secure_bootloader\pca10040_s132_ble.

    Best regards,

    Edvin

  • Actually, just save the test value in a separate array, so there will not be as much logging:

        uint32_t block_cfg[4] = {0x00000000};
        uint32_t block_protect_failed[4] = {0x00000000};
        NRF_LOG_INFO("START;");
        
        ret_code_t err_code = NRF_SUCCESS;
        
        for (uint8_t i=0; i<4; i++)
        {
            for (uint8_t j=0; j<32; j++)
            {
                uint32_t test_value = 0x000000000;
                test_value = 0x01 << j;
                block_cfg[i] = test_value;
                
                err_code = sd_flash_protect(block_cfg[0], block_cfg[1], block_cfg[2], block_cfg[3]);
                
                if (err_code != NRF_SUCCESS)
                {
                    //NRF_LOG_INFO("failed i=%d, j=%d", i, j);
                    block_protect_failed[i] |= test_value;
                }
            }
            block_cfg[i] = 0x00000000;
        }
        NRF_LOG_INFO("DONE 0x%08x:0x%08x:0x%08x:0x%08x", block_protect_failed[0], block_protect_failed[1], block_protect_failed[2], block_protect_failed[3]);

Related