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

  • Hi again!

    What happens before you call flash_init? If possible, please share your main function or main.c. 

    In addition, could you try to build without the overlay, so that we can rule out any potential issues there? 

    Best regards,
    Carl Richard

  • Hi Carl,

    I cannot build without the overlay file. I don't think it has anything to do with it. I am attaching the overlay file just in case you may spot something.nrf52833dk_nrf52833.overlay

    What happens before you call flash_init?

    I call nvs_init() from within my function flash_init() that gets called from the main() function. Note, the failure occurs in nvs_startup() which is called from nvs_init().

    static struct nvs_fs fs;

    void main( void )

    {

       initialise();

       ...

    }

    void initialise( void )
    {
       // Setup a2d channels
       adc_device_setup();
       k_sleep( K_MSEC(1000) );

       // Setup SPI devices
       radio_spi_setup();
       

       //spi_init();
       k_sleep( K_MSEC(1000) );

       // Configure LR1110
       radio_gfsk_modem_config();
       k_sleep( K_MSEC(1000) );

       // Setup and Initialise timers
       timer_init();

       // Start timers
       timer_start();

      // Initialise Flash
       flash_init(); 

    }

    void flash_init( void )
    {
    int32_t rc = 0;
    struct flash_pages_info info;

    /* define the nvs file system by settings with:
    * sector_size equal to the pagesize,
    * 3 sectors
    * starting at FLASH_AREA_OFFSET(storage)
    */
    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 )
    {
    printk( "Unable to get page info" );
    }

    fs.sector_size = info.size;
    fs.sector_count = 3U;

    rc = nvs_init( &fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL );
    if ( rc )
    {
    printk( "Flash Init failed\n" );
    }

    // Initialise static data flash area
    flash_init_static();

    // Initialise dynamic data flash area
    flash_init_dynamic();

    #if NDEBUG
    /* Finally, lock the flash */
    //TBD!!! flash_SetLockByte(0x80U);
    #endif


    }//flash_init()

  • Hi again!

    I agree that nothing in the overlay file should affect the flash, so that's probably not the culprit. Just wanted to make sure, but if it's not possible that's okay!

    Can you confirm that the exact same code (except for the overlay) works with the nRF52833DK and the custom nRF5340 board? Could you test the standard zephyr/samples/subsys/nvs sample on the board and see if the behavior is similar?

    Best regards,
    Carl Richard

  • Can you confirm that the exact same code (except for the overlay) works with the nRF52833DK and the custom nRF5340 board?

    The exact same code including the same overlay works fine on the nRF52833DK.

    Also the same code but with a different overlay file works fine on the nRF5340PDK and nRF5340 proprietary board.

  • Thank you for the information. I'm asking the developers to see if they have any input. What were your results from testing with the zephyr/samples/subsys/nvs sample?

    Best regards,
    Carl Richard

Reply Children
Related