Using the NuttX’s USB Mass Storage to copy SPI NOR Flash Content

I’m using an 8MiB SPI NOR (Winbond W25Q64) on my board and I was looking for a way to copy its content.

Some readers could recall I used the hexdump and screen to copy small files from NuttX, but it is not an option when you need to copy big files. For instance, I want to copy a more than 5MiB file.

Then I decided to use the NuttX USBMSC driver to export the SPI NOR partition.

The first thing to do is enable the USBMSC driver:

Device Drivers  --->
[*] USB Device Driver Support  --->
--- USB Device Driver Support

[*]   USB Mass storage class device  
(64)    Max packet size for endpoint0  
(2)     Bulk OUT endpoint number
(3)     Bulk IN endpoint number
(4)     The number of write requests that can be in flight
(4)     The number of read requests that can be in flight
(64)    Bulk IN request size
(64)    Bulk OUT request size
(0x584e) Mass storage Vendor ID
(NuttX) Mass storage vendor string
(0x5342) Mass storage Product ID
(Mass Storage) Mass storage product string
(0x399) USB MSC Version Number
[*]     Mass storage removable
(128)   USBMSC SCSI daemon priority
(2048)  USBMSC SCSI daemon stack size

Now we need to enable the USB Mass Storage Commands:

System Libraries and NSH Add-Ons  --->
[*] USB Mass Storage Device Commands  --->

--- USB Mass Storage Device Commands
(1)   Number of LUNs
(0)   LUN1 Minor Device Number
(/dev/smart0p1) LUN1 Device Path

As you can see I changed the default LUN1 (Logic Unit 1) from /dev/mmcsd1 to /dev/smart0p1 since it is my SPI NOR Flash partition.

Also I created a stm32_usbmsc.c file with the “int usbmsc_archinitialize(void)” function just returning 0, since the SPI NOR initialization is done automatically.

After compiling and flashing the nuttx.bin on my board I started the USB Mass Storage with the “msconn” command:

NuttShell (NSH)
nsh> msconn
mcsonn_main: Creating block drivers
mcsonn_main: Configuring with NLUNS=1
mcsonn_main: handle=2000c320
mcsonn_main: Bind LUN=0 to /dev/smart0p1
mcsonn_main: Connected

Immediately I listen the new USB device connected on my Linux, but the device didn’t appear in the Nautilus. Using dmesg I could see what was going on:

[10875.354625] usb 3-4: new full-speed USB device number 6 using xhci_hcd
[10875.484111] usb 3-4: New USB device found, idVendor=584e, idProduct=5342
[10875.484118] usb 3-4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[10875.484122] usb 3-4: Product: Mass Storage
[10875.484125] usb 3-4: Manufacturer: NuttX
[10875.484127] usb 3-4: SerialNumber: 0101
[10875.545293] usb-storage 3-4:1.0: USB Mass Storage device detected
[10875.545467] scsi6 : usb-storage 3-4:1.0
[10875.545611] usbcore: registered new interface driver usb-storage
[10876.543778] scsi 6:0:0:0: Direct-Access     NuttX    Mass Storage     0101 PQ: 0 ANSI: 2
[10876.544518] sd 6:0:0:0: Attached scsi generic sg2 type 0
[10876.544848] sd 6:0:0:0: [sdb] 10240 512-byte logical blocks: (5.24 MB/5.00 MiB)
[10876.761447] sd 6:0:0:0: [sdb] Write Protect is off
[10876.761456] sd 6:0:0:0: [sdb] Mode Sense: 0b 00 00 00
[10876.981478] sd 6:0:0:0: [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[10877.446426]  sdb: unknown partition table
[10877.881947] sd 6:0:0:0: [sdb] Attached SCSI removable disk

Because the NuttX Mass Storage Partition /dev/smart0p1 is not a FAT partition, but SmartFS, Linux couldn’t recognize it.

No problem, I just need to see the partition content.

Using the dd command I copied the flash partition:

$ sudo dd if=/dev/sdb of=/tmp/smartfs.bin
10240+0 records in
10240+0 records out
5242880 bytes (5.2 MB) copied, 9.58846 s, 547 kB/s

That is all! If you don’t know yet, NuttX Rocks!

UPDATE: Ken Pettit created a FUSE support for SmartFS, you can find it (called nxfuse) in the tools repository from NuttX project in the bitbucket.