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