/*------------------------------------------------------------------------*/\r
-/* Sample Code of OS Dependent Functions for FatFs */\r
-/* (C)ChaN, 2017 */\r
+/* A Sample Code of User Provided OS Dependent Functions for FatFs */\r
/*------------------------------------------------------------------------*/\r
\r
-\r
#include "ff.h"\r
\r
\r
-\r
-#if FF_USE_LFN == 3 /* Dynamic memory allocation */\r
+#if FF_USE_LFN == 3 /* Use dynamic memory allocation */\r
\r
/*------------------------------------------------------------------------*/\r
-/* Allocate a memory block */\r
+/* Allocate/Free a Memory Block */\r
/*------------------------------------------------------------------------*/\r
\r
-void* ff_memalloc ( /* Returns pointer to the allocated memory block (null on not enough core) */\r
+#include <stdlib.h> /* with POSIX API */\r
+\r
+\r
+void* ff_memalloc ( /* Returns pointer to the allocated memory block (null if not enough core) */\r
UINT msize /* Number of bytes to allocate */\r
)\r
{\r
- return malloc(msize); /* Allocate a new memory block with POSIX API */\r
+ return malloc((size_t)msize); /* Allocate a new memory block */\r
}\r
\r
\r
-/*------------------------------------------------------------------------*/\r
-/* Free a memory block */\r
-/*------------------------------------------------------------------------*/\r
-\r
void ff_memfree (\r
- void* mblock /* Pointer to the memory block to free (nothing to do for null) */\r
+ void* mblock /* Pointer to the memory block to free (no effect if null) */\r
)\r
{\r
- free(mblock); /* Free the memory block with POSIX API */\r
+ free(mblock); /* Free the memory block */\r
}\r
\r
#endif\r
\r
\r
\r
-#if FF_FS_REENTRANT /* Mutal exclusion */\r
\r
+#if FF_FS_REENTRANT /* Mutal exclusion */\r
/*------------------------------------------------------------------------*/\r
-/* Create a Synchronization Object */\r
+/* Definitions of Mutex */\r
/*------------------------------------------------------------------------*/\r
-/* This function is called in f_mount() function to create a new\r
-/ synchronization object for the volume, such as semaphore and mutex.\r
-/ When a 0 is returned, the f_mount() function fails with FR_INT_ERR.\r
-*/\r
\r
-//const osMutexDef_t Mutex[FF_VOLUMES]; /* CMSIS-RTOS */\r
+#define OS_TYPE 0 /* 0:Win32, 1:uITRON4.0, 2:uC/OS-II, 3:FreeRTOS, 4:CMSIS-RTOS */\r
+\r
\r
+#if OS_TYPE == 0 /* Win32 */\r
+#include <windows.h>\r
+static HANDLE Mutex[FF_VOLUMES + 1]; /* Table of mutex handle */\r
+\r
+#elif OS_TYPE == 1 /* uITRON */\r
+#include "itron.h"\r
+#include "kernel.h"\r
+static mtxid Mutex[FF_VOLUMES + 1]; /* Table of mutex ID */\r
+\r
+#elif OS_TYPE == 2 /* uc/OS-II */\r
+#include "includes.h"\r
+static OS_EVENT *Mutex[FF_VOLUMES + 1]; /* Table of mutex pinter */\r
+\r
+#elif OS_TYPE == 3 /* FreeRTOS */\r
+#include "FreeRTOS.h"\r
+#include "semphr.h"\r
+static SemaphoreHandle_t Mutex[FF_VOLUMES + 1]; /* Table of mutex handle */\r
+\r
+#elif OS_TYPE == 4 /* CMSIS-RTOS */\r
+#include "cmsis_os.h"\r
+static osMutexId Mutex[FF_VOLUMES + 1]; /* Table of mutex ID */\r
+\r
+#endif\r
+\r
+\r
+\r
+/*------------------------------------------------------------------------*/\r
+/* Create a Mutex */\r
+/*------------------------------------------------------------------------*/\r
+/* This function is called in f_mount function to create a new mutex\r
+/ or semaphore for the volume. When a 0 is returned, the f_mount function\r
+/ fails with FR_INT_ERR.\r
+*/\r
\r
-int ff_cre_syncobj ( /* 1:Function succeeded, 0:Could not create the sync object */\r
- BYTE vol, /* Corresponding volume (logical drive number) */\r
- FF_SYNC_t* sobj /* Pointer to return the created sync object */\r
+int ff_mutex_create ( /* Returns 1:Function succeeded or 0:Could not create the mutex */\r
+ int vol /* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */\r
)\r
{\r
- /* Win32 */\r
- *sobj = CreateMutex(NULL, FALSE, NULL);\r
- return (int)(*sobj != INVALID_HANDLE_VALUE);\r
-\r
- /* uITRON */\r
-// T_CSEM csem = {TA_TPRI,1,1};\r
-// *sobj = acre_sem(&csem);\r
-// return (int)(*sobj > 0);\r
-\r
- /* uC/OS-II */\r
-// OS_ERR err;\r
-// *sobj = OSMutexCreate(0, &err);\r
-// return (int)(err == OS_NO_ERR);\r
-\r
- /* FreeRTOS */\r
-// *sobj = xSemaphoreCreateMutex();\r
-// return (int)(*sobj != NULL);\r
-\r
- /* CMSIS-RTOS */\r
-// *sobj = osMutexCreate(Mutex + vol);\r
-// return (int)(*sobj != NULL);\r
+#if OS_TYPE == 0 /* Win32 */\r
+ Mutex[vol] = CreateMutex(NULL, FALSE, NULL);\r
+ return (int)(Mutex[vol] != INVALID_HANDLE_VALUE);\r
+\r
+#elif OS_TYPE == 1 /* uITRON */\r
+ T_CMTX cmtx = {TA_TPRI,1};\r
+\r
+ Mutex[vol] = acre_mtx(&cmtx);\r
+ return (int)(Mutex[vol] > 0);\r
+\r
+#elif OS_TYPE == 2 /* uC/OS-II */\r
+ OS_ERR err;\r
+\r
+ Mutex[vol] = OSMutexCreate(0, &err);\r
+ return (int)(err == OS_NO_ERR);\r
+\r
+#elif OS_TYPE == 3 /* FreeRTOS */\r
+ Mutex[vol] = xSemaphoreCreateMutex();\r
+ return (int)(Mutex[vol] != NULL);\r
+\r
+#elif OS_TYPE == 4 /* CMSIS-RTOS */\r
+ osMutexDef(cmsis_os_mutex);\r
+\r
+ Mutex[vol] = osMutexCreate(osMutex(cmsis_os_mutex));\r
+ return (int)(Mutex[vol] != NULL);\r
+\r
+#endif\r
}\r
\r
\r
/*------------------------------------------------------------------------*/\r
-/* Delete a Synchronization Object */\r
+/* Delete a Mutex */\r
/*------------------------------------------------------------------------*/\r
-/* This function is called in f_mount() function to delete a synchronization\r
-/ object that created with ff_cre_syncobj() function. When a 0 is returned,\r
-/ the f_mount() function fails with FR_INT_ERR.\r
+/* This function is called in f_mount function to delete a mutex or\r
+/ semaphore of the volume created with ff_mutex_create function.\r
*/\r
\r
-int ff_del_syncobj ( /* 1:Function succeeded, 0:Could not delete due to an error */\r
- FF_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */\r
+void ff_mutex_delete ( /* Returns 1:Function succeeded or 0:Could not delete due to an error */\r
+ int vol /* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */\r
)\r
{\r
- /* Win32 */\r
- return (int)CloseHandle(sobj);\r
+#if OS_TYPE == 0 /* Win32 */\r
+ CloseHandle(Mutex[vol]);\r
\r
- /* uITRON */\r
-// return (int)(del_sem(sobj) == E_OK);\r
+#elif OS_TYPE == 1 /* uITRON */\r
+ del_mtx(Mutex[vol]);\r
\r
- /* uC/OS-II */\r
-// OS_ERR err;\r
-// OSMutexDel(sobj, OS_DEL_ALWAYS, &err);\r
-// return (int)(err == OS_NO_ERR);\r
+#elif OS_TYPE == 2 /* uC/OS-II */\r
+ OS_ERR err;\r
\r
- /* FreeRTOS */\r
-// vSemaphoreDelete(sobj);\r
-// return 1;\r
+ OSMutexDel(Mutex[vol], OS_DEL_ALWAYS, &err);\r
\r
- /* CMSIS-RTOS */\r
-// return (int)(osMutexDelete(sobj) == osOK);\r
+#elif OS_TYPE == 3 /* FreeRTOS */\r
+ vSemaphoreDelete(Mutex[vol]);\r
+\r
+#elif OS_TYPE == 4 /* CMSIS-RTOS */\r
+ osMutexDelete(Mutex[vol]);\r
+\r
+#endif\r
}\r
\r
\r
/*------------------------------------------------------------------------*/\r
-/* Request Grant to Access the Volume */\r
+/* Request a Grant to Access the Volume */\r
/*------------------------------------------------------------------------*/\r
-/* This function is called on entering file functions to lock the volume.\r
+/* This function is called on enter file functions to lock the volume.\r
/ When a 0 is returned, the file function fails with FR_TIMEOUT.\r
*/\r
\r
-int ff_req_grant ( /* 1:Got a grant to access the volume, 0:Could not get a grant */\r
- FF_SYNC_t sobj /* Sync object to wait */\r
+int ff_mutex_take ( /* Returns 1:Succeeded or 0:Timeout */\r
+ int vol /* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */\r
)\r
{\r
- /* Win32 */\r
- return (int)(WaitForSingleObject(sobj, FF_FS_TIMEOUT) == WAIT_OBJECT_0);\r
+#if OS_TYPE == 0 /* Win32 */\r
+ return (int)(WaitForSingleObject(Mutex[vol], FF_FS_TIMEOUT) == WAIT_OBJECT_0);\r
+\r
+#elif OS_TYPE == 1 /* uITRON */\r
+ return (int)(tloc_mtx(Mutex[vol], FF_FS_TIMEOUT) == E_OK);\r
+\r
+#elif OS_TYPE == 2 /* uC/OS-II */\r
+ OS_ERR err;\r
\r
- /* uITRON */\r
-// return (int)(wai_sem(sobj) == E_OK);\r
+ OSMutexPend(Mutex[vol], FF_FS_TIMEOUT, &err));\r
+ return (int)(err == OS_NO_ERR);\r
\r
- /* uC/OS-II */\r
-// OS_ERR err;\r
-// OSMutexPend(sobj, FF_FS_TIMEOUT, &err));\r
-// return (int)(err == OS_NO_ERR);\r
+#elif OS_TYPE == 3 /* FreeRTOS */\r
+ return (int)(xSemaphoreTake(Mutex[vol], FF_FS_TIMEOUT) == pdTRUE);\r
\r
- /* FreeRTOS */\r
-// return (int)(xSemaphoreTake(sobj, FF_FS_TIMEOUT) == pdTRUE);\r
+#elif OS_TYPE == 4 /* CMSIS-RTOS */\r
+ return (int)(osMutexWait(Mutex[vol], FF_FS_TIMEOUT) == osOK);\r
\r
- /* CMSIS-RTOS */\r
-// return (int)(osMutexWait(sobj, FF_FS_TIMEOUT) == osOK);\r
+#endif\r
}\r
\r
\r
+\r
/*------------------------------------------------------------------------*/\r
-/* Release Grant to Access the Volume */\r
+/* Release a Grant to Access the Volume */\r
/*------------------------------------------------------------------------*/\r
-/* This function is called on leaving file functions to unlock the volume.\r
+/* This function is called on leave file functions to unlock the volume.\r
*/\r
\r
-void ff_rel_grant (\r
- FF_SYNC_t sobj /* Sync object to be signaled */\r
+void ff_mutex_give (\r
+ int vol /* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */\r
)\r
{\r
- /* Win32 */\r
- ReleaseMutex(sobj);\r
+#if OS_TYPE == 0 /* Win32 */\r
+ ReleaseMutex(Mutex[vol]);\r
\r
- /* uITRON */\r
-// sig_sem(sobj);\r
+#elif OS_TYPE == 1 /* uITRON */\r
+ unl_mtx(Mutex[vol]);\r
\r
- /* uC/OS-II */\r
-// OSMutexPost(sobj);\r
+#elif OS_TYPE == 2 /* uC/OS-II */\r
+ OSMutexPost(Mutex[vol]);\r
\r
- /* FreeRTOS */\r
-// xSemaphoreGive(sobj);\r
+#elif OS_TYPE == 3 /* FreeRTOS */\r
+ xSemaphoreGive(Mutex[vol]);\r
\r
- /* CMSIS-RTOS */\r
-// osMutexRelease(sobj);\r
-}\r
+#elif OS_TYPE == 4 /* CMSIS-RTOS */\r
+ osMutexRelease(Mutex[vol]);\r
\r
#endif\r
+}\r
+\r
+#endif /* FF_FS_REENTRANT */\r
\r