Unable to mount fat FS using external partition manager using pm_static.yml file

Hi,

I am trying to mount Fat FS using pm_static.yml instead of devicetree overlay fixed partition. I can generate a memory report, but when I try to mount file system I get the following mount errors. 

Errors:

winbondw25q02@0 SPI flash testing
==========================

Perform test on single sector
Test 1: Flash erase
*** Booting nRF Connect SDK v2.7.0-5cb85570ca43 ***
*** Using Zephyr OS v3.6.99-100befc70c74 ***
[00:00:00.257,232] <err> usb_msc: Storage init ERROR !!!! - Aborting USB init
Flash erase succeeded!

Test 2: Flash write
Attempting to write zu bytes
Data read matches data written. Good!!
[00:00:00.380,065] <err> fs: fs mount error (-5)
Error mounting FATFS: -5. Formatting now...
[00:00:00.380,126] <err> fs: fs not mounted (mp == 0x200000d0)
Error unmounting FATFS: -22
Error formatting FATFS: 3
[00:00:00.380,218] <err> fs: fs mount error (-5)
Error mounting FATFS after formatting: -5
[00:00:00.380,249] <err> fs: mount point not found!!
[00:00:00.380,279] <err> flash_test: Failed to open file /NAND:/test.txt (err: -2)
[00:00:00.380,279] <err> fs: mount point not found!!
[00:00:00.380,310] <err> flash_test: Failed to open file /NAND:/test.txt (err: -2)
[00:00:00.380,401] <dbg> flash_test: enable_usb_device: USB mass storage enabled
[00:00:00.380,432] <inf> flash_test: USB mass storage enabled.

Prj.Conf

# Copyright (c) 2018 Nordic Semiconductor
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

# Enable the UART driver
CONFIG_UART_ASYNC_API=y
CONFIG_NRFX_UARTE0=y

# print
CONFIG_NEWLIB_LIBC=y
CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y

# I2C
CONFIG_I2C=y
CONFIG_I2C_NRFX=y
CONFIG_NRFX_TWIM1=y
CONFIG_NFCT_PINS_AS_GPIOS=y

#SPI
CONFIG_SPI=y
CONFIG_SPI_ASYNC=y
CONFIG_SPI_SLAVE=y

CONFIG_HEAP_MEM_POOL_SIZE=2048
# Enable DK LED and Buttons library
CONFIG_DK_LIBRARY=y
CONFIG_STDOUT_CONSOLE=y

#USB related configs
CONFIG_USB_DEVICE_STACK=y
CONFIG_USB_DEVICE_PRODUCT="Zephyr MSC sample"
CONFIG_USB_DEVICE_PID=0x0008
CONFIG_LOG=y
CONFIG_USB_DRIVER_LOG_LEVEL_ERR=y
CONFIG_USB_MASS_STORAGE=y
CONFIG_USB_DEVICE_LOG_LEVEL_ERR=y
CONFIG_USB_MASS_STORAGE_LOG_LEVEL_ERR=y
CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n
CONFIG_APP_MSC_STORAGE_FLASH_FATFS=y
CONFIG_MAIN_STACK_SIZE=10240
CONFIG_FILE_SYSTEM=y
CONFIG_FILE_SYSTEM_LITTLEFS=n

CONFIG_SPI_NOR=y
CONFIG_FLASH_JESD216_API=y
CONFIG_SPI_NRFX=y
CONFIG_SPI_NOR_IDLE_IN_DPD=y

#FLASH Config ##############################################
CONFIG_DISK_ACCESS=y
CONFIG_FAT_FILESYSTEM_ELM=y
CONFIG_FS_FATFS_LFN=y

CONFIG_FLASH=y
CONFIG_FLASH_MAP=y
CONFIG_FLASH_LOG_LEVEL_ERR=y
CONFIG_MPU_ALLOW_FLASH_WRITE=y
CONFIG_DISK_DRIVER_FLASH=y
CONFIG_PM_OVERRIDE_EXTERNAL_DRIVER_CHECK=y

overlay file:

/ {
	chosen {
		nordic,pm-ext-flash = &winbond;
	};
};

/* Disable conflicting buttons and UART */
&button2 {
	status = "disabled";
};

&button3 {
	status = "disabled";
};

&gpio_fwd {
	status = "disabled";
};

&pinctrl {
		spi_master_default: spi_master_default {
				group1 {
						psels = <NRF_PSEL(SPIM_SCK, 0, 2)>,
										<NRF_PSEL(SPIM_MOSI, 0, 9)>,
										<NRF_PSEL(SPIM_MISO, 0, 3)>;
				};
		};

		spi_master_sleep: spi_master_sleep {
				group1 {
						psels = <NRF_PSEL(SPIM_SCK, 0, 2)>,
										<NRF_PSEL(SPIM_MOSI, 0, 9)>,
										<NRF_PSEL(SPIM_MISO, 0, 3)>;
						low-power-enable;
				};
		};
};

&spi4 {
		compatible = "nordic,nrf-spim";
		pinctrl-0 = <&spi_master_default>;
		pinctrl-1 = <&spi_master_sleep>;
		pinctrl-names = "default", "sleep";
		cs-gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;	
		status = "okay";
		winbond:winbondw25q02@0 {
			compatible = "jedec,spi-nor";
			reg = <0>;
			spi-max-frequency = <32000000>;
			jedec-id = [ ef 70 22 ];
			size = <268435456>;
			has-dpd;
		};
};

pm_static.yml and memory report

app:
  address: 0x00010200
  end_address: 0x00E4000
  region: flash_primary
  size: 0x00D3E00

external_flash:
  address: 0x00000000
  device: DT_CHOSEN(nordic_pm_ext_flash)
  end_address: 0x10000000  # 256MB
  region: external_flash
  size: 0x10000000

mcuboot:
  address: 0x00000000
  end_address: 0x00010000
  region: flash_primary
  size: 0x00010000

mcuboot_pad:
  address: 0x00010000
  end_address: 0x00010200
  region: flash_primary
  size: 0x00000200

mcuboot_primary:
  address: 0x00010000
  end_address: 0x00E4000
  orig_span: &id001
    - mcuboot_pad
    - app
  region: flash_primary
  size: 0x00D4000
  span: *id001

mcuboot_secondary:
  address: 0x00000000
  device: DT_CHOSEN(nordic_pm_ext_flash)
  end_address: 0x00D4000
  region: external_flash
  size: 0x00D4000

mcuboot_secondary_1:
  address: 0x00D4000
  device: DT_CHOSEN(nordic_pm_ext_flash)
  end_address: 0x0114000
  region: external_flash
  size: 0x0040000

EMPTY_1:
  address: 0x0114000
  device: DT_CHOSEN(nordic_pm_ext_flash)
  end_address: 0x0120000
  region: external_flash
  size: 0x000C000

mcuboot_primary_2:
  address: 0x0120000
  device: DT_CHOSEN(nordic_pm_ext_flash)
  end_address: 0x0160000
  region: external_flash
  size: 0x0040000

mcuboot_secondary_2:
  address: 0x0160000
  device: DT_CHOSEN(nordic_pm_ext_flash)
  end_address: 0x01A0000
  region: external_flash
  size: 0x0040000

storage_partition:
  address: 0x01A0000  # Start of FATFS storage partition after mcuboot_secondary_2
  device: DT_CHOSEN(nordic_pm_ext_flash)
  end_address: 0x10000000  # End of storage partition (remaining memory)
  region: external_flash
  size: 0x0FE50000  # Remaining memory for storage (260416KB or approx 254MB)
  type: storage

msc_disk0:
  address: 0x01A0000  # Place MSC Disk inside storage_partition
  device: DT_CHOSEN(nordic_pm_ext_flash)
  end_address: 0x01B0000  # 0x01A0000 + 0x10000 (64KB for disk with cache)
  region: storage_partition  
  type: cache
  cache_size: 0x10000  # 64KB cache size
  disk_name: "NAND"
 external_flash (0x10000000 - 262144kB):
+----------------------------------------------------+
| 0x0: external_flash (0x10000000 - 262144kB)        |
| 0x0: mcuboot_secondary (0xd4000 - 848kB)           |
| 0xd4000: mcuboot_secondary_1 (0x40000 - 256kB)     |
| 0x114000: EMPTY_1 (0xc000 - 48kB)                  |
| 0x120000: mcuboot_primary_2 (0x40000 - 256kB)      |
| 0x160000: mcuboot_secondary_2 (0x40000 - 256kB)    |
| 0x1a0000: storage_partition (0xfe50000 - 260416kB) |
+----------------------------------------------------+

  flash_primary (0x100000 - 1024kB):
+----------------------------------------------+
| 0x0: mcuboot (0x10000 - 64kB)                |
+---0x10000: mcuboot_primary (0xd4000 - 848kB)-+
| 0x10000: mcuboot_pad (0x200 - 512B)          |
| 0x10200: app (0xefe00 - 959kB)               |
+----------------------------------------------+

  otp (0x2fc - 764B):
+------------------------------+
| 0xff8100: otp (0x2fc - 764B) |
+------------------------------+

  sram_primary (0x80000 - 512kB):
+--------------------------------------------+
| 0x20000000: sram_primary (0x80000 - 512kB) |
+--------------------------------------------+

main.c

#include <sample_usbd.h>
#include <zephyr/kernel.h>
#include <zephyr/drivers/flash.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <stdio.h>
#include <string.h>
#include <zephyr/fs/fs.h>
#include <zephyr/storage/disk_access.h>
#include <zephyr/logging/log.h>
#include <ff.h>  // FATFS definition
#include <zephyr/usb/usb_device.h>
#include <zephyr/usb/usbd.h>
#include <zephyr/usb/class/usbd_msc.h>

#define STORAGE_PARTITION		storage_partition
#define STORAGE_PARTITION_ID		DEVICE_DT_GET(DT_CHOSEN_nordic_pm_ext_flash)

LOG_MODULE_REGISTER(flash_test, LOG_LEVEL_DBG);

#if defined(CONFIG_BOARD_ADAFRUIT_FEATHER_STM32F405)
#define SPI_FLASH_TEST_REGION_OFFSET 0xf000
#else
#define SPI_FLASH_TEST_REGION_OFFSET 0xff000
#endif

#define SPI_FLASH_SECTOR_SIZE 4096
#define FATFS_MOUNT_POINT "/NAND:"
static FATFS fat_fs;

static struct fs_mount_t fatfs_mount = {
    .type = FS_FATFS,
    .fs_data = &fat_fs,
    .mnt_point = FATFS_MOUNT_POINT,
};

// Define a LUN for USB MSC (similar to your original code)
USBD_DEFINE_MSC_LUN(NAND, "Zephyr", "FlashDisk", "0.00");

// Declare the "erased" array
const uint8_t erased[] = { 0xff, 0xff, 0xff, 0xff };

// Function to enable USB device for mass storage
static int enable_usb_device(void)
{
    int err = usb_enable(NULL);  // Use standard Zephyr USB enable function
    if (err != 0) {
        LOG_ERR("Failed to enable USB device support: %d", err);
        return err;
    }
    LOG_DBG("USB mass storage enabled");
    return 0;
}

void format_fatfs(void)
{
    struct fs_mount_t *mp = &fatfs_mount;
    int res = fs_unmount(mp);  // Unmount before formatting
    if (res != 0) {
        printk("Error unmounting FATFS: %d\n", res);
    }

    MKFS_PARM fs_options = {
        .fmt = FM_FAT,  // FAT format
        .n_fat = 1,     // Number of FATs (1 or 2)
        .align = 0,     // Alignment (0 for default)
        .n_root = 0,    // Number of root directory entries (0 for default)
        .au_size = 0    // Allocation unit size (0 for default)
    };

    res = f_mkfs("", &fs_options, NULL, 0);  // Format the filesystem
    if (res == FR_OK) {
        printk("FATFS format successful.\n");
    } else {
        printk("Error formatting FATFS: %d\n", res);
    }
}

void mount_fatfs(void)
{
    int res = fs_mount(&fatfs_mount);
    if (res == 0) {
        printk("FATFS mounted successfully.\n");
    } else {
        printk("Error mounting FATFS: %d. Formatting now...\n", res);
        format_fatfs();  // Format the flash if mounting fails
        res = fs_mount(&fatfs_mount);  // Try to mount again after formatting
        if (res == 0) {
            printk("FATFS mounted successfully after formatting.\n");
        } else {
            printk("Error mounting FATFS after formatting: %d\n", res);
        }
    }
}

void create_write_file(const char *file_path)
{
    struct fs_file_t file;
    int res;

    fs_file_t_init(&file);
    res = fs_open(&file, file_path, FS_O_CREATE | FS_O_RDWR);
    if (res < 0) {
        LOG_ERR("Failed to open file %s (err: %d)", file_path, res);
        return;
    }

    const char *sample_data = "Hello FATFS on SPI Flash!";
    res = fs_write(&file, sample_data, strlen(sample_data));
    if (res < 0) {
        LOG_ERR("Failed to write to file %s (err: %d)", file_path, res);
        fs_close(&file);
        return;
    }

    fs_close(&file);
    printk("File write successful!\n");
}

void read_file(const char *file_path)
{
    struct fs_file_t file;
    int res;
    char buffer[64];

    fs_file_t_init(&file);
    res = fs_open(&file, file_path, FS_O_READ);
    if (res < 0) {
        LOG_ERR("Failed to open file %s (err: %d)", file_path, res);
        return;
    }

    printk("Reading file content:\n");
    while ((res = fs_read(&file, buffer, sizeof(buffer) - 1)) > 0) {
        buffer[res] = '\0';  // Null-terminate the read data
        printk("%s", buffer);  // Print to console
    }

    fs_close(&file);
}

void single_sector_test(const struct device *flash_dev)
{
    const uint8_t expected[] = {0x55, 0xaa, 0x66, 0x99};
    const size_t len = sizeof(expected);
    uint8_t buf[sizeof(expected)];
    int rc;

    printf("\nPerform test on single sector\n");
    printf("Test 1: Flash erase\n");

    rc = flash_erase(flash_dev, SPI_FLASH_TEST_REGION_OFFSET, SPI_FLASH_SECTOR_SIZE);
    if (rc != 0) {
        printf("Flash erase failed! %d\n", rc);
    } else {
        memset(buf, 0, len);
        rc = flash_read(flash_dev, SPI_FLASH_TEST_REGION_OFFSET, buf, len);
        if (rc != 0) {
            printf("Flash read failed! %d\n", rc);
            return;
        }
        if (memcmp(erased, buf, len) != 0) {
            printf("Flash erase failed at offset 0x%x got 0x%x\n",
                SPI_FLASH_TEST_REGION_OFFSET, *(uint32_t *)buf);
            return;
        }
        printf("Flash erase succeeded!\n");
    }

    printf("\nTest 2: Flash write\n");

    printf("Attempting to write %zu bytes\n", len);
    rc = flash_write(flash_dev, SPI_FLASH_TEST_REGION_OFFSET, expected, len);
    if (rc != 0) {
        printf("Flash write failed! %d\n", rc);
        return;
    }

    memset(buf, 0, len);
    rc = flash_read(flash_dev, SPI_FLASH_TEST_REGION_OFFSET, buf, len);
    if (rc != 0) {
        printf("Flash read failed! %d\n", rc);
        return;
    }

    if (memcmp(expected, buf, len) == 0) {
        printf("Data read matches data written. Good!!\n");
    } else {
        printf("Data read does not match data written!!\n");
    }
}

void winbond_begin(void)
{
    const struct device *flash_dev = DEVICE_DT_GET(DT_CHOSEN(nordic_pm_ext_flash));

    if (!device_is_ready(flash_dev)) {
        printk("%s: device not ready.\n", flash_dev->name);
        return;
    }

    printf("\n%s SPI flash testing\n", flash_dev->name);
    printf("==========================\n");

    // Perform a sector test to ensure flash is working
    single_sector_test(flash_dev);

    // Mount the FATFS file system or format if necessary
    mount_fatfs();

    // Perform file operations (create and read a file)
    const char *file_path = FATFS_MOUNT_POINT "/test.txt";
    create_write_file(file_path);
    read_file(file_path);

    // Enable USB for mass storage
    int usb_err = enable_usb_device();
    if (usb_err == 0) {
        LOG_INF("USB mass storage enabled.");
    } else {
        LOG_ERR("Failed to enable USB mass storage.");
    }
}

regards,

Barsha

Parents
  • Hi

    How are you powering the SD card/reader on your end. The VDD on the nRF5340 DK is too low for some SD cards, so you can try using a 3.3V external power source and see if that changes anything.

    Are you using any of the Filesystem samples available in Zephyr as a template here or have you developed this project yourself? https://docs.nordicsemi.com/bundle/ncs-latest/page/zephyr/samples/subsys/fs/fs.html File systems documentation can also be found here: https://docs.nordicsemi.com/bundle/ncs-latest/page/zephyr/services/file_system/index.html 

    If you're not able to get anywhere, try finding out what function in your project is returning this error 5 when running. Error message 5 points to an I/O error, so my first guess would be that the power source isn't suficient, if not it is likely due to how the SD card is connected to the nRF5340 or that the pins used for communicating aren't set up correctly.

    Best regards,

    Simon

  • Hi Simonr,

    When I try to build the same code without this pm_static.yml and add fixed partition part in the overlay file I can mount the Fat FS into my winbond NOR storage and even write into it:

    overlay file:

     / {
    	chosen {
    		nordic,pm-ext-flash = &winbond;
    	};
    };
    
    /* Disable conflicting buttons and UART */
    &button2 {
    	status = "disabled";
    };
    
    &button3 {
    	status = "disabled";
    };
    
    &gpio_fwd {
    	status = "disabled";
    };
    
    &pinctrl {
    		spi_master_default: spi_master_default {
    				group1 {
    						psels = <NRF_PSEL(SPIM_SCK, 0, 2)>,
    										<NRF_PSEL(SPIM_MOSI, 0, 9)>,
    										<NRF_PSEL(SPIM_MISO, 0, 3)>;
    				};
    		};
    
    		spi_master_sleep: spi_master_sleep {
    				group1 {
    						psels = <NRF_PSEL(SPIM_SCK, 0, 2)>,
    										<NRF_PSEL(SPIM_MOSI, 0, 9)>,
    										<NRF_PSEL(SPIM_MISO, 0, 3)>;
    						low-power-enable;
    				};
    		};
    };
    
    &spi4 {
    		compatible = "nordic,nrf-spim";
    		pinctrl-0 = <&spi_master_default>;
    		pinctrl-1 = <&spi_master_sleep>;
    		pinctrl-names = "default", "sleep";
    		cs-gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;	
    		status = "okay";
    		winbond:winbondw25q02@0 {
    			compatible = "jedec,spi-nor";
    			reg = <0>;
    	//      irq-gpios = <&gpio0 21 0>;
    			spi-max-frequency = <32000000>;
    			//label = "WINBOND";
    			jedec-id = [ ef 70 22 ];
    			size = <0x10000000>;
    			has-dpd;
    			// sfdp-bfp = [
    		 	// 	e5 20 f1 ff  ff ff ff 03  44 eb 08 6b  08 3b 04 bb
    		 	// 	ee ff ff ff  ff ff 00 ff  ff ff 00 ff  0c 20 0f 52
    		 	// 	10 d8 00 ff  23 72 f5 00  82 ed 04 cc  44 83 68 44
    		 	// 	30 b0 30 b0  f7 c4 d5 5c  00 be 29 ff  f0 d0 ff ff
    		 	// ];
    		};
    };
    
    /delete-node/ &storage_partition;
    
    &winbond {
    	partitions {
    		compatible = "fixed-partitions";
    		#address-cells = <1>;
    		#size-cells = <1>;
    
    		storage_partition: partition@0 {
    			label = "storage";
    			reg = <0x00000000 0x01000000>;
    		};
    	};
    };
    
    / {
    	msc_disk0 {
    		compatible = "zephyr,flash-disk";
    		partition = <&storage_partition>;
    		disk-name = "NAND";
    		cache-size = <65536>;
    	};
    };

    output terminal:

    winbondw25q02@0 SPI flash testing
    ==========================
    
    Perform test on single sector
    Test 1: Flash erase
    *** Booting nRF Connect SDK v2.7.0-5cb85570ca43 ***
    *** Using Zephyr OS v3.6.99-100befc70c74 ***
    Flash erase succeeded!
    
    Test 2: Flash write
    Attempting to write 4 bytes
    Data read matches data written. Good!!
    [00:00:00.378,845] <inf> flashdisk: Initialize device NAND
    [00:00:00.378,875] <inf> flashdisk: offset 0, sector size 512, page size 4096, volume size 16777216
    [00:00:00.386,016] <inf> flashdisk: Initialize device NAND
    [00:00:00.386,047] <inf> flashdisk: offset 0, sector size 512, page size 4096, volume size 16777216
    [00:00:01.456,390] <inf> flashdisk: Initialize device NAND
    [00:00:01.456,420] <inf> flashdisk: offset 0, sector size 512, page size 4096, volume size 16777216
    FATFS mounted successfully.
    File write successful!
    Reading file content:
    Hello FATFS on SPI Flash!
    


    But my application also requires bluetooth functionality, and when I add CONFIG_BT=y in project config, it says "partition manager enabled and all partitions of devicetree will now be ignored" and I get the following build error:


    C:/ncs/v2.7.0/zephyr/drivers/disk/flashdisk.c:484:1: error: return type defaults to 'int' [-Werror=implicit-int]
    484 | PM_FOREACH_AFFILIATED_TO_disk(DEFINE_FLASHDISKS_CACHE)
    | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~


    That is why I thought pm_static.yml would fix this problem, but its still the same. However, with CONFIG_BT=n I can at least build and generate the memory report but still cant mount.

Reply
  • Hi Simonr,

    When I try to build the same code without this pm_static.yml and add fixed partition part in the overlay file I can mount the Fat FS into my winbond NOR storage and even write into it:

    overlay file:

     / {
    	chosen {
    		nordic,pm-ext-flash = &winbond;
    	};
    };
    
    /* Disable conflicting buttons and UART */
    &button2 {
    	status = "disabled";
    };
    
    &button3 {
    	status = "disabled";
    };
    
    &gpio_fwd {
    	status = "disabled";
    };
    
    &pinctrl {
    		spi_master_default: spi_master_default {
    				group1 {
    						psels = <NRF_PSEL(SPIM_SCK, 0, 2)>,
    										<NRF_PSEL(SPIM_MOSI, 0, 9)>,
    										<NRF_PSEL(SPIM_MISO, 0, 3)>;
    				};
    		};
    
    		spi_master_sleep: spi_master_sleep {
    				group1 {
    						psels = <NRF_PSEL(SPIM_SCK, 0, 2)>,
    										<NRF_PSEL(SPIM_MOSI, 0, 9)>,
    										<NRF_PSEL(SPIM_MISO, 0, 3)>;
    						low-power-enable;
    				};
    		};
    };
    
    &spi4 {
    		compatible = "nordic,nrf-spim";
    		pinctrl-0 = <&spi_master_default>;
    		pinctrl-1 = <&spi_master_sleep>;
    		pinctrl-names = "default", "sleep";
    		cs-gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;	
    		status = "okay";
    		winbond:winbondw25q02@0 {
    			compatible = "jedec,spi-nor";
    			reg = <0>;
    	//      irq-gpios = <&gpio0 21 0>;
    			spi-max-frequency = <32000000>;
    			//label = "WINBOND";
    			jedec-id = [ ef 70 22 ];
    			size = <0x10000000>;
    			has-dpd;
    			// sfdp-bfp = [
    		 	// 	e5 20 f1 ff  ff ff ff 03  44 eb 08 6b  08 3b 04 bb
    		 	// 	ee ff ff ff  ff ff 00 ff  ff ff 00 ff  0c 20 0f 52
    		 	// 	10 d8 00 ff  23 72 f5 00  82 ed 04 cc  44 83 68 44
    		 	// 	30 b0 30 b0  f7 c4 d5 5c  00 be 29 ff  f0 d0 ff ff
    		 	// ];
    		};
    };
    
    /delete-node/ &storage_partition;
    
    &winbond {
    	partitions {
    		compatible = "fixed-partitions";
    		#address-cells = <1>;
    		#size-cells = <1>;
    
    		storage_partition: partition@0 {
    			label = "storage";
    			reg = <0x00000000 0x01000000>;
    		};
    	};
    };
    
    / {
    	msc_disk0 {
    		compatible = "zephyr,flash-disk";
    		partition = <&storage_partition>;
    		disk-name = "NAND";
    		cache-size = <65536>;
    	};
    };

    output terminal:

    winbondw25q02@0 SPI flash testing
    ==========================
    
    Perform test on single sector
    Test 1: Flash erase
    *** Booting nRF Connect SDK v2.7.0-5cb85570ca43 ***
    *** Using Zephyr OS v3.6.99-100befc70c74 ***
    Flash erase succeeded!
    
    Test 2: Flash write
    Attempting to write 4 bytes
    Data read matches data written. Good!!
    [00:00:00.378,845] <inf> flashdisk: Initialize device NAND
    [00:00:00.378,875] <inf> flashdisk: offset 0, sector size 512, page size 4096, volume size 16777216
    [00:00:00.386,016] <inf> flashdisk: Initialize device NAND
    [00:00:00.386,047] <inf> flashdisk: offset 0, sector size 512, page size 4096, volume size 16777216
    [00:00:01.456,390] <inf> flashdisk: Initialize device NAND
    [00:00:01.456,420] <inf> flashdisk: offset 0, sector size 512, page size 4096, volume size 16777216
    FATFS mounted successfully.
    File write successful!
    Reading file content:
    Hello FATFS on SPI Flash!
    


    But my application also requires bluetooth functionality, and when I add CONFIG_BT=y in project config, it says "partition manager enabled and all partitions of devicetree will now be ignored" and I get the following build error:


    C:/ncs/v2.7.0/zephyr/drivers/disk/flashdisk.c:484:1: error: return type defaults to 'int' [-Werror=implicit-int]
    484 | PM_FOREACH_AFFILIATED_TO_disk(DEFINE_FLASHDISKS_CACHE)
    | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~


    That is why I thought pm_static.yml would fix this problem, but its still the same. However, with CONFIG_BT=n I can at least build and generate the memory report but still cant mount.

Children
  • I have a similar setup on a custom PCB using nrf5340 with external flash chip.

    See  RE: DFU using USB file system (not serial emulation)? 

    in that thread is my pm_static.yml - btw I define staticallly all the partitions on the internal and external flash to ensure that future builds don't move them, and break mcuboot DFU...

    For mounting the FAT FS, I use the ELM FAT subsystem also. I don't actually do a mkfs at all, but it works...

    My init code (you'll need to replace my log_X calls...also I decided to call my fatfs flash area a different name to ensure no interaction with any other random code zephyr/nrf decide to pull in...)

    #include <zephyr/kernel.h>
    #include <zephyr/logging/log.h>
    #include <zephyr/usb/usb_device.h>
    #include <zephyr/usb/usbd.h>
    #include <zephyr/usb/class/usbd_msc.h>
    #include <zephyr/fs/fs.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    #include "util/wutils.h"
    
    #if CONFIG_DISK_DRIVER_FLASH
    #include <zephyr/storage/flash_map.h>
    #endif
    
    #if CONFIG_FAT_FILESYSTEM_ELM
    #include <ff.h>
    #endif
    
    #include "usb_fs.h"
    
    //#define STORAGE_PARTITION		storage_partition
    #define STORAGE_PARTITION		fatfs_storage
    #define STORAGE_PARTITION_ID		FIXED_PARTITION_ID(STORAGE_PARTITION)
    
    static struct fs_mount_t _fs_mnt;
    
    static int _erase_flash(unsigned int id) {
    	const struct flash_area *pfa;
    	int rc = -1;
    
    	rc = flash_area_open(id, &pfa);
    	if (rc<0) {
    		log_warn("Erasing flash area ... failed to open it (%d)",rc);
    		return rc;
    	}
    	log_warn("Opened flash area (%d) -> trying to erase it....",rc);
    	rc = flash_area_erase(pfa, 0, pfa->fa_size);
    	if (rc<0) {
    		log_warn("Erasing flash area ... failed! (%d)",rc);
    	} else {
    		log_warn("Erased flash area OK.");
    	}
    	flash_area_close(pfa);
    	return rc;
    }
    static int _setup_flash(unsigned int id, struct fs_mount_t *mnt)
    {
    	int rc = -1;
    #if CONFIG_DISK_DRIVER_FLASH
    	const struct flash_area *pfa;
    
    	mnt->storage_dev = (void *)id;
    	rc = flash_area_open(id, &pfa);
    	if (rc < 0) {
    		log_warn("Failed to open flash area (%d) -> trying to erase it....",rc);
    		rc = flash_area_erase(pfa, 0, pfa->fa_size);
    		if (rc<0) {
    			log_warn("Erasing flash area ... failed! (%d)",rc);
    			flash_area_close(pfa);
    			return rc;
    		} 
    		log_warn("Erased flash area OK.");
    		rc = flash_area_open(id, &pfa);
    		if (rc<0) {
    			log_warn("Erasing flash area ... didn't help, still can't open it! (%d)",rc);
    			flash_area_close(pfa);
    			return rc;
    		} 
    	}
    	log_info("Flash USB mass storage opened : area %u at 0x%x on %s for %u bytes\n",
    		id, (unsigned int)pfa->fa_off, pfa->fa_dev->name,
    		(unsigned int)pfa->fa_size);
    #endif
    	return pfa->fa_size;
    }
    
    static int _mount_app_fs(struct fs_mount_t *mnt, char* mnt_point)
    {
    	int rc;
    
    #if CONFIG_FAT_FILESYSTEM_ELM
    	static FATFS fat_fs;
    
    	mnt->type = FS_FATFS;
    	mnt->fs_data = &fat_fs;
    	mnt->mnt_point = mnt_point;
    #else
    	log_warn("no file system type defined in firmware build, no FS mount available.");
    	return -1;
    #endif
    	rc = fs_mount(mnt);
    
    	return rc;
    }
    
    static bool _setup_disk(struct fs_mount_t *mp, char* mnt_point) {
    	int rc;
    	int flash_partition_size = 0;
    	if (IS_ENABLED(CONFIG_DISK_DRIVER_FLASH)) {
    		// _erase_flash(STORAGE_PARTITION_ID);		// Only do this if created a FATFS on partition of wrong size initially...
    		flash_partition_size = _setup_flash(STORAGE_PARTITION_ID, mp);
    		if (flash_partition_size < 0) {
    			log_error("Failed to setup flash area");
    			return false;
    		}
    	} else {
    		log_error("No flash driver enabled");
    		return false;
    	}
    
    	if (!IS_ENABLED(CONFIG_FAT_FILESYSTEM_ELM)) {
    		log_error("No file system enabled");
    		return false;
    	}
    
    	rc = _mount_app_fs(mp, mnt_point);
    	if (rc < 0) {
    		log_error("Failed to mount filesystem on %s", mnt_point);
    		return false;
    	}
    	// If fatfs size is not the partition size, then we need to erase the partition and start again
    	struct fs_statvfs fvol;
    	rc = fs_statvfs(mnt_point, &fvol);
    	log_info("statvfs says block size %d, total blocks %d -> %u bytes volume size", fvol.f_blocks, fvol.f_frsize, fvol.f_blocks*fvol.f_frsize);
    	if (abs((fvol.f_blocks*fvol.f_frsize)-flash_partition_size)>100000) {		// approx
    		log_warn("File system size (%u) not equal to flash zone size (%u) -> wiping and reformatting", (fvol.f_blocks*fvol.f_frsize), flash_partition_size);
    		_erase_flash(STORAGE_PARTITION_ID);		// Only do this if created a FATFS on partition of wrong size initially...
    		// And redo?
    		// Need to close parition, unmountfs?
    		fs_unmount(mp);
    		flash_partition_size = _setup_flash(STORAGE_PARTITION_ID, mp);
    		rc = _mount_app_fs(mp, mnt_point);
    		if (rc < 0) {
    			log_error("Failed to mount filesystem on %s", mnt_point);
    			return false;
    		}
    	}
    	/* Allow log messages to flush to avoid interleaved output */
    	k_sleep(K_MSEC(50));
    
    	return true;
    }
    
    And then call during init phase:
    	if (_setup_disk(&_fs_mnt, "/NAND:")) {
    		log_info("USB mass storage mode enabled.\n");
    	} else {
        	log_warn("USB mass storage mode FS failed!");
        }

    Hopefully this will help you... it took me a while to get to this point...

  • Hi BrianW,

    Thank you so much for your response.

    I tried following your suggestion and now my code looks like this:
    main.c

    /*
     * Copyright (c) 2016 Intel Corporation.
     * Copyright (c) 2019-2020 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #include <sample_usbd.h>
    
    #include <zephyr/kernel.h>
    #include <zephyr/logging/log.h>
    #include <zephyr/usb/usb_device.h>
    #include <zephyr/usb/usbd.h>
    #include <zephyr/usb/class/usbd_msc.h>
    #include <zephyr/fs/fs.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    LOG_MODULE_REGISTER(main);
    
    #include <zephyr/storage/flash_map.h>
    #include <ff.h>
    
    #if CONFIG_FILE_SYSTEM_LITTLEFS
    #include <zephyr/fs/littlefs.h>
    FS_LITTLEFS_DECLARE_DEFAULT_CONFIG(storage);
    #endif
    
    #define STORAGE_PARTITION fatfs_storage
    #define STORAGE_PARTITION_ID FIXED_PARTITION_ID(STORAGE_PARTITION)
    
    static struct fs_mount_t _fs_mnt;
    
    #if defined(CONFIG_USB_DEVICE_STACK_NEXT)
    static struct usbd_context *sample_usbd;
    
    #if CONFIG_DISK_DRIVER_RAM
    USBD_DEFINE_MSC_LUN(RAM, "Zephyr", "RAMDisk", "0.00");
    #endif
    
    USBD_DEFINE_MSC_LUN(NAND, "Zephyr", "FlashDisk", "0.00");
    
    #if CONFIG_DISK_DRIVER_SDMMC
    USBD_DEFINE_MSC_LUN(SD, "Zephyr", "SD", "0.00");
    #endif
    
    static int enable_usb_device_next(void)
    {
    	int err;
    
    	sample_usbd = sample_usbd_init_device(NULL);
    	if (sample_usbd == NULL)
    	{
    		LOG_ERR("Failed to initialize USB device");
    		return -ENODEV;
    	}
    
    	err = usbd_enable(sample_usbd);
    	if (err)
    	{
    		LOG_ERR("Failed to enable device support");
    		return err;
    	}
    
    	LOG_DBG("USB device support enabled");
    
    	return 0;
    }
    #endif /* IS_ENABLED(CONFIG_USB_DEVICE_STACK_NEXT) */
    
    static int _erase_flash(unsigned int id)
    {
    	const struct flash_area *pfa;
    	int rc = -1;
    
    	rc = flash_area_open(id, &pfa);
    	if (rc < 0)
    	{
    		LOG_ERR("Erasing flash area ... failed to open it (%d)", rc);
    		return rc;
    	}
    	LOG_ERR("Opened flash area (%d) -> trying to erase it....", rc);
    	rc = flash_area_erase(pfa, 0, pfa->fa_size);
    	if (rc < 0)
    	{
    		LOG_ERR("Erasing flash area ... failed! (%d)", rc);
    	}
    	else
    	{
    		LOG_ERR("Erased flash area OK.");
    	}
    	flash_area_close(pfa);
    	return rc;
    }
    
    static int _setup_flash(unsigned int id, struct fs_mount_t *mnt)
    {
    	int rc = -1;
    #if CONFIG_DISK_DRIVER_FLASH
    	const struct flash_area *pfa;
    
    	mnt->storage_dev = (void *)id;
    	rc = flash_area_open(id, &pfa);
    	if (rc < 0)
    	{
    		LOG_ERR("Failed to open flash area (%d) -> trying to erase it....", rc);
    		rc = flash_area_erase(pfa, 0, pfa->fa_size);
    		if (rc < 0)
    		{
    			LOG_ERR("Erasing flash area ... failed! (%d)", rc);
    			flash_area_close(pfa);
    			return rc;
    		}
    		LOG_ERR("Erased flash area OK.");
    		rc = flash_area_open(id, &pfa);
    		if (rc < 0)
    		{
    			LOG_ERR("Erasing flash area ... didn't help, still can't open it! (%d)", rc);
    			flash_area_close(pfa);
    			return rc;
    		}
    	}
    	LOG_ERR("Flash USB mass storage opened : area %u at 0x%x on %s for %u bytes\n",
    			id, (unsigned int)pfa->fa_off, pfa->fa_dev->name,
    			(unsigned int)pfa->fa_size);
    #endif
    	return pfa->fa_size;
    }
    
    static int _mount_app_fs(struct fs_mount_t *mnt, char *mnt_point)
    {
    	int rc;
    
    #if CONFIG_FAT_FILESYSTEM_ELM
    	static FATFS fat_fs;
    
    	mnt->type = FS_FATFS;
    	mnt->fs_data = &fat_fs;
    	mnt->mnt_point = mnt_point;
    #else
    	LOG_ERR("no file system type defined in firmware build, no FS mount available.");
    	return -1;
    #endif
    	rc = fs_mount(mnt);
    
    	return rc;
    }
    
    static bool _setup_disk(struct fs_mount_t *mp, char *mnt_point)
    {
    	int rc;
    	int flash_partition_size = 0;
    	if (IS_ENABLED(CONFIG_DISK_DRIVER_FLASH))
    	{
    		// _erase_flash(STORAGE_PARTITION_ID);		// Only do this if created a FATFS on partition of wrong size initially...
    		flash_partition_size = _setup_flash(STORAGE_PARTITION_ID, mp);
    		if (flash_partition_size < 0)
    		{
    			LOG_ERR("Failed to setup flash area");
    			return false;
    		}
    	}
    	else
    	{
    		LOG_ERR("No flash driver enabled");
    		return false;
    	}
    
    	if (!IS_ENABLED(CONFIG_FAT_FILESYSTEM_ELM))
    	{
    		LOG_ERR("No file system enabled");
    		return false;
    	}
    
    	rc = _mount_app_fs(mp, mnt_point);
    	if (rc < 0)
    	{
    		LOG_ERR("Failed to mount filesystem on %s", mnt_point);
    		return false;
    	}
    	// If fatfs size is not the partition size, then we need to erase the partition and start again
    	struct fs_statvfs fvol;
    	rc = fs_statvfs(mnt_point, &fvol);
    	LOG_INF("statvfs says block size %d, total blocks %d -> %u bytes volume size", fvol.f_blocks, fvol.f_frsize, fvol.f_blocks * fvol.f_frsize);
    	if (abs((fvol.f_blocks * fvol.f_frsize) - flash_partition_size) > 100000)
    	{ // approx
    		LOG_ERR("File system size (%u) not equal to flash zone size (%u) -> wiping and reformatting", (fvol.f_blocks * fvol.f_frsize), flash_partition_size);
    		_erase_flash(STORAGE_PARTITION_ID); // Only do this if created a FATFS on partition of wrong size initially...
    		// And redo?
    		// Need to close parition, unmountfs?
    		fs_unmount(mp);
    		flash_partition_size = _setup_flash(STORAGE_PARTITION_ID, mp);
    		rc = _mount_app_fs(mp, mnt_point);
    		if (rc < 0)
    		{
    			LOG_ERR("Failed to mount filesystem on %s", mnt_point);
    			return false;
    		}
    	}
    	/* Allow log messages to flush to avoid interleaved output */
    	k_sleep(K_MSEC(50));
    
    	return true;
    }
    
    int main(void)
    {
    	int ret;
    
    	if (_setup_disk(&_fs_mnt, "/NAND:"))
    	{
    		LOG_INF("USB mass storage mode enabled.\n");
    	}
    	else
    	{
    		LOG_ERR("USB mass storage mode FS failed!");
    	}
    
    #if defined(CONFIG_USB_DEVICE_STACK_NEXT)
    	ret = enable_usb_device_next();
    #else
    	ret = usb_enable(NULL);
    #endif
    	if (ret != 0)
    	{
    		LOG_ERR("Failed to enable USB");
    		return 0;
    	}
    
    	LOG_INF("The device is put in USB mass storage mode.\n");
    	return 0;
    }
    

    Here is my complete pm_static.yml file that I used:

    mcuboot:
        address: 0x0
        end_address: 0xe000
        region: flash_primary
        size: 0xe000
    
    mcuboot_pad:
        address: 0xe000
        end_address: 0xe200
        region: flash_primary
        size: 0x200
    
    app:
        address: 0xe200
        end_address: 0x100000
        region: flash_primary
        size: 0xf1e00
    
    mcuboot_primary_app:
        address: 0xe200
        end_address: 0x100000
        region: flash_primary
        size: 0xf1e00
        span: [app]
    
    mcuboot_primary:
        address: 0xe000
        end_address: 0x100000
        region: flash_primary
        size: 0xf2000
        span: [mcuboot_pad, mcuboot_primary_app]
    
    # define partition for fatfs disk, on the external flash storage (probably the device defined by nordic,pm-ext-flash in the DTS)
    fatfs_storage:
        region: external_flash
        affiliation: 
            - disk
        extra_params: {
            disk_name: "NAND",
            disk_cache_size: 4096,
            disk_sector_size: 512,
            disk_read_only: 0
        }
        # 6Mb size, external flash is 8Mb total
        address: 0x0
        size: 0x600000
    
    nvs_storage:
        region: external_flash
        affiliation: 
            - nvs
        # 64kB size, its just for small stuff
        address: 0x600000
        size: 0x10000
    
    mcuboot_secondary_1:
        region: external_flash
        affiliation: 
            - mcuboot
        # 256kb size, its for netcore flash image
        address: 0x610000
        size: 0x40000
    
    mcuboot_secondary:
        region: external_flash
        affiliation: 
            - mcuboot
        address: 0x650000
        # MUST be same size as the primary application slot size, and share_size does not appear to work
        size: 0xf1e00
        #share_size: [mcuboot_primary_app]
    
    # internal cuisine
    otp:
        address: 0xff8100
        end_address: 0xff83fc
        region: otp
        size: 0x2fc
    pcd_sram:
        address: 0x20000000
        end_address: 0x20002000
        #placement:
        #    after:
        #    - start
        region: sram_primary
        size: 0x2000
    rpmsg_nrf53_sram:
        address: 0x20070000
        end_address: 0x20080000
        #placement:
        #    before:
        #    - end
        region: sram_primary
        size: 0x10000
    sram_primary:
        address: 0x20002000
        end_address: 0x20070000
        region: sram_primary
        size: 0x6e000
    
    # TODO need fake flash ram flash partition to do cpunet DFU...
    #mcuboot_primary_1:
    #  address: 0x0
    #  device: nordic_ram_flash_controller
    #  end_address: 0x40000
    #  region: ram_flash
    #  size: 0x40000
    #
    #ram_flash:
    #  address: 0x40000
    #  end_address: 0x40000
    #  region: ram_flash
    #  size: 0x0

    Here is my overlay:

    / {
    	chosen {
    		nordic,pm-ext-flash = &winbond;
    	};
    };
    
    
    
    
    &button2 {
    	status = "disabled";
    };
    
    &button3 {
    	status = "disabled";
    };
    
    &gpio_fwd {
    	status = "disabled";
    };
    
    &uicr {nfct-pins-as-gpios; };
    
    &pinctrl {
    	spi_master_default: spi_master_default {
    		group1 {
    			psels = <NRF_PSEL(SPIM_SCK, 0, 2)>,   // SCLK
    			<NRF_PSEL(SPIM_MOSI, 0, 9)>,  // MOSI
    			<NRF_PSEL(SPIM_MISO, 0, 3)>;  // MISO
    		};
    	};
    
    	spi_master_sleep: spi_master_sleep {
    		group1 {
    			psels = <NRF_PSEL(SPIM_SCK, 0, 2)>,   // SCLK
    			<NRF_PSEL(SPIM_MOSI, 0, 9)>,  // MOSI
    			<NRF_PSEL(SPIM_MISO, 0, 3)>;  // MISO
    			low-power-enable;
    		};
    	};
    };
    
    
    &spi3 {
    	compatible = "nordic,nrf-spim";
    	pinctrl-0 = <&spi_master_default>;
    	pinctrl-1 = <&spi_master_sleep>;
    	pinctrl-names = "default", "sleep";
    	cs-gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;    // Chip Select (CS) on Pin 11
    	status = "okay";
    	winbond: winbond@0 {
    		compatible = "jedec,spi-nor";
    		reg = <0>;                               // CS0
    		spi-max-frequency = <32000000>;
    		// SPI max frequency (32 MHz)
    		jedec-id = [ ef 70 22  ];                  // JEDEC ID for W25Q02JV
    		size = <268435456>;                      // 256MB NOR flash size
    		has-dpd;                                 // Deep Power Down (DPD) support
    	};
    };
    

    And using this I get this partition report:

     external_flash (0x10000000 - 262144kB): 
    +-------------------------------------------------+
    | 0x0: external_flash (0x10000000 - 262144kB)     |
    | 0x0: fatfs_storage (0x600000 - 6144kB)          |
    | 0x600000: nvs_storage (0x10000 - 64kB)          |
    | 0x610000: mcuboot_secondary_1 (0x40000 - 256kB) |
    | 0x650000: mcuboot_secondary (0xf1e00 - 967kB)   |
    +-------------------------------------------------+
    
      flash_primary (0x100000 - 1024kB):
    +-------------------------------------------------+
    | 0x0: mcuboot (0xe000 - 56kB)                    |
    +---0xe000: mcuboot_primary (0xf2000 - 968kB)-----+
    | 0xe000: mcuboot_pad (0x200 - 512B)              |
    +---0xe200: mcuboot_primary_app (0xf1e00 - 967kB)-+
    | 0xe200: app (0xf1e00 - 967kB)                   |
    +-------------------------------------------------+
    
      otp (0x2fc - 764B):
    +------------------------------+
    | 0xff8100: otp (0x2fc - 764B) |
    +------------------------------+
    
      sram_primary (0x80000 - 512kB):
    +-----------------------------------------------+
    | 0x20000000: pcd_sram (0x2000 - 8kB)           |
    | 0x20002000: sram_primary (0x6e000 - 440kB)    |
    | 0x20070000: rpmsg_nrf53_sram (0x10000 - 64kB) |
    +-----------------------------------------------+
    
     CPUNET flash_primary (0x40000 - 256kB):
    +--------------------------------------+
    +---0x1000000: app (0x40000 - 256kB)---+
    | 0x1000000: hci_ipc (0x40000 - 256kB) |
    +--------------------------------------+
    
     CPUNET sram_primary (0x10000 - 64kB):
    +-------------------------------------------+
    | 0x21000000: sram_primary (0x10000 - 64kB) |
    +-------------------------------------------+

    prj.conf

    CONFIG_STDOUT_CONSOLE=y
    
    # CONFIG_LOG=y
    # CONFIG_RTT_CONSOLE=y
    # CONFIG_LOG_BACKEND_RTT=y
    CONFIG_LOG_BACKEND_UART=y
    
    CONFIG_FLASH=y
    
    # # Enable mcumgr.
    # CONFIG_MCUMGR=y
    
    # # Enable most core commands.
    # CONFIG_MCUMGR_CMD_IMG_MGMT=y
    # CONFIG_MCUMGR_CMD_OS_MGMT=y
    
    # # Ensure an MCUboot-compatible binary is generated.
    # CONFIG_BOOTLOADER_MCUBOOT=y
    
    # CONFIG_MULTITHREADING=y
    
    # # Some command handlers require a large stack.
    # CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096
    
    # CONFIG_NORDIC_QSPI_NOR=y
    # CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
    # CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16
    
    # CONFIG_MCUMGR_SMP_UART=y
    
    # CONFIG_MCUBOOT_IMAGE_VERSION="0.1.1+8"
    
    # CONFIG_PM_PARTITION_REGION_FATFS_STORAGE_EXTERNAL=y
    
    
    #USB related configs
    CONFIG_USB_DEVICE_STACK=y
    CONFIG_USB_DEVICE_PRODUCT="Very FATFS storage"
    CONFIG_USB_DEVICE_PID=0x0008
    CONFIG_LOG=y
    CONFIG_USB_DRIVER_LOG_LEVEL_ERR=y
    CONFIG_USB_MASS_STORAGE=y
    CONFIG_USB_DEVICE_LOG_LEVEL_ERR=y
    CONFIG_USB_MASS_STORAGE_LOG_LEVEL_ERR=y
    CONFIG_USB_CDC_ACM=n
    CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n
    CONFIG_APP_MSC_STORAGE_FLASH_FATFS=y
    CONFIG_MAIN_STACK_SIZE=10240
    CONFIG_APP_WIPE_STORAGE=y
    CONFIG_NORDIC_QSPI_NOR=n
    CONFIG_SPI=y
    CONFIG_SPI_NOR=y
    CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
    CONFIG_NRFX_SPIM3=y
    
    CONFIG_MULTITHREADING=y
    CONFIG_PM_OVERRIDE_EXTERNAL_DRIVER_CHECK=y
    CONFIG_BT=y
    

    After doing this now, when I flash I get nothing in the terminal, not even 
    *** Booting nRF Connect SDK v2.7.0-5cb85570ca43 ***
    *** Using Zephyr OS v3.6.99-100befc70c74 ***workingFlash.zip

    I have also attached the zip file, if you want to take a look. It is my first time working with storage, file system and Bluetooth together, I would really appreciate if you could provide any further suggestions here.

    Regards,

    Barsha

  • If its possible can you share your prj.conf and overlay file?

  • It looks like your prj.conf has commented out the critical mcuboot keys?

    # CONFIG_BOOTLOADER_MCUBOOT=y

    if you make a partition map with mcuboot at 0x0, you need to build an image with mcuboot in there...

    in prj.conf:
    CONFIG_BOOTLOADER_MCUBOOT=y
    # put slot2 in external flash
    CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y
    CONFIG_MCUBOOT_BOOTLOADER_MODE_SWAP_WITHOUT_SCRATCH=y
    And then you need to put a 'mcuboot.conf' file in the directory 'child_image' containing:
    CONFIG_MCUBOOT_SERIAL=n
    CONFIG_BOOT_MAX_IMG_SECTORS=256
    CONFIG_FPROTECT=n

    CONFIG_BOOTLOADER_MCUBOOT=y
    (this is also where you put the config for image signing keys files etc).
    My proj.conf (but this is still a work in progress especially as I'm fighting with the wifi stuff right now..)
    #
    # Copyright (c) 2021 Nordic Semiconductor ASA
    #
    # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
    #
    #debug core dump : TODO change to use flash partition
    CONFIG_DEBUG_COREDUMP=n
    CONFIG_DEBUG_COREDUMP_BACKEND_LOGGING=n
    CONFIG_DEBUG_COREDUMP_MEMORY_DUMP_MIN=n
    
    # debug/memory/thread/stack check analysis : 
    # TODO remove for runtime
    CONFIG_DEBUG=n
    CONFIG_DEBUG_INFO=n
    
    CONFIG_THREAD_NAME=y
    # TODO remove for runtime
    CONFIG_THREAD_ANALYZER=y
    CONFIG_THREAD_ANALYZER_USE_PRINTK=n
    CONFIG_THREAD_ANALYZER_AUTO=n
    #CONFIG_THREAD_ANALYZER_AUTO_INTERVAL=60
    #CONFIG_THREAD_ANALYZER_RUN_UNLOCKED=y
    
    CONFIG_SYS_HEAP_RUNTIME_STATS=y
    CONFIG_INIT_STACKS=y
    
    # TODO remove for runtime
    CONFIG_ASSERT=y
    CONFIG_ASSERT_VERBOSE=y
    CONFIG_ASSERT_NO_COND_INFO=n
    CONFIG_ASSERT_NO_MSG_INFO=n
    CONFIG_STACK_SENTINEL=y
    # system HALT on error (useful for debugger?)
    # TODO remove for runtime
    CONFIG_RESET_ON_FATAL_ERROR=n
    CONFIG_REBOOT=y
    
    #CONFIG_NCS_SAMPLES_DEFAULTS=y
    CONFIG_LOG=y
    CONFIG_LOG_MODE_MINIMAL=y
    CONFIG_LOG_MODE_IMMEDIATE=y
    CONFIG_LOG_BACKEND_UART=y
    CONFIG_LOG_DEFAULT_LEVEL=3
    CONFIG_LOG_PRINTK=n
    # warning : if shell enabled this caused fatal crash at boot...
    CONFIG_SHELL=n
    CONFIG_SHELL_MINIMAL=n
    CONFIG_SHELL_LOG_BACKEND=n
    
    # cannot access binary says ninja, also the info is not available to the source code
    #CONFIG_BINDESC=y
    #CONFIG_BINDESC_DEFINE=y
    #CONFIG_BINDESC_DEFINE_BUILD_TIME=y
    #CONFIG_BINDESC_BUILD_DATE_TIME_STRING=y
    #CONFIG_BINDESC_BUILD_DATE_TIME_STRING_FORMAT="%Y-%m-%dT%H:%M"
    
    CONFIG_GPIO=y
    CONFIG_GPIO_MCP230XX=y
    CONFIG_SERIAL=y
    CONFIG_UART_CONSOLE=y
    CONFIG_UART_INTERRUPT_DRIVEN=y
    CONFIG_UART_ASYNC_API=y
    CONFIG_UART_LINE_CTRL=y
    
    CONFIG_I2C=y
    CONFIG_I2C_CALLBACK=y
    CONFIG_I2C_NRFX=y
    #CONFIG_I2C_NRFX_TWIM=y
    #CONFIG_NRFX_TXI_ENABLED=y
    
    CONFIG_SPI=y
    CONFIG_SPI_ASYNC=y
    
    # Using AEF event system for inter-module comm and sync
    CONFIG_APP_EVENT_MANAGER=y
    CONFIG_APP_EVENT_MANAGER_POSTINIT_HOOK=y
    CONFIG_CAF=y
    CONFIG_CAF_PM_EVENTS=y
    CONFIG_CAF_POWER_MANAGER=n
    #CONFIG_CAF_BUTTONS=y
    #CONFIG_CAF_BUTTONS_DEF_PATH="cc1_med_buttons_def.h"
    CONFIG_CAF_BUTTON_EVENTS=y
    #CONFIG_CAF_BUTTONS_PM_EVENTS=y
    # button polarity inverse on DK board... tbd on real hw
    #CONFIG_CAF_BUTTONS_POLARITY_INVERSED=y
    #CONFIG_CAF_BUTTONS_PM_KEEP_ALIVE=n
    CONFIG_CAF_CLICK_DETECTOR=y
    CONFIG_CAF_CLICK_DETECTOR_LONG_CLICK_MSEC=2000
    CONFIG_CAF_CLICK_DETECTOR_PM_EVENTS=y
    CONFIG_CAF_CLICK_DETECTOR_DEF_PATH="cc1_med_buttons_click_def.h"
    CONFIG_LED=y
    CONFIG_LED_GPIO=y
    
    # libaries
    CONFIG_NEWLIB_LIBC=y
    CONFIG_NEWLIB_LIBC_NANO=n
    CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y
    CONFIG_COMMON_LIBC_CALLOC=y
    CONFIG_COMMON_LIBC_REALLOCARRAY=y
    # use malloc that maps to k_malloc(), and allocate all remaing RAM to heap (-1)
    CONFIG_COMMON_LIBC_MALLOC=y
    CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=180000
    CONFIG_HEAP_MEM_POOL_SIZE=50000
    
    CONFIG_FLASH=y
    CONFIG_I2S=y
    CONFIG_I2S_NRFX=y
    CONFIG_NRFX_PDM=y
    CONFIG_PWM=y
    CONFIG_SYS_HASH_MAP=y
    # using cJSON
    CONFIG_CJSON_LIB=y
    CONFIG_JSON_LIBRARY=n
    CONFIG_BASE64=y
    CONFIG_UTF8=y
    CONFIG_CHARACTER_FRAMEBUFFER=y
    # using NVS system for blobmgr. NVS partition defined in pm_static.yml
    CONFIG_NVS=y
    
    CONFIG_STDOUT_CONSOLE=y
    
    # turn on Partition manager (must be on) to use partitions from pm_static.yml
    CONFIG_PM_SINGLE_IMAGE=y
    
    #USB related configs
    CONFIG_USB_DEVICE_STACK=y
    CONFIG_USB_DEVICE_PRODUCT="Infrafon CC2-WDD"
    # USB VID is MCS electronics, who sell individual PIDs. 0x138F is for CC2 purchases 25/08/2024
    CONFIG_USB_DEVICE_VID=0x16D0
    CONFIG_USB_DEVICE_PID=0x138F
    CONFIG_USB_DRIVER_LOG_LEVEL_ERR=y
    
    CONFIG_USB_DEVICE_HID=y
    CONFIG_USB_HID_DEVICE_COUNT=2
    
    CONFIG_USB_MASS_STORAGE=y
    CONFIG_USB_DEVICE_LOG_LEVEL_ERR=y
    CONFIG_USB_MASS_STORAGE_LOG_LEVEL_ERR=y
    CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n
    CONFIG_NORDIC_QSPI_NOR=y
    
    # flash disk config
    # The mx25 erase page size
    CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
    CONFIG_DISK_DRIVERS=y
    CONFIG_DISK_DRIVER_FLASH=y
    # use ELM FATFS with long file names (not 8.3)
    CONFIG_FILE_SYSTEM=y
    CONFIG_FAT_FILESYSTEM_ELM=y
    CONFIG_FS_FATFS_MOUNT_MKFS=y
    CONFIG_FS_FATFS_LFN=y
    CONFIG_FS_FATFS_EXFAT=n
    
    CONFIG_MASS_STORAGE_DISK_NAME="NAND"
    CONFIG_FLASH_MAP=y
    CONFIG_FLASH_PAGE_LAYOUT=y
    
    # BT/BLE config
    CONFIG_BT=y
    CONFIG_BT_PERIPHERAL=y
    CONFIG_BT_DEVICE_NAME="CC2-WDD-2"
    CONFIG_BT_DEVICE_APPEARANCE=512
    CONFIG_BT_DEVICE_NAME_DYNAMIC=y
    
    CONFIG_BT_EXT_ADV=y
    CONFIG_BT_EXT_ADV_MAX_ADV_SET=2
    
    CONFIG_BT_DIS=y
    CONFIG_BT_DIS_PNP=y
    CONFIG_BT_DIS_MANUF="Infrafon"
    CONFIG_BT_DIS_PNP_VID_SRC=2
    CONFIG_BT_DIS_PNP_VID=0x1915
    CONFIG_BT_DIS_PNP_PID=0xEEF1
    CONFIG_BT_DIS_PNP_VER=0x0100
    
    CONFIG_BT_OBSERVER=y
    CONFIG_BT_SCAN=y
    CONFIG_BT_NUS=y
    
    # WIFI config
    CONFIG_WIFI=y
    CONFIG_WIFI_NRF700X=y
    CONFIG_NRF_WIFI_PATCHES_BUILTIN=y
    #CONFIG_NRF700X_RADIO_COEX=y
    CONFIG_NRF_WIFI_LOW_POWER=y
    CONFIG_NRF_WIFI_IF_AUTO_START=y
    
    CONFIG_NRF700X_AP_MODE=n
    CONFIG_NRF700X_P2P_MODE=n
    CONFIG_NRF700X_STA_MODE=y
    
    # WPA supplicant
    CONFIG_WPA_SUPP=y
    #CONFIG_WPA_SUPP_LOG_LEVEL_INF=y
    #CONFIG_WIFI_NM=y
    #CONFIG_WIFI_NM_LOG_LEVEL_INF=y
    
    # No, follwing is experimental bad code
    #CONFIG_WIFI_NM_WPA_SUPPLICANT=y
    #CONFIG_WIFI_NM_WPA_SUPPLICANT_LOG_LEVEL_INF=y
    #CONFIG_NO_WPA=n
    
    CONFIG_NET_L2_ETHERNET=y
    #CONFIG_NET_L2_WIFI_MGMT=y
    
    # Networking layers
    CONFIG_NETWORKING=y
    CONFIG_NET_SOCKETS=y
    CONFIG_NET_LOG=y
    CONFIG_NET_IPV4=y
    CONFIG_NET_UDP=y
    CONFIG_NET_TCP=y
    CONFIG_NET_DHCPV4=y
    #CONFIG_DNS_RESOLVER=y
    #CONFIG_HTTP_CLIENT=y
    #CONFIG_MQTT_LIB=y
    
    CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT=1
    CONFIG_NET_MAX_CONTEXTS=5
    CONFIG_NET_CONTEXT_SYNC_RECV=y
    #Note that sockets are used by WPA suppliant code
    CONFIG_NET_SOCKETS_POLL_MAX=10
    
    # net_config is only for testing to set IP address directly
    CONFIG_NET_CONFIG_SETTINGS=n
    #CONFIG_NET_CONFIG_SETTINGS=y
    #CONFIG_NET_CONFIG_INIT_TIMEOUT=0
    # Must call net_config_init() explicitly
    #CONFIG_NET_CONFIG_AUTO_INIT=n
    #CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.168.1.99"
    #CONFIG_NET_CONFIG_MY_IPV4_NETMASK="255.255.255.0"
    #CONFIG_NET_CONFIG_MY_IPV4_GW="192.168.1.1"
    
    # Memory usage
    CONFIG_NET_TX_STACK_SIZE=4096
    CONFIG_NET_RX_STACK_SIZE=4096
    CONFIG_WPA_SUPP_WQ_STACK_SIZE=4096
    CONFIG_NET_MGMT_EVENT_STACK_SIZE=4096
    
    # Optimized networking settings for memory usage (STA MODE IOT DEVICES profile)
    # https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/protocols/wifi/stack_configuration.html
    CONFIG_NRF700X_MAX_TX_TOKENS=5
    CONFIG_NRF700X_MAX_TX_AGGREGATION=1
    CONFIG_NRF700X_RX_NUM_BUFS=6
    
    CONFIG_NET_TC_TX_COUNT=1
    CONFIG_NET_PKT_RX_COUNT=6
    CONFIG_NET_PKT_TX_COUNT=6
    
    CONFIG_NET_BUF_RX_COUNT=6
    CONFIG_NET_BUF_TX_COUNT=12
    # can take BUF_DATAT_SIZE down to 500
    CONFIG_NET_BUF_DATA_SIZE=800
    
    # NFC config
    CONFIG_NFC_T2T_NRFXLIB=y
    CONFIG_NFC_T4T_NRFXLIB=y
    CONFIG_NFC_T4T_ISODEP=y
    
    CONFIG_NFC_NDEF=y
    CONFIG_NFC_NDEF_MSG=y
    CONFIG_NFC_NDEF_RECORD=y
    CONFIG_NFC_NDEF_URI_REC=y
    CONFIG_NFC_NDEF_URI_MSG=y
    
    CONFIG_MAIN_STACK_SIZE=4096
    # need big stack for system workqueue thread, as this is where we execute pretty much all real operations
    #CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=32796
    CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096
    
    CONFIG_BOOTLOADER_MCUBOOT=y
    # put slot2 in external flash
    CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y
    CONFIG_MCUBOOT_BOOTLOADER_MODE_SWAP_WITHOUT_SCRATCH=y
    CONFIG_MCUBOOT_GENERATE_UNSIGNED_IMAGE=y
    #CONFIG_MCUBOOT_BOOTUTIL_LIB=n
    #CONFIG_MCUBOOT_IMG_MANAGER=n
    CONFIG_MCUBOOT_SHELL=n
    #CONFIG_MCUBOOT_USB_SUPPORT=n
    #CONFIG_MCUBOOT_UTIL_LOG_LEVEL_ERR=n
    
    # sign with our own key
    CONFIG_MCUBOOT_BUILD_STRATEGY_FROM_SOURCE=y
    #CONFIG_BOOT_SIGNATURE_KEY_FILE="/work/dev/if-device-nrf53/keys/bootloader_priv-ecdsa256.pem"
    #CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="/work/dev/if-device-nrf53/keys/bootloader_priv-ecdsa256.pem"
    # not using 2 stage bootloader
    #CONFIG_SECURE_BOOT=y
    #CONFIG_SB_SIGNING_KEY_FILE="/work/dev/if-device-nrf53/keys/bootloader_priv-ecdsa256.pem"
    #CONFIG_SB_SIGNING_OPENSSL=y
    # want bin and hexes
    CONFIG_BUILD_OUTPUT_BIN=y
    CONFIG_BUILD_OUTPUT_HEX=y
    
    # to allow net CPU update (complex & hard...)
    #CONFIG_UPDATEABLE_IMAGE_NUMBER=2
    #CONFIG_PCD_APP=y
    #CONFIG_FLASH_SIMULATOR=y
    #CONFIG_NRF53_MULTI_IMAGE_UPDATE=n
    #CONFIG_USE_NRF53_MULTI_IMAGE_WITHOUT_UPGRADE_ONLY=n
    
    # Enable DFU target for application image, this lets us write an image downloaded from whereever into the secondary slot for update by mcuboot
    CONFIG_DFU_TARGET=y
    CONFIG_STREAM_FLASH=y
    CONFIG_STREAM_FLASH_ERASE=y
    CONFIG_DFU_TARGET_STREAM=y
    CONFIG_IMG_MANAGER=y
    CONFIG_DFU_TARGET_MCUBOOT=y
    and child_image/mcuboot.conf
    CONFIG_MCUBOOT_SERIAL=n
    CONFIG_BOOT_MAX_IMG_SECTORS=256
    CONFIG_FPROTECT=n
    
    CONFIG_BOOTLOADER_MCUBOOT=y
    CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256=y
    CONFIG_BOOT_SIGNATURE_KEY_FILE="/work/dev/if-device-nrf53/keys/bootloader_priv-ecdsa256.pem"
    #CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="/work/dev/if-device-nrf53/keys/bootloader_priv-ecdsa256.pem"
    
    
     
    I don't use an overlay, just a single DTS file as my board is custom. And my flash chip is different (only 8Mb...)
  • Hi BrianW,

    I really appreciate your help. I am finally able to mount fat FS into my storage. I removed the MCU boot part, since I am just storing sensor data for now into my storage. Thank you again!

    Regards,

    Barsha 

Related