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

cloud_client uses nvs library to report an error: invalid address: 0x00100ff8:8

I want to use nvs in nrf cloud. A conflict is found between the nrf_cloud library and the nvs library. The nrf_cloud library will cause the nvs library to be unavailable, and an error will be reported: flash_nrf: invalid address: 0x00100ff8:8.

I added nvs library to cloud_client to reproduce this problem. This is my prj.conf:

Added 

CONFIG_NVS=y
CONFIG_NVS_LOG_LEVEL_DBG=y
CONFIG_MPU_ALLOW_FLASH_WRITE=y

#
# Copyright (c) 2020 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

# General config
CONFIG_NEWLIB_LIBC=y
CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y
CONFIG_RESET_ON_FATAL_ERROR=n
CONFIG_NCS_SAMPLES_DEFAULTS=y

# Log level
# For more verbose and detailed log output, set the log level to
# CONFIG_CLOUD_CLIENT_LOG_LEVEL_DBG=y instead.
CONFIG_CLOUD_CLIENT_LOG_LEVEL_INF=y

# Network
CONFIG_NETWORKING=y
CONFIG_NET_NATIVE=n
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_OFFLOAD=y

# LTE link control
CONFIG_LTE_LINK_CONTROL=y
#CONFIG_LTE_NETWORK_MODE_LTE_M=y
CONFIG_LTE_AUTO_INIT_AND_CONNECT=n

CONFIG_LTE_NETWORK_MODE_NBIOT_GPS=y
CONFIG_LTE_LEGACY_PCO_MODE=y

# Modem library
CONFIG_NRF_MODEM_LIB=y

# DK
CONFIG_DK_LIBRARY=y

# AT commands interface
CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_AT_HOST_LIBRARY=y

# Generic cloud API
CONFIG_CLOUD_API=y

# Selected cloud backend
CONFIG_CLOUD_BACKEND="NRF_CLOUD"

# nRF Cloud
CONFIG_NRF_CLOUD=y
CONFIG_NRF_CLOUD_CONNECTION_POLL_THREAD=y

# AWS IoT
# CONFIG_AWS_IOT=y
# CONFIG_AWS_IOT_CLIENT_ID_STATIC="my-thing"
# CONFIG_AWS_IOT_BROKER_HOST_NAME="example.endpoint.com"
# CONFIG_AWS_IOT_SEC_TAG=201
# CONFIG_AWS_IOT_TOPIC_UPDATE_DELTA_SUBSCRIBE=y

# Azure IoT Hub
# CONFIG_AZURE_IOT_HUB=y
# CONFIG_AZURE_IOT_HUB_DEVICE_ID="my-device"
# CONFIG_AZURE_IOT_HUB_HOSTNAME="example.endpoint.com"
# CONFIG_AZURE_IOT_HUB_SEC_TAG=10

# MQTT
CONFIG_MQTT_KEEPALIVE=1200

# Heap and stacks
# Extended memory heap size needed for encoding nRF Cloud messages to JSON
CONFIG_HEAP_MEM_POOL_SIZE=8192
CONFIG_MAIN_STACK_SIZE=4096
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048

# Settings, used by nRF Cloud library.
CONFIG_SETTINGS=y
CONFIG_SETTINGS_FCB=y
CONFIG_FCB=y

# Flash storage, used by settings.
CONFIG_FLASH=y
CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_FLASH_MAP=y
CONFIG_MPU_ALLOW_FLASH_WRITE=y

# NVS
CONFIG_NVS=y
CONFIG_NVS_LOG_LEVEL_DBG=y
CONFIG_MPU_ALLOW_FLASH_WRITE=y

main.c:

static struct nvs_fs fs;
struct flash_pages_info info;
#define GOKE_BINARY_ID 7

int nvs_read_binary_state(bool *flag){
        int rc;
	rc = nvs_read(&fs, GOKE_BINARY_ID, flag, 1);
	if (rc > 0) { /* item was found, show it */
		LOG_INF("Id: %d, binary_state: %d\n", GOKE_BINARY_ID, *flag);
	} else   {/* item was not found, add it */
		LOG_INF("No binary_state found");
                return -1;
	}
        return 0;
}

int nvs_write_binary_state(bool *flag){
        int rc;
	rc = nvs_write(&fs, GOKE_BINARY_ID, flag, 1);
        if(rc < 0){
                LOG_ERR("NVS write binary_state error!");
                return rc;
        }
        return 0;
}

int nvs_setup(void)
{
	int rc;
	fs.offset = FLASH_AREA_OFFSET(storage);;
	rc = flash_get_page_info_by_offs(
		device_get_binding(DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL),
		fs.offset, &info);
	if (rc) {
		LOG_ERR("Unable to get page info");
                return rc;
	}
	fs.sector_size = info.size;
	fs.sector_count = 3U;

	rc = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
	if (rc) {
		LOG_ERR("Flash Init failed");
                return rc;
	}
        return 0;
}

void main(void)
{
	int err;
        bool flag;

	LOG_INF("Cloud client has started");
        if(nvs_setup()){
                LOG_ERR("Init nvs error!");
        }
        if(nvs_read_binary_state(&flag)){
                LOG_ERR("read nvs error!");
        }
        if(nvs_write_binary_state(&flag)){
                LOG_ERR("write nvs error!");
        }

	cloud_backend = cloud_get_binding(CONFIG_CLOUD_BACKEND);
	__ASSERT(cloud_backend != NULL, "%s backend not found",
		 CONFIG_CLOUD_BACKEND);

	err = cloud_init(cloud_backend, cloud_event_handler);
	if (err) {
		LOG_ERR("Cloud backend could not be initialized, error: %d",
			err);
	}

	work_init();
	modem_configure();

#if defined(CONFIG_CLOUD_PUBLICATION_BUTTON_PRESS)
	err = dk_buttons_init(button_handler);
	if (err) {
		LOG_ERR("dk_buttons_init, error: %d", err);
	}
#endif
	LOG_INF("Connecting to LTE network, this may take several minutes...");

	k_sem_take(&lte_connected, K_FOREVER);

	LOG_INF("Connected to LTE network");
	LOG_INF("Connecting to cloud");

	k_delayed_work_submit(&connect_work, K_NO_WAIT);
}

log:

SPM: NS image at 0xc000
SPM: NS MSP at 0x2001d5a8
SPM: NS reset vector at 0x12e49
SPM: prepare to jump to Non-Secure image.

[15:44:22.555]收←◆*
[15:44:22.579]收←◆** Booting Zephyr OS build v2.4.99-ncs1  ***
I: Cloud client has started
E: invalid address: 0x00100ff8:8
I: 3 Sectors of 4096 bytes
I: alloc wra: 0, ff0
I: data wra: 0, 8
E: invalid address 0x00100ff8:8
I: No binary_state found
E: read nvs error!
E: invalid address: 0x00100ff8:8
E: NVS write binary_state error!
E: write nvs error!
I: Using legacy LTE PCO mode...

[15:44:22.653]收←◆I: Connecting to LTE network, this may take several minutes...

demo:

cloud_client_test.rar

  • The starting address of settings_storage is 0xfe000, which is the cause of the bug. But I still can't find out where the problem is. The starting address of settings_storage described in the compiled dts file is 0xfa000. Can you give some guidance?

  • The partitions you see when running ninja rom_report is automatically generated by the Partition Manager. It uses the files nrf/samples/spm/pm.yml, nrf/subsys/partition_manager/pm.yml.nvs and nrf/subsys/partition_manager/pm.yml.settings to decide the position and sizes of the partitions. The main application does not have a pm.yml file, but it's location will get decided relative to all the other.

    However, you can generate all the partitions yourself, check out:

    Configuring Static Partitions

    nrf/applications/asset_tracker/configuration/thingy91_nrf9160ns/pm_static.yml  

    In addition to running ninja rom_report, you can look at the file nrf/samples/cloud_client_test/build/partitions.yml to see the generated partitions.

    xinjiang said:
    he starting address of settings_storage described in the compiled dts file is 0xfa000.

    The partition sizes and locations from the dts will be ignored when your applcation has child images (your case).

    Best regards,

    Simon

  • Thank you! There is another question. Why does the nvs library report an error when starting from address 0xfe000?

  • I'm sorry for not addressing your initial issue earlier. I was a little too fast to reply, and oversaw the obvious cause. My apologies for that.


    Comments:

    I added some printk's to your code:

    int nvs_setup(void)
    {
        .
        .
        .
    	fs.sector_size = info.size;
    	fs.sector_count = 3U;
    	printk("Sector size: %d | Sector count: %d | Total size = %d\n",info.size, 3, 3*info.size);

    It gave the following: "Sector size: 4096 | Sector count: 3 | Total size = 12288"

    This will give you a size of 12288=0x3000, which will occupy the flash 0xfe000-0x101000 (0xfe000+0x3000=0x101000). This will overflow the total flash, 0x100000.

    Why are you not using the nvs_storage area? If you run ninja rom_report from cloud_client_test/build, you will see the following

    +------------------------------------------+
    | 0x0: spm (0xc000 - 48kB)                 |
    | 0xc000: app (0xec000 - 944kB)            |
    | 0xf8000: nvs_storage (0x6000 - 24kB)     |
    | 0xfe000: settings_storage (0x2000 - 8kB) |
    +------------------------------------------+

    Solution:

    Configure nvs accordingly instead:

    fs.offset = 0xf8000;
    fs.sector_size = 0x1000;
    fs.sector_count = 6U;

    This will make it use this partition:

     0xf8000: nvs_storage (0x6000 - 24kB) 

    Since 0x1000*6=0x6000

    I tested this and did not get the "invalid address" errors anymore, but I got a read error however: 

    I: No binary_state found
    E: read nvs error!

    I did not get time to look into these, but please tell me if you want me to

    Best regards,

    Simon

Related