zoukankan      html  css  js  c++  java
  • FATFS文件系统

    折腾了差不多快三天,总算出点眉目,操作流程,打开,浏览,读写都没啥问题了。

    char[] char* a这个C确实比较基础,调用<string.h>中的函数来完成操作,又熟悉了一遍吼吼

    我们需要的两个主要文件:ff.c 和diskio.c  其中ff.c是我们所需要调用的所有方法,diskio.c是我们移植需要写的底层函数。

    又走了不少弯路,不过也学到不少,神舟代码移植简单,但是功能不强大,不支持长文件名,并且版本居然是07的不是最新的我晕。而且原子的用动态内存来做,省资源,顺便加深对指针内存的认识,另外昨晚折腾char []也过去了吼吼。

    因为在ffconf.h里面设置对长文件名的支持为方法3,所以必须实现ff_memallocff_memfree这两个函数

    同时因为在ffconf.h里面设置对长文件名的支持为方法3 必须实现:When enable LFN,
    /  a Unicode handling functions ff_convert() and ff_wtoupper() must be added
    /  to the project. */

    这个转换函数在cc936.c文件中,

    原子支持两个盘符,0:SD  1:FLASH,因为我还没有加入flash读写,所以先把flash代码屏蔽掉。

    就是把之前SD卡初始化,读,写函数封装进去

    disk_initialize
     1 //初始化磁盘
     2 DSTATUS disk_initialize (
     3     BYTE drv                /* Physical drive nmuber (0..) */
     4 )
     5 {    
     6     u8 res=0;        
     7     switch(drv)
     8     {
     9         case SD_CARD://SD卡
    10             res = SD_Initialize();//SD_Initialize() 
    11              if(res)//STM32 SPI的bug,在sd卡操作失败的时候如果不执行下面的语句,可能导致SPI读写异常
    12             {
    13                 SD_SPI_SpeedLow();
    14                 SD_SPI_ReadWriteByte(0xff);//提供额外的8个时钟
    15                 SD_SPI_SpeedHigh();
    16             }
    17               break;
    18         case EX_FLASH://外部flash
    19 //            SPI_Flash_Init();
    20 //            if(SPI_FLASH_TYPE==W25Q64)FLASH_SECTOR_COUNT=2048*6;//W25Q64
    21 //            else FLASH_SECTOR_COUNT=2048*2;                        //其他
    22              break;
    23         default:
    24             res=1; 
    25     }         
    26     if(res)return  STA_NOINIT;
    27     else return 0; //初始化成功
    28 }   
    disk_read
     1 //读扇区
     2  //drv:磁盘编号0~9
     3  //*buff:数据接收缓冲首地址
     4  //sector:扇区地址
     5  //count:需要读取的扇区数
     6 DRESULT disk_read (
     7     BYTE drv,        /* Physical drive nmuber (0..) */
     8     BYTE *buff,        /* Data buffer to store read data */
     9     DWORD sector,    /* Sector address (LBA) */
    10     BYTE count        /* Number of sectors to read (1..255) */
    11 )
    12 {
    13     u8 res=0; 
    14     if (!count)return RES_PARERR;//count不能等于0,否则返回参数错误              
    15     switch(drv)
    16     {
    17         case SD_CARD://SD卡
    18             res=SD_ReadDisk(buff,sector,count);     
    19              if(res)//STM32 SPI的bug,在sd卡操作失败的时候如果不执行下面的语句,可能导致SPI读写异常
    20             {
    21                 SD_SPI_SpeedLow();
    22                 SD_SPI_ReadWriteByte(0xff);//提供额外的8个时钟
    23                 SD_SPI_SpeedHigh();
    24             }
    25             break;
    26         case EX_FLASH://外部flash
    27 //            for(;count>0;count--)
    28 //            {
    29 //                SPI_Flash_Read(buff,sector*FLASH_SECTOR_SIZE,FLASH_SECTOR_SIZE);
    30 //                sector++;
    31 //                buff+=FLASH_SECTOR_SIZE;
    32 //            }
    33 //            res=0;
    34             break;
    35         default:
    36             res=1; 
    37     }
    38    //处理返回值,将SPI_SD_driver.c的返回值转成ff.c的返回值
    39     if(res==0x00)return RES_OK;     
    40     else return RES_ERROR;       
    41 }  
    disk_write
     1  //写扇区
     2  //drv:磁盘编号0~9
     3  //*buff:发送数据首地址
     4  //sector:扇区地址
     5  //count:需要写入的扇区数        
     6 #if _READONLY == 0
     7 DRESULT disk_write (
     8     BYTE drv,            /* Physical drive nmuber (0..) */
     9     const BYTE *buff,            /* Data to be written */
    10     DWORD sector,        /* Sector address (LBA) */
    11     BYTE count            /* Number of sectors to write (1..255) */
    12 )
    13 {
    14     u8 res=0;  
    15     if (!count)return RES_PARERR;//count不能等于0,否则返回参数错误              
    16     switch(drv)
    17     {
    18         case SD_CARD://SD卡
    19             res=SD_WriteDisk((u8*)buff,sector,count);
    20             break;
    21         case EX_FLASH://外部flash
    22 //            for(;count>0;count--)
    23 //            {                                            
    24 //                SPI_Flash_Write((u8*)buff,sector*FLASH_SECTOR_SIZE,FLASH_SECTOR_SIZE);
    25 //                sector++;
    26 //                buff+=FLASH_SECTOR_SIZE;
    27 //            }
    28 //            res=0;
    29             break;
    30         default:
    31             res=1; 
    32     }
    33     //处理返回值,将SPI_SD_driver.c的返回值转成ff.c的返回值
    34     if(res == 0x00)return RES_OK;     
    35     else return RES_ERROR;         
    36 }
    37 #endif /* _READONLY */

    另外//获得时间
    //User defined function to give a current time to fatfs module      */
    //31-25: Year(0-127 org.1980), 24-21: Month(1-12), 20-16: Day(1-31) */                                                                                                                                                                                                                                         
    //15-11: Hour(0-23), 10-5: Minute(0-59), 4-0: Second(0-29 *2) */                                                                                                                                                                                                                                               
    DWORD get_fattime (void)

    需要实时时钟我就没封装了这里,测试了 一下,很简单。这里配置好之后,新建文件就会有时间戳了。

    一些其他的实用的函数:

    mf_scan_files
     1 //遍历文件
     2  //path:路径
     3  //返回值:执行结果
     4 u8 mf_scan_files(u8 * path)
     5 {
     6     FRESULT res;      
     7     char *fn;   /* This function is assuming non-Unicode cfg. */     
     8     FILINFO fileinfo;
     9     DIR dir; 
    10 
    11 #if _USE_LFN
    12      fileinfo.lfsize = _MAX_LFN * 2 + 1;
    13     fileinfo.lfname = mymalloc(SRAMIN,fileinfo.lfsize);
    14 #endif          
    15 
    16     res = f_opendir(&dir,(const TCHAR*)path); //打开一个目录
    17     if (res == FR_OK) 
    18     {    
    19         printf("\r\n"); 
    20         while(1)
    21         {
    22             res = f_readdir(&dir, &fileinfo);                   //读取目录下的一个文件
    23             if (res != FR_OK || fileinfo.fname[0] == 0) break;  //错误了/到末尾了,退出
    24             //if (fileinfo.fname[0] == '.') continue;             //忽略上级目录
    25 #if _USE_LFN
    26             fn = *fileinfo.lfname ? fileinfo.lfname : fileinfo.fname;
    27 #else                               
    28             fn = fileinfo.fname;
    29 #endif                                                  /* It is a file. */
    30             printf("%s/", path);//打印路径    
    31             printf("%s fdate: %d dtime: %d\r\n",  fn,fileinfo.fdate,fileinfo.ftime);//打印文件名      
    32         } 
    33     }      
    34     myfree(SRAMIN,fileinfo.lfname);
    35     return res;      
    36 }

    此函数遍历路径下的所有文件,其中_USE_LFN 表示使用长文件名
    如果fileinfo.fname[0] == 0表示遍历完了

    fileinfo.fattrib 文件属性,可以了解到文件属性是文件夹还是文件等等属性

    mf_showfree
     1 //显示剩余容量
     2 //drv:盘符
     3 //返回值:剩余容量(字节)
     4 u32 mf_showfree(u8 *drv)
     5 {
     6     FATFS *fs1;
     7     u8 res;
     8     DWORD fre_clust=0, fre_sect=0, tot_sect=0;
     9     //得到磁盘信息及空闲簇数量
    10     res = f_getfree((const TCHAR*)drv, &fre_clust, &fs1);
    11     if(res==0)
    12     {                                               
    13         tot_sect = (fs1->n_fatent - 2) * fs1->csize;//得到总扇区数
    14         fre_sect = fre_clust * fs1->csize;            //得到空闲扇区数       
    15 //#if _MAX_SS!=512
    16 //        tot_sect*=fs1->ssize/512;
    17 //        fre_sect*=fs1->ssize/512;
    18 //#endif      
    19         if(tot_sect<20480)//总容量小于10M
    20         {
    21             /* Print free space in unit of KB (assuming 512 bytes/sector) */
    22             printf("\r\n磁盘总容量:%d KB\r\n"
    23                    "可用空间:%d KB\r\n",
    24                    tot_sect>>1,fre_sect>>1);
    25         }else
    26         {
    27             /* Print free space in unit of KB (assuming 512 bytes/sector) */
    28             printf("\r\n磁盘总容量:%d MB\r\n"
    29                    "可用空间:%d MB\r\n",
    30                    tot_sect>>11,fre_sect>>11);
    31         }
    32     }
    33     return fre_sect;
    34 }        

    显示磁盘总容量以及所剩空间大小

    set_timestamp
    1 //给文件设置时间戳
    2 FRESULT set_timestamp (    char *obj,   int year,    int month,    int mday,    int hour,    int min,    int sec  )
    3  { 
    4    FILINFO fno;  
    5  //   printf("set_timestamp file name %s \r\n",obj);
    6    fno.fdate = (WORD)(((year - 1980) * 512U) | month * 32U | mday);
    7    fno.ftime = (WORD)(hour * 2048U | min * 32U | sec / 2U); 
    8    return f_utime(obj, &fno); 
    9  }

    修改时间戳

    一些常用操作 以下函数都是ff.c中

     挂载一个磁盘:FATFS fs; f_mount(0, &fs) //0代表盘符

    打开目录:f_opendir(&dirs, path)   //DIR dirs;

    读目录:f_readdir(&dirs, &finfo)  // FILINFO finfo;

    打开一个文件读写:

    FIL fsrc

    //   res = f_open(&fsrc, filename2, FA_OPEN_EXISTING | FA_READ | FA_WRITE);  ///新建一个文件可以用 FA_CREATE_ALWAYS代替 FA_OPEN_EXISTING
    //         res = f_read(&fsrc, buffer, 100, &br);
    //         printf("\n\r file contex is: \n\r%s\n\r", buffer);
    //   res = f_write(&fsrc, &armjishu, sizeof(armjishu), &bw); 
    //         f_close(&fsrc);

    删除一个文件:f_unlink(path)

  • 相关阅读:
    Object类-try-catch-finally-throw-throws-自定义异常
    修饰符-包-内部类-代码块执行顺序
    ZOJ 1241 Geometry Made Simple
    ZOJ 1029 Moving Tables
    ZOJ 1047 Image Perimeters
    ZOJ 1024 Calendar Game
    动态规划 -- 01背包问题
    Kmeans算法的应用实例(Matlab版本)
    Matlab优化存储器读写来改善程序性能
    struct和typedef struct的区别
  • 原文地址:https://www.cnblogs.com/wwjdwy/p/3031393.html
Copyright © 2011-2022 走看看