1.. zephyr:code-sample:: usb-mass 2 :name: USB Mass Storage 3 :relevant-api: usbd_api usbd_msc_device _usb_device_core_api file_system_api 4 5 Expose board's RAM or FLASH as a USB disk using USB Mass Storage driver. 6 7Overview 8******** 9 10This sample app demonstrates use of a USB Mass Storage driver by the Zephyr 11project. This very simple driver enumerates a board with either RAM or FLASH 12into an USB disk. This sample can be found under 13:zephyr_file:`samples/subsys/usb/mass` in the Zephyr project tree. 14 15Requirements 16************ 17 18This project requires a USB device driver, and either 96KiB of RAM or a FLASH device. 19 20Building and Running 21******************** 22 23This sample can be built for multiple boards, customized through overlays found 24in :zephyr_file:`samples/subsys/usb/mass/boards` in the Zephyr project tree. 25The selection between a RAM-based or a FLASH-based disk and file system 26can be chosen passing Kconfig configuration via the -D command-line switch. 27 28RAM-disk Example without any file system 29======================================== 30 31The default configurations selects RAM-based disk without any file system. 32This example only needs additional 96KiB RAM for the RAM-disk and is intended 33for testing USB mass storage class implementation. 34 35.. zephyr-app-commands:: 36 :zephyr-app: samples/subsys/usb/mass 37 :board: reel_board 38 :gen-args: -DEXTRA_DTC_OVERLAY_FILE="ramdisk.overlay" 39 :goals: build 40 :compact: 41 42 43FAT FS Example 44============== 45 46If more than 96KiB are available, FAT files system can be used 47with a RAM-disk. Alternatively it is possible with the FLASH-based disk. 48In this example we will build the sample with a RAM-based disk: 49 50.. zephyr-app-commands:: 51 :zephyr-app: samples/subsys/usb/mass 52 :board: reel_board 53 :gen-args: -DEXTRA_DTC_OVERLAY_FILE="ramdisk.overlay" -DCONFIG_APP_MSC_STORAGE_RAM=y 54 :goals: build 55 :compact: 56 57 58In this example we will build the sample with a FLASH-based disk and FAT 59file system for Adafruit Feather nRF52840 Express. This board configures 60to use the external 16 MiBi QSPI flash chip with a 2 MiBy FAT partition. 61 62.. zephyr-app-commands:: 63 :zephyr-app: samples/subsys/usb/mass 64 :board: adafruit_feather_nrf52840_sense 65 :gen-args: -DCONFIG_APP_MSC_STORAGE_FLASH_FATFS=y 66 :goals: build 67 :compact: 68 69After you have built and flashed the sample app image to your board, plug the 70board into a host device, for example, a PC running Linux. 71The board will be detected as shown by the Linux journalctl command: 72 73.. code-block:: console 74 75 $ journalctl -k -n 17 76 usb 2-2.4: new full-speed USB device number 29 using xhci_hcd 77 usb 2-2.4: New USB device found, idVendor=2fe3, idProduct=0008, bcdDevice= 2.03 78 usb 2-2.4: New USB device strings: Mfr=1, Product=2, SerialNumber=3 79 usb 2-2.4: Product: Zephyr MSC sample 80 usb 2-2.4: Manufacturer: ZEPHYR 81 usb 2-2.4: SerialNumber: 86FE679A598AC47A 82 usb-storage 2-2.4:1.0: USB Mass Storage device detected 83 scsi host3: usb-storage 2-2.4:1.0 84 scsi 3:0:0:0: Direct-Access ZEPHYR ZEPHYR USB DISK 0.01 PQ: 0 ANSI: 0 CCS 85 sd 3:0:0:0: Attached scsi generic sg4 type 0 86 sd 3:0:0:0: [sdb] 256 512-byte logical blocks: (131 kB/128 KiB) 87 sd 3:0:0:0: [sdb] Write Protect is off 88 sd 3:0:0:0: [sdb] Mode Sense: 03 00 00 00 89 sd 3:0:0:0: [sdb] No Caching mode page found 90 sd 3:0:0:0: [sdb] Assuming drive cache: write through 91 sdb: 92 sd 3:0:0:0: [sdb] Attached SCSI removable disk 93 94The output to the console will look something like this 95(file system contents will be different): 96 97.. code-block:: none 98 99 *** Booting Zephyr OS build zephyr-v2.3.0-1991-g4c8d1496eafb *** 100 Area 4 at 0x0 on GD25Q16 for 2097152 bytes 101 Mount /NAND:: 0 102 /NAND:: bsize = 512 ; frsize = 1024 ; blocks = 2028 ; bfree = 1901 103 /NAND: opendir: 0 104 F 0 SAMPLE.TXT 105 End of files 106 [00:00:00.077,423] <inf> main: The device is put in USB mass storage mode. 107 108On most operating systems the drive will be automatically mounted. 109 110SD Card Example 111=============== 112 113This example requires SD card support, see :ref:`disk_access_api`, and 114a SD card formatted with FAT filesystem. 115 116If a board with SD card controller is available, the example can be built as 117follows: 118 119.. zephyr-app-commands:: 120 :zephyr-app: samples/subsys/usb/mass 121 :board: mimxrt1050_evk 122 :gen-args: -DCONFIG_APP_MSC_STORAGE_SDCARD=y 123 :goals: build 124 :compact: 125 126In case the board has no support for SD card controller, but the card can 127be connected to SPI using e.g. a shield, example can be built as follows: 128 129.. zephyr-app-commands:: 130 :zephyr-app: samples/subsys/usb/mass 131 :board: nrf52840dk/nrf52840 132 :shield: waveshare_epaper_gdeh0154a07 133 :gen-args: -DCONFIG_APP_MSC_STORAGE_SDCARD=y 134 :goals: build 135 :compact: 136 137Depending on the size of the media it can take time until the file system has 138initialized the card and it is available via USB. It should also be noted that 139the transfer speed over SPI is very slow. 140 141.. code-block:: none 142 143 *** Booting Zephyr OS build v2.5.0-rc3-73-gd85067f0a759 *** 144 Mount /SD:: 0 145 [00:00:00.281,585] <inf> sdhc_spi: Found a ~3751 MiB SDHC card. 146 [00:00:00.282,867] <inf> sdhc_spi: Manufacturer ID=27 OEM='SM' Name='00000' Revision=0x10 Serial=0x16fdd47b 147 [00:00:00.308,654] <inf> sdhc_spi: Found a ~3751 MiB SDHC card. 148 [00:00:00.309,906] <inf> sdhc_spi: Manufacturer ID=27 OEM='SM' Name='00000' Revision=0x10 Serial=0x16fdd47b 149 /SD:: bsize = 512 ; frsize = 32768 ; blocks = 119776 ; bfree = 119773 150 /SD: opendir: 0 151 D 0 42 152 F 1111 TEST.TXT 153 End of files 154 [00:00:18.588,043] <inf> main: The device is put in USB mass storage mode. 155 156LittleFS Example 157================ 158 159This board configures to use the external 64 MiBi QSPI flash chip with a 160128 KiBy `littlefs`_ partition compatible with the one produced by the 161:zephyr:code-sample:`littlefs` sample. 162 163.. zephyr-app-commands:: 164 :zephyr-app: samples/subsys/usb/mass 165 :board: nrf52840dk/nrf52840 166 :gen-args: -DCONFIG_APP_MSC_STORAGE_FLASH_LITTLEFS=y 167 :goals: build 168 :compact: 169 170After you have built and flashed the sample app image to your board, 171connect the board's two USB connectors (debug and nRF USB) to a host 172running a littlefs-FUSE-capable operating system. The output to the 173console will look something like this (file system contents will be 174different): 175 176.. code-block:: none 177 178 *** Booting Zephyr OS build zephyr-v2.2.0-1966-g7815942d5fc5 *** 179 Area 4 at 0x0 on MX25R64 for 65536 bytes 180 [00:00:00.005,310] <inf> main: The device is put in USB mass storage mode. 181 182 [00:00:00.009,002] <inf> littlefs: LittleFS version 2.2, disk version 2.0 183 [00:00:00.009,063] <inf> littlefs: FS at MX25R64:0x0 is 16 0x1000-byte blocks with 512 cye 184 [00:00:00.009,063] <inf> littlefs: sizes: rd 16 ; pr 16 ; ca 64 ; la 32 185 [00:00:00.011,718] <inf> littlefs: /lfs mounted 186 Mount /lfs: 0 187 /lfs: bsize = 16 ; frsize = 4096 ; blocks = 16 ; bfree = 13 188 /lfs opendir: 0 189 F 8 hi 190 F 128 linux 191 F 5 newfile 192 End of files 193 194For information on mounting littlefs file system on Linux or FreeBSD 195systems refer to the "littlefs Usage" section below. 196 197littlefs Usage 198============== 199 200While a FAT-based file system can be mounted by many systems automatically, 201mounting the littlefs file system on a Linux or FreeBSD system can be 202accomplished using the `littlefs-FUSE`_ utility. 203 204First determine the local device name from the system log, e.g.: 205 206.. code-block:: none 207 208 Apr 25 08:10:25 tirzah kernel: [570310.921039] scsi 17:0:0:0: Direct-Access ZEPHYR ZEPHYR USB DISK 0.01 PQ: 0 ANSI: 0 CCS 209 Apr 25 08:10:25 tirzah kernel: [570310.921550] sd 17:0:0:0: Attached scsi generic sg4 type 0 210 Apr 25 08:10:25 tirzah kernel: [570310.922277] sd 17:0:0:0: [sdd] 256 512-byte logical blocks: (131 kB/128 KiB) 211 Apr 25 08:10:25 tirzah kernel: [570310.922696] sd 17:0:0:0: [sdd] Write Protect is off 212 213This shows that the block device associated with the USB drive is 214``/dev/sdd``: 215 216.. code-block:: shell 217 218 tirzah[447]$ ll /dev/sdd 219 brw-rw---- 1 root disk 8, 48 Apr 25 08:10 /dev/sdd 220 221This can be mounted as a file system with the following commands: 222 223.. code-block:: shell 224 225 sudo chmod a+rw /dev/sdd # required to allow user access 226 mkdir /tmp/lfs 227 lfs \ 228 --read_size=16 \ 229 --prog_size=16 \ 230 --block_size=4096 \ 231 --block_count=32 \ 232 --cache_size=64 \ 233 --lookahead_size=32 \ 234 /dev/sdd /tmp/lfs 235 236which produces output like this (disk contents will vary): 237 238.. code-block:: none 239 240 tirzah[467]$ ls -l /tmp/lfs 241 total 0 242 -rwxrwxrwx 0 root root 8 Dec 31 1969 hi 243 -rwxrwxrwx 0 root root 128 Dec 31 1969 linux 244 -rwxrwxrwx 0 root root 5 Dec 31 1969 newfile 245 246``lfs`` is a mount command and you should take care to unmount the 247device before removing the USB drive: 248 249.. code-block:: shell 250 251 umount /tmp/lfs 252 253littlefs parameter selection 254---------------------------- 255 256Be aware that the parameters passed to :command:`lfs` in the example 257above **must** exactly match the corresponding parameters used to 258initialize the file system. The required parameters can be observed 259from the Zephyr mount log messages: 260 261.. code-block:: none 262 263 [00:00:00.009,002] <inf> littlefs: LittleFS version 2.2, disk version 2.0 264 [00:00:00.009,063] <inf> littlefs: FS at MX25R64:0x0 is 16 0x1000-byte blocks with 512 cye 265 [00:00:00.009,063] <inf> littlefs: sizes: rd 16 ; pr 16 ; ca 64 ; la 32 266 267* ``--read_size`` corresponds to the ``rd`` size and is 16; 268* ``--prog_size`` corresponds to the ``pr`` size and is 16; 269* ``--block_size`` comes from ``0x1000-byte blocks`` and is 4096 (0x1000); 270* ``--block_count`` comes from ``16 0x1000-byte blocks`` and is 16; 271* ``--cache_size`` comes from the ``ca`` size and is 64; 272* ``--lookahead_size`` comes from the ``la`` size and is 32 273 274If any of the parameters are inconsistent between the Zephyr and Linux 275specification the file system will not mount correctly. 276 277.. _littlefs: https://github.com/littlefs-project/littlefs 278.. _littlefs-FUSE: https://github.com/littlefs-project/littlefs-fuse 279