2020-08-18 06:30 AM
Hi,
I created a project using the STM32CubeIDE for a STM32F2xx. This project include USB in host mode with a mass storage class, FATFS and FreeRTOS.
With freeRTOS, FATFS is put in REETRANT mode. I also put the MAX_SS to 4096 because I need the sector size to be bigger for a fafts-flash implementation.
When I do a f_mount, the fs->sobj is created and lock. In the f_mount function we called find_volume which then eventually call the function "USBH_ioctl" in usbh_ioctl to get the sector size.
The current implementation is casting the void * buff parameter to a DWORD *. But, in this case the void * buff is a pointer to (fs)->ssize which is a WORD.
So the current implementation is corrupting the fs->sobj which is place right after the ssize variable in the fs structure.
typedef struct {
union{
UINT d32[_MAX_SS/4]; /* Force 32bits alignement */
BYTE d8[_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
}win;
BYTE fs_type; /* FAT sub-type (0:Not mounted) */
BYTE drv; /* Physical drive number */
BYTE csize; /* Sectors per cluster (1,2,4...128) */
BYTE n_fats; /* Number of FAT copies (1 or 2) */
BYTE wflag; /* win[] flag (b0:dirty) */
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
WORD id; /* File system mount ID */
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
#if _MAX_SS != _MIN_SS
WORD ssize; /* Bytes per sector (512, 1024, 2048 or 4096) */
#endif
#if _FS_REENTRANT
_SYNC_t sobj; /* Identifier of sync object */
#endif
#if !_FS_READONLY
DWORD last_clust; /* Last allocated cluster */
DWORD free_clust; /* Number of free clusters */
#endif
#if _FS_RPATH
DWORD cdir; /* Current directory start cluster (0:root) */
#endif
DWORD n_fatent; /* Number of FAT entries, = number of clusters + 2 */
DWORD fsize; /* Sectors per FAT */
DWORD volbase; /* Volume start sector */
DWORD fatbase; /* FAT start sector */
DWORD dirbase; /* Root directory start sector (FAT32:Cluster#) */
DWORD database; /* Data start sector */
DWORD winsect; /* Current sector appearing in the win[] */
} FATFS;
Event the comment of the get_Sector_size is saying a WORD... see current code of USBH_ioctl() in usbh_diskio.c
/* Get R/W sector size (WORD) */
case GET_SECTOR_SIZE :
if(USBH_MSC_GetLUNInfo(&HOST_HANDLE, lun, &info) == USBH_OK)
{
*(DWORD*)buff = info.capacity.block_size;
res = RES_OK;
}
else
{
res = RES_ERROR;
}
break;
If I make the following change, there is no more memory corruption
*(DWORD*)buff = info.capacity.block_size; -> *(WORD*)buff = info.capacity.block_size;
It can be me who doesn't use the library correctly... I would appreciate if somebody can confirm this problem and let me know the best way to get it corrected for everybody.
Let me know if you need more details
Regards