/*----------------------------------------------------------------------------/
/ Petit FatFs - FAT file system module R0.02 (C)ChaN, 2009
/-----------------------------------------------------------------------------/
/ Petit FatFs module is an open source software to implement FAT file system to
/ small embedded systems. This is a free software and is opened for education,
/ research and commercial developments under license policy of following trems.
/
/ Copyright (C) 2009, ChaN, all right reserved.
/
/ * The Petit FatFs module is a free software and there is NO WARRANTY.
/ * No restriction on use. You can use, modify and redistribute it for
/ personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY.
/ * Redistributions of source code must retain the above copyright notice.
/
/-----------------------------------------------------------------------------/
/ Jun 15,'09 R0.01a First release. (Branched from FatFs R0.07b.)
/
/ Dec 14,'09 R0.02 Added multiple code page support.
/ Added write funciton.
/ Changed stream read mode interface.
/----------------------------------------------------------------------------*/
#include "includes.h"
/*--------------------------------------------------------------------------
Private Functions
---------------------------------------------------------------------------*/
static
FATFS *FatFs; /* Pointer to the file system object (logical drive) */
/*-----------------------------------------------------------------------*/
/* String functions */
/*-----------------------------------------------------------------------*/
/* Fill memory */
static
void mem_set (void* dst, int val, int cnt) {
char *d = (char*)dst;
while (cnt--) *d++ = (char)val;
}
/* Compare memory to memory */
static
int mem_cmp (const void* dst, const void* src, int cnt) {
const char *d = (const char *)dst, *s = (const char *)src;
int r = 0;
while (cnt-- && (r = *d++ - *s++) == 0) ;
return r;
}
/*-----------------------------------------------------------------------*/
/* FAT access - Read value of a FAT entry */
/*-----------------------------------------------------------------------*/
static
CLUST get_fat ( /* 1:IO error, Else:Cluster status */
CLUST clst /* Cluster# to get the link information */
)
{
WORD wc, bc, ofs;
BYTE buf[4];
FATFS *fs = FatFs;
if (clst < 2 || clst >= fs->max_clust) /* Range check */
return 1;
switch (fs->fs_type) {
case FS_FAT12 :
bc = (WORD)clst; bc += bc / 2;
ofs = bc % 512; bc /= 512;
if (ofs != 511) {
if (disk_readp(buf, fs->fatbase + bc, ofs, 2)) break;
} else {
if (disk_readp(buf, fs->fatbase + bc, 511, 1)) break;
if (disk_readp(buf+1, fs->fatbase + bc + 1, 0, 1)) break;
}
wc = LD_WORD(buf);
return (clst & 1) ? (wc >> 4) : (wc & 0xFFF);
case FS_FAT16 :
if (disk_readp(buf, fs->fatbase + clst / 256, (WORD)(((WORD)clst % 256) * 2), 2)) break;
return LD_WORD(buf);
#if _FS_FAT32
case FS_FAT32 :
if (disk_readp(buf, fs->fatbase + clst / 128, (WORD)(((WORD)clst % 128) * 4), 4)) break;
return LD_DWORD(buf) & 0x0FFFFFFF;
#endif
}
return 1; /* An error occured at the disk I/O layer */
}
/*-----------------------------------------------------------------------*/
/* Get sector# from cluster# */
/*-----------------------------------------------------------------------*/
static
DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */
CLUST clst /* Cluster# to be converted */
)
{
FATFS *fs = FatFs;
clst -= 2;
if (clst >= (fs->max_clust - 2)) return 0; /* Invalid cluster# */
return (DWORD)clst * fs->csize + fs->database;
}
/*-----------------------------------------------------------------------*/
/* Directory handling - Rewind directory index */
/*-----------------------------------------------------------------------*/
static
FRESULT dir_rewind (
DIR *dj /* Pointer to directory object */
)
{
CLUST clst;
FATFS *fs = FatFs;
dj->index = 0;
clst = dj->sclust;
if (clst == 1 || clst >= fs->max_clust) /* Check start cluster range */
return FR_DISK_ERR;
#if _FS_FAT32
if (!clst && fs->fs_type == FS_FAT32) /* Replace cluster# 0 with root cluster# if in FAT32 */
clst = fs->dirbase;
#endif
dj->clust = clst; /* Current cluster */
dj->sect = clst ? clust2sect(clst) : fs->dirbase; /* Current sector */
return FR_OK; /* Seek succeeded */
}
/*-----------------------------------------------------------------------*/
/* Directory handling - Move directory index next */
/*-----------------------------------------------------------------------*/
static
FRESULT dir_next ( /* FR_OK:Succeeded, FR_NO_FILE:End of table */
DIR *dj /* Pointer to directory object */
)
{
CLUST clst;
WORD i;
FATFS *fs = FatFs;
i = dj->index + 1;
if (!i || !dj->sect) /* Report EOT when index has reached 65535 */
return FR_NO_FILE;
if (!(i & (16-1))) { /* Sector changed? */
dj->sect++; /* Next sector */
if (dj->clust == 0) { /* Static table */
if (i >= fs->n_rootdir) /* Report EOT when end of table */
return FR_NO_FILE;
}
else { /* Dynamic table */
if (((i / 16) & (fs->csize-1)) == 0) { /* Cluster changed? */
clst = get_fat(dj->clust); /* Get next cluster */
if (clst <= 1) return FR_DISK_ERR;
if (clst >= fs->max_clust) /* When it reached end of dynamic table */
return FR_NO_FILE; /* Report EOT */
dj->clust = clst; /* Initialize data for new cluster */
dj->sect = clust2sect(clst);
}
}
}
dj->index = i;
return FR_OK;
}
/*-----------------------------------------------------------------------*/
/* Directory handling - Find an object in the directory */
/*-----------------------------------------------------------------------*/
static
FRESULT dir_find (
DIR *dj /* Pointer to the directory object linked to the file name */
)
{
FRESULT res;
BYTE c, *dir;
res = dir_rewind(dj); /* Rewind directory object */
if (res != FR_OK) return res;
dir = FatFs->buf;
do {
res = disk_readp(dir, dj->sect, (WORD)((dj->index % 16) * 32), 32) /* Read an entry */
? FR_DISK_ERR : FR_OK;
if (res != FR_OK) break;
c = dir[DIR_Name]; /* First character */
if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */
if (!(dir[DIR_Attr] & AM_VOL) && !mem_cmp(dir, dj->fn, 11)) /* Is it a valid entry? */
break;
res = dir_next(dj); /* Next entry */
} while (res == FR_OK);
return res;
}
/*-----------------------------------------------------------------------*/
/* Read an object from the directory */
/*-----------------------------------------------------------------------*/
#if _USE_DIR
static
FRESULT dir_read (
DIR *dj /* Pointer to the directory object to store read object name */
)
{
FRESULT res;
BYTE a, c, *dir;
res = FR_NO_FILE;
dir = FatFs->buf;
while (dj->sect) {
res = disk_readp(dir, dj->sect, (WORD)((dj->index % 16) * 32), 32) /* Read an entry */
? FR_DISK_ERR : FR_OK;
if (res != FR_OK) break;
c = dir[DIR_Name];
if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */
a = dir[DIR_Attr] & AM_MASK;
if (c != 0xE5 && c != '.' && !(a & AM_VOL)) /* Is it a valid entry? */
break;
res = dir_next(dj); /* Next entry */
if (res != FR_OK) break;
}
if (res != FR_OK) dj->sect = 0;
return res;
}
#endif
/*-----------------------------------------------------------------------*/
/* Pick a segment and create the object name in directory for
pff.zip_pff
版权申诉
78 浏览量
2022-09-23
10:39:17
上传
评论
收藏 6KB ZIP 举报
局外狗
- 粉丝: 69
- 资源: 1万+
最新资源
- Docker-Configuration-and-Usage-Guide.md
- MATLAB中colorbar的设置
- A33-Core3核心板硬件手册外围电路设计参考配套开发底板(DSN格式原理图+Protel及PADS PCB图)文件.zip
- javaweb中jsp相关知识 代码及笔记
- Unified Procedural Animation 4.27.zip
- An Introduction to MySQL Database
- 基于MATLAB实现学生成绩查询系统
- 23043721-1.STP
- proteus仿真-基于51单片机的PWM温度控制实例
- 基于MATLAB实现图像去噪 滤波 锐化 边缘检测 源程序代码
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈