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

Writing to and reading from flash on nRF5340

Hello,

I am trying to use part of the code from this example https://github.com/zephyrproject-rtos/zephyr/blob/master/samples/subsys/nvs

to write to and read from flash on nRF5340 SoC. However, I am getting the following linking error when building the project in Segger.

I am using Segger v5.34a, NCS v1.5.0-rc1 and Zephyr v2.4.99-ncs1-rc1.

I am including the following header files

#include <zephyr.h>
#include <power/reboot.h>
#include <device.h>
#include <string.h>
#include <drivers/flash.h>
#include <storage/flash_map.h>
#include <fs/nvs.h>

Can you please help ?

1> Linking ‘zephyr_prebuilt.elf’
1> C:\Zypher\v1.5.0-rc1\toolchain\opt/bin/arm-none-eabi-gcc zephyr/CMakeFiles/zephyr_prebuilt.dir/misc/empty_file.c.obj -Wl,-T zephyr/linker.cmd -Wl,-Map=C:/Sandbox/PID4-Firmware/app_core/build_nrf5340pdk_nrf5340_cpuapp_flash/zephyr/zephyr_prebuilt.map -Wl,--whole-archive app/libapp.a zephyr/libzephyr.a zephyr/arch/common/libarch__common.a zephyr/arch/arch/arm/core/aarch32/libarch__arm__core__aarch32.a zephyr/arch/arch/arm/core/aarch32/cortex_m/libarch__arm__core__aarch32__cortex_m.a zephyr/arch/arch/arm/core/aarch32/cortex_m/mpu/libarch__arm__core__aarch32__cortex_m__mpu.a zephyr/arch/arch/arm/core/aarch32/cortex_m/cmse/libarch__arm__core__aarch32__cortex_m__cmse.a zephyr/lib/libc/newlib/liblib__libc__newlib.a zephyr/lib/posix/liblib__posix.a zephyr/soc/arm/common/cortex_m/libsoc__arm__common__cortex_m.a zephyr/boards/boards/arm/nrf5340pdk_nrf5340_cpuapp/libboards__arm__nrf5340dk_nrf5340.a zephyr/drivers/adc/libdrivers__adc.a zephyr/drivers/gpio/libdrivers__gpio.a zephyr/drivers/ipm/libdrivers__ipm.a zephyr/drivers/spi/libdrivers__spi.a modules/nrf/lib/fatal_error/lib..__nrf__lib__fatal_error.a modules/nrf/drivers/hw_cc310/lib..__nrf__drivers__hw_cc310.a modules/hal_nordic/libmodules__hal_nordic.a -Wl,--no-whole-archive zephyr/kernel/libkernel.a zephyr/CMakeFiles/offsets.dir/./arch/arm/core/offsets/offsets.c.obj -Lc:/zypher/v1.5.0-rc1/toolchain/opt/bin/../lib/gcc/arm-none-eabi/9.2.1/thumb/v8-m.main/nofp -LC:/Sandbox/PID4-Firmware/app_core/build_nrf5340pdk_nrf5340_cpuapp_flash/zephyr -lgcc -Wl,--print-memory-usage zephyr/arch/common/libisr_tables.a C:/Zypher/v1.5.0-rc1/nrfxlib/crypto/nrf_cc312_platform/lib/cortex-m33/soft-float/no-interrupts/libnrf_cc312_platform_0.9.7.a -mcpu=cortex-m33 -mthumb -mabi=aapcs -Wl,--gc-sections -Wl,--build-id=none -Wl,--sort-common=descending -Wl,--sort-section=alignment -Wl,-u,_OffsetAbsSyms -Wl,-u,_ConfigAbsSyms -nostdlib -static -no-pie -Wl,-X -Wl,-N -Wl,--orphan-handling=warn -lm -Wl,-lc -LC:/Zypher/v1.5.0-rc1/toolchain/opt/arm-none-eabi/lib/thumb/v8-m.main/nofp -u_printf_float -Wl,-lgcc -lc -specs=nano.specs -o zephyr\zephyr_prebuilt.elf
1> Memory region Used Size Region Size %age Used
1> FLASH: 73512 B 1 MB 7.01%
1> SRAM: 28680 B 448 KB 6.25%
1> c:/zypher/v1.5.0-rc1/toolchain/opt/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: app/libapp.a(pid4_flash.c.obj): in function `flash_get_page_info_by_offs':
1> C:\Sandbox\PID4-Firmware\app_core\build_nrf5340pdk_nrf5340_cpuapp_flash/zephyr/include/generated/syscalls/flash.h:85: undefined reference to `z_impl_flash_get_page_info_by_offs'
1> c:/zypher/v1.5.0-rc1/toolchain/opt/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: app/libapp.a(pid4_flash.c.obj): in function `flash_init':
1> C:\Sandbox\PID4-Firmware\app_core\build_nrf5340pdk_nrf5340_cpuapp_flash/../src/flash/pid4_flash.c:45: undefined reference to `nvs_init'
1> collect2.exe: error: ld returned 1 exit status
1> IDT_LIST: 104 B 2 KB 5.08%
Build failed

Kind regards

Mohamed

Parents
  • Hello,

    I have just realised what the problem was. I needed to add this to my prj.conf file

    CONFIG_FLASH=y
    CONFIG_NVS=y

    I have also noticed the existence of other APIs flash_read() and flash_write(). 

    What is the difference between flash_read() and nvs_read() and the corresponding write APIs?

    Kind regards

    Mohamed

  • Hi!

    Great that you managed to fix the issue. The flash API is a more low level API used for interacting directly with the flash peripheral. The NVS API uses the flash API for easier organization and usage of storage. What you chose depends on your application, but NVS is commonly used for storing BLE bonding data for example.

    Best regards,
    Carl Richard

  • Thanks. Have you tried to run "nrfjprog --recover" on the custom board before flashing the application to ensure that the flash is properly erased?

    Best regards,
    Carl Richard

  • nrfjprog --recover

    With this command nvs_startup() is not returning an error and neither is nvs_init().

    Why is this?

    However, I am not seeing the output I expected to see. This is what I am seeing in the Debug Terminal.

    Note, I have reduced the number of reboots to only 3.

    [00:00:15.247,161] inf> fs_nvs: 3 Sectors of 4096 bytes
    [00:00:15.247,161] inf> fs_nvs: alloc wra: 0, d08
    [00:00:15.247,161] inf> fs_nvs: data wra: 0, 1fc

    Any reason why I am not seeing the other print messages?

    Kind regards

    Mohamed

  • Hi again! 

    This means that the device weren't properly erased before programming. I guess this is caused by how Segger Embedded Studio erases and flashes the device. If the board was used for something else earlier it's likely that there were some information left in the flash.

    The output you are seeing are (correct) log messages from the NVS subsystem. Is printk over serial enabled in the application?

    Best regards,
    Carl Richard

  • Good morning Carl,

    If the board was used for something else earlier it's likely that there were some information left in the flash.

    So, does this mean all 3 sectors were full? if this was the case then NVS should overwrite old information shouldn't it?

    Also, if this happens again, how can it be overcome from within the application?

    Is printk over serial enabled in the application?

    I usually do this in an overlay file but this sample project did not have one. I would have expected since the sample uses printk then the environment in the sample project would have already been setup for it to work.

    How can I enable printk over serial in the application?

    Kind regards

    Mohamed

  • Hi again!

    Learner said:
    So, does this mean all 3 sectors were full? if this was the case then NVS should overwrite old information shouldn't it?

    So it seems. My understanding is that NVS won't overwrite information that's not a part of the NVS file system, thus avoiding disruption of any other potential flash operations. I suggest that you use the flash API to erase the affected memory if this situation occurs.

    The sample should be configured correctly, but as you are using a custom board there may be some additional modifications required. Could you try with your original application and overlay again to see if the messages are printed correctly there?

    Best regards,
    Carl Richard

Reply
  • Hi again!

    Learner said:
    So, does this mean all 3 sectors were full? if this was the case then NVS should overwrite old information shouldn't it?

    So it seems. My understanding is that NVS won't overwrite information that's not a part of the NVS file system, thus avoiding disruption of any other potential flash operations. I suggest that you use the flash API to erase the affected memory if this situation occurs.

    The sample should be configured correctly, but as you are using a custom board there may be some additional modifications required. Could you try with your original application and overlay again to see if the messages are printed correctly there?

    Best regards,
    Carl Richard

Children
Related