Flash memory error : FDS_ERR_NO_PAGES

Hi DevZone !

I am using the nRF52840 for development and after some tests one of the chips could not access its memory flash in the function fds_init() in the library fds.c. I debugged it with Ozone and I saw the error FDS_ERR_NO_PAGES popping up. Can I repair the flash in some way ? Any suggestion on why it happened ?

Thank you !

Joel V.

  • Hi,

    fds_init() will return FDS_ERR_NO_PAGES If there is no space available in flash memory to install the file system. Which would imply that something in your application is consuming the memory. Do you see this on the other samples with the same application? Could you also elaborate a bit more on your application?

    regards

    Jared 

  • Hi,

    This is the only sample who did this but it has one main difference with the others is that this sample could have reboot more often than the others. The application is a mesh network capturing datas. I use the flash to store configurations for the nodes like its address, channel, etc. I am using only one page of the flash (a configuration page). I dont understand how it could have consume all the memory in flash. 

    Thanks

    Joel V.

  • Hi,

    Are you using dynamic memory allocation in your application? Could you share the parts in your application where you write to flash?

    regards
    Jared 

  • Hi, 

    I am not. My application is only reading the flash at boot if the flash is already written:

    fds_flash_record_t fds_config = {0};
    
    //Open the record and read its contents. 
    rc = fds_record_open(&desc, &fds_config);
    APP_ERROR_CHECK(rc);
    
    //Copy the configuration from flash into config.
    memcpy(&config, fds_config.p_data, sizeof(config_t));
    
    //Close the record when done reading.
    rc = fds_record_close(&desc);
    APP_ERROR_CHECK(rc); 

    And it is writing flash if it is a brand new processor:

    rc = fds_record_write(&desc, &config_record);
    if(rc != NRF_SUCCESS){
        rc = fds_gc();
        APP_ERROR_CHECK(rc);
        config_init(mesh_config);
    }
    APP_ERROR_CHECK(rc);

    I also have a function that overwrites the flash if I want to, but this function is usually commented and I am 90% certain that it was but here is the code portion:

    fds_record_desc_t desc = {0};
    fds_find_token_t  tok  = {0};
    rc = fds_record_find(CONFIG_FILE, CONFIG_REC_KEY, &desc, &tok);
    if(rc == NRF_SUCCESS){
        //rc = fds_record_update(&desc, &config_record);
        rc = fds_record_delete(&desc);
        APP_ERROR_CHECK(rc);
        rc = fds_record_write(&desc, &config_record);
        APP_ERROR_CHECK(rc);
        if(rc != NRF_SUCCESS)
        {
            rc = fds_gc();
            APP_ERROR_CHECK(rc);
        }
        APP_ERROR_CHECK(rc);
    }

    I tried using fds_record_update in this portion but I dont recall it was working I dont know why.

    Is it possible that the flash may have been corrupted in a hardware way ? For exemple by inversing poles or I dont know ?

    Thanks,

    Joel V.

  • I don't think I am. I am only using fds library for reading configurations at boot:

    rc = fds_init();
    rc = fds_gc();
    APP_ERROR_CHECK(rc);
    
    
    fds_record_desc_t desc = {0};
    fds_find_token_t  tok  = {0};
    
    rc = fds_record_find(CONFIG_FILE, CONFIG_REC_KEY, &desc, &tok);
    if (rc == NRF_SUCCESS){
        //rc = fds_record_delete(&desc);
        //APP_ERROR_CHECK(rc);
        fds_flash_record_t fds_config = {0};
    
        //Open the record and read its contents. 
        rc = fds_record_open(&desc, &fds_config);
        APP_ERROR_CHECK(rc);
    
        //Copy the configuration from flash into config.
        memcpy(&config, fds_config.p_data, sizeof(config_t));
    
        //Close the record when done reading.
        rc = fds_record_close(&desc);
        APP_ERROR_CHECK(rc); 

    I am writing only once when the processor is brand new:

     fds_record_t config_record ={
                .file_id           = CONFIG_FILE,
                .key               = CONFIG_REC_KEY,
                .data.p_data       = &config,
                /* The length of a record is always expressed in 4-byte units (words). */
                .data.length_words = (sizeof(config_t)+3)/sizeof(uint32_t),
            };
            
    rc = fds_record_write(&desc, &config_record);
    if(rc != NRF_SUCCESS){
        rc = fds_gc();
        APP_ERROR_CHECK(rc);
        config_init(mesh_config);
    }
    APP_ERROR_CHECK(rc);

    I however have a funtion to overwrite the flash when I want to make a modification right away but I usually comment it after dumping the program and the dump again. I am 90% certain that I did that but this is the code portion that does that:

    fds_record_t config_record ={
            .file_id           = CONFIG_FILE,
            .key               = CONFIG_REC_KEY,
            .data.p_data       = &config,
            //The length of a record is always expressed in 4-byte units (words). 
            .data.length_words = (sizeof(config_t)+3)/sizeof(uint32_t),
        };
    fds_record_desc_t desc = {0};
    fds_find_token_t  tok  = {0};
    rc = fds_record_find(CONFIG_FILE, CONFIG_REC_KEY, &desc, &tok);
    if(rc == NRF_SUCCESS){
        //rc = fds_record_update(&desc, &config_record);
        rc = fds_record_delete(&desc);
        APP_ERROR_CHECK(rc);
        rc = fds_record_write(&desc, &config_record);
        APP_ERROR_CHECK(rc);
        if(rc != NRF_SUCCESS)
        {
            rc = fds_gc();
            APP_ERROR_CHECK(rc);
        }
        APP_ERROR_CHECK(rc);
    }

    I at first tried to use fds_record_update instead of delete/write but I dont recall it worked so I did this instead. I don'T know if it could cause such problem I don't think so.

    I am however wondering if it could be possible to corrupted the memory flash in a hardware way. (i.e.: inverting poles or idk)

    Thank you very much for your answers,

    Joel V.

Related