cancel
Showing results for 
Search instead for 
Did you mean: 

FATFS + FreeRTOS memory corruption, need confirmation

PSarr.1
Associate II

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

0 REPLIES 0