#include "partition.h"
#include "fat16.h"
#include "fat16_config.h"
#include <stdlib.h>
#include <string.h>
/**
* \addtogroup fat16 FAT16 support
*
* This module implements FAT16 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
* FAT16 implementation.
*
* \author Roland Riegel
*/
/**
* \addtogroup fat16_config FAT16 configuration
* Preprocessor defines to configure the FAT16 implementation.
*/
/**
* \addtogroup fat16_fs FAT16 access
* Basic functions for handling a FAT16 filesystem.
*/
/**
* \addtogroup fat16_file FAT16 file functions
* Functions for managing files.
*/
/**
* \addtogroup fat16_dir FAT16 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 FAT16_DIRENTRY_DELETED 0xe5
#define FAT16_DIRENTRY_LFNLAST (1 << 6)
#define FAT16_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 (FAT16_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 fat16_header_struct
{
uint32_t size;
uint32_t fat_offset;
uint32_t fat_size;
uint16_t sector_size;
uint16_t cluster_size;
uint32_t root_dir_offset;
uint32_t cluster_zero_offset;
};
struct fat16_fs_struct
{
struct partition_struct* partition;
struct fat16_header_struct header;
};
struct fat16_file_struct
{
struct fat16_fs_struct* fs;
struct fat16_dir_entry_struct dir_entry;
uint32_t pos;
};
struct fat16_dir_struct
{
struct fat16_fs_struct* fs;
struct fat16_dir_entry_struct dir_entry;
uint16_t entry_next;
};
struct fat16_read_callback_arg
{
uint16_t entry_cur;
uint16_t entry_num;
uint32_t entry_offset;
uint8_t byte_count;
};
static uint8_t fat16_read_header(struct fat16_fs_struct* fs);
static uint8_t fat16_read_root_dir_entry(const struct fat16_fs_struct* fs, uint16_t entry_num, struct fat16_dir_entry_struct* dir_entry);
static uint8_t fat16_read_sub_dir_entry(const struct fat16_fs_struct* fs, uint16_t entry_num, const struct fat16_dir_entry_struct* parent, struct fat16_dir_entry_struct* dir_entry);
static uint8_t fat16_dir_entry_seek_callback(uint8_t* buffer, uint32_t offset, void* p);
static uint8_t fat16_dir_entry_read_callback(uint8_t* buffer, uint32_t offset, void* p);
static uint8_t fat16_interpret_dir_entry(struct fat16_dir_entry_struct* dir_entry, const uint8_t* raw_entry);
static uint16_t fat16_get_next_cluster(const struct fat16_fs_struct* fs, uint16_t cluster_num);
static uint16_t fat16_append_cluster(const struct fat16_fs_struct* fs, uint16_t cluster_num);
static uint8_t fat16_free_cluster(struct fat16_fs_struct* fs, uint16_t cluster_num);
static uint8_t fat16_write_dir_entry(struct fat16_fs_struct* fs, const struct fat16_dir_entry_struct* dir_entry);
/**
* \ingroup fat16_fs
* Opens a FAT16 filesystem.
*
* \param[in] partition Discriptor of partition on which the filesystem resides.
* \returns 0 on error, a FAT16 filesystem descriptor on success.
* \see fat16_open
*/
struct fat16_fs_struct* fat16_open(struct partition_struct* partition)
{
if(!partition ||
#if FAT16_WRITE_SUPPORT
!partition->device_write
#else
0
#endif
)
return 0;
struct fat16_fs_struct* fs = malloc(sizeof(*fs));
if(!fs)
return 0;
memset(fs, 0, sizeof(*fs));
fs->partition = partition;
if(!fat16_read_header(fs))
{
free(fs);
return 0;
}
return fs;
}
/**
* \ingroup fat16_fs
* Closes a FAT16 filesystem.
*
* When this function returns, the given filesystem descriptor
* will be invalid.
*
* \param[in] fs The filesystem to close.
* \see fat16_open
*/
void fat16_close(struct fat16_fs_struct* fs)
{
if(!fs)
return;
free(fs);
}
/**
* \ingroup fat16_fs
* Reads and parses the header of a FAT16 filesystem.
*
* \param[inout] fs The filesystem for which to parse the header.
* \returns 0 on failure, 1 on success.
*/
uint8_t fat16_read_header(struct fat16_fs_struct* fs)
{
uint8_t buffer[25];
struct partition_struct* partition;
struct fat16_header_struct* header;
if(!fs || !fs->partition)
return 0;
partition = fs->partition;
header = &fs->header;
if(partition->type != PARTITION_TYPE_FAT16 &&
partition->type != PARTITION_TYPE_FAT16_LBA)
return 0;
uint32_t partition_offset = partition->offset * 512;
if(!partition->device_read(partition_offset + 0x0b, buffer, sizeof(buffer)))
return 0;
memset(header, 0, sizeof(*header));
uint16_t bytes_per_sector = ((uint16_t) buffer[0x00]) |
((uint16_t) buffer[0x01] << 8);
uint8_t sectors_per_cluster = buffer[0x02];
uint16_t reserved_sectors = ((uint16_t) buffer[0x03]) |
((uint16_t) buffer[0x04] << 8);
uint8_t fat_copies = buffer[0x05];
uint16_t max_root_entries = ((uint16_t) buffer[0x06]) |
((uint16_t) buffer[0x07] << 8);
uint16_t sectors_per_fat = ((uint16_t) buffer[0x0b]) |
((uint16_t) buffer[0x0c] << 8);
uint32_t sector_count = ((uint32_t) buffer[0x15]) |
((uint32_t) buffer[0x16] << 8) |
((uint32_t) buffer[0x17] << 16) |
((uint32_t) buffer[0x18] << 24);
header->size = sector_count * bytes_per_sector;
header->fat_offset = /* jump to partition */
partition_offset +
/* jump to fat */
(uint32_t) reserved_sectors * bytes_per_sector;
header->fat_size = (uint32_t) sectors_per_fat * bytes_per_sector;
header->sector_size = bytes_per_sector;
header->cluster_size = (uint32_t) bytes_per_sector * sectors_per_cluster;
header->root_dir_offset = /* jump to fats */
header->fat_offset +
/* jump to
没有合适的资源?快使用搜索试试~ 我知道了~
System_File_Code.rar_system_file
共19个文件
h:10个
c:8个
makefile:1个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 39 浏览量
2022-09-20
16:35:29
上传
评论
收藏 35KB RAR 举报
温馨提示
系统文件编程代码,其中一个基于AVR平台,另一个支持长文件名。
资源推荐
资源详情
资源评论
收起资源包目录
System_File_Code.rar (19个子文件)
System_File_Code
SD卡和FAT16读写源代码 支持长文件名和子目录
fat16.c 47KB
main.c 13KB
partition.h 4KB
uart.h 186B
sd_raw.h 681B
fat16_config.h 318B
sd_raw_config.h 1KB
sd_raw.c 17KB
partition.c 3KB
uart.c 2KB
Makefile 878B
fat16.h 3KB
AVR下读写SD卡的源代码
fat.h 3KB
main.c 3KB
mmc.h 2KB
fat.c 10KB
main.h 278B
typedefs.h 5KB
mmc.c 9KB
共 19 条
- 1
资源评论
alvarocfc
- 粉丝: 105
- 资源: 1万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功