fat文件系统中,根目录中存储目录条,每个目录条占用32个字节。含义如下:

在fat文件系统中,这种为短文件名(8+3)目录条信息。

指定根目录条目、文件首蔟号,配置文件的首蔟号


#if !FF_FS_READONLY//不是只读
//配置文件存储的首蔟号
static void st_clust (FATFS* fs,    //文件对象。/* Pointer to the fs object */BYTE* dir, //目录条目。/* Pointer to the key entry */DWORD cl   //蔟号。/* Value to be set */
)
{st_word(dir + DIR_FstClusLO, (WORD)cl);//写低16位蔟号if (fs->fs_type == FS_FAT32) {//对于fat32文件系统,写高16位蔟号st_word(dir + DIR_FstClusHI, (WORD)(cl >> 16));}
}
#endif

根据指定的目录条,返回文件所在蔟号

//返回短目录条目中文件蔟号
static DWORD ld_clust ( /* Returns the top cluster value of the SFN entry */FATFS* fs,          //指向文件系统对象。/* Pointer to the fs object */const BYTE* dir        //指向目录条目。/* Pointer to the key entry */
)
{DWORD cl;//dir + DIR_FstClusLO:指向目录条目中的文件所在蔟号(低16位)
//ld_word获取2个字节蔟号
//如果是fat32文件系统,则再获取两个字节文件所在蔟号(高16位)cl = ld_word(dir + DIR_FstClusLO);//DIR_FstClusLO:26if (fs->fs_type == FS_FAT32) {cl |= (DWORD)ld_word(dir + DIR_FstClusHI) << 16;//DIR_FstClusHI:20}return cl;
}

长文件名结构信息:

创建一个根目录条目中长文件名条目。
给出长文件名字符串、条目指针、长文件名的序号、短文件名的校验和

//创建一个长文件名
static void put_lfn (const WCHAR* lfn,//长文件名。   /* Pointer to the LFN */BYTE* dir,//条目。/* Pointer to the LFN entry to be created */BYTE ord,//长文件名的序号。/* LFN order (1-20) */BYTE sum //短文件名的校验和。/* Checksum of the corresponding SFN */
)
{UINT i, s;WCHAR wc;dir[LDIR_Chksum] = sum;//短文件名的校验和。/* Set checksum */dir[LDIR_Attr] = AM_LFN;//长文件名的属性,固定为0x0F。/* Set attribute. LFN entry */dir[LDIR_Type] = 0;//长文件名类型为0st_word(dir + LDIR_FstClusLO, 0);//26、27必须为0i = (ord - 1) * 13;//获取偏移量。/* Get offset in the LFN working buffer */s = wc = 0;do {if (wc != 0xFFFF) wc = lfn[i++];//获取一个字符。/* Get an effective character */st_word(dir + LfnOfs[s], wc);//写入条目中。/* Put it */if (wc == 0) wc = 0xFFFF;//如果到了文件名结尾,则wc修改为全F,后续条目中文件名字段全部填写全F。/* Padding characters for following items */} while (++s < 13);if (wc == 0xFFFF || !lfn[i]) //文件名结束ord |= LLEF;//配置长文件名条目结束标志。/* Last LFN part is the start of LFN sequence */dir[LDIR_Ord] = ord;//序号。/* Set the LFN order */
}

注意,这里只是生成一个长文件名中某一条长文件名信息。

长文件名的比较和采集:

//长文件名比较
static int cmp_lfn (        /* 1:matched, 0:not matched */const WCHAR* lfnbuf,  /* Pointer to the LFN working buffer to be compared */BYTE* dir             /* Pointer to the directory entry containing the part of LFN */
)
{UINT i, s;WCHAR wc, uc;//长文件名条目中偏移量26、27必须为0
//短文件名条目中偏移量26、27为文件所在蔟号,蔟号大于等于2if (ld_word(dir + LDIR_FstClusLO) != 0) return 0;  /* Check LDIR_FstClusLO *///长文件名条目中第一个字节的bit0~bit5表示长文件名序号,序号从1开始
//一个32字节的长文件名条目中包含13个字符的文件名,每个字符用两个字节的unicode字符表示
//i就是长文件名中的字符偏移量
//i=0表示比较0-12个字符
//i=13表示比较13-25个字符
//依次类推i = ((dir[LDIR_Ord] & 0x3F) - 1) * 13;   /* Offset in the LFN buffer *///长文件名条目中,如果文件名结束,则下一个字符所在位置的两个字节都为全0、剩下字符所在位置全部填写FF。
/*
示例:11111111111111111111111111.txt
偏移:  00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
条目3: 43 2E 00 74 00 78 00 74 00 00 00 0F 00 E4 FF FF FF FF FF FF FF FF FF FF FF FF 00 00 FF FF FF FF
条目2: 02 31 00 31 00 31 00 31 00 31 00 0F 00 E4 31 00 31 00 31 00 31 00 31 00 31 00 00 00 31 00 31 00
条目1: 01 31 00 31 00 31 00 31 00 31 00 0F 00 E4 31 00 31 00 31 00 31 00 31 00 31 00 00 00 31 00 31 00
短条目:31 31 31 31 31 31 7E 31 54 58 54 20 00 89 31 57 8A 55 8A 55 00 00 32 57 8A 55 00 00 00 00 00 00
可以看出条目3中9~10个字符为00,后续所有文件名所在位置全部为FF(14,16,18,20,22,24,28,30)
文件名位置偏移量:LfnOfs[] = {1,3,5,7,9,14,16,18,20,22,24,28,30};
条目3中第一个字节的bit6为1表示结束,即长文件名的最后一个条目
*/for (wc = 1, s = 0; s < 13; s++) {//扫描13个字符。/* Process all characters in the entry */uc = ld_word(dir + LfnOfs[s]);//获取一个文件名字符   /* Pick an LFN character */if (wc != 0) {//为0表示扫描完了文件名//长文件名长度不能能超过配置的最大文件名长度//转成大写后进行比较if (i >= FF_MAX_LFN + 1 || ff_wtoupper(uc) != ff_wtoupper(lfnbuf[i++])) {  /* Compare it */return 0;                   /* Not matched */}wc = uc;} else {if (uc != 0xFFFF) return 0;//条目中内容错了。/* Check filler *///wc为0,uc为FFFF,不应该跳出循环??}}//如果长文件名条目是该长文件名的最后一个条目
//并且wc不为0
//并且需要比较的文件名没比较完
//则返回0
//即长文件名条目比较完了,需要比较的文件名没比较完,长度不一致
//wc不为0:表示长文件名最后一个条目中最后两个字节正好是文件名的最后一个字符
/*示例:1111111111111111111111.txt
42 31 00 31 00 31 00 31 00 31 00 0F 00 44 31 00 31 00 31 00 31 00 2E 00 74 00 00 00 78 00 74 00
01 31 00 31 00 31 00 31 00 31 00 0F 00 44 31 00 31 00 31 00 31 00 31 00 31 00 00 00 31 00 31 00
31 31 31 31 31 31 7E 32 54 58 54 20 00 09 79 5A 8A 55 8A 55 00 00 7A 5A 8A 55 00 00 00 00 00 00
*/if ((dir[LDIR_Ord] & LLEF) && wc && lfnbuf[i]) return 0;  /* Last segment matched but different length */return 1;//匹配。/* The part of LFN matched */
}#if FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2 || FF_USE_LABEL || FF_FS_EXFAT
/*-----------------------------------------------------*/
/* FAT-LFN: Pick a part of file name from an LFN entry */
/*-----------------------------------------------------*/
//采集一个长文件名
//返回0表示无效,返回1表示有效。
static int pick_lfn (   /* 1:succeeded, 0:buffer overflow or invalid LFN entry */WCHAR* lfnbuf,//指向存储长文件名的buf。/* Pointer to the LFN working buffer */BYTE* dir//条目。/* Pointer to the LFN entry */
)
{UINT i, s;WCHAR wc, uc;//长文件名条目中偏移量26、27必须为0
//短文件名条目中偏移量26、27为文件所在蔟号,蔟号大于等于2if (ld_word(dir + LDIR_FstClusLO) != 0) return 0;  /* Check LDIR_FstClusLO is 0 *///长文件名中的偏移量i = ((dir[LDIR_Ord] & ~LLEF) - 1) * 13;  /* Offset in the LFN buffer */
//扫描13个字符for (wc = 1, s = 0; s < 13; s++) {      /* Process all characters in the entry */uc = ld_word(dir + LfnOfs[s]);//获取一个字符。/* Pick an LFN character */if (wc != 0) {if (i >= FF_MAX_LFN + 1) return 0;//空间不足。/* Buffer overflow? */lfnbuf[i++] = wc = uc;//存储到lfnbuf中。uc为0的时候也会存储到buf中,是文件名结束符。/* Store it */} else {if (uc != 0xFFFF) return 0;//目录中数据错误。/* Check filler *///wc为0,uc为FFFF,不应该跳出循环??}}//条目处理完了,但是wc不为0,表示文件名正好存储满最后个条目
//文件名为字符串,需要在最后添加结束符0if (dir[LDIR_Ord] & LLEF && wc != 0) { /* Put terminator if it is the last LFN part and not terminated */if (i >= FF_MAX_LFN + 1) return 0;//判断是否超过存储空间   /* Buffer overflow? */lfnbuf[i] = 0;//添加结束符0}return 1;//文件名是有效的。/* The part of LFN is valid */
}

短文件名校验和计算:

//计算短文件名校验和
static BYTE sum_sfn (const BYTE* dir//短文件名的条目/* Pointer to the SFN entry */
)
{BYTE sum = 0;//初始值为0UINT n = 11;//8+3,共11个字节do {//向右循环移位1位,然后累加sum = (sum >> 1) + (sum << 7) + *dir++;} while (--n);return sum;
}

fatfs文件系统中目录代码分析相关推荐

  1. linux内核中链表代码分析---list.h头文件分析(二)【转】

    转自:http://blog.chinaunix.net/uid-30254565-id-5637598.html linux内核中链表代码分析---list.h头文件分析(二) 16年2月28日16 ...

  2. linux内核中链表代码分析---list.h头文件分析(一)

    linux内核中链表代码分析---list.h头文件分析(一) 16年2月27日17:13:14 在学习数据结构时,有一个重要的知识点就是链表.对于链表的一些基本操作,它的最好学习资料就是内核中的li ...

  3. FAT16文件系统之目录项分析(四)

    FAT16文件系统的FDT分析 1:FDT位置 FDT的含义为文件目录表,它在一个文件系统中的具体位置是紧跟在FAT2之后. 定位过程: A:系统通过读取该分区表信息,定位到其DBR扇区 B:读取DB ...

  4. FAT32文件系统之目录项分析 (四)

    在FAT32文件系统下,分区根目录下的文件及文件夹的目录项存放在根目录区中,分区子目录下的文件及文件 夹的目录项存放在子目录区中,根目录和子目录区都在数据区中. FAT32目录项类型 FAT32与FA ...

  5. 关于ucos中os_tmr.c中的代码分析

    我本身也是个初学者,喜欢嵌入式而自学ucos系统,ucos是个开源的代码,短小而又简单,这是我学习的笔记,希望能对喜欢ucos的人有一点帮助,因本人也是初学者,如有错误迎指点.一般的书多是2.5版本, ...

  6. LCM在Kernel中的代码分析

    lcm的分析首先是mtkfb.c 1.mtk_init中platform_driver_register(&mtkfb_driver)注册平台驱动 panelmaster_init(); DB ...

  7. linux创建根目录代码,Linux文件系统之目录的建立

    一:前言 在用户空间中,建立目录所用的API为mkdir().它在内核中的系统调用入口是sys_mkdir().今天跟踪一下 函数来分析linux文件系统中目录的建立过程. 二:sys_mkdir() ...

  8. vs 2015 C 语言,VS2015中C/C++代码分析

    VS2015中C/C++代码分析 03/31/2015 8 分钟可看完 本文内容 [原文发表时间]:2015/2/24 1:00 PM 来自 Joe Morris & Jim Springfi ...

  9. linux 如何赋值目录,Linux文件系统之目录的建立

    一:前言 在用户空间中,建立目录所用的API为mkdir().它在内核中的系统调用入口是sys_mkdir().今天跟踪一下 函数来分析linux文件系统中目录的建立过程. 二:sys_mkdir() ...

最新文章

  1. 判别模型和生成模型的区别
  2. 首次曝光!腾讯新任 H4 级高管余仁杰提议将公司总部搬往南极
  3. Mybatis解决字段名与实体类属性名不相同的冲突
  4. 35天 GRE: V160+Q168+W3.5
  5. Redis 五种数据类型
  6. startindex 不能大于字符串长度_「12」学习MySQL第二类函数:字符串函数
  7. pytorch卷积神经网络_资源|卷积神经网络迁移学习pytorch实战推荐
  8. sqlite3.OperationalError: no such column: **
  9. 促销惊喜活动优惠海报设计,可临摹PSD分层格式
  10. 拟合方程是什么matlab,matlab离散型数据拟合方程,求系数,哪个大神能说说方法...
  11. DHTML【9】--Javascript
  12. 火山同传助力第四届CTDC首席技术官领袖峰会
  13. Navicat for MySQ破译版
  14. 英语学习必备:Eudic欧路词典 for Mac增强版
  15. spring源码解析百度网盘下载
  16. 如何php实现即时到账,paypal即时到账php实现代码-PHPphp技巧
  17. 02-若依权限管理子系统简介(自己了解)
  18. 华硕主板前置音频设置
  19. vue 用webpack打包文件名添加版本号
  20. 吐槽板。(就当是个留言板吧....)

热门文章

  1. 有没有可以刷python题的软件_你想要的Python面试都在这里了【315+道题】
  2. ODPS 数据全量/增量同步方案
  3. sysinfo 函数
  4. particles.js粒子特效(常用登录页背景)
  5. FreeSwitch(十一):基本功能与实现
  6. 海贼王顶上战争篇OP歌词
  7. VsCode中使用jupyter,matplotlib不显示图像的问题
  8. 一些寓意深刻的经典短文
  9. HBuilder 的使用1
  10. linux目录跳转指令