0
\$\begingroup\$

I'm working with an STM32F3DISCOVERY board. I want to provide USB mass storage functionality over the user USB plug on the board (not the one of the ST-LINK).

I'm following ST's video tutorial as closely as possible, with only the following distinctions:

  • I use a different chip/board
  • I use STM32CubeIDE, Version: 1.3.1, Build: 6291_20200406_0752 (UTC)
  • I use a smaller buffer/media size (16K)

When I plug it into windows, it asks me to format the disk just like in the video. However, the formatting process does not complete.

I get the same message as Youtube commenter "Rtek100":

Windows was unable to complete the format.

Trying to format with windows disk management, I got the error message:

The cluster size is too large for the file system

I tried the same thing under linux with the disks utility and got the following result: enter image description here


What causes this problem?

Is it related to the settings of the high and low speed clock settings? When he assigns "BYPASS Clock Source" to the High Speed Clock, he mentions that it will come from the ST-LINK. Does this mean that I need to power the ST-LINK USB plug?

update

I watched the tutorial again and found that I have missed to increase the heap size. The problem is still the same. On linux the error message changed (see below), although I'm not sure if this is related to the heap size.

comments

On Linux, after it fails, run dmesg | tail -n100 and look for I/O related errors and post them here.

To my surprise, the error message is now different (for possible reasons, see update above):

enter image description here

I tried dmesg and the following is what I get for unplugging, replugging the device. The attempt to format the disk added no further entries to dmesg.

[  968.463379] usb 2-1.2: USB disconnect, device number 9
[  971.502067] usb 2-1.2: new full-speed USB device number 10 using ehci-pci
[  971.613248] usb 2-1.2: New USB device found, idVendor=0483, idProduct=572a
[  971.613253] usb 2-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[  971.613256] usb 2-1.2: Product: STM32 Mass Storage
[  971.613258] usb 2-1.2: Manufacturer: STMicroelectronics
[  971.613260] usb 2-1.2: SerialNumber: 206636734136
[  971.614248] usb-storage 2-1.2:1.0: USB Mass Storage device detected
[  971.614759] scsi host0: usb-storage 2-1.2:1.0
[  972.619001] scsi 0:0:0:0: Direct-Access     STM      Product          0.01 PQ: 0 ANSI: 2
[  972.619599] sd 0:0:0:0: Attached scsi generic sg3 type 0
[  972.620374] sd 0:0:0:0: [sdc] 32 512-byte logical blocks: (16.4 kB/16.0 KiB)
[  972.621077] sd 0:0:0:0: [sdc] Write Protect is off
[  972.621080] sd 0:0:0:0: [sdc] Mode Sense: 00 00 00 00
[  972.621701] sd 0:0:0:0: [sdc] Asking for cache data failed
[  972.621707] sd 0:0:0:0: [sdc] Assuming drive cache: write through
[  972.653486] sd 0:0:0:0: [sdc] Attached SCSI removable disk

I ran fdisk as well:

$ sudo fdisk -l /dev/sdc 
Disk /dev/sdc: 16 KiB, 16384 bytes, 32 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

16 kilobytes? Is that the correct size of your device? I think mkfs is telling you that it can't create a filesystem that small.

Yes, that's correct. The tutorial uses 64, but my chip does not have that much SRAM, so I went with a smaller size.

I checked FAT size limits:

FAT32 minimum : 1 sector per cluster × 65,525 clusters = 33,548,800 bytes (32,762.5 KB)

This might be the cause of the problem, but if 33,548,800 bytes is the lower limit, why do the 64k work in the video? What am I missing here?

\$\endgroup\$
5
  • \$\begingroup\$ On Linux, after it fails, run dmesg | tail -n100 and look for I/O related errors and post them here. \$\endgroup\$ Commented Jul 17, 2020 at 16:44
  • \$\begingroup\$ @user253751 thank you for the recommendation. I added the requested information. \$\endgroup\$ Commented Jul 17, 2020 at 17:39
  • 4
    \$\begingroup\$ 16 kilobytes? Is that the correct size of your device? I think mkfs is telling you that it can't create a filesystem that small. \$\endgroup\$ Commented Jul 17, 2020 at 18:32
  • \$\begingroup\$ @user253751 so is this a limitation of mkfs? I did some research (see edit), which suggests that this is indeed quite small. But then how come the 64k in the video work? Coincidence? \$\endgroup\$ Commented Jul 17, 2020 at 19:17
  • 1
    \$\begingroup\$ You can actually test mkfs by trying to mkfs a file (which simulates a hard drive). You can look up how to make a certain sized file in Linux, then mkfs it. See if it works for 16k and 64k. \$\endgroup\$ Commented Jul 17, 2020 at 19:23

1 Answer 1

1
\$\begingroup\$

So I've run some tests to try to explain why it works for 64 KiB and not some smaller sizes. As a disclaimer, this explanation isn't based on the FAT specification, but on the tool mkfs.vfat you used.

TL;DR:

you need at least 34 KiB

Firstly, you can create an appropriately sized file by using dd and then format it as FAT with some options to guarantee the minimum amount of overhead:

dd if=/dev/zero of=desired_file_name bs=512 count=desired_sector_count

mkfs.vfat -I -n "TEST" -f1 -r16 -R1 -s1 -v file_you_created

So, starting off at a 32 KiB guess, which equates 64 sectors of 512 B, you get the result:

mkfs.vfat: Too few blocks for viable filesystem

Bad luck. But what is the tool checking to decide that? It turns out the source code for dosfstools's mkfs.fat says:

if (blocks < start_data_block + 32) /* Arbitrary undersize filesystem! */
    die("Too few blocks for viable filesystem");

Source: GitHub

Since the conversion ratio is 2 sectors <> 1 block, the program expects at least 64 sectors of data space. But that's not everything. The metadata space occupies a minimum of 3 sectors (boot, directory, FAT), which gives a start_data_block of 2 blocks (with 1 empty sector before the data for block alignment). So the minimum is 34 blocks, or 68 sectors, or 34816 bytes.

dd if=/dev/zero of=minimum bs=512 count=68
mkfs.vfat -I -n "TEST" -f1 -r16 -R1 -s1 -v minimum
(...)
mkfs.fat 4.1 (2017-01-24)
minimum has 64 heads and 32 sectors per track,
hidden sectors 0x0000;
logical sector size is 512,
using 0xf8 media descriptor, with 68 sectors;
drive number 0x80;
filesystem has 1 12-bit FAT and 1 sector per cluster.
FAT size is 1 sector, and provides 65 clusters.
There is 1 reserved sector.
Root directory contains 16 slots and uses 1 sectors.
Volume ID is 4d6a32d7, volume label TEST       .

Success at 34 KiB!

By the way, you checked the FAT size limits for FAT32. A volume this small is FAT12.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.