api_misc.c
上传用户:yj_qqy
上传日期:2017-01-28
资源大小:2911k
文件大小:14k
源码类别:

uCOS

开发平台:

C/C++

  1. /*
  2. **********************************************************************
  3. *                          Micrium, Inc.
  4. *                      949 Crestview Circle
  5. *                     Weston,  FL 33327-1848
  6. *
  7. *                            uC/FS
  8. *
  9. *             (c) Copyright 2001 - 2003, Micrium, Inc.
  10. *                      All rights reserved.
  11. *
  12. ***********************************************************************
  13. ----------------------------------------------------------------------
  14. File        : api_misc.c
  15. Purpose     : Misc. API functions
  16. ----------------------------------------------------------------------
  17. Known problems or limitations with current version
  18. ----------------------------------------------------------------------
  19. None.
  20. ---------------------------END-OF-HEADER------------------------------
  21. */
  22. /*********************************************************************
  23. *
  24. *             #include Section
  25. *
  26. **********************************************************************
  27. */
  28. #include "fs_port.h"
  29. #ifndef FS_FARCHARPTR
  30.   #define FS_FARCHARPTR char *
  31. #endif
  32. #include "fs_conf.h"
  33. #include "fs_dev.h"
  34. #include "fs_api.h"
  35. #include "fs_os.h"
  36. #include "fs_fsl.h"
  37. #include "fs_int.h"
  38. #include "api_int.h"
  39. #if FS_USE_FAT_FSL
  40.   #include "fs_fat.h"
  41. #endif
  42. #include "fs_clib.h"
  43. /*********************************************************************
  44. *
  45. *             #define constants
  46. *
  47. **********************************************************************
  48. */
  49. #define FS_VALID_MODE_NUM     (sizeof(_FS_valid_modes) / sizeof(_FS_mode_type))
  50. /*********************************************************************
  51. *
  52. *             Local data types
  53. *
  54. **********************************************************************
  55. */
  56. typedef struct {
  57.   FS_FARCHARPTR mode;
  58.   unsigned char mode_r;     /* mode READ                    */
  59.   unsigned char mode_w;     /* mode WRITE                   */
  60.   unsigned char mode_a;     /* mode APPEND                  */
  61.   unsigned char mode_c;     /* mode CREATE                  */
  62.   unsigned char mode_b;     /* mode BINARY                  */
  63. } _FS_mode_type;
  64. /*********************************************************************
  65. *
  66. *             Local variables        
  67. *
  68. **********************************************************************
  69. */
  70. static const _FS_mode_type _FS_valid_modes[] = {
  71.   /*       READ  WRITE  APPEND  CREATE  BINARY */
  72.   { "r"   ,  1,    0,     0,       0,     0 },
  73.   { "w"   ,  0,    1,     0,       1,     0 },
  74.   { "a"   ,  0,    1,     1,       1,     0 },
  75.   { "rb"  ,  1,    0,     0,       0,     1 },
  76.   { "wb"  ,  0,    1,     0,       1,     1 },
  77.   { "ab"  ,  0,    1,     1,       1,     1 },
  78.   { "r+"  ,  1,    1,     0,       0,     0 },
  79.   { "w+"  ,  1,    1,     0,       1,     0 },
  80.   { "a+"  ,  1,    1,     1,       1,     0 },
  81.   { "r+b" ,  1,    1,     0,       0,     1 },
  82.   { "rb+" ,  1,    1,     0,       0,     1 },
  83.   { "w+b" ,  1,    1,     0,       1,     1 },
  84.   { "wb+" ,  1,    1,     0,       1,     1 },
  85.   { "a+b" ,  1,    1,     1,       1,     1 },
  86.   { "ab+" ,  1,    1,     1,       1,     1 }
  87. };
  88. static const unsigned int _FS_maxopen = FS_MAXOPEN;
  89. static FS_FILE            _FS_filehandle[FS_MAXOPEN];
  90. /*********************************************************************
  91. *
  92. *             Global functions
  93. *
  94. **********************************************************************
  95. */
  96. /*********************************************************************
  97. *
  98. *             FS__find_fsl
  99. *
  100.   Description:
  101.   FS internal function. Find correct index in the device information
  102.   table referred by FS__pDevInfo for a given fully qualified name.
  103.   Parameters:
  104.   pFullName   - Fully qualified name. 
  105.   pFilename   - Address of a pointer, which is modified to point to
  106.                 the file name part of pFullName.
  107.   Return value:
  108.   <0          - Unable to find the device.
  109.   >=0         - Index of the device in the device information table.
  110. */
  111. int FS__find_fsl(const char *pFullName, FS_FARCHARPTR *pFileName) {
  112.   int idx;
  113.   int i;
  114.   int j;
  115.   int m;
  116.   FS_FARCHARPTR s;
  117.   /* Find correct FSL (device:unit:name) */
  118.   s = (FS_FARCHARPTR)FS__CLIB_strchr(pFullName, ':');
  119.   if (s) {
  120.     /* Scan for device name */
  121.     idx = 0;
  122.     m = (int)((FS_u32)(s) - (FS_u32)(pFullName));
  123.     while (1) {
  124.       j = FS__CLIB_strlen(FS__pDevInfo[idx].devname);
  125.       if (m > j) {
  126.         j = m;
  127.       }
  128.       i = FS__CLIB_strncmp(FS__pDevInfo[idx].devname, pFullName, j);
  129.       idx++;
  130.       if (idx >= (int)FS__maxdev) {
  131.         break;  /* End of device information table reached */
  132.       }
  133.       if (i == 0) {
  134.         break;  /* Device found */
  135.       }
  136.     }
  137.     if (i == 0) {
  138.       idx--;  /* Correct index */
  139.     }
  140.     else {
  141.       return -1;  /* Device not found */
  142.     }
  143.     s++;
  144.   }
  145.   else {
  146.     /* use 1st FSL as default */
  147.     idx = 0;
  148.     s = (FS_FARCHARPTR) pFullName;
  149.   }
  150.   *pFileName = s;
  151.   return idx;
  152. }
  153. /*********************************************************************
  154. *
  155. *             FS_FOpen
  156. *
  157.   Description:
  158.   API function. Open an existing file or create a new one.
  159.   Parameters:
  160.   pFileName   - Fully qualified file name. 
  161.   pMode       - Mode for opening the file.
  162.   
  163.   Return value:
  164.   ==0         - Unable to open the file.
  165.   !=0         - Address of an FS_FILE data structure.
  166. */
  167. FS_FILE *FS_FOpen(const char *pFileName, const char *pMode) {
  168.   FS_FARCHARPTR s;
  169.   FS_FILE *handle;
  170.   unsigned int i;
  171.   int idx;
  172.   int j;
  173.   int c;
  174.   /* Find correct FSL  (device:unit:name) */
  175.   idx = FS__find_fsl(pFileName, &s);
  176.   if (idx < 0) {
  177.     return 0;  /* Device not found */
  178.   }
  179.   if (FS__pDevInfo[idx].fs_ptr->fsl_fopen) {
  180.     /*  Find next free entry in _FS_filehandle */
  181.     FS_X_OS_LockFileHandle();
  182.     i = 0;
  183.     while (1) {
  184.       if (i >= _FS_maxopen) {
  185.         break;  /* No free entry found. */
  186.       }
  187.       if (!_FS_filehandle[i].inuse) {
  188.         break;  /* Unused entry found */
  189.       }
  190.       i++;
  191.     }
  192.     if (i < _FS_maxopen) {
  193.       /*
  194.          Check for valid mode string and set flags in file
  195.          handle
  196.       */
  197.       j = 0;
  198.       while (1) {
  199.         if (j >= FS_VALID_MODE_NUM) {
  200.           break;  /* Not in list of valid modes */
  201.         }
  202.         c = FS__CLIB_strcmp(pMode, _FS_valid_modes[j].mode);
  203.         if (c == 0) {
  204.           break;  /* Mode found in list */
  205.         }
  206.         j++;
  207.       }
  208.       if (j < FS_VALID_MODE_NUM) {
  209.         /* Set mode flags according to the mode string */
  210.         _FS_filehandle[i].mode_r = _FS_valid_modes[j].mode_r;
  211.         _FS_filehandle[i].mode_w = _FS_valid_modes[j].mode_w;
  212.         _FS_filehandle[i].mode_a = _FS_valid_modes[j].mode_a;
  213.         _FS_filehandle[i].mode_c = _FS_valid_modes[j].mode_c;
  214.         _FS_filehandle[i].mode_b = _FS_valid_modes[j].mode_b;
  215.       }
  216.       else {
  217.         FS_X_OS_UnlockFileHandle();
  218.         return 0;
  219.       }
  220.       _FS_filehandle[i].dev_index = idx;
  221.       /* Execute the FSL function */
  222.       handle = (FS__pDevInfo[idx].fs_ptr->fsl_fopen)(s, pMode, &_FS_filehandle[i]);
  223.       FS_X_OS_UnlockFileHandle();
  224.       return handle;
  225.     }
  226.     FS_X_OS_UnlockFileHandle();
  227.   }
  228.   return 0;
  229. }
  230. /*********************************************************************
  231. *
  232. *             FS_FClose
  233. *
  234.   Description:
  235.   API function. Close a file referred by pFile.
  236.   Parameters:
  237.   pFile       - Pointer to a FS_FILE data structure. 
  238.   
  239.   Return value:
  240.   None.
  241. */
  242. void FS_FClose(FS_FILE *pFile) {
  243.   if (!pFile) {
  244.     return;  /* No pointer to a FS_FILE structure */
  245.   }
  246.   FS_X_OS_LockFileHandle();
  247.   if (!pFile->inuse) {
  248.     FS_X_OS_UnlockFileHandle(); /* The FS_FILE structure is not in use */
  249.     return;
  250.   }
  251.   if (pFile->dev_index >= 0) {
  252.     if (FS__pDevInfo[pFile->dev_index].fs_ptr->fsl_fclose) {
  253.       /* Execute the FSL function */
  254.       (FS__pDevInfo[pFile->dev_index].fs_ptr->fsl_fclose)(pFile);
  255.     }
  256.   }
  257.   FS_X_OS_UnlockFileHandle();
  258. }
  259. /*********************************************************************
  260. *
  261. *             FS_Remove
  262. *
  263.   Description:
  264.   API function. Remove a file.
  265.   There is no real 'delete' function in the FSL, but the FSL's 'open'
  266.   function can delete a file. 
  267.   Parameters:
  268.   pFileName   - Fully qualified file name. 
  269.   
  270.   Return value:
  271.   ==0         - File has been removed.
  272.   ==-1        - An error has occured.
  273. */
  274. int FS_Remove(const char *pFileName) {
  275.   FS_FARCHARPTR s;
  276.   unsigned int i;
  277.   int idx;
  278.   int x;
  279.   /* Find correct FSL  (device:unit:name) */
  280.   idx = FS__find_fsl(pFileName, &s);
  281.   if (idx < 0) {
  282.     return -1;  /* Device not found */
  283.   }
  284.   if (FS__pDevInfo[idx].fs_ptr->fsl_fopen) {
  285.     /*  Find next free entry in _FS_filehandle */
  286.     FS_X_OS_LockFileHandle();
  287.     i = 0;
  288.     while (1) {
  289.       if (i >= _FS_maxopen) {
  290.         break;  /* No free file handle found */
  291.       }
  292.       if (!_FS_filehandle[i].inuse) {
  293.         break;  /* Free file handle found */
  294.       }
  295.       i++;
  296.     }
  297.     if (i < _FS_maxopen) {
  298.       /* Set file open mode to write & truncate */
  299.       _FS_filehandle[i].mode_r = 0;
  300.       _FS_filehandle[i].mode_w = 1;
  301.       _FS_filehandle[i].mode_a = 0;
  302.       _FS_filehandle[i].mode_c = 0;
  303.       _FS_filehandle[i].mode_b = 0;
  304.       _FS_filehandle[i].dev_index = idx;
  305.       /* 
  306.          Call the FSL function 'open' with the parameter 'del' to indicate,
  307.          that we want to delete the file.
  308.       */
  309.       (FS__pDevInfo[idx].fs_ptr->fsl_fopen)(s, "del", &_FS_filehandle[i]);
  310.       x = _FS_filehandle[i].error;
  311.       FS_X_OS_UnlockFileHandle();
  312.       return x;
  313.     }
  314.     FS_X_OS_UnlockFileHandle();
  315.   }
  316.   return -1;
  317. }
  318. /*********************************************************************
  319. *
  320. *             FS_IoCtl
  321. *
  322.   Description:
  323.   API function. Execute device command.
  324.   Parameters:
  325.   pDevName    - Fully qualified directory name. 
  326.   Cmd         - Command to be executed.
  327.   Aux         - Parameter depending on command.
  328.   pBuffer     - Pointer to a buffer used for the command.
  329.   
  330.   Return value:
  331.   Command specific. In general a negative value means an error.
  332. */
  333. int FS_IoCtl(const char *pDevName, FS_i32 Cmd, FS_i32 Aux, void *pBuffer) {
  334.   int idx;
  335.   int unit;
  336.   FS_FARCHARPTR s;
  337.   FS_FARCHARPTR t;
  338.   idx = FS__find_fsl(pDevName, &s);
  339.   if (idx < 0) {
  340.     return -1;  /* Device not found */
  341.   }
  342.   t = FS__CLIB_strchr(s, ':');  /* Find correct unit (unit:name) */
  343.   if (t) {
  344.     unit = FS__CLIB_atoi(s);  /* Scan for unit number */
  345.   }
  346.   else {
  347.     unit = 0;  /* Use 1st unit as default */
  348.   }
  349.   if (FS__pDevInfo[idx].fs_ptr->fsl_ioctl) {
  350.     /* Execute the FSL function */
  351.     idx = (FS__pDevInfo[idx].fs_ptr->fsl_ioctl)(idx, unit, Cmd, Aux, pBuffer);
  352.   }
  353.   else {
  354.     idx = -1;
  355.   }
  356.   return idx;
  357. }
  358. /*********************************************************************
  359. *
  360. *             FS_FSeek
  361. *
  362.   Description:
  363.   API function. Set current position of a file pointer.
  364.   FS_fseek does not support to position the fp behind end of a file. 
  365.   Parameters:
  366.   pFile       - Pointer to a FS_FILE data structure.
  367.   Offset      - Offset for setting the file pointer position.
  368.   Whence      - Mode for positioning the file pointer.
  369.   
  370.   Return value:
  371.   ==0         - File pointer has been positioned according to the
  372.                 parameters.
  373.   ==-1        - An error has occured.
  374. */
  375. int FS_FSeek(FS_FILE *pFile, FS_i32 Offset, int Whence) {
  376.   FS_i32 value;
  377.   
  378.   if (!pFile) {
  379.     return -1;
  380.   }
  381.   pFile->error     = FS_ERR_OK;    /* Clear any previous error */
  382.   pFile->CurClust  = 0;            /* Invalidate current cluster */
  383.   if (Whence == FS_SEEK_SET) {
  384.     if (Offset <= pFile->size) {
  385.       pFile->filepos = Offset;
  386.     }
  387.     else {
  388.       /* New position would be behind EOF */
  389.       pFile->error = FS_ERR_INVALIDPAR;
  390.       return -1;
  391.     }
  392.   }
  393.   else if (Whence == FS_SEEK_CUR) {
  394.     value = pFile->filepos + Offset;
  395.     if (value <= pFile->size) {
  396.       pFile->filepos += Offset;
  397.     }
  398.     else {
  399.       /* New position would be behind EOF */
  400.       pFile->error = FS_ERR_INVALIDPAR;
  401.       return -1;
  402.     }
  403.   }
  404.   else if (Whence == FS_SEEK_END) {
  405.     /* The file system does not support this */
  406.     pFile->error = FS_ERR_INVALIDPAR;
  407.     return -1;
  408.   }
  409.   else {
  410.     /* Parameter 'Whence' is invalid */
  411.     pFile->error = FS_ERR_INVALIDPAR;
  412.     return -1;
  413.   }
  414.   return 0;
  415. }
  416. /*********************************************************************
  417. *
  418. *             FS_FTell
  419. *
  420.   Description:
  421.   API function. Return position of a file pointer.
  422.   Parameters:
  423.   pFile       - Pointer to a FS_FILE data structure.
  424.   
  425.   Return value:
  426.   >=0         - Current position of the file pointer.
  427.   ==-1        - An error has occured.
  428. */
  429. FS_i32 FS_FTell(FS_FILE *pFile) {
  430.   if (!pFile) {
  431.     return -1;
  432.   }
  433.   return pFile->filepos;
  434. }
  435. /*********************************************************************
  436. *
  437. *             FS_FError
  438. *
  439.   Description:
  440.   API function. Return error status of a file.
  441.   Parameters:
  442.   pFile       - Pointer to a FS_FILE data structure.
  443.   
  444.   Return value:
  445.   ==FS_ERR_OK - No error.
  446.   !=FS_ERR_OK - An error has occured.
  447. */
  448. FS_i16 FS_FError(FS_FILE *pFile) {
  449.   if (!pFile) {
  450.     return 0;
  451.   }
  452.   return pFile->error;
  453. }
  454. /*********************************************************************
  455. *
  456. *             FS_ClearErr
  457. *
  458.   Description:
  459.   API function. Clear error status of a file.
  460.   Parameters:
  461.   pFile       - Pointer to a FS_FILE data structure.
  462.   
  463.   Return value:
  464.   None.
  465. */
  466. void FS_ClearErr(FS_FILE *pFile) {
  467.   if (!pFile) {
  468.     return;
  469.   }
  470.   pFile->error = FS_ERR_OK;
  471. }
  472. /*********************************************************************
  473. *
  474. *             FS_Init
  475. *
  476.   Description:
  477.   API function. Start the file system.
  478.   Parameters:
  479.   None.
  480.   
  481.   Return value:
  482.   ==0         - File system has been started.
  483.   !=0         - An error has occured.
  484. */
  485. int FS_Init(void) {
  486.   int x;
  487.   
  488.   x = FS_X_OS_Init();  /* Init the OS, e.g. create semaphores  */
  489. #if FS_USE_FAT_FSL
  490.   if (x == 0) {
  491.     FS__fat_block_init(); /* Init the FAT layers memory pool */
  492.   }
  493. #endif
  494.   return x;
  495. }
  496. /*********************************************************************
  497. *
  498. *             FS_Exit
  499. *
  500.   Description:
  501.   API function. Stop the file system.
  502.   Parameters:
  503.   None.
  504.   
  505.   Return value:
  506.   ==0         - File system has been stopped.
  507.   !=0         - An error has occured.
  508. */
  509. int FS_Exit(void) {
  510.   return FS_X_OS_Exit();
  511. }