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

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        : fat_in.c
  15. Purpose     : FAT read routines
  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_conf.h"
  29. #include "fs_port.h"
  30. #include "fs_dev.h"
  31. #include "fs_api.h"
  32. #include "fs_fsl.h"
  33. #include "fs_int.h"
  34. #include "fs_os.h"
  35. #include "fs_lbl.h"
  36. #include "fs_fat.h"
  37. /*********************************************************************
  38. *
  39. *             Global functions
  40. *
  41. **********************************************************************
  42. */
  43. /*********************************************************************
  44. *
  45. *             FS__fat_fread
  46. *
  47.   Description:
  48.   FS internal function. Read data from a file.
  49.   Parameters:
  50.   pData       - Pointer to a data buffer for storing data transferred
  51.                 from file. 
  52.   Size        - Size of an element to be transferred from file to data
  53.                 buffer
  54.   N           - Number of elements to be transferred from the file.
  55.   pFile       - Pointer to a FS_FILE data structure.
  56.   
  57.   Return value:
  58.   Number of elements read.
  59. */
  60. FS_size_t FS__fat_fread(void *pData, FS_size_t Size, FS_size_t N, FS_FILE *pFile) {
  61.   FS_size_t todo;
  62.   FS_u32 i = 0;
  63.   FS_u32 j = 0;
  64.   FS_u32 fatsize;
  65.   FS_u32 fileclustnum;
  66.   FS_u32 diskclustnum;
  67.   FS_u32 prevclust;
  68.   FS_u32 dstart;
  69.   FS_u32 dsize;
  70.   FS_u32 datastart;
  71.   char *buffer;
  72.   int err;
  73.                                             
  74.   if (!pFile) {
  75.       return 0;  /* No valid pointer to a FS_FILE structure */
  76.   }
  77.   /* Check if media is OK */
  78.   err = FS__lb_status(FS__pDevInfo[pFile->dev_index].devdriver, pFile->fileid_lo);
  79.   if (err == FS_LBL_MEDIACHANGED) {
  80.     /* Media has changed */
  81.     pFile->error = FS_ERR_DISKCHANGED;
  82.     return 0;
  83.   }
  84.   else if (err < 0) {
  85.     /* Media cannot be accessed */
  86.     pFile->error = FS_ERR_READERROR;
  87.     return 0;
  88.   }
  89.   buffer = FS__fat_malloc(FS_FAT_SEC_SIZE);
  90.   if (!buffer) {
  91.     return 0;
  92.   }
  93.   fatsize = FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].FATSz16;
  94.   if (fatsize == 0) {
  95.     /* FAT32 */
  96.      fatsize = FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].FATSz32;
  97.   }
  98.   dstart    = FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].RsvdSecCnt + FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].NumFATs * fatsize;
  99.   dsize     = ((FS_u32)((FS_u32)FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].RootEntCnt) * FS_FAT_DENTRY_SIZE) / FS_FAT_SEC_SIZE;
  100.   datastart = dstart + dsize;
  101.   prevclust = 0;
  102.   todo = N * Size;
  103.   while (todo) {
  104.     if (pFile->filepos >= pFile->size) {
  105.       /* EOF has been reached */
  106.       pFile->error = FS_ERR_EOF;
  107.       FS__fat_free(buffer);
  108.       return ((N * Size - todo) / Size);
  109.     }
  110.     fileclustnum = pFile->filepos / (FS_FAT_SEC_SIZE * FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].SecPerClus);
  111.     if (prevclust == 0) {
  112.       diskclustnum = pFile->CurClust; 
  113.       if (diskclustnum == 0) {
  114.         /* Find current cluster by starting at 1st cluster of the file */
  115.         diskclustnum = FS__fat_diskclust(pFile->dev_index, pFile->fileid_lo, pFile->fileid_hi, fileclustnum);
  116.       }
  117.     }
  118.     else {
  119.       /* Get next cluster of the file */
  120.       diskclustnum = FS__fat_diskclust(pFile->dev_index, pFile->fileid_lo, prevclust, 1);
  121.     }
  122.     prevclust       = diskclustnum;
  123.     pFile->CurClust = diskclustnum;
  124.     if (diskclustnum == 0) {
  125.       /* Could not find current cluster */
  126.       pFile->error = FS_ERR_READERROR;
  127.       FS__fat_free(buffer);
  128.       return ((N * Size - todo) / Size);
  129.     }
  130.     diskclustnum -= 2;
  131.     j = (pFile->filepos % (FS_FAT_SEC_SIZE * FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].SecPerClus))/ FS_FAT_SEC_SIZE;
  132.     while (1) {
  133.       if (!todo) {
  134.         break;  /* Nothing more to write */
  135.       }
  136.       if (j >= (FS_u32)FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].SecPerClus) {
  137.         break;  /* End of the cluster reached */
  138.       }
  139.       if (pFile->filepos >= pFile->size) {
  140.         break;  /* End of the file reached */
  141.       }
  142.       err = FS__lb_read(FS__pDevInfo[pFile->dev_index].devdriver, pFile->fileid_lo,
  143.                     datastart +
  144.                     diskclustnum * FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].SecPerClus + j,
  145.                     (void*)buffer);
  146.       if (err < 0) {
  147.         pFile->error = FS_ERR_READERROR;
  148.         FS__fat_free(buffer);
  149.         return ((N * Size - todo) / Size);
  150.       }
  151.       i = pFile->filepos % FS_FAT_SEC_SIZE;
  152.       while (1) {
  153.         if (!todo) {
  154.           break;  /* Nothing more to write */
  155.         }
  156.         if (i >= FS_FAT_SEC_SIZE) {
  157.           break;  /* End of the sector reached */
  158.         }
  159.         if (pFile->filepos >= pFile->size) {
  160.           break;  /* End of the file reached */
  161.         }
  162.         *((char*)(((char*)pData) + N * Size - todo)) = buffer[i];
  163.         i++;
  164.         pFile->filepos++;
  165.         todo--;
  166.       }
  167.       j++;
  168.     }  /* Sector loop */
  169.   }  /* Cluster loop */
  170.   if (i >= FS_FAT_SEC_SIZE) {
  171.     if (j >= FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].SecPerClus) {
  172.       pFile->CurClust = FS__fat_diskclust(pFile->dev_index, pFile->fileid_lo, prevclust, 1);
  173.     }
  174.   }
  175.   FS__fat_free(buffer);
  176.   return ((N * Size - todo) / Size);
  177. }