dfs_elm.c 15 KB

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