问题:在做豪华版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天...
不过也有所收获.
---------------------------------
是的,这里确实是我哪个malloc的问题.
在内存池前加上4字节对齐,问题解决!
//内存池(4字节对齐)
__align(4) u8 mem1base[MEM1_MAX_SIZE]; //内部SRAM内存池
__align(4) u8 mem2base[MEM2_MAX_SIZE] __attribute__((at(0X68000000))); //外部SRAM内存池
如果强制用 pack 指令,最直接的影响就是程序的性能降低,虽然会节省 ram,但是省不了 flash
就算没有用 pack 指令,性能也可能会降低,而且如果运气不好,就会进入一些奇怪的错误中断了
修改 malloc 可以提高程序的兼容性。在 32 位机上通常是 4 字节对齐的。
一周热门 更多>