FatFS源代码中的函数逻辑关系

第一  调用函数 f_mount()

result = f_mount(&fs, FS_VOLUME_NAND, );    /* Mount a logical drive */
FS_VOLUME_NAND 代表 “路径”

第二  进入函数 f_mount()内

 /*-----------------------------------------------------------------------*/
/* Mount/Unmount a Logical Drive */
/*-----------------------------------------------------------------------*/ FRESULT f_mount (
FATFS* fs, /* Pointer to the file system object (NULL:unmount)*/
const TCHAR* path, /* Logical drive number to be mounted/unmounted */
BYTE opt /* 0:Do not mount (delayed mount), 1:Mount immediately */
)
{
FATFS *cfs;
int vol;
FRESULT res;
const TCHAR *rp = path; vol = get_ldnumber(&rp);
if (vol < ) return FR_INVALID_DRIVE;
cfs = FatFs[vol]; /* Pointer to fs object */ if (cfs) {
#if _FS_LOCK
clear_lock(cfs);
#endif
#if _FS_REENTRANT /* Discard sync object of the current volume */
if (!ff_del_syncobj(cfs->sobj)) return FR_INT_ERR;
#endif
cfs->fs_type = ; /* Clear old fs object */
} if (fs) {
fs->fs_type = ; /* Clear new fs object */
#if _FS_REENTRANT /* Create sync object for the new volume */
if (!ff_cre_syncobj((BYTE)vol, &fs->sobj)) return FR_INT_ERR;
#endif
}
FatFs[vol] = fs; /* Register new fs object */ if (!fs || opt != ) return FR_OK; /* Do not mount now, it will be mounted later */ res = find_volume(&fs, &path, ); /* Force mounted the volume */
LEAVE_FF(fs, res);
}

代码中第17行 vol = get_ldnumber(&rp) 将路径转换为 logical drive number

第三  进入函数 get_ldnumber()

 /*-----------------------------------------------------------------------*/
/* Get logical drive number from path name */
/*-----------------------------------------------------------------------*/ static
int get_ldnumber ( /* Returns logical drive number (-1:invalid drive) */
const TCHAR** path /* Pointer to pointer to the path name */
)
{
const TCHAR *tp, *tt;
UINT i;
int vol = -; if (*path) { /* If the pointer is not a null */
for (tt = *path; (UINT)*tt >= (_USE_LFN ? ' ' : '!') && *tt != ':'; tt++) ; /* Find ':' in the path */
if (*tt == ':') { /* If a ':' is exist in the path name */
tp = *path;
i = *tp++ - '';
if (i < && tp == tt) { /* Is there a numeric drive id? */
if (i < _VOLUMES) { /* If a drive id is found, get the value and strip it */
vol = (int)i;
*path = ++tt;
}
} else { /* No numeric drive number */
#if _STR_VOLUME_ID /* Find string drive id */
static const char* const str[] = {_VOLUME_STRS};
const char *sp;
char c;
TCHAR tc; i = ; tt++;
do {
sp = str[i]; tp = *path;
do { /* Compare a string drive id with path name */
c = *sp++; tc = *tp++;
if (IsLower(tc)) tc -= 0x20;
} while (c && (TCHAR)c == tc);
} while ((c || tp != tt) && ++i < _VOLUMES); /* Repeat for each id until pattern match */
if (i < _VOLUMES) { /* If a drive id is found, get the value and strip it */
vol = (int)i;
*path = tt;
}
#endif
}
return vol;
}
#if _FS_RPATH && _VOLUMES >= 2
vol = CurrVol; /* Current drive */
#else
vol = ; /* Drive 0 */
#endif
}
return vol;
}

本函数获取 path 后解析 path 得到 logical drive number

代码中

第15行 判断 path 的内容是否为空字符 NULL

第16行 检测冒号 ‘:’,for循环的条件为 路径名中的字符 >= (_USE_LFN ? ' ': '!') 且 != ‘:’,只要_USE_LFN>0则第一个条件恒满足,找到冒号‘:’后则第二个条件失败,即跳出循环

第17行 再次确认当前路径字符为冒号‘:’

第18行 暂存*path

第19行 得到路径中的首字符那个数字字符对应的数字

第20行 判断该数字在0~9之中,且路径中的第二个字符为冒号‘:’

第21行 判断该数字在定义的范围内

第22行 将该数字赋值给vol

第46行 最终将vol值返回

帮助理解的代码示例

示例一 指针与字符串

 #include "stdio.h"

 void ptf(char **p);

 int main(void)
{
char *pstr = "0:wojiushiyixia"; ptf(&pstr); return ;
} void ptf(char **p)
{
if(*p)
{
printf("*p = %d\n", *p);
printf("*p = %s\n", *p);
}
else
{
printf("*p = NULL\n");
} }

运行环境 C-Free5.0

运行结果

学习1__STM32--FatFS之逻辑盘符与物理盘符-LMLPHP

 示例二 多参数宏定义

 #include "stdio.h"

 #define _VOLUME_STRS    "RAM","NAND","CF","SD1","SD2","USB1","USB2","USB3"

 int main(void)
{
int i;
static const char* const str[] = {_VOLUME_STRS}; for(i = ; i < ; i++)
{
printf("str[%d] = %s\n", i, str[i]);
} return ;
}

运行环境 C-Free5.0

运行结果

学习1__STM32--FatFS之逻辑盘符与物理盘符-LMLPHP

05-11 00:34