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

运行结果

 示例二 多参数宏定义

 #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. JSP页面之间互相传值
  2. DAO跨事物调用---转账
  3. IOS Animation-动画基础、深入
  4. C# 得到sqlserver 数据库存储过程,触发器,视图,函数 的定义
  5. Web 服务编程,REST 与 SOAP(转)
  6. Centos 7.1+CDH5.7.2全部署流程
  7. JS 数据类型转换-转换函数、强制类型转换、利用js变量弱类型转换
  8. 疯狂Android第二章:Adapter以及部分控件使用
  9. strictmode
  10. VR全景:“互联网+之后的下一个“风口”
  11. Hadoop之HelloWorld
  12. How to preview html file in our browser at sublime text?
  13. 智能POS常见问题整理
  14. Python之路【目录】
  15. java--String equals方法
  16. kali linux安装中文输入法
  17. 面象对象设计原则之五:依赖倒置原则(The Dependency Inversion Principle,DIP)
  18. C#并行编程-PLINQ:声明式数据并行-转载
  19. openssl生成SSL证书的流程
  20. 理解FlumeNG的batchSize和transactionCapacity参数和传输事务的原理 【转】

热门文章

  1. CentOS 6.4 源码安装MySQL 5.6
  2. Docker部署运行springboot项目,并使用Dockerfile制作镜像
  3. css3特殊图形(气泡)
  4. 前K个高频元素
  5. 解决方法:CentOS7用yum安装软件显示错误:cannot find a valid baseurl for repo: base/7/x86_64
  6. linux安装php7.2.7
  7. Django--CRM--一级, 二级 菜单表
  8. comparable和comparator
  9. 有时候做JQ动画,鼠标经过,它会不停自己抖动不停,解决方法(此处,是兼容IE ,当鼠标经过,遮罩层从下移到上边的JQ动画效果)
  10. 一、VS2017支持Github