/*
* Copyright (c) 2006-2008 by Roland Riegel <feedback@roland-riegel.de>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of either the GNU General Public License version 2
* or the GNU Lesser General Public License version 2.1, both as
* published by the Free Software Foundation.
*/
#include "byteordering.h"
#include "partition.h"
#include "fat.h"
#include "fat_config.h"
#include "sd-reader_config.h"
#include <string.h>
#if USE_DYNAMIC_MEMORY
#include <stdlib.h>
#endif
/**
* \addtogroup fat FAT support
*
* This module implements FAT16/FAT32 read and write access.
*
* The following features are supported:
* - File names up to 31 characters long.
* - Unlimited depth of subdirectories.
* - Short 8.3 and long filenames.
* - Creating and deleting files.
* - Reading and writing from and to files.
* - File resizing.
* - File sizes of up to 4 gigabytes.
*
* @{
*/
/**
* \file
* FAT implementation (license: GPLv2 or LGPLv2.1)
*
* \author Roland Riegel
*/
/**
* \addtogroup fat_config FAT configuration
* Preprocessor defines to configure the FAT implementation.
*/
/**
* \addtogroup fat_fs FAT access
* Basic functions for handling a FAT filesystem.
*/
/**
* \addtogroup fat_file FAT file functions
* Functions for managing files.
*/
/**
* \addtogroup fat_dir FAT directory functions
* Functions for managing directories.
*/
/**
* @}
*/
#define FAT16_CLUSTER_FREE 0x0000
#define FAT16_CLUSTER_RESERVED_MIN 0xfff0
#define FAT16_CLUSTER_RESERVED_MAX 0xfff6
#define FAT16_CLUSTER_BAD 0xfff7
#define FAT16_CLUSTER_LAST_MIN 0xfff8
#define FAT16_CLUSTER_LAST_MAX 0xffff
#define FAT32_CLUSTER_FREE 0x00000000
#define FAT32_CLUSTER_RESERVED_MIN 0x0ffffff0
#define FAT32_CLUSTER_RESERVED_MAX 0x0ffffff6
#define FAT32_CLUSTER_BAD 0x0ffffff7
#define FAT32_CLUSTER_LAST_MIN 0x0ffffff8
#define FAT32_CLUSTER_LAST_MAX 0x0fffffff
#define FAT_DIRENTRY_DELETED 0xe5
#define FAT_DIRENTRY_LFNLAST (1 << 6)
#define FAT_DIRENTRY_LFNSEQMASK ((1 << 6) - 1)
/* Each entry within the directory table has a size of 32 bytes
* and either contains a 8.3 DOS-style file name or a part of a
* long file name, which may consist of several directory table
* entries at once.
*
* multi-byte integer values are stored little-endian!
*
* 8.3 file name entry:
* ====================
* offset length description
* 0 8 name (space padded)
* 8 3 extension (space padded)
* 11 1 attributes (FAT_ATTRIB_*)
*
* long file name (lfn) entry ordering for a single file name:
* ===========================================================
* LFN entry n
* ...
* LFN entry 2
* LFN entry 1
* 8.3 entry (see above)
*
* lfn entry:
* ==========
* offset length description
* 0 1 ordinal field
* 1 2 unicode character 1
* 3 3 unicode character 2
* 5 3 unicode character 3
* 7 3 unicode character 4
* 9 3 unicode character 5
* 11 1 attribute (always 0x0f)
* 12 1 type (reserved, always 0)
* 13 1 checksum
* 14 2 unicode character 6
* 16 2 unicode character 7
* 18 2 unicode character 8
* 20 2 unicode character 9
* 22 2 unicode character 10
* 24 2 unicode character 11
* 26 2 cluster (unused, always 0)
* 28 2 unicode character 12
* 30 2 unicode character 13
*
* The ordinal field contains a descending number, from n to 1.
* For the n'th lfn entry the ordinal field is or'ed with 0x40.
* For deleted lfn entries, the ordinal field is set to 0xe5.
*/
struct fat_header_struct
{
offset_t size;
offset_t fat_offset;
uint32_t fat_size;
uint16_t sector_size;
uint16_t cluster_size;
offset_t cluster_zero_offset;
offset_t root_dir_offset;
#if FAT_FAT32_SUPPORT
cluster_t root_dir_cluster;
#endif
};
struct fat_fs_struct
{
struct partition_struct* partition;
struct fat_header_struct header;
};
struct fat_file_struct
{
struct fat_fs_struct* fs;
struct fat_dir_entry_struct dir_entry;
offset_t pos;
cluster_t pos_cluster;
};
struct fat_dir_struct
{
struct fat_fs_struct* fs;
struct fat_dir_entry_struct dir_entry;
cluster_t entry_cluster;
uint16_t entry_offset;
};
struct fat_read_dir_callback_arg
{
struct fat_dir_entry_struct* dir_entry;
uintptr_t bytes_read;
uint8_t finished;
};
struct fat_usage_count_callback_arg
{
cluster_t cluster_count;
uintptr_t buffer_size;
};
#if !USE_DYNAMIC_MEMORY
static struct fat_fs_struct fat_fs_handles[FAT_FS_COUNT];
static struct fat_file_struct fat_file_handles[FAT_FILE_COUNT];
static struct fat_dir_struct fat_dir_handles[FAT_DIR_COUNT];
#endif
static uint8_t fat_read_header(struct fat_fs_struct* fs);
static cluster_t fat_get_next_cluster(const struct fat_fs_struct* fs, cluster_t cluster_num);
static offset_t fat_cluster_offset(const struct fat_fs_struct* fs, cluster_t cluster_num);
static uint8_t fat_dir_entry_read_callback(uint8_t* buffer, offset_t offset, void* p);
static uint8_t fat_interpret_dir_entry(struct fat_dir_entry_struct* dir_entry, const uint8_t* raw_entry);
static uint8_t fat_get_fs_free_16_callback(uint8_t* buffer, offset_t offset, void* p);
#if FAT_FAT32_SUPPORT
static uint8_t fat_get_fs_free_32_callback(uint8_t* buffer, offset_t offset, void* p);
#endif
#if FAT_WRITE_SUPPORT
static cluster_t fat_append_clusters(const struct fat_fs_struct* fs, cluster_t cluster_num, cluster_t count);
static uint8_t fat_free_clusters(const struct fat_fs_struct* fs, cluster_t cluster_num);
static uint8_t fat_terminate_clusters(const struct fat_fs_struct* fs, cluster_t cluster_num);
static uint8_t fat_clear_cluster(const struct fat_fs_struct* fs, cluster_t cluster_num);
static uintptr_t fat_clear_cluster_callback(uint8_t* buffer, offset_t offset, void* p);
static offset_t fat_find_offset_for_dir_entry(const struct fat_fs_struct* fs, const struct fat_dir_struct* parent, const struct fat_dir_entry_struct* dir_entry);
static uint8_t fat_write_dir_entry(const struct fat_fs_struct* fs, struct fat_dir_entry_struct* dir_entry);
#if FAT_DATETIME_SUPPORT
static void fat_set_file_modification_date(struct fat_dir_entry_struct* dir_entry, uint16_t year, uint8_t month, uint8_t day);
static void fat_set_file_modification_time(struct fat_dir_entry_struct* dir_entry, uint8_t hour, uint8_t min, uint8_t sec);
#endif
#endif
/**
* \ingroup fat_fs
* Opens a FAT filesystem.
*
* \param[in] partition Discriptor of partition on which the filesystem resides.
* \returns 0 on error, a FAT filesystem descriptor on success.
* \see fat_close
*/
struct fat_fs_struct* fat_open(struct partition_struct* partition)
{
if(!partition ||
#if FAT_WRITE_SUPPORT
!partition->device_write ||
!partition->device_write_interval
#else
0
#endif
)
return 0;
#if USE_DYNAMIC_MEMORY
struct fat_fs_struct* fs = malloc(sizeof(*fs));
if(!fs)
return 0;
#else
struct fat_fs_struct* fs = fat_fs_handles;
uint8_t i;
for(i = 0; i < FAT_FS_COUNT; ++i)
{
if(!fs->partition)
break;
++fs;
}
if(i >= FAT_FS_COUNT)
return 0;
#endif
memset(fs, 0, sizeof(*fs));
fs->partition = partition;
if(!fat_read_header(fs))
{
#if USE_DYNAMIC_MEMORY
free(fs);
#else
fs->partition = 0;
#endif
return 0;
}
return fs;
}
/**
* \ingroup fat_fs
* Closes a FAT filesystem.
*
* When this function returns, the given filesystem descriptor
* will be invalid.
*
* \param[in] fs The filesystem to close.
* \see fat_open
*/
void fat_close(struct fat_fs_struct* fs)
{
if(!fs)
return;
#if USE_DYNAMIC_MEMORY
free(fs);
#else
fs->partition = 0;
#endif
}
/**
* \ingroup fat_fs
* Reads and parses the header of a FAT filesystem.
*
* \param[inout] fs The
没有合适的资源?快使用搜索试试~ 我知道了~
sd-reader_source_20081121.zip
共64个文件
html:36个
h:9个
c:6个
需积分: 10 6 下载量 15 浏览量
2009-01-08
15:39:34
上传
评论
收藏 271KB ZIP 举报
温馨提示
sd-reader_source_20081121,格式很正规,是学习的好材料
资源推荐
资源详情
资源评论
收起资源包目录
sd-reader_source_20081121.zip (64个子文件)
sd-reader_source_20081121
sd-reader_config.h 1KB
main.c 20KB
fat.h 4KB
partition.c 5KB
partition.h 7KB
Doxyfile 53KB
fat.c 68KB
sd_raw.c 27KB
byteordering.h 3KB
partition_config.h 635B
ChangeLog 3KB
sd_raw.h 4KB
sd_raw_config.h 3KB
doc
pic02.jpg 31KB
html
fat_8c.html 13KB
tabs.css 2KB
group__config.html 3KB
group__partition__config.html 2KB
tab_r.gif 3KB
doxygen.css 9KB
sd__raw_8c.html 5KB
globals_type.html 2KB
byteordering_8h.html 6KB
fat_8h.html 15KB
group__fat__dir.html 15KB
modules.html 2KB
partition_8h.html 12KB
pic02.jpg 31KB
group__fat.html 50KB
group__fat__config.html 8KB
files.html 3KB
structpartition__struct.html 9KB
group__partition.html 29KB
globals_defs.html 7KB
sd-reader__config_8h.html 2KB
group__sd__raw.html 26KB
pic01.jpg 35KB
tab_b.gif 35B
doxygen.png 1KB
structfat__dir__entry__struct.html 6KB
annotated.html 2KB
group__fat__fs.html 8KB
functions.html 4KB
tab_l.gif 706B
functions_vars.html 4KB
globals.html 14KB
globals_func.html 8KB
partition__config_8h.html 2KB
partition_8c.html 3KB
index.html 10KB
group__byteordering.html 15KB
fat__config_8h.html 4KB
structsd__raw__info.html 11KB
byteordering_8c.html 2KB
group__fat__file.html 43KB
group__sd__raw__config.html 6KB
sd__raw__config_8h.html 3KB
sd__raw_8h.html 8KB
pic01.jpg 35KB
uart.h 651B
fat_config.h 2KB
Makefile 891B
byteordering.c 1KB
uart.c 4KB
共 64 条
- 1
资源评论
guizi6677
- 粉丝: 0
- 资源: 6
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- C/C++,数字序列-计算伯努利数(Bernoulli Number)的计算方法与源程序
- C/C++,树算法-二叉树的插入(Insert)算法之源程序
- C/C++,树算法-二叉树(BTree)的基本数据结构
- C/C++,贪婪算法-博鲁夫卡算法(Boruvka)的计算方法与源程序
- C/C++,优化算法-双离子推销员问题(Bitonic Travelling Salesman Problem)的计算方法与源
- C#,图论与图算法,图最短路径的迪杰斯特拉(Dijkstra)算法与源代码
- 使用codeblocks运行的二叉树的代码项目
- C/C++,图算法-Dinic最大流量算法
- C/C++,图算法-有向图的海尔霍尔泽(Hierholzer)算法及其源程序
- 基于paddle+flask实现的猪只识别计数python源码+数据集+模型+操作说明.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功