Improved comments and moved internal stuff to special header file

master
Ondřej Hruška 9 years ago
parent a2e837a92a
commit 70bb4237f1
  1. 6
      fat16.c
  2. 139
      fat16.h
  3. 62
      fat16_internal.h

@ -706,13 +706,13 @@ void fat16_first(FAT16_FILE* file)
/** Open a directory denoted by the file. */ /** Open a directory denoted by the file. */
bool fat16_opendir(FAT16_FILE* file) bool fat16_opendir(FAT16_FILE* dir)
{ {
// Don't open non-dirs and "." directory. // Don't open non-dirs and "." directory.
if (!(file->attribs & FA_DIR) || file->type == FT_SELF) if (!(dir->attribs & FA_DIR) || dir->type == FT_SELF)
return false; return false;
open_file(file->fat, file, file->clu_start, 0); open_file(dir->fat, dir, dir->clu_start, 0);
return true; return true;
} }

@ -1,6 +1,10 @@
#pragma once #pragma once
/** Abstract block device interface */ /**
* Abstract block device interface
*
* Populate this with pointers to your I/O functions.
*/
typedef struct typedef struct
{ {
// Sequential read // Sequential read
@ -20,7 +24,10 @@ typedef struct
// ------------------------------- // -------------------------------
/** file types (values don't matter) */ /**
* File types (values can be used for debug printing).
* Accessible using file->type
*/
typedef enum typedef enum
{ {
FT_NONE = '-', FT_NONE = '-',
@ -29,102 +36,73 @@ typedef enum
FT_PARENT = 'P', FT_PARENT = 'P',
FT_LABEL = 'L', FT_LABEL = 'L',
FT_LFN = '~', FT_LFN = '~',
FT_INVALID = 'i', // not recognized weird file FT_INVALID = '?', // not recognized weird file
FT_SELF = '.', FT_SELF = '.',
FT_FILE = 'F' FT_FILE = 'F'
} FAT16_FT; } FAT16_FT;
// File Attributes (bit flags) // Include definitions of fully internal structs
#define FA_READONLY 0x01 // read only file #include "fat16_internal.h"
#define FA_HIDDEN 0x02 // hidden file
#define FA_SYSTEM 0x04 // system file
#define FA_LABEL 0x08 // volume label entry, found only in root directory.
#define FA_DIR 0x10 // subdirectory
#define FA_ARCHIVE 0x20 // archive flag
/** Boot Sector structure - INTERNAL! */
typedef struct __attribute__((packed))
{
// Fields loaded directly from disk:
// 13 bytes skipped
uint8_t sectors_per_cluster;
uint16_t reserved_sectors;
uint8_t num_fats;
uint16_t root_entries;
// 3 bytes skipped
uint16_t fat_size_sectors;
// 8 bytes skipped
uint32_t total_sectors; // if "short size sectors" is used, it's copied here too
// 7 bytes skipped
char volume_label[11]; // space padded, no terminator
// Added fields:
uint32_t bytes_per_cluster;
} /**
Fat16BootSector; * File handle struct.
*
* File handle contains cursor, file name, type, size etc.
/** FAT filesystem handle - private fields! */ * Everything (files, dirs) is accessed using this.
*/
typedef struct __attribute__((packed)) typedef struct __attribute__((packed))
{ {
// Backing block device /**
const BLOCKDEV* dev; * Raw file name. Starting 0x05 was converted to 0xE5.
* To get PRINTABLE file name, use fat16_dispname()
// Root directory sector start */
uint32_t rd_addr; uint8_t name[11];
// Start of first cluster (number "2")
uint32_t data_addr;
// Start of fat table /**
uint32_t fat_addr; * File attributes - bit field composed of FA_* flags
* (internal)
// Boot sector data struct */
Fat16BootSector bs; uint8_t attribs;
}
FAT16;
// 14 bytes skipped (10 reserved, date, time)
/** File handle struct */ /** First cluster of the file. (internal) */
typedef struct __attribute__((packed))
{
// Fields loaded directly from disk:
uint8_t name[11]; // Starting 0x05 converted to 0xE5, other "magic chars" left intact
uint8_t attribs; // composed of FA_* constants
// 14 bytes skipped
uint16_t clu_start; uint16_t clu_start;
/**
* File size in bytes.
* This is the current allocated and readable file size.
*/
uint32_t size; uint32_t size;
// Added fields:
// --- the following fields are added when reading ---
/** File type. */
FAT16_FT type; FAT16_FT type;
// --- Private fields ---
// Cursor // --- INTERNAL FIELDS ---
// Cursor variables. (internal)
uint32_t cur_abs; // absolute position in device uint32_t cur_abs; // absolute position in device
uint32_t cur_rel; // relative position in file uint32_t cur_rel; // relative position in file
uint16_t cur_clu; // cluster where the cursor is uint16_t cur_clu; // cluster where the cursor is
uint16_t cur_ofs; // offset within the active cluster uint16_t cur_ofs; // offset within the active cluster
// File position in the directory // File position in the directory. (internal)
uint16_t clu; // first cluster of directory uint16_t clu; // first cluster of directory
uint16_t num; // fiel entry number uint16_t num; // file entry number
// pointer to FAT // Pointer to the FAT16 handle. (internal)
const FAT16* fat; const FAT16* fat;
} }
FAT16_FILE; FAT16_FILE;
/** Initialize a filesystem */ /** Initialize the file system - store into "fat" */
void fat16_init(const BLOCKDEV* dev, FAT16* fat); void fat16_init(const BLOCKDEV* dev, FAT16* fat);
@ -132,14 +110,13 @@ void fat16_init(const BLOCKDEV* dev, FAT16* fat);
* Open the first file of the root directory. * Open the first file of the root directory.
* The file may be invalid (eg. a volume label, deleted etc), * The file may be invalid (eg. a volume label, deleted etc),
* or blank (type FT_NONE) if the filesystem is empty. * or blank (type FT_NONE) if the filesystem is empty.
*
* Either way, the prev and next functions will work as expected.
*/ */
void fat16_root(const FAT16* fat, FAT16_FILE* file); void fat16_root(const FAT16* fat, FAT16_FILE* file);
/** /**
* Resolve the disk label. * Resolve the disk label.
* That can be in the Boot Sector, or in the first root directory entry.
*/ */
char* fat16_disk_label(const FAT16* fat, char* label_out); char* fat16_disk_label(const FAT16* fat, char* label_out);
@ -185,29 +162,29 @@ bool fat16_mkdir(FAT16_FILE* file, const char* name);
/** /**
* Write new file size (also to the disk). * Set new file size.
* Allocates / frees needed clusters, does not erase them. * Allocates / frees needed clusters, does NOT erase them.
*
* Useful mainly for shrinking.
*/ */
void fat16_resize(FAT16_FILE* file, uint32_t size); void fat16_resize(FAT16_FILE* file, uint32_t size);
/** /**
* Delete a file entry and free clusters. * Delete a *FILE* and free it's clusters.
* Does NOT work on folders.
*/ */
bool fat16_rmfile(FAT16_FILE* file); bool fat16_rmfile(FAT16_FILE* file);
/** /**
* Delete an empty directory. * Delete an empty *DIRECTORY* and free it's clusters.
* Calling with non-subfolder entry or non-empty directory will cause error.
*/ */
bool fat16_rmdir(FAT16_FILE* file); bool fat16_rmdir(FAT16_FILE* file);
/** /**
* Delete a file or directory, regardless of type. * Delete a file or directory, even FT_LFN and FT_INVALID.
* Directories are deleted recursively. * Directories are deleted recursively (!)
*/ */
bool fat16_delete(FAT16_FILE* file); bool fat16_delete(FAT16_FILE* file);
@ -226,17 +203,19 @@ bool fat16_next(FAT16_FILE* file);
/** /**
* Open a subdirectory denoted by the file. * Open a subdirectory denoted by the file.
* Provided handle changes to first entry of the directory. * Provided handle changes to the first entry of the directory.
*/ */
bool fat16_opendir(FAT16_FILE* file); bool fat16_opendir(FAT16_FILE* dir);
/** /**
* Open a parent directory. Fails in root. * Open a parent directory. Fails in root.
* Provided handle changes to the first entry of the parent directory.
*/ */
bool fat16_parent(FAT16_FILE* file); bool fat16_parent(FAT16_FILE* file);
/** Rewind to first file in directory */ /** Jump to first file in this directory */
void fat16_first(FAT16_FILE* file); void fat16_first(FAT16_FILE* file);

@ -0,0 +1,62 @@
#pragma once
// Internal types and stuff that is needed in the header for declarations,
// but is not a part of the public API.
/** Boot Sector structure */
typedef struct __attribute__((packed))
{
// Fields loaded directly from disk:
// 13 bytes skipped
uint8_t sectors_per_cluster;
uint16_t reserved_sectors;
uint8_t num_fats;
uint16_t root_entries;
// 3 bytes skipped
uint16_t fat_size_sectors;
// 8 bytes skipped
uint32_t total_sectors; // if "short size sectors" is used, it's copied here too
// 7 bytes skipped
char volume_label[11]; // space padded, no terminator
// Added fields:
uint32_t bytes_per_cluster;
}
Fat16BootSector;
/** FAT filesystem handle */
typedef struct __attribute__((packed))
{
// Backing block device
const BLOCKDEV* dev;
// Root directory sector start
uint32_t rd_addr;
// Start of first cluster (number "2")
uint32_t data_addr;
// Start of fat table
uint32_t fat_addr;
// Boot sector data struct
Fat16BootSector bs;
}
FAT16;
/**
* File Attributes (bit flags)
* Accessible using file->attribs
*/
#define FA_READONLY 0x01 // read only file
#define FA_HIDDEN 0x02 // hidden file
#define FA_SYSTEM 0x04 // system file
#define FA_LABEL 0x08 // volume label entry, found only in root directory.
#define FA_DIR 0x10 // subdirectory
#define FA_ARCHIVE 0x20 // archive flag
Loading…
Cancel
Save