It takes too long to read data using settings(Internal Flash).

bool nvma_param_get(const char *name, void *dest, size_t len)
{
	int rc;
	struct direct_immediate_value dov;

	dov.fetched = 0;
	dov.len = len;
	dov.dest = dest;

	rc = settings_load_subtree_direct(name, direct_loader_immediate_value, (void *)&dov);
	if (rc == 0) {
		if (!dov.fetched) {
			rc = -ENOENT;
            // LOG_WRN("get failed, no dir:%s", name);
		}
	} else {
        LOG_WRN("get failed (%d)", rc);
    }

	return (rc==0);
}

name:

#define NVM_APP_ID0             "nvm/appid00"
#define NVM_APP_DUID0           "nvm/appduid00"
#define NVM_APP_NOTIF_SW0       "nvm/appnotifsw00"
#define NVM_APP_NOTIF_DEST0     "nvm/appnotifdest00"
#define NVM_APP_LAST_COUNTER0   "nvm/applastcounter00"

Code:

#define NVM_APPID_MAPPING_SZ (16)

static uint32_t app_id_buffer[NVM_APPID_MAPPING_SZ] = { INVALID_APP_ID };
static uint32_t app_last_counter_buffer[NVM_APPID_MAPPING_SZ] = { 0 };

uint8_t nwk_mapping_init(void)
{
    uint8_t index = 0, counter = 0;
    for (index = 0; index < NVM_APPID_MAPPING_SZ; ++index) {

        app_id_buffer[index] = INVALID_APP_ID;
        counter += nvm_get_appid_by_index(index, &app_id_buffer[index]);

        counter += nvm_get_applastcounter_by_index(index, &app_last_counter_buffer[index]);
    }

    return counter;
}
bool nwk_mapping_init_write(void)
{
    uint8_t index = 0;
    for (index = 0; index < NVM_APPID_MAPPING_SZ; ++index) {

        nvm_set_appid_by_index(index, index);
        nvm_set_appnotifsw_by_index(index, 0xffffffff);
        nvm_set_appnotifdest_by_index(index, NWM_RECEIVER_SITE_ADDR);
        nvm_set_applastcounter_by_index(index, index);
    }

    return true;
}


int network_init(void)
{
    
    OSLOG_INF("network0, tick %u", OS_get_system_usec_32());
    nwk_mapping_init_write();
    OSLOG_INF("network1, tick %u", OS_get_system_usec_32());
    uint8_t counter = nwk_mapping_init();
    OSLOG_INF("network2, tick %u, counter %u", OS_get_system_usec_32(), counter);
    return 0;
}

Log1:

[00:00:00.090,301] <inf> netw: network0, tick 90301
[00:00:01.073,822] <inf> netw: network1, tick 1073822
[00:00:03.181,182] <inf> netw: network2, tick 3181182, counter 32

When the storage capacity is 64 entries, continuously reading 32 of them takes about 2 seconds.

After changing the path, run the write and read code again, and the time taken is as follows.

#define NVM_APP_ID0             "nvm1/appid00"
#define NVM_APP_DUID0           "nvm1/appduid00"
#define NVM_APP_NOTIF_SW0       "nvm1/appnotifsw00"
#define NVM_APP_NOTIF_DEST0     "nvm1/appnotifdest00"
#define NVM_APP_LAST_COUNTER0   "nvm1/applastcounter00"

Log2:

[00:00:00.154,479] <inf> netw: network0, tick 154479
[00:00:05.811,981] <inf> netw: network1, tick 5811981
[00:00:14.455,413] <inf> netw: network2, tick 14455383, counter 32

When the storage capacity is 128 entries, continuously reading 32 of them takes about 9 seconds.

How should I optimize it?

Parents
  • Hi Elfving,

    Currently, this sample has not been tested.

    I using these code to read/write data.

    /**
     * Initialization of settings and backend
     *
     * Can be called at application startup.
     * In case the backend is a FS Remember to call it after the FS was mounted.
     * For FCB backend it can be called without such a restriction.
     *
     * @return 0 on success, non-zero on failure.
     */
    int settings_subsys_init(void);
    
    /**
     * Write a single serialized value to persisted storage (if it has
     * changed value).
     *
     * @param name Name/key of the settings item.
     * @param value Pointer to the value of the settings item. This value will
     * be transferred to the @ref settings_handler::h_export handler implementation.
     * @param val_len Length of the value.
     *
     * @return 0 on success, non-zero on failure.
     */
    int settings_save_one(const char *name, const void *value, size_t val_len);
    
    /**
     * Load limited set of serialized items using given callback.
     *
     * This function bypasses the normal data workflow in settings module.
     * All the settings values that are found are passed to the given callback.
     *
     * @note
     * This function does not call commit function.
     * It works as a blocking function, so it is up to the user to call
     * any kind of commit function when this operation ends.
     *
     * @param[in]     subtree subtree name of the subtree to be loaded.
     * @param[in]     cb      pointer to the callback function.
     * @param[in,out] param   parameter to be passed when callback
     *                        function is called.
     * @return 0 on success, non-zero on failure.
     */
    int settings_load_subtree_direct(
    	const char             *subtree,
    	settings_load_direct_cb cb,
    	void                   *param);

    Regards,

    Leo

  • Have a look at this previous reply by a coworker of mine. Could you try using an FCB backend and see if it helps?

    Regards,

    Elfving

Reply Children
No Data
Related