README.rst
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