LittleFS External Configuration



Hello Support Team,

I hope this message finds you well.

I've been experimenting with the LittleFS sample available at the following link: LittleFS Sample Code. The sample works flawlessly with internal memory. However, after integrating it into my project, I made a few modifications to better suit my needs:

  • Utilized the MCU
  • Implemented external flash
  • Enabled BLE functionality

Despite my efforts, I am encountering issues with incorrect partition information for the LittleFS storage. Here are the details of my current configuration:

I found various article but no solution and also i see wrong partition information 

littlefs_storage:
  address: 0x00700000
  end_address: 0x00800000
  placement:
    before:
      - end
  region: external_flash
  size: 0x00100000

// To get started, press Ctrl+Space (or Option+Esc) to bring up the completion menu and view the available nodes.

// You can also use the buttons in the sidebar to perform actions on nodes.
// Actions currently available include:

// * Enabling / disabling the node
// * Adding the bus to a bus
// * Removing the node
// * Connecting ADC channels

// For more help, browse the DeviceTree documentation at https://docs.zephyrproject.org/latest/guides/dts/index.html
// You can also visit the nRF DeviceTree extension documentation at https://nrfconnect.github.io/vscode-nrf-connect/devicetree/nrfdevicetree.html


/ {
	zephyr,user {
		io-channels = <&adc 0>;
	};
};


&comp {
	compatible = "nordic,nrf-lpcomp";
	status = "okay";
};
&adc {
	#address-cells = <1>;
	#size-cells = <0>;
    status ="okay";

	channel@0 {
		reg = <0>;
		zephyr,gain = "ADC_GAIN_1_6";
		zephyr,reference = "ADC_REF_INTERNAL";
		zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
		zephyr,input-positive = <NRF_SAADC_AIN2>; 
	};
	channel@1 {
		reg = <1>;
		zephyr,gain = "ADC_GAIN_1_6";
		zephyr,reference = "ADC_REF_INTERNAL";
		zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
		zephyr,input-positive = <NRF_SAADC_AIN3>;
	};
     // Channel 2 - Used for manual battery power reading
     channel@2 {
	 	reg = <2>;
	 	zephyr,gain = "ADC_GAIN_1_6";
	 	zephyr,reference = "ADC_REF_INTERNAL";
	 	zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
	 	zephyr,input-positive = <NRF_SAADC_AIN7>;
	 };
    
};

/ {
    aliases {
        sw0 = &button1;
        led0 = &green_led;
        spi-flash0 = &is25lp064a;
        adc0 = &adc;
    };
    
    chosen {
        zephyr,extflash = &is25lp064a;
		nordic,pm-ext-flash = &is25lp064a;
		zephyr,settings-partition = &settings_partition;
    };

    buttons {
        compatible = "gpio-keys";
        button1: button_1 {
            gpios = <&gpio1 1 GPIO_PULL_UP>;
            label = "Push button switch 1";
        };
    };
};


&qspi {
	pinctrl-0 = <&qspi_default>;
	pinctrl-1 = <&qspi_sleep>;
	pinctrl-names = "default", "sleep";
	is25lp064a: is25lp064a@0 {
		compatible = "nordic,qspi-nor";
		reg = <0>;
		//writeoc = "pp4io";
		//readoc = "read4io";
		sck-frequency = <133000000>;
		jedec-id = [9d 60 17];
		size = <8388608>; //8 MB or DT_SIZE_M(8)
        partitions {
            compatible = "fixed-partitions";
            #address-cells = <1>;
            #size-cells = <1>;
		ext_partition: partition@0 {
			label = "image-ext";
			reg = <0x00000000 0x00700000>; //7 MB
		};
		lfs1_partition: partition@700000 {
			label = "lfs1";
			reg = <0x00700000 0x00100000>; // 1 MB
		};
    };

	};
};

&pinctrl {
    qspi_default: qspi_default {
        group1 {
            psels = <NRF_PSEL(QSPI_SCK,1, 4)>,    // SCK
                    <NRF_PSEL(QSPI_CSN,0, 26)>,    // CSN
                    <NRF_PSEL(QSPI_IO0,0, 30)>,    // IO0
                    <NRF_PSEL(QSPI_IO1,0, 29)>,    // IO1
                    <NRF_PSEL(QSPI_IO2,0, 28)>,    // IO2
                    <NRF_PSEL(QSPI_IO3,1, 2)>;    // IO3
        };
    };
    qspi_sleep: qspi_sleep {
        group1 {
            psels = <NRF_PSEL(QSPI_SCK,1, 4)>,    // SCK
                    <NRF_PSEL(QSPI_CSN,0, 26)>,    // CSN
                    <NRF_PSEL(QSPI_IO0,0, 30)>,    // IO0
                    <NRF_PSEL(QSPI_IO1,0, 29)>,    // IO1
                    <NRF_PSEL(QSPI_IO2,0, 28)>,    // IO2
                    <NRF_PSEL(QSPI_IO3,1, 2)>;    // IO3
        };
    };
};

&is25lp064a {
    address-size-32;
};


/ {
	fstab {
		compatible = "zephyr,fstab";
		lfs1: lfs1 {
			compatible = "zephyr,fstab,littlefs";
			read-size = <16>; //64
			prog-size = <16>;//64
			cache-size = <64>;
			lookahead-size = <32>; //128
			block-cycles = <512>; //1024
			partition = <&lfs1_partition>;
			mount-point = "/lfs1";
			automount;
		};
	};
};


/delete-node/ &storage_partition;

&flash0 {

	partitions {
		compatible = "fixed-partitions";
		#address-cells = <1>;
		#size-cells = <1>;

		boot_partition: partition@0 {
			label = "mcuboot";
			reg = <0x00000000 0x0000C000>;
		};
		slot0_partition: partition@c000 {
			label = "image-0";
			reg = <0x0000C000 0x00067000>;
		};
		slot1_partition: partition@73000 {
			label = "image-1";
			reg = <0x00073000 0x00067000>;
		};
		scratch_partition: partition@da000 {
			label = "image-scratch";
			reg = <0x000da000 0x0001e000>;
		};

		/*
		 * The flash starting at 0x000f8000 and ending at
		 * 0x000fffff is reserved for use by the application.
		 */

		/*
		 * Storage partition will be used by FCB/LittleFS/NVS
		 * if enabled.
		 */
		settings_partition: partition@f8000 {
			label = "settings";
			reg = <0x000f8000 0x00008000>; 
		};
	};
};

my code 

#define ARCHIVE_FILE_PATH "/lfs1/archive.dat"
#define PARTITION_NODE DT_NODELABEL(lfs1)

#if DT_NODE_EXISTS(PARTITION_NODE)
FS_FSTAB_DECLARE_ENTRY(PARTITION_NODE);
#else /* PARTITION_NODE */
FS_LITTLEFS_DECLARE_DEFAULT_CONFIG(storage);
static struct fs_mount_t lfs_storage_mnt = {
	.type = FS_LITTLEFS,
	.fs_data = &storage,
	.storage_dev = (void *)FIXED_PARTITION_ID(storage_partition),
	.mnt_point = "/lfs",
};
#endif /* PARTITION_NODE */

	struct fs_mount_t *mp =
#if DT_NODE_EXISTS(PARTITION_NODE)
		&FS_FSTAB_ENTRY(PARTITION_NODE)
#else
		&lfs_storage_mnt
#endif
		;

int data_archive_init(void) {
    

    	/* Do not mount if auto-mount has been enabled */
#if !DT_NODE_EXISTS(PARTITION_NODE) ||						\
	!(FSTAB_ENTRY_DT_MOUNT_FLAGS(PARTITION_NODE) & FS_MOUNT_FLAG_AUTOMOUNT)
	int rc = fs_mount(mp);
	if (rc < 0) {
		LOG_ERR("FAIL: mount id %" PRIuPTR " at %s: %d\n",
		       (uintptr_t)mp->storage_dev, mp->mnt_point, rc);
		return rc;
	}
	LOG_INF("%s mount: %d\n", mp->mnt_point, rc);
#else
	LOG_INF("%s automounted\n", mp->mnt_point);
#endif


    LOG_INF("Filesystem mounted successfully");
    return 0;
}

output

Issues Encountered:

  1. Enabling Bluetooth in the LittleFS sample app causes the LittleFS to NOT use external flash.*
  2. Problems with binding external flash (external flash + SPI + OTA). **

I have scoured through various articles, the Zephyr documentation, and forums, including Discord, but have yet to find a viable solution.

Could you please provide guidance or suggestions on resolving these issues?

Enabling Bluetooth to the Littlefs sample app will make the littlefs **NOT** use external flash. 

** External Flash get binding is Issue. (external flash + spi + OTA)  

  • Could it be that there is something wrong with my flash config. 

    with normal flash access everything is working. 
    when i change to littlefs the mounting breaks. 

    &qspi {
    	pinctrl-0 = <&qspi_default>;
    	pinctrl-1 = <&qspi_sleep>;
    	pinctrl-names = "default", "sleep";
    	is25lp064a: is25lp064a@0 {
    		compatible = "nordic,qspi-nor";
    		reg = <0>;
    		writeoc = "pp4io";
    		readoc = "read4io";
    		sck-frequency = <8000000>;
    		jedec-id = [9d 60 17];
    		size = <8388608>; //8 MB or DT_SIZE_M(8)
    	};
    };
    
    &pinctrl {
        qspi_default: qspi_default {
            group1 {
                psels = <NRF_PSEL(QSPI_SCK,1, 4)>,    // SCK
                        <NRF_PSEL(QSPI_CSN,0, 26)>,    // CSN
                        <NRF_PSEL(QSPI_IO0,0, 30)>,    // IO0
                        <NRF_PSEL(QSPI_IO1,0, 29)>,    // IO1
                        <NRF_PSEL(QSPI_IO2,0, 28)>,    // IO2
                        <NRF_PSEL(QSPI_IO3,1, 2)>;    // IO3
            };
        };
        qspi_sleep: qspi_sleep {
            group1 {
                psels = <NRF_PSEL(QSPI_SCK,1, 4)>,    // SCK
                        <NRF_PSEL(QSPI_CSN,0, 26)>,    // CSN
                        <NRF_PSEL(QSPI_IO0,0, 30)>,    // IO0
                        <NRF_PSEL(QSPI_IO1,0, 29)>,    // IO1
                        <NRF_PSEL(QSPI_IO2,0, 28)>,    // IO2
                        <NRF_PSEL(QSPI_IO3,1, 2)>;    // IO3
            };
        };
    };
    
    &is25lp064a {
        address-size-32;
    };

    Is there a way to debug this further?

    I just try all option form this post!

     Unable to use LittleFS on External Flash on nrf9160 

  • &is25lp064a {
    address-size-32;
    };
    was the issue and no custom storagenames (default works without pm_static)

Related