Hi,

Background

I’m currently developing an application that would gather data from a couple of sensors and send them either via LTE or WiFi depending on the WiFi availability. I want to use WiFi in order to save as much LTE data as possible.
To make a prototype of the solution I bought nRF9160 Feather and nRF7002-EB.

Current Status

I’m using NCS version 2.6.2 (but I tried also on 2.5.3).
Currently I have developed a simple program to gather the data from the LIS2DH and print the data using serial logs, everything works fine.
Now I started to configure the WiFi and I followed the Nordic DevAcademy WiFi Fundamentals course and I added a simple WiFi configuration plus a code for WiFi shell provisioning.

Error

When I try to build the program, linker throws an error that section 'text' will not fit in region 'FLASH', region 'FLASH' overflowed by 351524 bytes.

Build log:

----- Installing platform NS -----
[448/462] Linking C executable zephyr\zephyr_pre0.elf
FAILED: zephyr/zephyr_pre0.elf zephyr/zephyr_pre0.map D:/test/app/build/circuitdojo_feather_nrf9160_ns/zephyr/zephyr_pre0.map
cmd.exe /C "cd . && C:\ncs\toolchains\cf2149caf2\opt\zephyr-sdk\arm-zephyr-eabi\bin\arm-zephyr-eabi-gcc.exe  -gdwarf-4 @CMakeFiles\zephyr_pre0.rsp -o zephyr\zephyr_pre0.elf  && cmd.exe /C "cd /D D:\test\app\build\circuitdojo_feather_nrf9160_ns\zephyr && C:\Users\Igor\.zephyrtools\cmake\cmake-3.22.0-windows-x86_64\bin\cmake.exe -E true""
c:/ncs/toolchains/cf2149caf2/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd.exe: zephyr\zephyr_pre0.elf section 'text' will not fit in region 'FLASH'
c:/ncs/toolchains/cf2149caf2/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd.exe: region 'FLASH' overflowed by 351524 bytes
collect2.exe: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.
FATAL ERROR: command exited with status 1: 'C:\Users\Igor\.zephyrtools\cmake\cmake-3.22.0-windows-x86_64\bin\cmake.EXE' --build 'D:\test\app\build\circuitdojo_feather_nrf9160_ns'

Taken steps

I’ve tried to disable all logging and it saved around 50 kB, still it showed region 'FLASH' overflowed by 300000 bytes.

I’ve tried to configure the partitions in overlay file (see it’s commented in appendix). This didn’t improve anything. Maybe I’ve done it wrong, I’m not sure. For now, I’m not thinking about the FOTA and I’m only using the ns version, so I thought that I should be able to just use one slot which could be using the whole FLASH available.

Conclusions

I guess it should fit in the flash without a problem but now I’m a bit stuck how to configure it properly.

Appendix

Overlay file

/ {
    aliases {
        gyro0 = &l3g4200;
        temp0 = &mlx90614;
        acoustic0 = &inmp441;
    };

    nordic_wlan0: nordic_wlan0 {
            compatible = "nordic,wlan0";
            status = "okay";
    };

    chosen {
        zephyr,wifi = &nordic_wlan0;
    };

    nrf70_tx_power_ceiling: nrf70_tx_power_ceiling_node {
        status = "okay";
        compatible = "nordic,nrf700x-tx-power-ceiling";
        max-pwr-2g-dsss = <0x54>;
        max-pwr-2g-mcs0 = <0x40>;
        max-pwr-2g-mcs7 = <0x40>;
        max-pwr-5g-low-mcs0 = <0x34>;
        max-pwr-5g-low-mcs7 = <0x34>;
        max-pwr-5g-mid-mcs0 = <0x34>;
        max-pwr-5g-mid-mcs7 = <0x34>;
        max-pwr-5g-high-mcs0 = <0x30>;
        max-pwr-5g-high-mcs7 = <0x30>;
    };
};

&pinctrl {
    i2s0_default: i2s0_default {
        group1 {
            psels = <NRF_PSEL(I2S_SCK_M, 0, 15)>,
                    <NRF_PSEL(I2S_SDIN, 0, 14)>,
                    <NRF_PSEL(I2S_LRCK_M, 0, 13)>;
        };
    };

    i2s0_sleep: i2s0_sleep {
        group1 {
            psels = <NRF_PSEL(I2S_SCK_M, 0, 15)>,
                    <NRF_PSEL(I2S_SDIN, 0, 14)>,
                    <NRF_PSEL(I2S_LRCK_M, 0, 13)>;
            low-power-enable;
        };
    };

    spi2_default: spi2_default {
        group1 {
            psels = <NRF_PSEL(SPIM_SCK, 0, 19)>,
                    <NRF_PSEL(SPIM_MOSI, 0, 21)>,
                    <NRF_PSEL(SPIM_MISO, 0, 22)>;
        };
    };

    spi2_sleep: spi2_sleep {
        group1 {
            psels = <NRF_PSEL(SPIM_SCK, 0, 19)>,
                    <NRF_PSEL(SPIM_MOSI, 0, 21)>,
                    <NRF_PSEL(SPIM_MISO, 0, 22)>;
            low-power-enable;
        };
    };
};

&i2c1 {
    mlx90614: mlx90614@5A {
        compatible = "i2c-device";
        status = "okay";
        reg = <0x5A>;
        label = "MLX90614";
    };

    l3g4200: l3g4200@D3 {
        compatible = "i2c-device";
        status = "okay";
        reg = <0xD3>;
        label = "L3G4200";
    };
};

&spi2 {
    compatible = "nordic,nrf-spim";
    status = "okay";
    cs-gpios = < &gpio0 1 GPIO_ACTIVE_LOW >;
    pinctrl-0 = <&spi2_default>;
    pinctrl-1 = <&spi2_sleep>;
    pinctrl-names = "default", "sleep";

    nrf700x: nrf7002@0 {
        compatible = "nordic,nrf700x-spi";
        reg = <0>;
        bucken-gpios = <&gpio0 0 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>;
        iovdd-ctrl-gpios = <&gpio0 0 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>;
        host-irq-gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>;
        spi-max-frequency = <DT_FREQ_M(8)>;
    };
};

&i2s0 {
    compatible = "nordic,nrf-i2s";
    status = "okay";
    pinctrl-0 = <&i2s0_default>;
    pinctrl-1 = <&i2s0_sleep>;
    pinctrl-names = "default", "sleep";

    inmp441: inmp441@0 {
        compatible = "i2s-device";
        status = "okay";
        reg = <0>;
    };
};

/* custom partitioning */
/*
/delete-node/ &slot0_partition;
/delete-node/ &slot0_ns_partition;
/delete-node/ &slot1_partition;
/delete-node/ &slot1_ns_partition;

&flash0 {
    partitions {
        compatible = "fixed-partitions";
        #address-cells = < 0x1 >;
        #size-cells = < 0x1 >;

        slot0_ns_partition: partition@10000 {
            label = "image-0-nonsecure";
            reg = < 0x10000 0xe0000 >;
        };
    };
};
*/

prj.conf

CONFIG_GPIO=y

# Enable Zephyr application to be booted by MCUboot
CONFIG_BOOTLOADER_MCUBOOT=y

##############################################
# COMMUNICATION
##############################################

# I2C (TWI)
CONFIG_I2C=y

# I2S
# CONFIG_I2S=y

##############################################
# NETWORK
##############################################

# WiFi
CONFIG_WIFI=y
CONFIG_WIFI_NRF700X=y
CONFIG_WPA_SUPP=y

###### WiFi PROVISIONING ######
CONFIG_WIFI_CREDENTIALS=y

# static provisioning
CONFIG_WIFI_CREDENTIALS_STATIC=n
# CONFIG_WIFI_CREDENTIALS_STATIC_SSID="<your_network_SSID>"
# CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="<your_network_password>"

# CLI provisioning
# enable shell provisioning
CONFIG_SHELL=y
CONFIG_WIFI_CREDENTIALS_SHELL=y
CONFIG_SHELL_STACK_SIZE=4400

###### NETWORKING MANAGEMENT API ######
CONFIG_NET_MGMT=y
CONFIG_NET_MGMT_EVENT=y
CONFIG_NET_MGMT_EVENT_INFO=y
CONFIG_NET_MGMT_EVENT_STACK_SIZE=4096
# enable connection manager
CONFIG_NET_CONNECTION_MANAGER=y
# automatic connection feature <net/wifi_mgmt_ext.h>
CONFIG_WIFI_MGMT_EXT=y

###### NETWORKING ######
# configure the Zephyr networking API
CONFIG_NETWORKING=y
CONFIG_NET_NATIVE=y
CONFIG_NET_SOCKETS=y
CONFIG_NET_L2_ETHERNET=y
CONFIG_NET_IPV6=n
CONFIG_NET_IPV4=y
CONFIG_NET_DHCPV4=y

##############################################
# EXTERNAL DEVICES
##############################################

CONFIG_SENSOR=y

###### ACCELEROMETER ######
CONFIG_LIS2DH=y
#CONFIG_LIS2DH_TRIGGER_GLOBAL_THREAD=y

##############################################
# DEBUGGING
##############################################

###### LOGGING ######
CONFIG_CONSOLE=y
CONFIG_LOG=y

CONFIG_NEWLIB_LIBC=y
CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y

    The WiFi stack takes up a ton of space. You can set up MCUBoot to use the external flash to give you more space.

    Let me know if you want more info here.

    As they come out with new releases I’m sure Nordic will optimize the size as well.

      Yeah, I was thinking about it. So, can Zephyr run from external flash? That would be a nice solution for now.

      As the second scenario, I’m thinking to move the main application to nRF5340 maybe, as this would also give me a Bluetooth which probably I would also need in the future. It looks like the nRF7002-DK is based on it. But then I also don’t know how much space the Bluetooth and Cellular take, so any tips considering running from external flash would be nice.

        istefanski Yeah, I was thinking about it. So, can Zephyr run from external flash? That would be a nice solution for now.

        Sort of. Right now the internal flash is split in two (two partitions of 512 kB each) When you want to update the device it will load the new image to the unused partition and reconfigure the bootloader to load from that slot. This would effectively move your second “slot” to external flash. The only difference is that the binary firmware in the external flash will be copied over to the device flash once verified. It allows you to run applications up to 1MB in size.

        You will need a programmer to make modifications to the bootloader for this though.

        You’ll need these entries in your .conf:

        # SPI Flash
        CONFIG_SPI=y
        CONFIG_SPI_NOR=y
        CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
        CONFIG_SPI_NOR_SFDP_RUNTIME=y
        
        # Enable flash operations.
        CONFIG_FLASH=y
        CONFIG_FLASH_MAP=y
        CONFIG_FLASH_PAGE_LAYOUT=y
        
        # Enable the LittleFS file system.
        CONFIG_FILE_SYSTEM=y
        CONFIG_FILE_SYSTEM_LITTLEFS=y

        Most importantly you’ll need:

        CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y

        This will tell Nordic’s partition manager to configure the bootloader and application to use external flash as the second slot.

        I recommend a Raspberry Pi Debug Probe for a programmer. I have a programming jig that I will be releasing shortly that works with boards that don’t have headers. You’ll need a Tag Connect connector otherwise for external programming on the current design.

          Terms and Conditions | Privacy Policy