OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 73947|回复: 90

FatFs源码剖析

  [复制链接]

12

主题

39

帖子

4

精华

高级会员

Rank: 4

积分
724
金钱
724
注册时间
2013-5-10
在线时间
2 小时
发表于 2014-2-19 22:57:30 | 显示全部楼层 |阅读模式

一、介绍:

本文以网上开源文件系统FatFs 0.01为研究对象,剖析FatFs文件系统的核心操作。FatFs目前最新版本已更新到0.10a版本,而我之所以选择0.01版本,是因为这是最早的发布版本,与最新的版本相比,去掉了很多高级应用,且代码量相对较小,宏开关也少了许多,易于阅读和理解,用来研究它的雏形再合适不过了,所以笔者选择0.01版本进行剖析。当大家了解了0.01的核心思想后,再回去看最新的版本,也就容易理解多了。

FatFs历史版本下载:http://elm-chan.org/fsw/ff/00index_e.html    在官网的最下面,能找到所有版本的下载链接。

 

二、重点:

1. FatFs中有两个重要的缓冲区:win[]和buffer。win[]在FATFS结构体中,buffer在FIL结构体中。

    win[]:系统缓冲区。当操作MBR,DBR,FAT表,根目录区时,使用该缓冲区;

    buffer:文件缓冲区。当对文件的内容进行操作时,如读、写、修改时,才使用该缓冲区。

   

2. 在对文件的f_read和f_write过程中(不考虑f_lseek的情况),只有需要读写的最后一个扇区(内容小于512字节)才会被暂存到buffer中,而前面的扇区内容是直接通过磁盘驱动disk_read/disk_write在用户缓冲区和物理磁盘之间进行交互的。

 

注意:FatFs 0.01与最新的版本还是不少差异的,如在0.01中,buffer只是个指针,需要用户自己定义文件缓冲区,并将buffer指向该缓冲区。而最新版本中,FIL已经有自己的buf[_MAX_SS]。在0.01中没有f_mount()函数,所以需要手动将全局指针FatFs指向自己定义的变量fs。具体的操作流程可参考官网上的示例代码。

 

三、关键函数总结:

1. f_open

 f_open()

{

    1. 初始化SD卡,初始化FATFS对象;

    2. 查找文件的目录项;

    3. 填充文件结构体FIL。

}

 

2. f_read

f_read()

{

    1. 从物理磁盘直接读取所需扇区到用户缓冲区,这个过程中未使用buffer缓冲区;

    2. 如果最后一扇区要读取的字节数少于512,则先将最后一扇区读到buffer中,然后再从buffer拷贝需要的字节到用户缓冲区中。

}

 

 

 

3. f_write

f_write()

{

    1. 从用户缓冲区直接写入到物理磁盘,这个过程中未使用buffer缓冲区;

    2. 如果要写入的最后一扇区内容少于512字节,则先从物理磁盘读取最后一扇区的内容到buffer中,然后修改buffer中的相应内容,并设置回写标记,这样下次调用f_close/f_write时,就会将buffer回写到物理磁盘中。

}

 

 

 

4. f_close

关键是调用了f_sync函数。

 

5. f_sync

f_sync()

{

    1. 将buffer回写到物理磁盘中;

    2. 读取文件对应的目录项到win[]中,更新参数,并回写。

}

 

 

 

 

5. move_window

move_window专用于操作win[]系统缓冲区。

 

move_window(B);

调用前:

                    

 

执行中:

 

 

调用后:

                      

 

 

四、源码注释

本人在不破坏源码逻辑的前提下,对FatFs 0.01源代码进行了中文注释,个别函数重新修改了排版布局,以方便阅读。结合以上示意图即伪代码,相信大家会很快理解FatFs 0.01的核心思想及架构。

  1. #include <string.h>   
  2. #include "ff.h"         /* FatFs declarations */   
  3. #include "diskio.h"     /* Include file for user provided functions */   
  4.   
  5.   
  6. FATFS *FatFs;           /* ointer to the file system object */  
  7.   
  8.   
  9. /*------------------------------------------------------------------------- 
  10.   Module rivate Functions 
  11. -------------------------------------------------------------------------*/  
  12.   
  13. /*----------------------*/  
  14. /* Change Window Offset */  
  15.   
  16. //读取新的扇区内容到临时缓冲区win[],   
  17. //如果sector为0,则只需要把win[]的内容写入对应的物理扇区即可   
  18. static  
  19. BOOL move_window (  
  20.     DWORD sector        /* Sector number to make apperance in the FatFs->win */  
  21. )                       /* Move to zero only writes back dirty window */  
  22. {  
  23.     DWORD wsect;        //wsect用于检索FAT备份表的相应扇区   
  24.     FATFS *fs = FatFs;  
  25.   
  26.   
  27.     wsect = FatFs->winsect;  
  28.     /*首先检查目标扇区号是否与win[]对应的扇区号相同,如果相同则不进行任何操作。*/  
  29.     if (wsect != sector) {  /* Changed current window */  
  30. #ifndef _FS_READONLY   
  31.         BYTE n;  
  32.   
  33.         //首先检测win[]的内容是否做过修改,如果修改过,则需要先将其写入SD卡中。   
  34.         if (FatFs->dirtyflag) {  /* Write back dirty window if needed */  
  35.             if (disk_write(FatFs->win, wsect, 1) != RES_OK) return FALSE;  
  36.   
  37.             //清除修改标记   
  38.             FatFs->dirtyflag = 0;  
  39.               
  40.             /*如果当前操作的是FAT表,那么需要将修改后的FAT表拷贝到对应的FAT备份中*/  
  41.             if (wsect < (FatFs->fatbase + FatFs->sects_fat)) { /* In FAT area */  
  42.                 for (n = FatFs->n_fats; n >= 2; n--) {    /* Refrect the change to all FAT copies */  
  43.                     wsect += FatFs->sects_fat;  
  44.                     if (disk_write(FatFs->win, wsect, 1) != RES_OK) break;  
  45.                 }  
  46.             }  
  47.         }  
  48. #endif   
  49.   
  50.         //然后再读取新的扇区内容到win[]中   
  51.         if (sector) {  
  52.             if (disk_read(FatFs->win, sector, 1) != RES_OK) return FALSE;  
  53.             FatFs->winsect = sector; //更新当前缓冲区的扇区号   
  54.         }  
  55.     }  
  56.     return TRUE;  
  57. }  
  58.   
  59.   
  60.   
  61.   
  62.   
  63.   
  64.   
  65. /*--------------------------------------------------------------------------*/  
  66. /* ublic Funciotns                                                         */  
  67. /*--------------------------------------------------------------------------*/  
  68.   
  69.   
  70. /*----------------------------------------------------------*/  
  71. /* Load File System Information and Initialize FatFs Module */  
  72. //本函数做三件事:   
  73. // 1.初始化SD卡   
  74. // 2.检查文件系统类型,FAT16还是FAT32   
  75. // 3.填充FatFs对象,即记录物理磁盘的相关参数   
  76. FRESULT f_mountdrv ()  
  77. {  
  78.     BYTE fat;  
  79.     DWORD sect, fatend;  
  80.     FATFS *fs = FatFs;  
  81.   
  82.   
  83.     if (!fs) return FR_NOT_ENABLED;  
  84.   
  85.     //首先对文件系统对象清空   
  86.     /* Initialize file system object */  
  87.     memset(fs, 0, sizeof(FATFS));  
  88.   
  89.     //然后初始化SD卡   
  90.     /* Initialize disk drive */  
  91.     if (disk_initialize() & STA_NOINIT) return FR_NOT_READY;  
  92.   
  93.     //接着收搜索DBR系统引导记录,先检查第0扇区是否就是DBR(无MBR的SD卡),如果是则检查文件系统的类型;   
  94.     //如果不是则说明第0扇区是MBR,则根据MBR中的信息定位到DBR所在扇区,并检查该文件系统的类型   
  95.     /* Search FAT partition */  
  96.     fat = check_fs(sect = 0);       /* Check sector 0 as an SFD format */  
  97.     if (!fat) {                     /* Not a FAT boot record, it will be an FDISK format */  
  98.         /* Check a pri-partition listed in top of the partition table */  
  99.         if (fs->win[0x1C2]) {                    /* Is the partition existing? */  
  100.             sect = LD_DWORD(&(fs->win[0x1C6]));  /* artition offset in LBA */  
  101.             fat = check_fs(sect);               /* Check the partition */  
  102.         }  
  103.     }  
  104.     if (!fat) return FR_NO_FILESYSTEM;  /* No FAT patition */  
  105.   
  106.     //初始化文件系统对象,根据DBR参数信息对Fs成员赋值   
  107.     /* Initialize file system object */  
  108.   
  109.     //文件系统类型:FAT16/FAT32   
  110.     fs->fs_type = fat;                               /* FAT type */  
  111.   
  112.     //单个FAT表所占的扇区数   
  113.     fs->sects_fat =                              /* Sectors per FAT */  
  114.         (fat == FS_FAT32) ? LD_DWORD(&(fs->win[0x24])): LD_WORD(&(fs->win[0x16]));  
  115.   
  116.     //单个簇所占的扇区数   
  117.     fs->sects_clust = fs->win[0x0D];              /* Sectors per cluster */  
  118.   
  119.     //FAT表总数   
  120.     fs->n_fats = fs->win[0x10];                       /* Number of FAT copies */  
  121.   
  122.     //FAT表起始扇区(物理扇区)   
  123.     fs->fatbase = sect + LD_WORD(&(fs->win[0x0E]));   /* FAT start sector (physical) */  
  124.   
  125.     //根目录项数   
  126.     fs->n_rootdir = LD_WORD(&(fs->win[0x11]));        /* Nmuber of root directory entries */  
  127.   
  128.     //计算根目录起始扇区、数据起始扇区(物理扇区地址)   
  129.     fatend = fs->sects_fat * fs->n_fats + fs->fatbase;  
  130.     if (fat == FS_FAT32) {  
  131.         fs->dirbase = LD_DWORD(&(fs->win[0x2C])); /* Directory start cluster */  
  132.         fs->database = fatend;                       /* Data start sector (physical) */  
  133.     } else {  
  134.         fs->dirbase = fatend;                        /* Directory start sector (physical) */  
  135.         fs->database = fs->n_rootdir / 16 + fatend;   /* Data start sector (physical) */  
  136.     }  
  137.   
  138.     //最大簇号   
  139.     fs->max_clust =                              /* Maximum cluster number */  
  140.         (LD_DWORD(&(fs->win[0x20])) - fs->database + sect) / fs->sects_clust + 2;  
  141.   
  142.     return FR_OK;  
  143. }  
  144.   
  145.   
  146.   
  147.   
  148.   
  149. /*-----------------------*/  
  150. /* Open or Create a File */  
  151.   
  152. FRESULT f_open (  
  153.     FIL *fp,            /* ointer to the buffer of new file object to create */  
  154.     const char *path,   /* ointer to the file path */  
  155.     BYTE mode           /* Access mode and file open mode flags */  
  156. )  
  157. {  
  158.     FRESULT res;  
  159.     BYTE *dir;  
  160.     DIR dirscan;  
  161.     char fn[8+3+1];         //8.3 DOS文件名   
  162.     FATFS *fs = FatFs;  
  163.   
  164.     /*首先初始化SD卡,检测文件系统类型,初始化FATFS对象*/  
  165.     if ((res = check_mounted()) != FR_OK) return res;  
  166.       
  167. #ifndef _FS_READONLY   
  168.   
  169.     //如果磁盘设置为写保护,则返回错误码:FR_WRITE_PROTECTED   
  170.     if ((mode & (FA_WRITE|FA_CREATE_ALWAYS)) && (disk_status() & STA_PROTECT))  
  171.         return FR_WRITE_PROTECTED;  
  172. #endif   
  173.   
  174.     //根据用户提供的文件路径path,将文件名对应的目录项及其整个扇区读取到win[]中,   
  175.     //并填充目录项dirscan、标准格式的文件名fn,以及目录项在win[]中的字节偏移量dir   
  176.     res = trace_path(&dirscan, fn, path, &dir); /* Trace the file path */  
  177.   
  178. #ifndef _FS_READONLY   
  179.     /* Create or Open a File */  
  180.     if (mode & (FA_CREATE_ALWAYS|FA_OPEN_ALWAYS)) {  
  181.         DWORD dw;  
  182.   
  183.         //如果文件不存在,则强制新建文件   
  184.         if (res != FR_OK) {     /* No file, create new */  
  185.             mode |= FA_CREATE_ALWAYS;  
  186.             if (res != FR_NO_FILE) return res;  
  187.             dir = reserve_direntry(&dirscan);   /* Reserve a directory entry */  
  188.             if (dir == NULL) return FR_DENIED;  
  189.             memcpy(dir, fn, 8+3);       /* Initialize the new entry */  
  190.             *(dir+12) = fn[11];  
  191.             memset(dir+13, 0, 32-13);  
  192.         }   
  193.         else {              /* File already exists */  
  194.             if ((dir == NULL) || (*(dir+11) & (AM_RDO|AM_DIR))) /* Could not overwrite (R/O or DIR) */  
  195.                 return FR_DENIED;  
  196.               
  197.             //如果文件存在,但又以FA_CREATE_ALWAYS方式打开文件,则重写文件   
  198.             if (mode & FA_CREATE_ALWAYS) {  /* Resize it to zero */  
  199.                 dw = fs->winsect;            /* Remove the cluster chain */  
  200.                 if (!remove_chain(((DWORD)LD_WORD(dir+20) << 16) | LD_WORD(dir+26))  
  201.                     || !move_window(dw) )  
  202.                     return FR_RW_ERROR;  
  203.                 ST_WORD(dir+20, 0); ST_WORD(dir+26, 0); /* cluster = 0 */  
  204.                 ST_DWORD(dir+28, 0);                    /* size = 0 */  
  205.             }  
  206.         }  
  207.   
  208.         //如果是强制新建文件操作,则还需更新时间和日期   
  209.         if (mode & FA_CREATE_ALWAYS) {  
  210.             *(dir+11) = AM_ARC;  
  211.             dw = get_fattime();  
  212.             ST_DWORD(dir+14, dw);   /* Created time */  
  213.             ST_DWORD(dir+22, dw);   /* Updated time */  
  214.             fs->dirtyflag = 1;  
  215.         }  
  216.     }  
  217.     /* Open a File */  
  218.     else {  
  219. #endif   
  220.         if (res != FR_OK) return res;       /* Trace failed */  
  221.   
  222.         //如果打开的是一个目录文件,则返回错误码:FR_NO_FILE   
  223.         if ((dir == NULL) || (*(dir+11) & AM_DIR))  /* It is a directory */  
  224.             return FR_NO_FILE;  
  225.           
  226. #ifndef _FS_READONLY   
  227.   
  228.         //如果以FA_WRITE方式打开Read-Only属性的文件,则返回错误码:FR_DENIED   
  229.         if ((mode & FA_WRITE) && (*(dir+11) & AM_RDO)) /* R/O violation */  
  230.             return FR_DENIED;  
  231.     }  
  232. #endif   
  233.   
  234.     //填充FIL文件结构体参数   
  235. #ifdef _FS_READONLY   
  236.     fp->flag = mode & (FA_UNBUFFERED|FA_READ);  
  237. #else   
  238.     fp->flag = mode & (FA_UNBUFFERED|FA_WRITE|FA_READ);  
  239.     fp->dir_sect = fs->winsect;               /* ointer to the directory entry */  
  240.     fp->dir_ptr = dir;  
  241. #endif   
  242.     fp->org_clust =  ((DWORD)LD_WORD(dir+20) << 16) | LD_WORD(dir+26); /* File start cluster */  
  243.     fp->fsize = LD_DWORD(dir+28);        /* File size */  
  244.     fp->fptr = 0;                        /* File ptr */  
  245.   
  246.     //这一步很重要,它将直接导致f_read和f_write操作中的逻辑顺序   
  247.     fp->sect_clust = 1;                  /* Sector counter */  
  248.       
  249.     fs->files++;  
  250.     return FR_OK;  
  251. }  
  252.   
  253.  

FatFs0.01源码中文注释.zip

229.91 KB, 下载次数: 6488

FatFs 0.01学习笔记.pdf

300.88 KB, 下载次数: 8991

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165371
金钱
165371
注册时间
2010-12-1
在线时间
2110 小时
发表于 2014-2-19 23:01:30 | 显示全部楼层
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

170

主题

917

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1824
金钱
1824
注册时间
2013-4-13
在线时间
63 小时
发表于 2014-2-19 23:04:29 | 显示全部楼层
好东西!谢谢
手艺人要内外兼修。
回复 支持 反对

使用道具 举报

12

主题

39

帖子

4

精华

高级会员

Rank: 4

积分
724
金钱
724
注册时间
2013-5-10
在线时间
2 小时
 楼主| 发表于 2014-2-19 23:21:39 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
多谢原子哥捧场,不过我想把贴出来的代码放到代码浏览控件里面,就像CSDN显示代码片段一样,看起来很舒服,怎么弄呢?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165371
金钱
165371
注册时间
2010-12-1
在线时间
2110 小时
发表于 2014-2-19 23:40:14 | 显示全部楼层
回复【4楼】hexiaolong2008:
---------------------------------
这个得论坛更新编辑框,才可以。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

13

主题

45

帖子

0

精华

初级会员

Rank: 2

积分
166
金钱
166
注册时间
2013-8-27
在线时间
12 小时
发表于 2014-2-20 08:58:04 | 显示全部楼层
cool
回复 支持 反对

使用道具 举报

13

主题

314

帖子

0

精华

高级会员

Rank: 4

积分
713
金钱
713
注册时间
2012-7-20
在线时间
102 小时
发表于 2014-2-20 09:48:48 | 显示全部楼层
感谢分享
回复 支持 反对

使用道具 举报

39

主题

2026

帖子

1

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2020
金钱
2020
注册时间
2013-5-1
在线时间
87 小时
发表于 2014-2-20 11:01:37 | 显示全部楼层
好贴~支持!
博观而约取,厚积而薄发。
回复 支持 反对

使用道具 举报

14

主题

41

帖子

0

精华

初级会员

Rank: 2

积分
117
金钱
117
注册时间
2014-2-19
在线时间
0 小时
发表于 2014-2-20 11:19:19 | 显示全部楼层
大赞楼主无私
回复 支持 反对

使用道具 举报

105

主题

522

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1386
金钱
1386
注册时间
2012-10-23
在线时间
97 小时
发表于 2014-2-20 11:43:35 | 显示全部楼层
讲得好
回复 支持 反对

使用道具 举报

17

主题

93

帖子

0

精华

初级会员

Rank: 2

积分
181
金钱
181
注册时间
2013-10-9
在线时间
0 小时
发表于 2014-2-20 12:00:55 | 显示全部楼层
mark
回复 支持 反对

使用道具 举报

120

主题

7878

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12012
金钱
12012
注册时间
2013-9-10
在线时间
427 小时
发表于 2014-2-20 14:45:25 | 显示全部楼层
好,学习了,支持
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

2

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
157
金钱
157
注册时间
2014-2-10
在线时间
19 小时
发表于 2014-2-20 15:39:00 | 显示全部楼层
这个帖子相当牛皮呀!
回复 支持 反对

使用道具 举报

41

主题

99

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
283
金钱
283
注册时间
2013-8-1
在线时间
0 小时
发表于 2014-2-20 17:40:18 | 显示全部楼层
大牛,您好。单片机上移植的FATFS文件系统最大单个文件只能到4G,请问如何能支持4G的文件,能移植上NTFS吗?
回复 支持 反对

使用道具 举报

12

主题

39

帖子

4

精华

高级会员

Rank: 4

积分
724
金钱
724
注册时间
2013-5-10
在线时间
2 小时
 楼主| 发表于 2014-2-20 17:44:36 | 显示全部楼层
回复【14楼】yongyooh:
---------------------------------
不是只有FatFs才有4G的限制的,只要是FAT32文件系统,都不能支持大于4G的文件操作,就算PC机也一样。
至于有没有嵌入式下的ntfs文件系统,这个嘛我还不知道,问度娘吧!
回复 支持 反对

使用道具 举报

41

主题

99

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
283
金钱
283
注册时间
2013-8-1
在线时间
0 小时
发表于 2014-2-20 19:27:18 | 显示全部楼层
回复【15楼】hexiaolong2008:
---------------------------------
哎,现在做东西就有这个瓶颈啊,度娘说了,NTFS没有开放源码,坑爹啊,有没有办法把大于4G的文件分割成小于4G的文件,导入U盘里,然后U盘读出后再形成一个大于4G的文件,请问可行吗?
回复 支持 反对

使用道具 举报

7

主题

36

帖子

0

精华

初级会员

Rank: 2

积分
84
金钱
84
注册时间
2012-12-21
在线时间
0 小时
发表于 2014-4-10 17:16:55 | 显示全部楼层
回复【15楼】hexiaolong2008:
---------------------------------
兄弟,你确定fatfs最大支持4g的sd卡啊?
怪不得前几天弄了好久的移植8g卡,运行到 f_open(&fdst, "0:/Demo.TXT", FA_OPEN_ALWAYS | FA_WRITE);这个函数的时候,总是返回         FR_NOT_ENABLED


看来我还是太差劲了。。。。
回复 支持 反对

使用道具 举报

0

主题

5

帖子

0

精华

新手上路

积分
26
金钱
26
注册时间
2013-11-19
在线时间
0 小时
发表于 2014-4-11 19:25:26 | 显示全部楼层
回复【17楼】hunxiyi:
---------------------------------
是FAT32最大只能支持单个文件不超过4G,并不是说FatFs不支持8G的卡,移植时要注意不同容量的卡底层驱动是不一样的
回复 支持 反对

使用道具 举报

7

主题

36

帖子

0

精华

初级会员

Rank: 2

积分
84
金钱
84
注册时间
2012-12-21
在线时间
0 小时
发表于 2014-4-11 23:58:32 | 显示全部楼层
回复【18楼】LoveSmallXuan:
---------------------------------
昨晚已经成功了。。。嘎嘎,不过只实现了创建、打开、写、读文件,还有创建文件夹
回复 支持 反对

使用道具 举报

12

主题

77

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
352
金钱
352
注册时间
2014-1-22
在线时间
43 小时
发表于 2014-7-1 21:44:09 | 显示全部楼层
最近一直在看文件系统,这篇文章有加深了印象。
我最近在调用fread函数的时候出现了问题, 因为需求问题,需要读取文件内容到nand 中,因为nand是以页的方式读写的,我使用的nand一页大小是2112(2KB +62)Byte;所以要需要用到大小为2048的字符型数组(假设为A[2048]),这个时候问题来了,我在调用fread()函数的时候,一次读取2048个字节到数组A[2048]中,但是发现前面36个字节不是我想要的内容,36个字符内容来源无从考证(此处用了Winhex打开文件做了仔细的对比);
如果A数组大小为1024的话,内容是一致的;
然后就接着修改,增加了一个大小为1024的字符型数组(假设为B[1024]),分两次调用fread()函数,每次读取1024字节到B[1024]数组中,然后在再把B数组中的内容copy到A中,这个时候问题出现了,在第一次调用fread()语句结束后,A[2048]数组中的512~530字节内容被莫名的修改(注意:此处刚刚执行完fread()函数,还没用调用memcpy()函数,而且两个数组都初始化为0的),然后调用memcpy()内容正常,在第二次调用完fread()语句的时候,A[2048]数组中的508~512字节又被莫名的改掉了(注意:此处还是没有调用任何与A[]数组有关的函数);
接着修改, 又增加一个字符型数组,运行到完fread()函数的时候,发现B[1024]数组根本没有任何内容考出;
好郁闷。。。。。不知道是不是哪里设置出现了问题。。
任何一件事情,只要心甘情愿,总是能够变得简单。
回复 支持 反对

使用道具 举报

12

主题

77

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
352
金钱
352
注册时间
2014-1-22
在线时间
43 小时
发表于 2014-7-1 21:48:43 | 显示全部楼层
部分代码如下:
uint8_t A[2048]={0};
uint8_t B[1024]={0};//第二次修改增加的
//uint8_t Buf[512]={0};//第三次修改增加的
for(i=0;i<2;i++)
{
f_read(fsrc,B,1024,&br);
memcpy(A+1024*i,B,1024);
memset(B,0,sizeof(B));
}
任何一件事情,只要心甘情愿,总是能够变得简单。
回复 支持 反对

使用道具 举报

12

主题

77

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
352
金钱
352
注册时间
2014-1-22
在线时间
43 小时
发表于 2014-7-3 10:39:48 | 显示全部楼层
没有人出现过这样的问题吗?好悲伤啊啊,,,我现在怀疑是FATFS文件系统函数出现问题,原子哥教程里面好像没有FAFTS文件系统啊
任何一件事情,只要心甘情愿,总是能够变得简单。
回复 支持 反对

使用道具 举报

5

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
63
金钱
63
注册时间
2014-6-28
在线时间
0 小时
发表于 2014-7-31 22:42:04 | 显示全部楼层
win[]:系统缓冲区。当操作MBR,DBR,FAT表,根目录区时,使用该缓冲区;  这句话可能欠妥, 
if (wsect < (FatFs->fatbase + FatFs->sects_fat)) { /* In FAT area */ /
for (n = FatFs->n_fats; n >= 2; n--) { /* Refrect the change to all FAT copies */
wsect += FatFs->sects_fat;
if (disk_write(FatFs->win, wsect, 1) != RES_OK) break;
贴出的是move_window部分源码, 
如果可以操作MBR和DBR的话, 那么if (wsect < (FatFs->fatbase + FatFs->sects_fat)) { /* In FAT area */ /
这个判断就是有问题, 所以我猜测是不能操作MBR和DBR的
回复 支持 反对

使用道具 举报

12

主题

39

帖子

4

精华

高级会员

Rank: 4

积分
724
金钱
724
注册时间
2013-5-10
在线时间
2 小时
 楼主| 发表于 2014-10-11 14:22:04 | 显示全部楼层
回复【23楼】paullenoard:
---------------------------------
没有问题的,在你调用f_mountdrv()的时候就会去检查当前是否存在MBR,通过check_fs()去判断的,而该函数内部则是读取MBR到win[]中去的,如果没有MBR,那么读取到得肯定就是DBR了。所以是没有什么欠妥的。
回复 支持 反对

使用道具 举报

66

主题

237

帖子

0

精华

高级会员

Rank: 4

积分
943
金钱
943
注册时间
2013-5-17
在线时间
192 小时
发表于 2014-10-13 15:34:45 | 显示全部楼层
好东西,最近要学文件系统了
回复 支持 反对

使用道具 举报

70

主题

6758

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
12991
金钱
12991
注册时间
2012-11-26
在线时间
3789 小时
发表于 2014-10-13 15:57:01 | 显示全部楼层
好东西   MARK
学无止境
回复 支持 反对

使用道具 举报

8

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2014-5-22
在线时间
0 小时
发表于 2014-10-13 21:22:03 | 显示全部楼层
好帖,必须顶一下
回复 支持 反对

使用道具 举报

5

主题

49

帖子

0

精华

初级会员

Rank: 2

积分
179
金钱
179
注册时间
2014-8-29
在线时间
11 小时
发表于 2014-10-31 23:07:02 | 显示全部楼层
现在还不会用,在学习
有深圳的大牛带我飞吗?
回复 支持 反对

使用道具 举报

9

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
99
金钱
99
注册时间
2014-3-20
在线时间
9 小时
发表于 2014-11-1 01:22:21 | 显示全部楼层
MARK      A
回复 支持 反对

使用道具 举报

15

主题

143

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
243
金钱
243
注册时间
2014-10-31
在线时间
4 小时
发表于 2015-3-29 09:57:38 | 显示全部楼层
好东西,果断收藏!
总有一天,要为自由而活
回复 支持 反对

使用道具 举报

4

主题

11

帖子

0

精华

新手上路

积分
49
金钱
49
注册时间
2013-2-26
在线时间
3 小时
发表于 2015-4-20 21:54:50 | 显示全部楼层
好东西!谢谢
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手上路

积分
27
金钱
27
注册时间
2015-4-28
在线时间
0 小时
发表于 2015-4-28 16:35:31 | 显示全部楼层
怒Mark~
回复 支持 反对

使用道具 举报

50

主题

385

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1126
金钱
1126
注册时间
2014-8-24
在线时间
146 小时
发表于 2015-4-28 17:26:59 | 显示全部楼层
mark,学习
回复 支持 反对

使用道具 举报

7

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
95
金钱
95
注册时间
2014-12-13
在线时间
13 小时
发表于 2015-4-29 08:41:43 | 显示全部楼层
好帖,记号下慢慢学习
回复 支持 反对

使用道具 举报

7

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
77
金钱
77
注册时间
2014-7-17
在线时间
0 小时
发表于 2015-5-8 16:21:04 | 显示全部楼层
你们好我是小白,想学FAFTS文件系统,目的是使用SD卡读取文件,储存数据文件。我应该怎么理解这个东西,网上的资料很杂,我应该着重去看什么资料比较少弯路,希望有人理解我的意思,感谢
回复 支持 反对

使用道具 举报

12

主题

39

帖子

4

精华

高级会员

Rank: 4

积分
724
金钱
724
注册时间
2013-5-10
在线时间
2 小时
 楼主| 发表于 2015-5-11 22:56:27 | 显示全部楼层
回复【35楼】小生QQB:
---------------------------------
先去找一个FatFS的简单Demo,比如读、改、写三部曲的那种,然后把代码复制粘贴到自己的测试程序上,能够在自己的程序上跑通且正常运行后,再去慢慢研究每个函数是什么意思,参数要怎样传递,建议直接看FatFS自带的html文档,里面有详细介绍怎么使用和函数的意义。等简单的学会了,高级的应用根据自己的需求慢慢也就能搞定了。
回复 支持 反对

使用道具 举报

7

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
77
金钱
77
注册时间
2014-7-17
在线时间
0 小时
发表于 2015-5-25 13:56:50 | 显示全部楼层
回复【36楼】hexiaolong2008:
---------------------------------
谢谢,方法对我很有效
回复 支持 反对

使用道具 举报

52

主题

142

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
441
金钱
441
注册时间
2013-10-17
在线时间
23 小时
发表于 2015-6-26 15:24:37 | 显示全部楼层
楼主的配图是哪弄的
回复 支持 反对

使用道具 举报

18

主题

107

帖子

1

精华

高级会员

Rank: 4

积分
570
金钱
570
注册时间
2013-11-28
在线时间
51 小时
发表于 2015-7-4 21:58:09 | 显示全部楼层
请问楼主,对SD卡格式化的函数是否有使用过,OK吗?谢谢!
学习只为了路程走得更远....!
回复 支持 反对

使用道具 举报

12

主题

39

帖子

4

精华

高级会员

Rank: 4

积分
724
金钱
724
注册时间
2013-5-10
在线时间
2 小时
 楼主| 发表于 2015-7-14 13:38:23 | 显示全部楼层
回复【38楼】The_Professo_Lee:
---------------------------------
Visio 2003
回复 支持 反对

使用道具 举报

12

主题

39

帖子

4

精华

高级会员

Rank: 4

积分
724
金钱
724
注册时间
2013-5-10
在线时间
2 小时
 楼主| 发表于 2015-7-14 13:38:58 | 显示全部楼层
回复【39楼】techxuan:
---------------------------------
没用过。
回复 支持 反对

使用道具 举报

52

主题

142

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
441
金钱
441
注册时间
2013-10-17
在线时间
23 小时
发表于 2015-7-17 09:44:49 | 显示全部楼层
回复【40楼】hexiaolong2008:
---------------------------------
楼主靠自己理解画的图哦  强!
回复 支持 反对

使用道具 举报

66

主题

237

帖子

0

精华

高级会员

Rank: 4

积分
943
金钱
943
注册时间
2013-5-17
在线时间
192 小时
发表于 2015-8-3 11:30:15 | 显示全部楼层
谢谢,学习一下
回复 支持 反对

使用道具 举报

93

主题

746

帖子

1

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1849
金钱
1849
注册时间
2012-9-16
在线时间
286 小时
发表于 2015-8-3 14:46:59 | 显示全部楼层
今天才看到?
纵浪大化中,不喜亦不惧;应尽便须尽,无复独多虑!
回复 支持 反对

使用道具 举报

13

主题

38

帖子

0

精华

初级会员

Rank: 2

积分
112
金钱
112
注册时间
2013-7-9
在线时间
6 小时
发表于 2015-9-10 09:50:33 | 显示全部楼层
回复【2楼】正点原子:
------------------------------楼主威武,学习了
回复 支持 反对

使用道具 举报

1

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
54
金钱
54
注册时间
2015-10-23
在线时间
6 小时
发表于 2015-10-25 15:52:37 | 显示全部楼层
好贴   看完后 思路清晰多了。
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手上路

积分
39
金钱
39
注册时间
2015-10-28
在线时间
4 小时
发表于 2015-11-3 13:50:58 | 显示全部楼层
mark......
回复 支持 反对

使用道具 举报

5

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
117
金钱
117
注册时间
2013-7-31
在线时间
23 小时
发表于 2015-12-25 15:01:02 | 显示全部楼层
MARK.................
回复 支持 反对

使用道具 举报

38

主题

248

帖子

0

精华

版主

Rank: 7Rank: 7Rank: 7

积分
463
金钱
463
注册时间
2011-2-11
在线时间
12 小时
发表于 2016-1-4 09:31:08 | 显示全部楼层
这么好的资料得mark一下。
Openedv大力支持的开源RTOS  --Trochili RTOS(飞鸟)
回复 支持 反对

使用道具 举报

1

主题

78

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
211
金钱
211
注册时间
2015-12-10
在线时间
49 小时
发表于 2016-3-24 20:11:14 | 显示全部楼层
一篇技术总结好文。
逆水行舟不进则退
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-26 15:13

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表