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)

 

 

posted @ 2013-04-19 20:38  wwjdwy  阅读(2114)  评论(4编辑  收藏  举报