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

nRF5340 NVS and readback_protection

Hi Everybody,

We found little or no literature about readback_protection on the nRF5340 SOC. Our issue is that for development and debugging it is not practical to use nrfjprog -recover in order to re-flash as that completely erases the storage partition too. What is the right way to retain NVS data?

Thank you.

Regards,

Milan 

  • Yes, with the options parameter to be set to 1, it results in the same behaviour. 

  • Hi,

    This is very interesting, but for some reason I have not been able to reproduce it, even while testing with WDT. Is it possible to provide a project that demonstrate this on a DK? (could be just a diff showing what you need to add to an example project to trigger the issue).

  • Hi, of course. I just added the watchdog to the network coordinator example for a quick test. The problem is the same.

    /*
     * Copyright (c) 2020 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
     */
    
    /** @file
     *  @brief Simple Zigbee network coordinator implementation
     */
    
    #include <zephyr.h>
    #include <device.h>
    #include <logging/log.h>
    #include <dk_buttons_and_leds.h>
    
    #include <zboss_api.h>
    #include <zb_mem_config_max.h>
    #include <zigbee/zigbee_error_handler.h>
    #include <zigbee/zigbee_app_utils.h>
    #include <zb_nrf_platform.h>
    #include <drivers/watchdog.h>
    
    LOG_MODULE_REGISTER(main, LOG_LEVEL_INF);
    
    #if DT_NODE_HAS_STATUS(DT_ALIAS(watchdog0), okay)
    #elif DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_watchdog)
    #define WDT_NODE DT_INST(0, nordic_nrf_watchdog)
    #endif
    /*
     * If the devicetree has a watchdog node, get its label property.
     */
    #ifdef WDT_NODE
    #define WDT_DEV_NAME DT_LABEL(WDT_NODE)
    #else
    #define WDT_DEV_NAME ""
    #error "Unsupported SoC and no watchdog0 alias in zephyr.dts"
    #endif
    
    const struct device *wdt; /*There could only be one watchdog instance for nRF*/
    int wdt_channel_id;
    
    static void wdt_callback(const struct device *wdt_dev, int channel_id)
    {
    	static bool handled_event;
    
    	if (handled_event)
    	{
    		return;
    	}
    
    	wdt_feed(wdt_dev, channel_id);
    
    	LOG_ERR("Watchdog handled things..ready to reset");
    	handled_event = true;
    }
    
    uint8_t wdt_test()
    {
    	struct wdt_timeout_cfg wdt_config;
    	/* Reset SoC when watchdog timer expires. */
    	wdt_config.flags = WDT_FLAG_RESET_SOC;
    	/* Expire watchdog after 1000 milliseconds. */
    	wdt_config.window.min = 0U;
    	wdt_config.window.max = 1000;
    
    	/* Set up watchdog callback. Jump into it when watchdog expired. */
    	wdt_config.callback = wdt_callback;
    
    	LOG_WRN("Initialize Watchdog");
    
    	wdt = device_get_binding(WDT_DEV_NAME);
    	if (!wdt)
    	{
    		LOG_ERR("Cannot get WDT device");
    		return -1;
    	}
    
    	/*Add WDT channel*/
    
    	wdt_channel_id = wdt_install_timeout(wdt, &wdt_config);
    	if (wdt_channel_id == -ENOTSUP)
    	{
    		wdt_config.callback = NULL;
    		wdt_channel_id = wdt_install_timeout(wdt, &wdt_config);
    	}
    	if (wdt_channel_id < 0)
    	{
    		LOG_ERR("Watchdog channel install error");
    		return -1;
    	}
    	LOG_WRN("Watchdog added to channel %i", wdt_channel_id);
    
    	/*Start Watchdog*/
    
    	int err = wdt_setup(wdt, 1);
    	if (err < 0)
    	{
    		LOG_ERR("Watchdog setup error");
    		return err;
    	}
    
    	return 0;
    }
    
    #define RUN_STATUS_LED DK_LED1
    #define RUN_LED_BLINK_INTERVAL 1000
    
    /* LED indicating that network is opened for new nodes */
    #define ZIGBEE_NETWORK_STATE_LED DK_LED3
    
    /* Button which reopens the Zigbee Network */
    #define KEY_ZIGBEE_NETWORK_REOPEN DK_BTN1_MSK
    
    /**
     * If set to ZB_TRUE then device will not open the network
     * after forming or reboot.
     */
    #define ZIGBEE_MANUAL_STEERING ZB_FALSE
    
    #define ZIGBEE_PERMIT_LEGACY_DEVICES ZB_FALSE
    
    #ifndef ZB_COORDINATOR_ROLE
    #error Define ZB_COORDINATOR_ROLE to compile coordinator source code.
    #endif
    
    /**@brief Callback used in order to visualise network steering period.
     *
     * @param[in]   param   Not used. Required by callback type definition.
     */
    static void steering_finished(zb_uint8_t param)
    {
    	ARG_UNUSED(param);
    	LOG_INF("Network steering finished");
    	dk_set_led_off(ZIGBEE_NETWORK_STATE_LED);
    }
    
    /**@brief Callback for button events.
     *
     * @param[in]   button_state  Bitmask containing buttons state.
     * @param[in]   has_changed   Bitmask containing buttons
     *                            that has changed their state.
     */
    static void button_changed(uint32_t button_state, uint32_t has_changed)
    {
    	/* Calculate bitmask of buttons that are pressed
    	 * and have changed their state.
    	 */
    	uint32_t buttons = button_state & has_changed;
    	zb_bool_t comm_status;
    
    	if (buttons & KEY_ZIGBEE_NETWORK_REOPEN)
    	{
    		(void)(ZB_SCHEDULE_APP_ALARM_CANCEL(
    			steering_finished, ZB_ALARM_ANY_PARAM));
    
    		comm_status = bdb_start_top_level_commissioning(
    			ZB_BDB_NETWORK_STEERING);
    		if (comm_status)
    		{
    			LOG_INF("Top level comissioning restated");
    		}
    		else
    		{
    			LOG_INF("Top level comissioning hasn't finished yet!");
    		}
    	}
    }
    
    /**@brief Function for initializing LEDs and Buttons. */
    static void configure_gpio(void)
    {
    	int err;
    
    	err = dk_buttons_init(button_changed);
    	if (err)
    	{
    		LOG_ERR("Cannot init buttons (err: %d)", err);
    	}
    
    	err = dk_leds_init();
    	if (err)
    	{
    		LOG_ERR("Cannot init LEDs (err: %d)", err);
    	}
    }
    
    /**@brief Zigbee stack event handler.
     *
     * @param[in]   bufid   Reference to the Zigbee stack buffer
     *                      used to pass signal.
     */
    void zboss_signal_handler(zb_bufid_t bufid)
    {
    	/* Read signal description out of memory buffer. */
    	zb_zdo_app_signal_hdr_t *sg_p = NULL;
    	zb_zdo_app_signal_type_t sig = zb_get_app_signal(bufid, &sg_p);
    	zb_ret_t status = ZB_GET_APP_SIGNAL_STATUS(bufid);
    	zb_ret_t zb_err_code;
    	zb_bool_t comm_status;
    	zb_time_t timeout_bi;
    
    	switch (sig)
    	{
    	case ZB_BDB_SIGNAL_DEVICE_REBOOT:
    		/* BDB initialization completed after device reboot,
    		 * use NVRAM contents during initialization.
    		 * Device joined/rejoined and started.
    		 */
    		if (status == RET_OK)
    		{
    			if (ZIGBEE_MANUAL_STEERING == ZB_FALSE)
    			{
    				LOG_INF("Start network steering");
    				comm_status = bdb_start_top_level_commissioning(
    					ZB_BDB_NETWORK_STEERING);
    				ZB_COMM_STATUS_CHECK(comm_status);
    			}
    			else
    			{
    				LOG_INF("Coordinator restarted successfully");
    			}
    		}
    		else
    		{
    			LOG_ERR("Failed to initialize Zigbee stack using NVRAM data (status: %d)",
    					status);
    		}
    		break;
    
    	case ZB_BDB_SIGNAL_STEERING:
    		if (status == RET_OK)
    		{
    			if (ZIGBEE_PERMIT_LEGACY_DEVICES == ZB_TRUE)
    			{
    				LOG_INF("Allow pre-Zigbee 3.0 devices to join the network");
    				zb_bdb_set_legacy_device_support(1);
    			}
    
    			/* Schedule an alarm to notify about the end
    			 * of steering period
    			 */
    			LOG_INF("Network steering started");
    			zb_err_code = ZB_SCHEDULE_APP_ALARM(
    				steering_finished, 0,
    				ZB_TIME_ONE_SECOND *
    					ZB_ZGP_DEFAULT_COMMISSIONING_WINDOW);
    			ZB_ERROR_CHECK(zb_err_code);
    		}
    		break;
    
    	case ZB_ZDO_SIGNAL_DEVICE_ANNCE:
    	{
    		zb_zdo_signal_device_annce_params_t *dev_annce_params =
    			ZB_ZDO_SIGNAL_GET_PARAMS(
    				sg_p, zb_zdo_signal_device_annce_params_t);
    
    		LOG_INF("New device commissioned or rejoined (short: 0x%04hx)",
    				dev_annce_params->device_short_addr);
    
    		zb_err_code = ZB_SCHEDULE_APP_ALARM_CANCEL(steering_finished,
    												   ZB_ALARM_ANY_PARAM);
    		if (zb_err_code == RET_OK)
    		{
    			LOG_INF("Joining period extended.");
    			zb_err_code = ZB_SCHEDULE_APP_ALARM(
    				steering_finished, 0,
    				ZB_TIME_ONE_SECOND *
    					ZB_ZGP_DEFAULT_COMMISSIONING_WINDOW);
    			ZB_ERROR_CHECK(zb_err_code);
    		}
    	}
    	break;
    
    	default:
    		/* Call default signal handler. */
    		ZB_ERROR_CHECK(zigbee_default_signal_handler(bufid));
    		break;
    	}
    
    	/* Update network status LED */
    	if (ZB_JOINED() &&
    		(ZB_SCHEDULE_GET_ALARM_TIME(steering_finished, ZB_ALARM_ANY_PARAM,
    									&timeout_bi) == RET_OK))
    	{
    		dk_set_led_on(ZIGBEE_NETWORK_STATE_LED);
    	}
    	else
    	{
    		dk_set_led_off(ZIGBEE_NETWORK_STATE_LED);
    	}
    
    	/*
    	 * All callbacks should either reuse or free passed buffers.
    	 * If bufid == 0, the buffer is invalid (not passed).
    	 */
    	if (bufid)
    	{
    		zb_buf_free(bufid);
    	}
    }
    
    void error(void)
    {
    	dk_set_leds_state(DK_ALL_LEDS_MSK, DK_NO_LEDS_MSK);
    
    	while (true)
    	{
    		/* Spin for ever */
    		k_sleep(K_MSEC(1000));
    	}
    }
    
    void main(void)
    {
    	int blink_status = 0;
    
    	LOG_INF("Starting ZBOSS Coordinator example");
    
    	/* Initialize */
    	configure_gpio();
    
    	/* Start Zigbee default thread */
    	zigbee_enable();
    
    	wdt_test();
    
    	LOG_INF("ZBOSS Coordinator example started");
    
    	while (1)
    	{
    		dk_set_led(RUN_STATUS_LED, (++blink_status) % 2);
    		k_sleep(K_MSEC(RUN_LED_BLINK_INTERVAL));
    		wdt_feed(wdt, wdt_channel_id);
    	}
    }
    

    #
    # Copyright (c) 2020 Nordic Semiconductor ASA
    #
    # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
    #
    
    CONFIG_NCS_SAMPLES_DEFAULTS=y
    
    CONFIG_UART_INTERRUPT_DRIVEN=y
    CONFIG_WATCHDOG=y
    CONFIG_SERIAL=y
    CONFIG_GPIO=y
    
    # Make sure printk is not printing to the UART console
    CONFIG_CONSOLE=y
    CONFIG_UART_CONSOLE=y
    
    CONFIG_HEAP_MEM_POOL_SIZE=2048
    CONFIG_MAIN_THREAD_PRIORITY=7
    CONFIG_MAIN_STACK_SIZE=2048
    
    CONFIG_ZIGBEE=y
    CONFIG_ZIGBEE_APP_UTILS=y
    CONFIG_ZIGBEE_ROLE_COORDINATOR=y
    
    # Enable DK LED and Buttons library
    CONFIG_DK_LIBRARY=y
    
    # This example requires more workqueue stack
    CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048
    
    # Use software cryptography on nRF5340
    CONFIG_TINYCRYPT=y
    CONFIG_CTR_DRBG_CSPRNG_GENERATOR=y
    CONFIG_ZIGBEE_USE_SOFTWARE_AES=y
    
    #Networking
    CONFIG_MPSL=n
    CONFIG_NET_IPV6_MLD=n
    CONFIG_NET_IPV6_NBR_CACHE=n
    CONFIG_NET_IPV6_RA_RDNSS=n
    CONFIG_NET_IP_ADDR_CHECK=n
    CONFIG_NET_UDP=n
    

  • Hello,

    I tested now with nRF Connect SDK 1.7.0 and your changes to the network_coordinator sample. I tested building for both nrf5340dk_nrf5340_cpuapp_ns and nrf5340dk_nrf5340_cpuapp, but in both cases I was able to program repeatedly using west flash.

    This is a bit of a mystery. Can you write how you build the application? And the DK version you are reproducing this on? Any other information that could help me reproduce would also be useful.

  • Okay. This is indeed a mistery now.

    I attached the build log. The DK version is 0.11.0. The nrf SDK is at 1.7.0. Zephyr is 2.6.99-ncs1

    ..@.. network_coordinator % west build -b nrf5340dk_nrf5340_cpuapp
    -- west build: generating a build system
    Including boilerplate (Zephyr base (cached)):  /../../zephyr/cmake/app/boilerplate.cmake
    -- Application:  /../../network_coordinator
    -- Zephyr version: 2.6.99 ( /../../zephyr), build: v2.6.99-ncs1
    -- Found west (found suitable version "0.11.1", minimum required is "0.7.1")
    -- Board: nrf5340dk_nrf5340_cpuapp
    -- Cache files will be written to:  /../Library/Caches/zephyr
    -- Found dtc: /usr/local/bin/dtc (found suitable version "1.6.0", minimum required is "1.4.6")
    -- Found toolchain: gnuarmemb (/usr/local/gcc_arm/gcc-arm-none-eabi-10-2020-q4-major)
    -- Found BOARD.dts:  /../../zephyr/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuapp.dts
    -- Generated zephyr.dts:  /../../network_coordinator/build/zephyr/zephyr.dts
    -- Generated devicetree_unfixed.h:  /../../network_coordinator/build/zephyr/include/generated/devicetree_unfixed.h
    -- Generated device_extern.h:  /../../network_coordinator/build/zephyr/include/generated/device_extern.h
    -- Including generated dts.cmake file:  /../../network_coordinator/build/zephyr/dts.cmake
    Parsing  /../../zephyr/Kconfig
    Loaded configuration ' /../../zephyr/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuapp_defconfig'
    Merged configuration ' /../../network_coordinator/prj_nrf5340dk_nrf5340_cpuapp.conf'
    Configuration saved to ' /../../network_coordinator/build/zephyr/.config'
    Kconfig header saved to ' /../../network_coordinator/build/zephyr/include/generated/autoconf.h'
    -- The C compiler identification is GNU 10.2.1
    -- The CXX compiler identification is GNU 10.2.1
    -- The ASM compiler identification is GNU
    -- Found assembler: /usr/local/gcc_arm/gcc-arm-none-eabi-10-2020-q4-major/bin/arm-none-eabi-gcc
    Adding '802154_rpmsg' firmware as child image since CONFIG_NRF_802154_SER_HOST is set to y
    
    === child image 802154_rpmsg - CPUNET begin ===
    Including boilerplate (Zephyr base):  /../../zephyr/cmake/app/boilerplate.cmake
    -- Application:  /../../zephyr/samples/boards/nrf/ieee802154/802154_rpmsg
    -- Zephyr version: 2.6.99 ( /../../zephyr), build: v2.6.99-ncs1
    -- Found Python3: /usr/local/bin/python3.9 (found suitable exact version "3.9.7") found components: Interpreter 
    -- Found west (found suitable version "0.11.1", minimum required is "0.7.1")
    -- Board: nrf5340dk_nrf5340_cpunet
    -- Cache files will be written to:  /../Library/Caches/zephyr
    -- Found dtc: /usr/local/bin/dtc (found suitable version "1.6.0", minimum required is "1.4.6")
    -- Found toolchain: gnuarmemb (/usr/local/gcc_arm/gcc-arm-none-eabi-10-2020-q4-major)
    -- Found BOARD.dts:  /../../zephyr/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpunet.dts
    -- Generated zephyr.dts:  /../../network_coordinator/build/802154_rpmsg/zephyr/zephyr.dts
    -- Generated devicetree_unfixed.h:  /../../network_coordinator/build/802154_rpmsg/zephyr/include/generated/devicetree_unfixed.h
    -- Generated device_extern.h:  /../../network_coordinator/build/802154_rpmsg/zephyr/include/generated/device_extern.h
    -- Including generated dts.cmake file:  /../../network_coordinator/build/802154_rpmsg/zephyr/dts.cmake
    Parsing  /../../zephyr/Kconfig
    Loaded configuration ' /../../zephyr/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpunet_defconfig'
    Merged configuration ' /../../zephyr/samples/boards/nrf/ieee802154/802154_rpmsg/prj.conf'
    Merged configuration ' /../../nrf/subsys/partition_manager/partition_manager_enabled.conf'
    Configuration saved to ' /../../network_coordinator/build/802154_rpmsg/zephyr/.config'
    Kconfig header saved to ' /../../network_coordinator/build/802154_rpmsg/zephyr/include/generated/autoconf.h'
    -- The C compiler identification is GNU 10.2.1
    -- The CXX compiler identification is GNU 10.2.1
    -- The ASM compiler identification is GNU
    -- Found assembler: /usr/local/gcc_arm/gcc-arm-none-eabi-10-2020-q4-major/bin/arm-none-eabi-gcc
    -- libmetal version: 1.0.0 ( /../../zephyr/samples/boards/nrf/ieee802154/802154_rpmsg)
    -- Build type:  
    -- Host:    Darwin/x86_64
    -- Target:  Generic/arm
    -- Machine: cortexm
    -- Looking for include file stdatomic.h
    -- Looking for include file stdatomic.h - found
    -- open-amp version: 1.0.0 ( /../../modules/lib/open-amp/open-amp)
    -- Host:    Darwin/x86_64
    -- Target:  Generic/arm
    -- Machine: cortexm
    -- C_FLAGS :  -Wall -Wextra
    -- Looking for include file fcntl.h
    -- Looking for include file fcntl.h - found
    -- Configuring done
    -- Generating done
    -- Build files have been written to:  /../../network_coordinator/build/802154_rpmsg
    === child image 802154_rpmsg - CPUNET end ===
    
    -- libmetal version: 1.0.0 ( /../../network_coordinator)
    -- Build type:  
    -- Host:    Darwin/x86_64
    -- Target:  Generic/arm
    -- Machine: cortexm
    -- Looking for include file stdatomic.h
    -- Looking for include file stdatomic.h - found
    -- open-amp version: 1.0.0 ( /../../modules/lib/open-amp/open-amp)
    -- Host:    Darwin/x86_64
    -- Target:  Generic/arm
    -- Machine: cortexm
    -- C_FLAGS :  -Wall -Wextra
    -- Looking for include file fcntl.h
    -- Looking for include file fcntl.h - found
    CMake Warning at  /../../nrfxlib/nrf_802154/sl/sl/CMakeLists.txt:14 (message):
      This combination of SoC and floating point ABI is not supported by the
      nrf_802154_sl
      lib.( /../../nrfxlib/nrf_802154/sl/sl/lib/nRF5340_CPUAPP/hard-float
      doesn't exist.)
    
    
    CMake Warning at  /../../zephyr/CMakeLists.txt:1612 (message):
      __ASSERT() statements are globally ENABLED
    
    
    -- Configuring done
    -- Generating done
    -- Build files have been written to:  /../../network_coordinator/build
    -- west build: building application
    [1/330] Preparing syscall dependency handling
    
    [7/330] Performing build step for '802154_rpmsg_subimage'
    [1/248] Preparing syscall dependency handling
    
    [239/248] Linking C executable zephyr/zephyr_prebuilt.elf
    
    [246/248] Linking C executable zephyr/zephyr.elf
    Memory region         Used Size  Region Size  %age Used
               FLASH:       67996 B       256 KB     25.94%
                SRAM:       26856 B        64 KB     40.98%
               SRAM1:          0 GB        64 KB      0.00%
            IDT_LIST:          0 GB         2 KB      0.00%
    [248/248] Generating zephyr/merged_CPUNET.hex
    [318/330] Linking C executable zephyr/zephyr_prebuilt.elf
    
    [328/330] Linking C executable zephyr/zephyr.elf
    Memory region         Used Size  Region Size  %age Used
               FLASH:      298692 B       976 KB     29.89%
                SRAM:       69688 B       512 KB     13.29%
            IDT_LIST:          0 GB         2 KB      0.00%
    [330/330] Generating zephyr/merged_domains.hex
    ..@.. network_coordinator % 

Related