FATFS一个小BUG搞了我2天才解决.特此发帖,希望大家不要重蹈我的覆辙.

2019-07-21 01:06发布

问题:在做豪华版fatfs实验的时候,发现从综合实验移植过来的fatfs部分,f_mkdir不能正常工作,跟踪调试发现死在move_window函数里面,如下图红线处.

只要执行过红线,就进入hard_fault了...
经验告诉我,这肯定是内存访问有问题.
于是对比成功和失败两个版本的fs,wsect,fs->fatbase,fs->fsize 他们对应值都一样!!!
这样,哥迷茫了...
于是使出浑身解数,疯狂替换反替换,结果还是一样...
后来发现我的综合实验使用了-o1,等优化选项.于是设置为一模一样.此时终于可以f_mkdir了...
但是作为普通实验,没必要开优化啊...所以还得找原因.
没办法,最后用绝招了,从最简单的做起,把不相干的代码统统砍掉.最后在去掉malloc的时候,奇迹终于出现了...
把如下代码:
//为exfuns申请内存
//返回值:0,成功
//1,失败
u8 exfuns_init(void)
{
 fs[0]=(FATFS*)mymalloc(SRAMIN,sizeof(FATFS)); //为磁盘0工作区申请内存 
 fs[1]=(FATFS*)mymalloc(SRAMIN,sizeof(FATFS)); //为磁盘1工作区申请内存
 file=(FIL*)mymalloc(SRAMIN,sizeof(FIL));  //为file申请内存
 ftemp=(FIL*)mymalloc(SRAMIN,sizeof(FIL));  //为ftemp申请内存
 fatbuf=(u8*)mymalloc(SRAMIN,512);    //为fatbuf申请内存
 if(fs[0]&&fs[1]&&file&&ftemp&&fatbuf)return 0;  //申请有一个失败,即失败.
 else return 1; 
}
不用malloc,而直接用全局数组来实现,就可以正常工作.
然后发现FATFS本来只有562字节,但是sizeof之后,却是564字节,反复数了N遍,确认FATFS只有562字节,这多了的2个字节,肯定就是FATFS结构体数据对其的问题了,于是赶紧在FATFS结构体前面加上__paked关键字.如下:
__packed typedef struct {
 BYTE fs_type;  /* FAT sub-type (0:Not mounted) */
 BYTE drv;   /* Physical drive number */
 BYTE csize;   /* Sectors per cluster (1,2,4...128) */
 BYTE n_fats;   /* Number of FAT copies (1,2) */
 BYTE wflag;   /* win[] dirty flag (1:must be written back) */
 BYTE fsi_flag;  /* fsinfo dirty flag (1:must be written back) */
 WORD id;    /* File system mount ID */
 WORD n_rootdir;  /* Number of root directory entries (FAT12/16) */
#if _MAX_SS != 512
 WORD ssize;   /* Bytes per sector (512, 1024, 2048 or 4096) */
#endif
#if _FS_REENTRANT
 _SYNC_t sobj;   /* Identifier of sync object */
#endif
#if !_FS_READONLY
 DWORD last_clust;  /* Last allocated cluster */
 DWORD free_clust;  /* Number of free clusters */
 DWORD fsi_sector;  /* fsinfo sector (FAT32) */
#endif
#if _FS_RPATH
 DWORD cdir;   /* Current directory start cluster (0:root) */
#endif
 DWORD n_fatent;  /* Number of FAT entries (= number of clusters + 2) */
 DWORD fsize;   /* Sectors per FAT */
 DWORD fatbase;  /* FAT start sector */
 DWORD dirbase;  /* Root directory start sector (FAT32:Cluster#) */
 DWORD database;  /* Data start sector */
 DWORD winsect;  /* Current sector appearing in the win[] */
 BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and Data on tiny cfg) */
} FATFS;

之后再用sizeof,得到FATFS大小是562字节了...
然后再次加入malloc,代码也可以正常工作了.
至此,该问题终于解决了.
究其原因,就是FATFS结构体的字节对齐问题.所以建议大家在自己建立结构体的时候,最好加上__packed关键字,免得再出现这种郁闷的情况.
浪费2天...
不过也有所收获.
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。