FATFS源码分析(一)——模块内部函数
FATFS源码中的ff.c文件里有一些通用的函数供FATFS内部使用(不仅仅用于FATFS,而是适用于大多数嵌入式开发中)。其编写考虑了不少的技巧,也有很高的质量,故分析之。
1. mem_cpy(void*dst,const void * src,UINT cnt) /* copy memory to memory*/
源源码如下:
static void mem_cpy (void* dst,const void* src, UINT cnt)
{
BYTE *d = (BYTE*)dst;
const BYTE *s= (const BYTE*)src;
#if_WORD_ACCESS == 1 // WORD TO WORD
while (cnt >= sizeof (int)) // 整WORD部分按 WORD copy
{
*(int*)d= *(int*)s;
d += sizeof (int); s+= sizeof(int);
cnt -= sizeof (int);
}
#endif
while (cnt--) //不足字部分按BYTE copy
*d++= *s++;
}
对于_WORD_ACESS其定义在ffconf.h中,它和平台相关。
#define_WORD_ACCESS 0 /* 0 or 1 */
它的注释如下:
/* The _WORD_ACCESSoption is an only platform dependent option. It defines
/ which access method is used to the word dataon the FAT volume./
/ 0: Byte-by-byteaccess. Always compatible with all platforms.
/ 1: Word access.Do not choose this unless under both the following conditions./
/ * Address misalignedmemory access is always allowed for ALL instructions.
/ * Byte order onthe memory is little-endian.
/ If it is the case, _WORD_ACCESS can also beset to 1 to improve performance and reduce code size. Following table shows anexample of some processor types. */
BYTE copy 方式适用于任何平台,但WORD acess 在以下两种情况时采用,会有更高的执行效率:
1. 所有的指令都允许非地址对齐的内存访问。
2. 小端模式(数据的低位存在低地址,ARM默认小端存储)。
2. mem_set(void*dst,int val,UINT cnt)
源码如下:
static void mem_set (void* dst,int val, UINT cnt)
{
BYTE *d = (BYTE*)dst;
while (cnt--) //以BYTE为单位逐个设置value
*d++= (BYTE)val;
}
3. mem_cmp(constvoid *dst,const void *src,UINT cnt)
源码如下:
/* Comparememory to memory */
static int mem_cmp (constvoid* dst,const void* src, UINT cnt)
{
const BYTE *d= (const BYTE*)dst,*s =(const BYTE*)src;
int r =0;
while (cnt-- && (r =*d++- *s++)== 0);
return r;
}
对于while(cnt -- && (r = *d++ - *s++)== 0); 如果*d++ ==*s++,那么r = 0,
While循环为真,执行下一byte的判断,直到cnt = 0或者r != 0,退出循环,返回r值, r为正表示dst >src,r为负表示dst< src,r = 0表示dst ==src。
4. chk_chr(const char *str, int chr) /* check if chr is contained in the string*/
// 返回0表示chr不在str中</span>
static int chk_chr (const char* str, int chr)
{
while(*str && *str != chr) str++; // 遍历str,比较chr是否在内
return*str;
}