2024-05-12 02:08 AM
Hello everyone.
I am working on a project which needs low level access to USB mass storage class such as reading sector size/count of an attached storage device but thus far I could not get anything out of my board which is nucleo-f446re.
I have initialized my board as a USB host mass storage class and I am abled to write on specific sectors such as sector number 10 and it DOES write it down using msc_scsi.c functions but I can't find any solution to determine sector count of attached device. I just can't find the appropriate function/data structure for it,
Can anyone please help me with it?
2024-05-12 02:32 AM
Hi,
i just can tell you, how i do it :
using the fatfs , start with mount ; then can use :
f_getfree("0:", &free_cluster, &fs); // to get free clusters
free_cluster = (free_cluster * USBfs.csize ) / 2000000UL ; // calculate free GB on device
or get/print total volume size :
sprintf(TempChar, "USB:%d GB",(int) ((USBfs.n_fatent * USBfs.csize + 500000UL) / 2000000UL));
+
If you want do everything without any filesystem (why ? cannot use card in PC anymore...)
look at fatfs functions, how the information is collected from filesystem on card:
2024-05-12 02:38 AM
Thanks for your reply but I am trying to avoid any file system layer whatsoever.
I am doing it for educational purposes, I know how to use file system layer functions to get info I need but what about device layer?
Let's say you have a device with corrupted filesystem which data cannot be relied on, obviously you cannot read sector size of storage from file system layer in this scenario so there must be some other ways to read that info
2024-05-12 03:18 AM - edited 2024-05-12 03:38 AM
Right, there is an info block on the device, because if you want format a corrupted file system, the format needs some info, what it should format then.
So search for this basic info - or just look at fatfs -> mkfs (= format) , what its reading from device, to get the info.
http://elm-chan.org/fsw/ff/doc/mkfs.html
here part of mkfs source :
/* Determine where the volume to be located (b_vol, sz_vol) */
if (_MULTI_PARTITION && part != 0) {
/* Get partition information from partition table in the MBR */
if (disk_read(pdrv, buf, 0, 1) != RES_OK) return FR_DISK_ERR; /* Load MBR */
if (ld_word(buf + BS_55AA) != 0xAA55) return FR_MKFS_ABORTED; /* Check if MBR is valid */
pte = buf + (MBR_Table + (part - 1) * SZ_PTE);
if (!pte[PTE_System]) return FR_MKFS_ABORTED; /* No partition? */
b_vol = ld_dword(pte + PTE_StLba); /* Get volume start sector */
sz_vol = ld_dword(pte + PTE_SizLba); /* Get volume size */
http://elm-chan.org/fsw/ff/doc/filename.html#vol
/* Create a single-partition in this function */
if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_vol) != RES_OK) return FR_DISK_ERR;
b_vol = (opt & FM_SFD) ? 0 : 63; /* Volume start sector */
if (sz_vol < b_vol) return FR_MKFS_ABORTED;
sz_vol -= b_vol; /* Volume size */
2024-05-12 03:26 AM
The disk layer should implement ioctl GET_SECTOR_COUNT, and also GET_SECTOR_SIZE, GET_BLOCK_SIZE. This is how fatfs knows it.
2024-05-12 05:51 AM
Thanks for your reply but I think that's still not it.
Its' reading MBR record which is sector 0 of any storage which holds info about partitions etc. But what if MBR is missing as well? The code you put here formats a partition using MBR record, which already has info about partition size in sectors ofcourse, but what if a device has been blanked colpmelety?
I have done it multiple times using my linux operation system using dd command, which wipes the device altogether leaving no data behind including MBR record.
How can we get disk sector size then?
2024-05-12 05:52 AM
Thanks pal.
I guess those commands are low level USB MSC commands, right?
How can I invoke them? By what function call I mean
2024-05-12 05:56 AM
By any chance, could it be this function?
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
2024-05-12 06:08 AM
And one more question, how can I associate USBH_HandleTypeDef with those functions?
2024-05-12 08:06 AM
SCSI command READ CAPACITY, there should be a 10 or 16 byte CDB version
The IDENTIFY command should get Block Size