Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

R0.14 : Volume mutex dead-loked => transfer to FatFs forum #11

Open
dbochard opened this issue Sep 20, 2021 · 0 comments
Open

R0.14 : Volume mutex dead-loked => transfer to FatFs forum #11

dbochard opened this issue Sep 20, 2021 · 0 comments

Comments

@dbochard
Copy link

dbochard commented Sep 20, 2021

Transfer to : http://elm-chan.org/fsw/ff/bd/?show=3629

Hello,

We are using fatFs R0.14 with freeRtos 10.3.1

At boot, we have a locked volume, the function lock_fs fails. The mutex is locked by one of our task, but this task is not blocked and we have more than 70% of idle. So, we made sure that this task has taken the mutex and have not been blocked (in fopen or fclose) before releasing the mutex. The task which locks the mutex have done some fopen and fclose and it seems that fatFs is not releasing the mutex. This trouble only happens very rarely, otherwise our device boots fine. For information, at boot, many tasks access the filesystem.

The first error code, on our console, is an fclose error (9). But it may be the cause or the first symptom.

To interface fatFs with freeRtos we are using this file (compilation with portENTER_CRITICAL and FF_FS_REENTRANT defined):

/*------------------------------------------------------------------------*/
/* Sample Code of OS Dependent Functions for FatFs                        */
/* (C)ChaN, 2018                                                          */
/*------------------------------------------------------------------------*/


#include "fatFs/ff.h"


#if FF_USE_LFN == 3	/* Dynamic memory allocation */

/*------------------------------------------------------------------------*/
/* Allocate a memory block                                                */
/*------------------------------------------------------------------------*/

void* ff_memalloc (	/* Returns pointer to the allocated memory block (null if not enough core) */
	UINT msize		/* Number of bytes to allocate */
)
{
#if defined portENTER_CRITICAL
  return pvPortMalloc(msize);
#else
	return malloc(msize);	/* Allocate a new memory block with POSIX API */
#endif
}


/*------------------------------------------------------------------------*/
/* Free a memory block                                                    */
/*------------------------------------------------------------------------*/

void ff_memfree (
	void* mblock	/* Pointer to the memory block to free (nothing to do if null) */
)
{
#if defined portENTER_CRITICAL
  vPortFree(mblock);
#else
	free(mblock);	/* Free the memory block with POSIX API */
#endif
}

#endif



#if FF_FS_REENTRANT	/* Mutal exclusion */

/*------------------------------------------------------------------------*/
/* Create a Synchronization Object                                        */
/*------------------------------------------------------------------------*/
/* This function is called in f_mount() function to create a new
/  synchronization object for the volume, such as semaphore and mutex.
/  When a 0 is returned, the f_mount() function fails with FR_INT_ERR.
*/

//const osMutexDef_t Mutex[FF_VOLUMES];	/* Table of CMSIS-RTOS mutex */


int ff_cre_syncobj (	/* 1:Function succeeded, 0:Could not create the sync object */
	BYTE vol,			/* Corresponding volume (logical drive number) */
	FF_SYNC_t* sobj		/* Pointer to return the created sync object */
)
{
#if defined(_WIN32) /* Win32 */
	*sobj = CreateMutex(NULL, FALSE, NULL);
	return (int)(*sobj != INVALID_HANDLE_VALUE);
#endif

	/* uITRON */
//	T_CSEM csem = {TA_TPRI,1,1};
//	*sobj = acre_sem(&csem);
//	return (int)(*sobj > 0);

	/* uC/OS-II */
//	OS_ERR err;
//	*sobj = OSMutexCreate(0, &err);
//	return (int)(err == OS_NO_ERR);

#if defined(portENTER_CRITICAL)   /* FreeRTOS */
	(void)vol;
	*sobj = xSemaphoreCreateMutex();
	return (int)(*sobj != NULL);
#endif

#if defined(osCMSIS) /* CMSIS-RTOS */
	*sobj = osMutexCreate(&Mutex[vol]);
	return (int)(*sobj != NULL);
#endif
}


/*------------------------------------------------------------------------*/
/* Delete a Synchronization Object                                        */
/*------------------------------------------------------------------------*/
/* This function is called in f_mount() function to delete a synchronization
/  object that created with ff_cre_syncobj() function. When a 0 is returned,
/  the f_mount() function fails with FR_INT_ERR.
*/

int ff_del_syncobj (	/* 1:Function succeeded, 0:Could not delete due to an error */
	FF_SYNC_t sobj		/* Sync object tied to the logical drive to be deleted */
)
{
#if defined(_WIN32) /* Win32 */
	return (int)CloseHandle(sobj);
#endif

	/* uITRON */
//	return (int)(del_sem(sobj) == E_OK);

	/* uC/OS-II */
//	OS_ERR err;
//	OSMutexDel(sobj, OS_DEL_ALWAYS, &err);
//	return (int)(err == OS_NO_ERR);

#if defined(portENTER_CRITICAL)   /* FreeRTOS */
  vSemaphoreDelete(sobj);
	return 1;
#endif

#if defined(osCMSIS) /* CMSIS-RTOS */
	return (int)(osMutexDelete(sobj) == osOK);
#endif
}


/*------------------------------------------------------------------------*/
/* Request Grant to Access the Volume                                     */
/*------------------------------------------------------------------------*/
/* This function is called on entering file functions to lock the volume.
/  When a 0 is returned, the file function fails with FR_TIMEOUT.
*/

int ff_req_grant (	/* 1:Got a grant to access the volume, 0:Could not get a grant */
	FF_SYNC_t sobj	/* Sync object to wait */
)
{
#if defined(_WIN32) /* Win32 */
	return (int)(WaitForSingleObject(sobj, FF_FS_TIMEOUT) == WAIT_OBJECT_0);
#endif

	/* uITRON */
//	return (int)(wai_sem(sobj) == E_OK);

	/* uC/OS-II */
//	OS_ERR err;
//	OSMutexPend(sobj, FF_FS_TIMEOUT, &err));
//	return (int)(err == OS_NO_ERR);

#if defined(portENTER_CRITICAL)   /* FreeRTOS */
	return (int)(xSemaphoreTake(sobj, FF_FS_TIMEOUT) == pdTRUE);
#endif

#if defined(osCMSIS) /* CMSIS-RTOS */
	return (int)(osMutexWait(sobj, FF_FS_TIMEOUT) == osOK);
#endif
}


/*------------------------------------------------------------------------*/
/* Release Grant to Access the Volume                                     */
/*------------------------------------------------------------------------*/
/* This function is called on leaving file functions to unlock the volume.
*/

void ff_rel_grant (
	FF_SYNC_t sobj	/* Sync object to be signaled */
)
{
#if defined(_WIN32) /* Win32 */
	ReleaseMutex(sobj);
#endif

	/* uITRON */
//	sig_sem(sobj);

	/* uC/OS-II */
//	OSMutexPost(sobj);

#if defined(portENTER_CRITICAL)   /* FreeRTOS */
	xSemaphoreGive(sobj);
#endif

#if defined(osCMSIS) /* CMSIS-RTOS */
	osMutexRelease(sobj);
#endif
}

#endif
@dbochard dbochard changed the title R0.14 : Volume mutex dead-loked R0.14 : Volume mutex dead-loked transféré sur le forum FatFs Sep 21, 2021
@dbochard dbochard changed the title R0.14 : Volume mutex dead-loked transféré sur le forum FatFs R0.14 : Volume mutex dead-loked => transfer to FatFs forum Sep 21, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant