dfs_elm.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783
  1. /*
  2. * File : dfs_elm.c
  3. * This file is part of Device File System in RT-Thread RTOS
  4. * COPYRIGHT (C) 2008-2011, RT-Thread Development Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://www.rt-thread.org/license/LICENSE.
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2008-02-22 QiuYi The first version.
  13. * 2011-10-08 Bernard fixed the block size in statfs.
  14. * 2011-11-23 Bernard fixed the rename issue.
  15. */
  16. #include <rtthread.h>
  17. #include "ffconf.h"
  18. #include "ff.h"
  19. /* ELM FatFs provide a DIR struct */
  20. #define HAVE_DIR_STRUCTURE
  21. #include <dfs_fs.h>
  22. #include <dfs_def.h>
  23. static rt_device_t disk[_VOLUMES] = {0};
  24. static int elm_result_to_dfs(FRESULT result)
  25. {
  26. int status = DFS_STATUS_OK;
  27. switch (result)
  28. {
  29. case FR_OK:
  30. break;
  31. case FR_NO_FILE:
  32. case FR_NO_PATH:
  33. case FR_NO_FILESYSTEM:
  34. status = -DFS_STATUS_ENOENT;
  35. break;
  36. case FR_INVALID_NAME:
  37. status = -DFS_STATUS_EINVAL;
  38. break;
  39. case FR_EXIST:
  40. case FR_INVALID_OBJECT:
  41. status = -DFS_STATUS_EEXIST;
  42. break;
  43. case FR_DISK_ERR:
  44. case FR_NOT_READY:
  45. case FR_INT_ERR:
  46. status = -DFS_STATUS_EIO;
  47. break;
  48. case FR_WRITE_PROTECTED:
  49. case FR_DENIED:
  50. status = -DFS_STATUS_EROFS;
  51. break;
  52. case FR_MKFS_ABORTED:
  53. status = -DFS_STATUS_EINVAL;
  54. break;
  55. default:
  56. status = -1;
  57. break;
  58. }
  59. return status;
  60. }
  61. int dfs_elm_mount(struct dfs_filesystem* fs, unsigned long rwflag, const void* data)
  62. {
  63. FATFS *fat;
  64. FRESULT result;
  65. rt_uint32_t index;
  66. /* handle RT-Thread device routine */
  67. for (index = 0; index < _VOLUMES; index ++)
  68. {
  69. if (disk[index] == RT_NULL)
  70. {
  71. break;
  72. }
  73. }
  74. if (index == _VOLUMES) return -DFS_STATUS_ENOSPC;
  75. /* get device */
  76. disk[index] = fs->dev_id;
  77. fat = (FATFS *) rt_malloc(sizeof(FATFS));
  78. if (fat == RT_NULL)
  79. {
  80. return -1;
  81. }
  82. /* mount fatfs, always 0 logic driver */
  83. result = f_mount(index, fat);
  84. if (result == FR_OK)
  85. fs->data = fat;
  86. else
  87. {
  88. rt_free(fat);
  89. return elm_result_to_dfs(result);
  90. }
  91. return 0;
  92. }
  93. int dfs_elm_unmount(struct dfs_filesystem* fs)
  94. {
  95. FATFS *fat;
  96. FRESULT result;
  97. rt_uint32_t index;
  98. fat = (FATFS*) fs->data;
  99. RT_ASSERT(fat != RT_NULL);
  100. /* find the device index and then umount it */
  101. for (index = 0; index < _VOLUMES; index ++)
  102. {
  103. if (disk[index] == fs->dev_id)
  104. {
  105. result = f_mount(index, RT_NULL);
  106. if (result == FR_OK)
  107. {
  108. fs->data = RT_NULL;
  109. disk[index] = RT_NULL;
  110. rt_free(fat);
  111. return DFS_STATUS_OK;
  112. }
  113. }
  114. }
  115. return -DFS_STATUS_ENOENT;
  116. }
  117. int dfs_elm_mkfs(const char* device_name)
  118. {
  119. BYTE drv;
  120. rt_device_t dev;
  121. FRESULT result;
  122. /* find device name */
  123. for (drv = 0; drv < _VOLUMES; drv ++)
  124. {
  125. dev = disk[drv];
  126. if (rt_strncmp(dev->parent.name, device_name, RT_NAME_MAX) == 0)
  127. {
  128. /* 1: no partition table */
  129. /* 0: auto selection of cluster size */
  130. result = f_mkfs(drv, 1, 0);
  131. if ( result != FR_OK)
  132. {
  133. rt_kprintf("format error\n");
  134. return elm_result_to_dfs(result);
  135. }
  136. return DFS_STATUS_OK;
  137. }
  138. }
  139. /* can't find device driver */
  140. rt_kprintf("can not find device driver: %s\n", device_name);
  141. return -DFS_STATUS_EIO;
  142. }
  143. int dfs_elm_statfs(struct dfs_filesystem* fs, struct statfs *buf)
  144. {
  145. FATFS *f;
  146. FRESULT res;
  147. char driver[4];
  148. DWORD fre_clust, fre_sect, tot_sect;
  149. RT_ASSERT(fs != RT_NULL);
  150. RT_ASSERT(buf != RT_NULL);
  151. f = (FATFS*) fs->data;
  152. rt_snprintf(driver, sizeof(driver), "%d:", f->drv);
  153. res = f_getfree(driver, &fre_clust, &f);
  154. if (res) return elm_result_to_dfs(res);
  155. /* Get total sectors and free sectors */
  156. tot_sect = (f->n_fatent - 2) * f->csize;
  157. fre_sect = fre_clust * f->csize;
  158. buf->f_bfree = fre_sect;
  159. buf->f_blocks = tot_sect;
  160. #if _MAX_SS != 512
  161. buf->f_bsize = f->ssize;
  162. #else
  163. buf->f_bsize = 512;
  164. #endif
  165. return 0;
  166. }
  167. int dfs_elm_open(struct dfs_fd* file)
  168. {
  169. FIL* fd;
  170. BYTE mode;
  171. FRESULT result;
  172. char *drivers_fn;
  173. #if (_VOLUMES > 1)
  174. int vol;
  175. extern int elm_get_vol(FATFS *fat);
  176. /* add path for ELM FatFS driver support */
  177. vol = elm_get_vol((FATFS *)file->fs->data);
  178. if (vol < 0) return -DFS_STATUS_ENOENT;
  179. drivers_fn = rt_malloc(256);
  180. if (drivers_fn == RT_NULL) return -DFS_STATUS_ENOMEM;
  181. rt_snprintf(drivers_fn, 256, "%d:%s", vol, file->path);
  182. #else
  183. drivers_fn = file->path;
  184. #endif
  185. if (file->flags & DFS_O_DIRECTORY)
  186. {
  187. DIR *dir;
  188. if (file->flags & DFS_O_CREAT)
  189. {
  190. result = f_mkdir(drivers_fn);
  191. if (result != FR_OK)
  192. {
  193. #if _VOLUMES > 1
  194. rt_free(drivers_fn);
  195. #endif
  196. return elm_result_to_dfs(result);
  197. }
  198. }
  199. /* open directory */
  200. dir = (DIR *)rt_malloc(sizeof(DIR));
  201. if (dir == RT_NULL)
  202. {
  203. #if _VOLUMES > 1
  204. rt_free(drivers_fn);
  205. #endif
  206. return -DFS_STATUS_ENOMEM;
  207. }
  208. result = f_opendir(dir, drivers_fn);
  209. #if _VOLUMES > 1
  210. rt_free(drivers_fn);
  211. #endif
  212. if (result != FR_OK)
  213. {
  214. rt_free(dir);
  215. return elm_result_to_dfs(result);
  216. }
  217. file->data = dir;
  218. return DFS_STATUS_OK;
  219. }
  220. else
  221. {
  222. mode = FA_READ;
  223. if (file->flags & DFS_O_WRONLY) mode |= FA_WRITE;
  224. if ((file->flags & DFS_O_ACCMODE) & DFS_O_RDWR) mode |= FA_WRITE;
  225. /* Opens the file, if it is existing. If not, a new file is created. */
  226. if (file->flags & DFS_O_CREAT) mode |= FA_OPEN_ALWAYS;
  227. /* Creates a new file. If the file is existing, it is truncated and overwritten. */
  228. if (file->flags & DFS_O_TRUNC) mode |= FA_CREATE_ALWAYS;
  229. /* Creates a new file. The function fails if the file is already existing. */
  230. if (file->flags & DFS_O_EXCL) mode |= FA_CREATE_NEW;
  231. /* allocate a fd */
  232. fd = (FIL*)rt_malloc(sizeof(FIL));
  233. if (fd == RT_NULL)
  234. {
  235. return -DFS_STATUS_ENOMEM;
  236. }
  237. result = f_open(fd, drivers_fn, mode);
  238. #if _VOLUMES > 1
  239. rt_free(drivers_fn);
  240. #endif
  241. if (result == FR_OK)
  242. {
  243. file->pos = fd->fptr;
  244. file->size = fd->fsize;
  245. file->data = fd;
  246. if (file->flags & DFS_O_APPEND)
  247. {
  248. file->pos = f_lseek(fd, fd->fsize);
  249. }
  250. }
  251. else
  252. {
  253. /* open failed, return */
  254. rt_free(fd);
  255. return elm_result_to_dfs(result);
  256. }
  257. }
  258. return DFS_STATUS_OK;
  259. }
  260. int dfs_elm_close(struct dfs_fd* file)
  261. {
  262. FRESULT result;
  263. result = FR_OK;
  264. if (file->type == FT_DIRECTORY)
  265. {
  266. DIR* dir;
  267. dir = (DIR*)(file->data);
  268. RT_ASSERT(dir != RT_NULL);
  269. /* release memory */
  270. rt_free(dir);
  271. }
  272. else if (file->type == FT_REGULAR)
  273. {
  274. FIL* fd;
  275. fd = (FIL*)(file->data);
  276. RT_ASSERT(fd != RT_NULL);
  277. result = f_close(fd);
  278. if (result == FR_OK)
  279. {
  280. /* release memory */
  281. rt_free(fd);
  282. }
  283. }
  284. return elm_result_to_dfs(result);
  285. }
  286. int dfs_elm_ioctl(struct dfs_fd* file, int cmd, void* args)
  287. {
  288. return -DFS_STATUS_ENOSYS;
  289. }
  290. int dfs_elm_read(struct dfs_fd* file, void* buf, rt_size_t len)
  291. {
  292. FIL* fd;
  293. FRESULT result;
  294. UINT byte_read;
  295. if (file->type == FT_DIRECTORY)
  296. {
  297. return -DFS_STATUS_EISDIR;
  298. }
  299. fd = (FIL*)(file->data);
  300. RT_ASSERT(fd != RT_NULL);
  301. result = f_read(fd, buf, len, &byte_read);
  302. /* update position */
  303. file->pos = fd->fptr;
  304. if (result == FR_OK) return byte_read;
  305. return elm_result_to_dfs(result);
  306. }
  307. int dfs_elm_write(struct dfs_fd* file, const void* buf, rt_size_t len)
  308. {
  309. FIL* fd;
  310. FRESULT result;
  311. UINT byte_write;
  312. if (file->type == FT_DIRECTORY)
  313. {
  314. return -DFS_STATUS_EISDIR;
  315. }
  316. fd = (FIL*)(file->data);
  317. RT_ASSERT(fd != RT_NULL);
  318. result = f_write(fd, buf, len, &byte_write);
  319. /* update position and file size */
  320. file->pos = fd->fptr;
  321. file->size = fd->fsize;
  322. if (result == FR_OK) return byte_write;
  323. return elm_result_to_dfs(result);
  324. }
  325. int dfs_elm_flush(struct dfs_fd* file)
  326. {
  327. FIL* fd;
  328. FRESULT result;
  329. fd = (FIL*)(file->data);
  330. RT_ASSERT(fd != RT_NULL);
  331. result = f_sync(fd);
  332. return elm_result_to_dfs(result);
  333. }
  334. int dfs_elm_lseek(struct dfs_fd* file, rt_off_t offset)
  335. {
  336. FRESULT result;
  337. if (file->type == FT_REGULAR)
  338. {
  339. FIL* fd;
  340. /* regular file type */
  341. fd = (FIL*)(file->data);
  342. RT_ASSERT(fd != RT_NULL);
  343. result = f_lseek(fd, offset);
  344. if (result == FR_OK)
  345. {
  346. /* return current position */
  347. return fd->fptr;
  348. }
  349. }
  350. else if (file->type == FT_DIRECTORY)
  351. {
  352. /* which is a directory */
  353. DIR* dir;
  354. dir = (DIR*)(file->data);
  355. RT_ASSERT(dir != RT_NULL);
  356. result = f_seekdir(dir, offset / sizeof(struct dirent));
  357. if (result == FR_OK)
  358. {
  359. /* update file position */
  360. file->pos = offset;
  361. return file->pos;
  362. }
  363. }
  364. return elm_result_to_dfs(result);
  365. }
  366. int dfs_elm_getdents(struct dfs_fd* file, struct dirent* dirp, rt_uint32_t count)
  367. {
  368. DIR* dir;
  369. FILINFO fno;
  370. FRESULT result;
  371. rt_uint32_t index;
  372. struct dirent* d;
  373. dir = (DIR*)(file->data);
  374. RT_ASSERT(dir != RT_NULL);
  375. /* make integer count */
  376. count = (count / sizeof(struct dirent)) * sizeof(struct dirent);
  377. if ( count == 0 ) return -DFS_STATUS_EINVAL;
  378. #if _USE_LFN
  379. /* allocate long file name */
  380. fno.lfname = rt_malloc(256);
  381. fno.lfsize = 256;
  382. #endif
  383. index = 0;
  384. while (1)
  385. {
  386. char *fn;
  387. d = dirp + index;
  388. result = f_readdir(dir, &fno);
  389. if (result != FR_OK || fno.fname[0] == 0) break;
  390. #if _USE_LFN
  391. fn = *fno.lfname? fno.lfname : fno.fname;
  392. #else
  393. fn = fno.fname;
  394. #endif
  395. d->d_type = DFS_DT_UNKNOWN;
  396. if (fno.fattrib & AM_DIR) d->d_type = DFS_DT_DIR;
  397. else d->d_type = DFS_DT_REG;
  398. d->d_namlen = rt_strlen(fn);
  399. d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
  400. rt_strncpy(d->d_name, fn, rt_strlen(fn) + 1);
  401. index ++;
  402. if ( index * sizeof(struct dirent) >= count )
  403. break;
  404. }
  405. #if _USE_LFN
  406. rt_free(fno.lfname);
  407. #endif
  408. if (index == 0)
  409. return elm_result_to_dfs(result);
  410. file->pos += index * sizeof(struct dirent);
  411. return index * sizeof(struct dirent);
  412. }
  413. int dfs_elm_unlink(struct dfs_filesystem* fs, const char* path)
  414. {
  415. FRESULT result;
  416. #if _VOLUMES > 1
  417. int vol;
  418. char *drivers_fn;
  419. extern int elm_get_vol(FATFS *fat);
  420. /* add path for ELM FatFS driver support */
  421. vol = elm_get_vol((FATFS *)fs->data);
  422. if (vol < 0) return -DFS_STATUS_ENOENT;
  423. drivers_fn = rt_malloc(256);
  424. if (drivers_fn == RT_NULL) return -DFS_STATUS_ENOMEM;
  425. rt_snprintf(drivers_fn, 256, "%d:%s", vol, path);
  426. #else
  427. const char *drivers_fn;
  428. drivers_fn = path;
  429. #endif
  430. result = f_unlink(drivers_fn);
  431. #if _VOLUMES > 1
  432. rt_free(drivers_fn);
  433. #endif
  434. return elm_result_to_dfs(result);
  435. }
  436. int dfs_elm_rename(struct dfs_filesystem* fs, const char* oldpath, const char* newpath)
  437. {
  438. FRESULT result;
  439. #if _VOLUMES > 1
  440. char *drivers_oldfn;
  441. const char *drivers_newfn;
  442. int vol;
  443. extern int elm_get_vol(FATFS *fat);
  444. /* add path for ELM FatFS driver support */
  445. vol = elm_get_vol((FATFS *)fs->data);
  446. if (vol < 0) return -DFS_STATUS_ENOENT;
  447. drivers_oldfn = rt_malloc(256);
  448. if (drivers_oldfn == RT_NULL) return -DFS_STATUS_ENOMEM;
  449. drivers_newfn = newpath;
  450. rt_snprintf(drivers_oldfn, 256, "%d:%s", vol, oldpath);
  451. #else
  452. const char *drivers_oldfn, *drivers_newfn;
  453. drivers_oldfn = oldpath;
  454. drivers_newfn = newpath;
  455. #endif
  456. result = f_rename(drivers_oldfn, drivers_newfn);
  457. #if _VOLUMES > 1
  458. rt_free(drivers_oldfn);
  459. #endif
  460. return elm_result_to_dfs(result);
  461. }
  462. int dfs_elm_stat(struct dfs_filesystem* fs, const char *path, struct stat *st)
  463. {
  464. FILINFO file_info;
  465. FRESULT result;
  466. #if _VOLUMES > 1
  467. int vol;
  468. char *drivers_fn;
  469. extern int elm_get_vol(FATFS *fat);
  470. /* add path for ELM FatFS driver support */
  471. vol = elm_get_vol((FATFS *)fs->data);
  472. if (vol < 0) return -DFS_STATUS_ENOENT;
  473. drivers_fn = rt_malloc(256);
  474. if (drivers_fn == RT_NULL) return -DFS_STATUS_ENOMEM;
  475. rt_snprintf(drivers_fn, 256, "%d:%s", vol, path);
  476. #else
  477. const char *drivers_fn;
  478. drivers_fn = path;
  479. #endif
  480. #if _USE_LFN
  481. /* allocate long file name */
  482. file_info.lfname = rt_malloc(256);
  483. file_info.lfsize = 256;
  484. #endif
  485. result = f_stat(drivers_fn, &file_info);
  486. #if _VOLUMES > 1
  487. rt_free(drivers_fn);
  488. #endif
  489. if (result == FR_OK)
  490. {
  491. /* convert to dfs stat structure */
  492. st->st_dev = 0;
  493. st->st_mode = DFS_S_IFREG | DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH |
  494. DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH;
  495. if (file_info.fattrib & AM_DIR)
  496. {
  497. st->st_mode &= ~DFS_S_IFREG;
  498. st->st_mode |= DFS_S_IFDIR | DFS_S_IXUSR | DFS_S_IXGRP | DFS_S_IXOTH;
  499. }
  500. if (file_info.fattrib & AM_RDO)
  501. st->st_mode &= ~(DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH);
  502. st->st_size = file_info.fsize;
  503. st->st_mtime = file_info.ftime;
  504. st->st_blksize = 512;
  505. }
  506. #if _USE_LFN
  507. rt_free(file_info.lfname);
  508. #endif
  509. return elm_result_to_dfs(result);
  510. }
  511. static const struct dfs_filesystem_operation dfs_elm =
  512. {
  513. "elm",
  514. dfs_elm_mount,
  515. dfs_elm_unmount,
  516. dfs_elm_mkfs,
  517. dfs_elm_statfs,
  518. dfs_elm_open,
  519. dfs_elm_close,
  520. dfs_elm_ioctl,
  521. dfs_elm_read,
  522. dfs_elm_write,
  523. dfs_elm_flush,
  524. dfs_elm_lseek,
  525. dfs_elm_getdents,
  526. dfs_elm_unlink,
  527. dfs_elm_stat,
  528. dfs_elm_rename,
  529. };
  530. int elm_init(void)
  531. {
  532. /* register fatfs file system */
  533. dfs_register(&dfs_elm);
  534. return 0;
  535. }
  536. /*
  537. * RT-Thread Device Interface for ELM FatFs
  538. */
  539. #include "diskio.h"
  540. /* Inidialize a Drive */
  541. DSTATUS disk_initialize (BYTE drv)
  542. {
  543. return 0;
  544. }
  545. /* Return Disk Status */
  546. DSTATUS disk_status (BYTE drv)
  547. {
  548. return 0;
  549. }
  550. /* Read Sector(s) */
  551. DRESULT disk_read (BYTE drv, BYTE *buff, DWORD sector, BYTE count)
  552. {
  553. rt_size_t result;
  554. rt_device_t device = disk[drv];
  555. result = rt_device_read(device, sector, buff, count);
  556. if (result == count)
  557. {
  558. return RES_OK;
  559. }
  560. return RES_ERROR;
  561. }
  562. /* Write Sector(s) */
  563. DRESULT disk_write (BYTE drv, const BYTE *buff, DWORD sector, BYTE count)
  564. {
  565. rt_size_t result;
  566. rt_device_t device = disk[drv];
  567. result = rt_device_write(device, sector, buff, count);
  568. if (result == count)
  569. {
  570. return RES_OK;
  571. }
  572. return RES_ERROR;
  573. }
  574. /* Miscellaneous Functions */
  575. DRESULT disk_ioctl (BYTE drv, BYTE ctrl, void *buff)
  576. {
  577. rt_device_t device = disk[drv];
  578. if (device == RT_NULL) return RES_ERROR;
  579. if (ctrl == GET_SECTOR_COUNT)
  580. {
  581. struct rt_device_blk_geometry geometry;
  582. rt_memset(&geometry, 0, sizeof(geometry));
  583. rt_device_control(device, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry);
  584. *(DWORD*)buff = geometry.sector_count;
  585. if (geometry.sector_count == 0) return RES_ERROR;
  586. }
  587. else if (ctrl == GET_SECTOR_SIZE)
  588. {
  589. struct rt_device_blk_geometry geometry;
  590. rt_memset(&geometry, 0, sizeof(geometry));
  591. rt_device_control(device, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry);
  592. *(WORD*)buff = geometry.bytes_per_sector;
  593. }
  594. else if (ctrl == GET_BLOCK_SIZE) /* Get erase block size in unit of sectors (DWORD) */
  595. {
  596. struct rt_device_blk_geometry geometry;
  597. rt_memset(&geometry, 0, sizeof(geometry));
  598. rt_device_control(device, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry);
  599. *(DWORD*)buff = geometry.block_size/geometry.bytes_per_sector;
  600. }
  601. return RES_OK;
  602. }
  603. rt_time_t get_fattime()
  604. {
  605. return 0;
  606. }
  607. #if _FS_REENTRANT
  608. int ff_cre_syncobj(BYTE drv, _SYNC_t* m)
  609. {
  610. char name[8];
  611. rt_mutex_t mutex;
  612. rt_snprintf(name, sizeof(name), "fat%d", drv);
  613. mutex = rt_mutex_create(name, RT_IPC_FLAG_FIFO);
  614. if (mutex != RT_NULL)
  615. {
  616. *m = mutex;
  617. return RT_TRUE;
  618. }
  619. return RT_FALSE;
  620. }
  621. int ff_del_syncobj(_SYNC_t m)
  622. {
  623. rt_mutex_delete(m);
  624. return RT_TRUE;
  625. }
  626. int ff_req_grant(_SYNC_t m)
  627. {
  628. if (rt_mutex_take(m, _FS_TIMEOUT) == RT_EOK) return RT_TRUE;
  629. return RT_FALSE;
  630. }
  631. void ff_rel_grant(_SYNC_t m)
  632. {
  633. rt_mutex_release(m);
  634. }
  635. #endif