fds_record_write stops prematurely.

Hello.

It is under development using nrf52832 (S132 v7.0.1, SDK v17.0.0) as a peripheral device.

I'm currently considering Flash Data Storage (FDS).

As settings, "FDS_VIRTUAL_PAGES" is set to 4, "FDS_VIRTUAL_PAGE_SIZE" is set to 1024, and the writable area is 12kB.
In order to check how many times 64Byte can be written to 12kB, I created a process that repeats fds_record_write and made it work, but it is not an error and the operation stops halfway. I checked the number of times I wrote when I stopped, but the number of times was different each time.

#include "app_error.h"
#include "fds.h"

/* Definition of sdk_config.h */
#define FDS_ENABLED 1
#define FDS_VIRTUAL_PAGES 4
#define FDS_VIRTUAL_PAGE_SIZE 1024
#define FDS_VIRTUAL_PAGES_RESERVED 0
#define FDS_BACKEND 2
#define FDS_OP_QUEUE_SIZE 4
#define FDS_CRC_CHECK_ON_READ 0
#define FDS_CRC_CHECK_ON_WRITE 0
#define FDS_MAX_USERS 4

#define FILE_ID      0x1000 /* The ID of the file to write the records into. */
#define RECORD_KEY   0x1100 /* A key for the first record. */

typedef struct {
    uint8_t test_data_a;
    uint8_t test_data_b[6];
    uint8_t test_data_c[16];
    uint8_t test_data_d[16];
    uint8_t test_data_e[16];
    uint8_t test_data_f[8];
    uint8_t test_data_g;
} T_FDS_LOG_DATA;

static T_FDS_LOG_DATA v_fds_log_data_write;

static fds_record_t m_record =
{
    .file_id           = FILE_ID,
    .key               = RECORD_KEY,
    .data.p_data       = &v_fds_log_data_write,
    /* The length of a record is always expressed in 4-byte units (words). */
    .data.length_words = (sizeof(v_fds_log_data_write) / sizeof(uint32_t)),
};

static fds_record_desc_t  record_desc;
static uint32_t cb_write_cnt = 0;

static void fds_evt_handler(fds_evt_t const * p_fds_evt);

/* FDS related initialization function */
void fds_evt_init(void)
{
    ret_code_t err_code;

    memset(&v_fds_log_data_write, 0xAA, sizeof(v_fds_log_data_write));

    err_code = fds_register(fds_evt_handler);
    APP_ERROR_CHECK(err_code);

    err_code = fds_init();
    APP_ERROR_CHECK(err_code);    

    return;
}

/* FDS event handler */
static void fds_evt_handler(fds_evt_t const * p_fds_evt)
{
    switch (p_fds_evt->id)
    {
        // Initialization completion event.
        case FDS_EVT_INIT:
            if (p_fds_evt->result != NRF_SUCCESS) {
                // Initialization failed.
            }
            else {
                fds_data_write();
            }
            break;

        // Write complete event.
        case FDS_EVT_WRITE:
            cb_write_cnt++;
            m_record.key = (uint16_t)cb_write_cnt;
            v_fds_log_data_write.test_data_a = (uint8_t)cb_write_cnt;
            fds_data_write();
            break;

        default:
            break;
    }

    return;
}

/* FDS write process*/
void fds_data_write(void)
{
    ret_code_t err_code;

    // Write a record to Flash.
    err_code = fds_record_write(&record_desc, &m_record);
    APP_ERROR_CHECK(err_code);

    return;
}

Why does it stop working? Is there a countermeasure?

Best regards.

Parents
  • Hi Kei, 

    When you mention the operation stopped half way, could you describe what exactly you observed ? 
    If you stop the MCU where would it be ? 

    Could you provide a simple application to reproduce the issue that I can test here ? 

  • Hello.

    I decided to stop the operation because I checked the memory with IDE (IAR Embedded Workbench) and confirmed that the value was not written. At this time, when I stopped the debugger, it was in the HardFault Handler.

    Regarding applications that can be tested, they cannot be published. The mechanism is to call fds_evt_init before the advertisement output. Subsequent processing is as described in the callback. I think that it can work by making the same mechanism with the sample code of SDK.

    Best regards.

  • Hi Kei, 

    I tried your code here and don't see the same problem. I attached the code here. The write worked for 159 records and the it stops. 159x64 = 10176 bytes matching with the roughly 12kB you reserved for the fds (there is some headers on each of the record).


    Note that you should do a flash eraseall before you test so that the previous database will be cleaned. 

    In addition when you declare your data to be written to fds they should be word aligned. I added __ALIGN(4) into: 

    __ALIGN(4) static T_FDS_LOG_DATA v_fds_log_data_write;

    Here is the log I get : 

    ble_app_hrs_fds.zip

Reply
  • Hi Kei, 

    I tried your code here and don't see the same problem. I attached the code here. The write worked for 159 records and the it stops. 159x64 = 10176 bytes matching with the roughly 12kB you reserved for the fds (there is some headers on each of the record).


    Note that you should do a flash eraseall before you test so that the previous database will be cleaned. 

    In addition when you declare your data to be written to fds they should be word aligned. I added __ALIGN(4) into: 

    __ALIGN(4) static T_FDS_LOG_DATA v_fds_log_data_write;

    Here is the log I get : 

    ble_app_hrs_fds.zip

Children
No Data
Related