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