fs_port_fatfs.c
Go to the documentation of this file.
1 /**
2  * @file fs_port_fatfs.c
3  * @brief File system abstraction layer (FatFs)
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2019 Oryx Embedded SARL. All rights reserved.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24  *
25  * @author Oryx Embedded SARL (www.oryx-embedded.com)
26  * @version 1.9.6
27  **/
28 
29 //Dependencies
30 #include <string.h>
31 #include "fs_port.h"
32 #include "fs_port_fatfs.h"
33 #include "error.h"
34 #include "debug.h"
35 
36 //FatFs revision
37 #define FATFS_R(major, minor, patch) ((major << 16) | (minor << 8) | (0x ## patch))
38 
39 //Check revision ID
40 #if (_FATFS == 124)
41  #define FATFS_REVISON FATFS_R(0, 7, c)
42 #elif (_FATFS == 126)
43  #define FATFS_REVISON FATFS_R(0, 7, e)
44 #elif (_FATFS == 8085)
45  #define FATFS_REVISON FATFS_R(0, 8, 0)
46 #elif (_FATFS == 8255)
47  #define FATFS_REVISON FATFS_R(0, 8, a)
48 #elif (_FATFS == 8237)
49  #define FATFS_REVISON FATFS_R(0, 8, b)
50 #elif (_FATFS == 6502)
51  #define FATFS_REVISON FATFS_R(0, 9, 0)
52 #elif (_FATFS == 4004)
53  #define FATFS_REVISON FATFS_R(0, 9, a)
54 #elif (_FATFS == 82786)
55  #define FATFS_REVISON FATFS_R(0, 9, b)
56 #elif (_FATFS == 80960)
57  #define FATFS_REVISON FATFS_R(0, 10, 0)
58 #elif (_FATFS == 29000)
59  #define FATFS_REVISON FATFS_R(0, 10, a)
60 #elif (_FATFS == 8051)
61  #define FATFS_REVISON FATFS_R(0, 10, b)
62 #elif (_FATFS == 80376)
63  #define FATFS_REVISON FATFS_R(0, 10, c)
64 #elif (_FATFS == 32020)
65  #define FATFS_REVISON FATFS_R(0, 11, 0)
66 #elif (_FATFS == 64180)
67  #define FATFS_REVISON FATFS_R(0, 11, a)
68 #elif (_FATFS == 88100)
69  #define FATFS_REVISON FATFS_R(0, 12, 0)
70 #elif (_FATFS == 80186)
71  #define FATFS_REVISON FATFS_R(0, 12, a)
72 #elif (_FATFS == 68020)
73  #define FATFS_REVISON FATFS_R(0, 12, b)
74 #elif (_FATFS == 68300)
75  #define FATFS_REVISON FATFS_R(0, 12, c)
76 #elif (FF_DEFINED == 87030)
77  #define FATFS_REVISON FATFS_R(0, 13, 0)
78 #elif (FF_DEFINED == 89352)
79  #define FATFS_REVISON FATFS_R(0, 13, a)
80 #elif (FF_DEFINED == 63463)
81  #define FATFS_REVISON FATFS_R(0, 13, b)
82 #elif (FF_DEFINED == 86604)
83  #define FATFS_REVISON FATFS_R(0, 13, c)
84 #else
85  #define FATFS_REVISON FATFS_R(0, 0, 0)
86 #endif
87 
88 //File system objects
89 static FATFS fs;
90 static FIL fileTable[FS_MAX_FILES];
91 static DIR dirTable[FS_MAX_DIRS];
92 
93 //Mutex that protects critical sections
94 static OsMutex fsMutex;
95 
96 
97 /**
98  * @brief File system initialization
99  * @return Error code
100  **/
101 
103 {
104  FRESULT res;
105 
106  //Clear file system objects
107  memset(fileTable, 0, sizeof(fileTable));
108  memset(dirTable, 0, sizeof(dirTable));
109 
110  //Create a mutex to protect critical sections
111  if(!osCreateMutex(&fsMutex))
112  {
113  //Failed to create mutex
114  return ERROR_OUT_OF_RESOURCES;
115  }
116 
117  //Mount file system
118 #if (FATFS_REVISON <= FATFS_R(0, 9, b))
119  res = f_mount(0, &fs);
120 #else
121  res = f_mount(&fs, "", 1);
122 #endif
123 
124  //Failed to mount file system?
125  if(res != FR_OK)
126  {
127  //Clean up side effects
128  osDeleteMutex(&fsMutex);
129  //Report an error
130  return ERROR_FAILURE;
131  }
132 
133  //Successful processing
134  return NO_ERROR;
135 }
136 
137 
138 /**
139  * @brief Check whether a file exists
140  * @param[in] path NULL-terminated string specifying the filename
141  * @return The function returns TRUE if the file exists. Otherwise FALSE is returned
142  **/
143 
145 {
146  FRESULT res;
147  FILINFO fno;
148 
149 #if (FATFS_REVISON <= FATFS_R(0, 11, a) && _USE_LFN != 0)
150  fno.lfname = NULL;
151  fno.lfsize = 0;
152 #endif
153 
154  //Make sure the pathname is valid
155  if(path == NULL)
156  return FALSE;
157 
158 #if ((FATFS_REVISON <= FATFS_R(0, 12, c) && _FS_REENTRANT == 0) || \
159  (FATFS_REVISON >= FATFS_R(0, 13, 0) && FF_FS_REENTRANT == 0))
160  //Enter critical section
161  osAcquireMutex(&fsMutex);
162 #endif
163 
164  //Check whether the file exists
165  res = f_stat(path, &fno);
166 
167 #if ((FATFS_REVISON <= FATFS_R(0, 12, c) && _FS_REENTRANT == 0) || \
168  (FATFS_REVISON >= FATFS_R(0, 13, 0) && FF_FS_REENTRANT == 0))
169  //Leave critical section
170  osReleaseMutex(&fsMutex);
171 #endif
172 
173  //Any error to report?
174  if(res != FR_OK)
175  return FALSE;
176 
177  //Valid file?
178  if(fno.fattrib & AM_DIR)
179  return FALSE;
180  else
181  return TRUE;
182 }
183 
184 
185 /**
186  * @brief Retrieve the size of the specified file
187  * @param[in] path NULL-terminated string specifying the filename
188  * @param[out] size Size of the file in bytes
189  * @return Error code
190  **/
191 
192 error_t fsGetFileSize(const char_t *path, uint32_t *size)
193 {
194  FRESULT res;
195  FILINFO fno;
196 
197 #if (FATFS_REVISON <= FATFS_R(0, 11, a) && _USE_LFN != 0)
198  fno.lfname = NULL;
199  fno.lfsize = 0;
200 #endif
201 
202  //Check parameters
203  if(path == NULL || size == NULL)
205 
206 #if ((FATFS_REVISON <= FATFS_R(0, 12, c) && _FS_REENTRANT == 0) || \
207  (FATFS_REVISON >= FATFS_R(0, 13, 0) && FF_FS_REENTRANT == 0))
208  //Enter critical section
209  osAcquireMutex(&fsMutex);
210 #endif
211 
212  //Retrieve information about the specified file
213  res = f_stat(path, &fno);
214 
215 #if ((FATFS_REVISON <= FATFS_R(0, 12, c) && _FS_REENTRANT == 0) || \
216  (FATFS_REVISON >= FATFS_R(0, 13, 0) && FF_FS_REENTRANT == 0))
217  //Leave critical section
218  osReleaseMutex(&fsMutex);
219 #endif
220 
221  //Any error to report?
222  if(res != FR_OK)
223  return ERROR_FAILURE;
224  //Valid file?
225  if(fno.fattrib & AM_DIR)
226  return ERROR_FAILURE;
227 
228  //Return the size of the file
229  *size = fno.fsize;
230 
231  //Successful processing
232  return NO_ERROR;
233 }
234 
235 
236 /**
237  * @brief Rename the specified file
238  * @param[in] oldPath NULL-terminated string specifying the pathname of the file to be renamed
239  * @param[in] newPath NULL-terminated string specifying the new filename
240  * @return Error code
241  **/
242 
243 error_t fsRenameFile(const char_t *oldPath, const char_t *newPath)
244 {
245  FRESULT res;
246 
247  //Check parameters
248  if(oldPath == NULL || newPath == NULL)
250 
251 #if ((FATFS_REVISON <= FATFS_R(0, 12, c) && _FS_REENTRANT == 0) || \
252  (FATFS_REVISON >= FATFS_R(0, 13, 0) && FF_FS_REENTRANT == 0))
253  //Enter critical section
254  osAcquireMutex(&fsMutex);
255 #endif
256 
257  //Rename the specified file
258  res = f_rename(oldPath, newPath);
259 
260 #if ((FATFS_REVISON <= FATFS_R(0, 12, c) && _FS_REENTRANT == 0) || \
261  (FATFS_REVISON >= FATFS_R(0, 13, 0) && FF_FS_REENTRANT == 0))
262  //Leave critical section
263  osReleaseMutex(&fsMutex);
264 #endif
265 
266  //Any error to report?
267  if(res != FR_OK)
268  return ERROR_FAILURE;
269 
270  //Successful processing
271  return NO_ERROR;
272 }
273 
274 
275 /**
276  * @brief Delete a file
277  * @param[in] path NULL-terminated string specifying the filename
278  * @return Error code
279  **/
280 
282 {
283  FRESULT res;
284 
285  //Make sure the pathname is valid
286  if(path == NULL)
288 
289 #if ((FATFS_REVISON <= FATFS_R(0, 12, c) && _FS_REENTRANT == 0) || \
290  (FATFS_REVISON >= FATFS_R(0, 13, 0) && FF_FS_REENTRANT == 0))
291  //Enter critical section
292  osAcquireMutex(&fsMutex);
293 #endif
294 
295  //Delete the specified file
296  res = f_unlink(path);
297 
298 #if ((FATFS_REVISON <= FATFS_R(0, 12, c) && _FS_REENTRANT == 0) || \
299  (FATFS_REVISON >= FATFS_R(0, 13, 0) && FF_FS_REENTRANT == 0))
300  //Leave critical section
301  osReleaseMutex(&fsMutex);
302 #endif
303 
304  //Any error to report?
305  if(res != FR_OK)
306  return ERROR_FAILURE;
307 
308  //Successful processing
309  return NO_ERROR;
310 }
311 
312 
313 /**
314  * @brief Open the specified file for reading or writing
315  * @param[in] path NULL-terminated string specifying the filename
316  * @param[in] mode Type of access permitted (FS_FILE_MODE_READ,
317  * FS_FILE_MODE_WRITE or FS_FILE_MODE_CREATE)
318  * @return File handle
319  **/
320 
322 {
323  uint_t i;
324  uint_t flags;
325  FRESULT res;
326 
327  //File pointer
328  FsFile *file = NULL;
329 
330  //Make sure the pathname is valid
331  if(path == NULL)
332  return NULL;
333 
334  //Enter critical section
335  osAcquireMutex(&fsMutex);
336 
337  //Loop through the file objects
338  for(i = 0; i < FS_MAX_FILES; i++)
339  {
340  //Unused file object found?
341 #if (FATFS_REVISON <= FATFS_R(0, 11, a))
342  if(fileTable[i].fs == NULL)
343 #else
344  if(fileTable[i].obj.fs == NULL)
345 #endif
346  {
347  //Default access mode
348  flags = 0;
349 
350  //Check access mode
351  if(mode & FS_FILE_MODE_READ)
352  flags |= FA_READ;
354  flags |= FA_WRITE;
356  flags |= FA_OPEN_ALWAYS;
358  flags |= FA_CREATE_ALWAYS;
359 
360  //Open the specified file
361  res = f_open(&fileTable[i], path, flags);
362 
363  //Check status code
364  if(res == FR_OK)
365  file = &fileTable[i];
366 
367  //Stop immediately
368  break;
369  }
370  }
371 
372  //Leave critical section
373  osReleaseMutex(&fsMutex);
374  //Return a handle to the file
375  return file;
376 }
377 
378 
379 /**
380  * @brief Move to specified position in file
381  * @param[in] file Handle that identifies the file
382  * @param[in] offset Number of bytes to move from origin
383  * @param[in] origin Position used as reference for the offset (FS_SEEK_SET,
384  * FS_SEEK_CUR or FS_SEEK_END)
385  * @return Error code
386  **/
387 
389 {
390  FRESULT res;
391 
392  //Make sure the file pointer is valid
393  if(file == NULL)
395 
396 #if ((FATFS_REVISON <= FATFS_R(0, 12, c) && _FS_REENTRANT == 0) || \
397  (FATFS_REVISON >= FATFS_R(0, 13, 0) && FF_FS_REENTRANT == 0))
398  //Enter critical section
399  osAcquireMutex(&fsMutex);
400 #endif
401 
402  //Offset is relative to the current file pointer position?
403  if(origin == FS_SEEK_CUR)
404  offset += f_tell((FIL *) file);
405  //Offset is relative to the end of the file?
406  else if(origin == FS_SEEK_END)
407  offset += f_size((FIL *) file);
408 
409  //Move read/write pointer
410  res = f_lseek((FIL *) file, offset);
411 
412 #if ((FATFS_REVISON <= FATFS_R(0, 12, c) && _FS_REENTRANT == 0) || \
413  (FATFS_REVISON >= FATFS_R(0, 13, 0) && FF_FS_REENTRANT == 0))
414  //Leave critical section
415  osReleaseMutex(&fsMutex);
416 #endif
417 
418  //Any error to report?
419  if(res != FR_OK)
420  return ERROR_FAILURE;
421 
422  //Successful processing
423  return NO_ERROR;
424 }
425 
426 
427 /**
428  * @brief Write data to the specified file
429  * @param[in] file Handle that identifies the file to be written
430  * @param[in] data Pointer to a buffer containing the data to be written
431  * @param[in] length Number of data bytes to write
432  * @return Error code
433  **/
434 
436 {
437  UINT n;
438  FRESULT res;
439 
440  //Make sure the file pointer is valid
441  if(file == NULL)
443 
444 #if ((FATFS_REVISON <= FATFS_R(0, 12, c) && _FS_REENTRANT == 0) || \
445  (FATFS_REVISON >= FATFS_R(0, 13, 0) && FF_FS_REENTRANT == 0))
446  //Enter critical section
447  osAcquireMutex(&fsMutex);
448 #endif
449 
450  //Write data
451  res = f_write((FIL *) file, data, length, &n);
452 
453 #if ((FATFS_REVISON <= FATFS_R(0, 12, c) && _FS_REENTRANT == 0) || \
454  (FATFS_REVISON >= FATFS_R(0, 13, 0) && FF_FS_REENTRANT == 0))
455  //Leave critical section
456  osReleaseMutex(&fsMutex);
457 #endif
458 
459  //Any error to report?
460  if(res != FR_OK)
461  return ERROR_FAILURE;
462 
463  //Sanity check
464  if(n != length)
465  return ERROR_FAILURE;
466 
467  //Successful processing
468  return NO_ERROR;
469 }
470 
471 
472 /**
473  * @brief Read data from the specified file
474  * @param[in] file Handle that identifies the file to be read
475  * @param[in] data Pointer to the buffer where to copy the data
476  * @param[in] size Size of the buffer, in bytes
477  * @param[out] length Number of data bytes that have been read
478  * @return Error code
479  **/
480 
481 error_t fsReadFile(FsFile *file, void *data, size_t size, size_t *length)
482 {
483  UINT n;
484  FRESULT res;
485 
486  //Check parameters
487  if(file == NULL || length == NULL)
489 
490  //No data has been read yet
491  *length = 0;
492 
493 #if ((FATFS_REVISON <= FATFS_R(0, 12, c) && _FS_REENTRANT == 0) || \
494  (FATFS_REVISON >= FATFS_R(0, 13, 0) && FF_FS_REENTRANT == 0))
495  //Enter critical section
496  osAcquireMutex(&fsMutex);
497 #endif
498 
499  //Read data
500  res = f_read((FIL *) file, data, size, &n);
501 
502 #if ((FATFS_REVISON <= FATFS_R(0, 12, c) && _FS_REENTRANT == 0) || \
503  (FATFS_REVISON >= FATFS_R(0, 13, 0) && FF_FS_REENTRANT == 0))
504  //Leave critical section
505  osReleaseMutex(&fsMutex);
506 #endif
507 
508  //Any error to report?
509  if(res != FR_OK)
510  return ERROR_FAILURE;
511 
512  //End of file?
513  if(!n)
514  return ERROR_END_OF_FILE;
515 
516  //Total number of data that have been read
517  *length = n;
518  //Successful processing
519  return NO_ERROR;
520 }
521 
522 
523 /**
524  * @brief Close a file
525  * @param[in] file Handle that identifies the file to be closed
526  **/
527 
529 {
530  //Make sure the file pointer is valid
531  if(file != NULL)
532  {
533  //Enter critical section
534  osAcquireMutex(&fsMutex);
535 
536  //Close the specified file
537  f_close((FIL *) file);
538 
539  //Mark the corresponding entry as free
540 #if (FATFS_REVISON <= FATFS_R(0, 11, a))
541  ((FIL *) file)->fs = NULL;
542 #else
543  ((FIL *) file)->obj.fs = NULL;
544 #endif
545 
546  //Leave critical section
547  osReleaseMutex(&fsMutex);
548  }
549 }
550 
551 
552 /**
553  * @brief Check whether a directory exists
554  * @param[in] path NULL-terminated string specifying the directory path
555  * @return The function returns TRUE if the directory exists. Otherwise FALSE is returned
556  **/
557 
559 {
560  FRESULT res;
561  FILINFO fno;
562 
563 #if (FATFS_REVISON <= FATFS_R(0, 11, a) && _USE_LFN != 0)
564  fno.lfname = NULL;
565  fno.lfsize = 0;
566 #endif
567 
568  //Make sure the pathname is valid
569  if(path == NULL)
570  return FALSE;
571 
572  //Root directory?
573  if(!strcmp(path, "/"))
574  return TRUE;
575 
576 #if ((FATFS_REVISON <= FATFS_R(0, 12, c) && _FS_REENTRANT == 0) || \
577  (FATFS_REVISON >= FATFS_R(0, 13, 0) && FF_FS_REENTRANT == 0))
578  //Enter critical section
579  osAcquireMutex(&fsMutex);
580 #endif
581 
582  //Check whether the file exists
583  res = f_stat(path, &fno);
584 
585 #if ((FATFS_REVISON <= FATFS_R(0, 12, c) && _FS_REENTRANT == 0) || \
586  (FATFS_REVISON >= FATFS_R(0, 13, 0) && FF_FS_REENTRANT == 0))
587  //Leave critical section
588  osReleaseMutex(&fsMutex);
589 #endif
590 
591  //Any error to report?
592  if(res != FR_OK)
593  return FALSE;
594 
595  //Valid directory?
596  if(fno.fattrib & AM_DIR)
597  return TRUE;
598  else
599  return FALSE;
600 }
601 
602 
603 /**
604  * @brief Create a directory
605  * @param[in] path NULL-terminated string specifying the directory path
606  * @return Error code
607  **/
608 
610 {
611  FRESULT res;
612 
613  //Make sure the pathname is valid
614  if(path == NULL)
616 
617 #if ((FATFS_REVISON <= FATFS_R(0, 12, c) && _FS_REENTRANT == 0) || \
618  (FATFS_REVISON >= FATFS_R(0, 13, 0) && FF_FS_REENTRANT == 0))
619  //Enter critical section
620  osAcquireMutex(&fsMutex);
621 #endif
622 
623  //Create a new directory
624  res = f_mkdir(path);
625 
626 #if ((FATFS_REVISON <= FATFS_R(0, 12, c) && _FS_REENTRANT == 0) || \
627  (FATFS_REVISON >= FATFS_R(0, 13, 0) && FF_FS_REENTRANT == 0))
628  //Leave critical section
629  osReleaseMutex(&fsMutex);
630 #endif
631 
632  //Any error to report?
633  if(res != FR_OK)
634  return ERROR_FAILURE;
635 
636  //Successful processing
637  return NO_ERROR;
638 }
639 
640 
641 /**
642  * @brief Remove a directory
643  * @param[in] path NULL-terminated string specifying the directory path
644  * @return Error code
645  **/
646 
648 {
649  FRESULT res;
650 
651  //Make sure the pathname is valid
652  if(path == NULL)
654 
655 #if ((FATFS_REVISON <= FATFS_R(0, 12, c) && _FS_REENTRANT == 0) || \
656  (FATFS_REVISON >= FATFS_R(0, 13, 0) && FF_FS_REENTRANT == 0))
657  //Enter critical section
658  osAcquireMutex(&fsMutex);
659 #endif
660 
661  //Remove the specified directory
662  res = f_unlink(path);
663 
664 #if ((FATFS_REVISON <= FATFS_R(0, 12, c) && _FS_REENTRANT == 0) || \
665  (FATFS_REVISON >= FATFS_R(0, 13, 0) && FF_FS_REENTRANT == 0))
666  //Leave critical section
667  osReleaseMutex(&fsMutex);
668 #endif
669 
670  //Any error to report?
671  if(res != FR_OK)
672  return ERROR_FAILURE;
673 
674  //Successful processing
675  return NO_ERROR;
676 }
677 
678 
679 /**
680  * @brief Open a directory stream
681  * @param[in] path NULL-terminated string specifying the directory path
682  * @return Directory handle
683  **/
684 
685 FsDir *fsOpenDir(const char_t *path)
686 {
687  uint_t i;
688  FRESULT res;
689 
690  //Directory pointer
691  FsDir *dir = NULL;
692 
693  //Make sure the pathname is valid
694  if(path == NULL)
695  return NULL;
696 
697  //Enter critical section
698  osAcquireMutex(&fsMutex);
699 
700  //Loop through the directory objects
701  for(i = 0; i < FS_MAX_DIRS; i++)
702  {
703  //Unused directory object found?
704 #if (FATFS_REVISON <= FATFS_R(0, 11, a))
705  if(dirTable[i].fs == NULL)
706 #else
707  if(dirTable[i].obj.fs == NULL)
708 #endif
709  {
710  //Open the specified directory
711  res = f_opendir(&dirTable[i], path);
712 
713  //Check status code
714  if(res == FR_OK)
715  dir = &dirTable[i];
716 
717  //Stop immediately
718  break;
719  }
720  }
721 
722  //Leave critical section
723  osReleaseMutex(&fsMutex);
724  //Return a handle to the directory
725  return dir;
726 }
727 
728 
729 /**
730  * @brief Read an entry from the specified directory stream
731  * @param[in] dir Handle that identifies the directory
732  * @param[out] dirEntry Pointer to a directory entry
733  * @return Error code
734  **/
735 
737 {
738  FRESULT res;
739  FILINFO fno;
740  char_t *fn;
741  size_t n;
742 
743 #if (FATFS_REVISON <= FATFS_R(0, 11, a) && _USE_LFN != 0)
744  char_t lfn[_MAX_LFN + 1];
745  fno.lfname = lfn;
746  fno.lfsize = sizeof(lfn);
747 #endif
748 
749  //Make sure the directory pointer is valid
750  if(dir == NULL)
752 
753 #if ((FATFS_REVISON <= FATFS_R(0, 12, c) && _FS_REENTRANT == 0) || \
754  (FATFS_REVISON >= FATFS_R(0, 13, 0) && FF_FS_REENTRANT == 0))
755  //Enter critical section
756  osAcquireMutex(&fsMutex);
757 #endif
758 
759  //Read the specified directory
760  res = f_readdir((DIR *) dir, &fno);
761 
762 #if ((FATFS_REVISON <= FATFS_R(0, 12, c) && _FS_REENTRANT == 0) || \
763  (FATFS_REVISON >= FATFS_R(0, 13, 0) && FF_FS_REENTRANT == 0))
764  //Leave critical section
765  osReleaseMutex(&fsMutex);
766 #endif
767 
768  //Any error to report?
769  if(res != FR_OK)
770  return ERROR_FAILURE;
771 
772  //End of the directory stream?
773  if(fno.fname[0] == '\0')
774  return ERROR_END_OF_STREAM;
775 
776  //Point to the long filename
777 #if (FATFS_REVISON <= FATFS_R(0, 11, a) && _USE_LFN != 0)
778  fn = (*fno.lfname != '\0') ? fno.lfname : fno.fname;
779 #else
780  fn = fno.fname;
781 #endif
782 
783  //File attributes
784  dirEntry->attributes = fno.fattrib;
785  //File size
786  dirEntry->size = fno.fsize;
787 
788  //Time of last modification
789  dirEntry->modified.year = 1980 + ((fno.fdate >> 9) & 0x7F);
790  dirEntry->modified.month = (fno.fdate >> 5) & 0x0F;
791  dirEntry->modified.day = fno.fdate & 0x1F;
792  dirEntry->modified.dayOfWeek = 0;
793  dirEntry->modified.hours = (fno.ftime >> 11) & 0x1F;
794  dirEntry->modified.minutes = (fno.ftime >> 5) & 0x3F;
795  dirEntry->modified.seconds = (fno.ftime & 0x1F) * 2;
796  dirEntry->modified.milliseconds = 0;
797 
798  //Make sure the date is valid
799  dirEntry->modified.month = MAX(dirEntry->modified.month, 1);
800  dirEntry->modified.month = MIN(dirEntry->modified.month, 12);
801  dirEntry->modified.day = MAX(dirEntry->modified.day, 1);
802  dirEntry->modified.day = MIN(dirEntry->modified.day, 31);
803 
804  //Retrieve the length of the file name
805  n = strlen(fn);
806  //Limit the number of characters to be copied
807  n = MIN(n, FS_MAX_NAME_LEN);
808 
809  //Copy file name
810  strncpy(dirEntry->name, fn, n);
811  //Properly terminate the string with a NULL character
812  dirEntry->name[n] = '\0';
813 
814  //Successful processing
815  return NO_ERROR;
816 }
817 
818 
819 /**
820  * @brief Close a directory stream
821  * @param[in] dir Handle that identifies the directory to be closed
822  **/
823 
824 void fsCloseDir(FsDir *dir)
825 {
826  //Make sure the directory pointer is valid
827  if(dir != NULL)
828  {
829  //Enter critical section
830  osAcquireMutex(&fsMutex);
831 
832 #if (FATFS_REVISON >= FATFS_R(0, 10, 0))
833  //Close the specified directory
834  f_closedir((DIR *) dir);
835 #endif
836 
837  //Mark the corresponding entry as free
838 #if (FATFS_REVISON <= FATFS_R(0, 11, a))
839  ((DIR *) dir)->fs = NULL;
840 #else
841  ((DIR *) dir)->obj.fs = NULL;
842 #endif
843 
844  //Leave critical section
845  osReleaseMutex(&fsMutex);
846  }
847 }
uint8_t length
Definition: dtls_misc.h:149
error_t fsSeekFile(FsFile *file, int_t offset, uint_t origin)
Move to specified position in file.
int bool_t
Definition: compiler_port.h:49
bool_t osCreateMutex(OsMutex *mutex)
Create a mutex object.
signed int int_t
Definition: compiler_port.h:44
error_t fsGetFileSize(const char_t *path, uint32_t *size)
Retrieve the size of the specified file.
uint16_t year
Definition: date_time.h:48
#define TRUE
Definition: os_port.h:50
error_t fsRemoveDir(const char_t *path)
Remove a directory.
const uint8_t res[]
Directory descriptor.
Definition: fs_port_posix.h:59
error_t fsCreateDir(const char_t *path)
Create a directory.
uint8_t day
Definition: date_time.h:50
error_t fsReadFile(FsFile *file, void *data, size_t size, size_t *length)
Read data from the specified file.
FsDir * fsOpenDir(const char_t *path)
Open a directory stream.
#define FALSE
Definition: os_port.h:46
Invalid parameter.
Definition: error.h:47
uint8_t minutes
Definition: date_time.h:53
error_t
Error codes.
Definition: error.h:42
#define FS_MAX_FILES
Definition: fs_port_fatfs.h:38
void fsCloseFile(FsFile *file)
Close a file.
error_t fsRenameFile(const char_t *oldPath, const char_t *newPath)
Rename the specified file.
bool_t fsFileExists(const char_t *path)
Check whether a file exists.
Generic error code.
Definition: error.h:45
error_t fsReadDir(FsDir *dir, FsDirEntry *dirEntry)
Read an entry from the specified directory stream.
FsFile * fsOpenFile(const char_t *path, uint_t mode)
Open the specified file for reading or writing.
#define FS_MAX_NAME_LEN
Definition: fs_port.h:40
uint8_t hours
Definition: date_time.h:52
Error codes description.
#define MIN(a, b)
Definition: os_port.h:62
uint8_t seconds
Definition: date_time.h:54
File system abstraction layer.
Mutex object.
char_t name[FS_MAX_NAME_LEN+1]
Definition: fs_port.h:100
uint8_t flags
Definition: tcp.h:314
#define MAX(a, b)
Definition: os_port.h:66
uint8_t month
Definition: date_time.h:49
char char_t
Definition: compiler_port.h:43
error_t fsInit(void)
File system initialization.
void osDeleteMutex(OsMutex *mutex)
Delete a mutex object.
DateTime modified
Definition: fs_port.h:99
uint8_t n
Directory entry.
Definition: fs_port.h:95
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
bool_t fsDirExists(const char_t *path)
Check whether a directory exists.
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
uint32_t attributes
Definition: fs_port.h:97
uint32_t size
Definition: fs_port.h:98
uint8_t file[128]
Definition: dhcp_common.h:213
error_t fsWriteFile(FsFile *file, void *data, size_t length)
Write data to the specified file.
uint16_t milliseconds
Definition: date_time.h:55
uint8_t mode
Definition: ntp_common.h:149
#define FS_MAX_DIRS
Definition: fs_port_fatfs.h:45
void fsCloseDir(FsDir *dir)
Close a directory stream.
uint8_t dayOfWeek
Definition: date_time.h:51
File system abstraction layer (FatFs)
unsigned int uint_t
Definition: compiler_port.h:45
uint8_t data[]
Definition: dtls_misc.h:176
error_t fsDeleteFile(const char_t *path)
Delete a file.
Success.
Definition: error.h:44
Debugging facilities.
void FsFile
File descriptor.
Definition: fs_port_fatfs.h:60