📄 fs.h
字号:
/*
* asixos/fs/fs.h
*
* Copyright (C) 2002 Asic Center
*
* 2002-08-18 Created by Pessia
*/
/*
* 'fs.h' is the main head file of AsixOS filesystem.
* It contains definition of all structures ( except 'FILE' ),
* and some status macros.
*/
#ifndef _FS_H
#define _FS_H
#include <filesys\list.h>
#include <sys\lmalloc.h>
/*
* Definition of return value
*/
#define FS_OK 0 /* success */
#define FS_ERROR (-1) /* general error */
#define FS_ERR_PAR (-2) /* error: wrong parameter */
#define FS_ERR_MAGIC (-3) /* error: wrong magic number */
#define FS_ERR_NOMEM (-4) /* error: fail to allocate memory */
/*
* Debug Macro:
* If it is defined, debug codes in file system will be activated.
* Otherwise, not.
*/
#define FS_DEBUG
#undef FS_DEBUG
#ifdef FS_DEBUG
#define PRINT_ERROR(str) printf(str)
#define PRINT_MSG(str) printf(str)
#else
#define PRINT_ERROR(str)
#define PRINT_MSG(str)
#endif
/*
* Because different system interface exists in different platform.
* Here, we use a serial of macros( or functions ) to seperate codes
* in file system from the differece.
* For example, in standard i/o definitions, 'malloc()' is used to
* allocate memory, while we use 'Sysmalloc()' in AsixOS.
* So, while porting file system, macros below should be carefully
* modified.
*/
#define FS_MALLOC(size) SysLmalloc(size)
#define FS_FREE(ptr) SysLfree(ptr)
#define FILE_S_LOCK_ID 7
#define FILEBUFFER_LOCK_ID 8
#define FS_LOCK(semid) twai_sem( semid, -1)
#define FS_UNLOCK( semid ) sig_sem( semid )
/*
* Definition of Limits
*/
#define BLOCKSIZE 512 /* size of one physical block */
#define MAX_AREA_SIZE (128*1024)
#define FLASH_AREA_SIZE (128*1024) /* size of one flash area ( best
to be same with size of bytes
written into flash a time). */
#define ICCARD_AREA_SIZE (4*1024) /* size of IC-CARD area.
When IC-CARD's size is small,
the whole card should be assigned
to be one area.*/
#define MAX_OPEN_FILE 10
#define FILE_NAME_MAX_LEN 12 /* max length of file name */
#define DIR_NAME_MAX_LEN FILE_NAME_MAX_LEN /* max length of directory name */
#define DIR_TREE_MAX_DEPTH 6 /* max depth of directory-tree( include '/') */
/* Limits of Directory Cache */
#define DIR_CACHE_NODE_MAX_NUM 20 /* max number of nodes in directory cache */
/* Limits of Path Parse */
#define NAME_MAX FILE_NAME_MAX_LEN /* max length of name of directory/file */
#define NODE_NUM DIR_TREE_MAX_DEPTH /* max number of nodes in 'PATH_NODE_S' */
#define NODE_LEN (FILE_NAME_MAX_LEN+2) /* max length of a node in 'PATH_NODE_S' */
/*
* Definition of some useful macros
*/
#define DIR_LENGTH sizeof(DCB_S)
/* Max number of sub-items in one direcotry control block */
#define MAX_DIR_NUM ((BLOCKSIZE-sizeof(FCB_S))/DIR_LENGTH)
/*the number of blockID in a FCB block*/
#define FCB_BLK_NUM (BLOCKSIZE - sizeof(FCB_S)) / 4
/*the number of blockID in a SUBFCB block*/
#define SUBFCB_BLK_NUM (BLOCKSIZE - sizeof(SUBFCB_S)) / 4
/*
* Definition of Magic Number for Structures
*/
#define FILE_MAGIC 0x90abcdef /* for structure FILE */
#define FCB_MAGIC 0x44350789 /* for structure FCB */
#define PATH_NODE_MAGIC 0xFFF2D9AF /* for structure PATH_NODE */
/*
* Definition of Flags used in File System
*/
/* Flag used in fcb module, to figure whether corresponding node
* in directory cache is being used or not. */
#define NOT_BE_USED 0
#define BE_USED 1
/* Flag used in fcb module, to figure how to use 'get_fcb',
* open-file or create-file. */
#define FS_CREATE_FILE 1
#define FS_OPEN_FILE 2
/* Flag used in fcb module, to figure status of each sub-item
* in father directory. */
#define FS_EXIST_FILE 1 /* figure it is item of file */
#define FS_DIR 2 /* figure it is item of directory */
#define FS_FREE_FILE 3 /* figure it is an unused item of directory */
/* Flag used in I/O buffer manager, to figure mode of
* write operation. */
#define IMMEDIATE_WRITE 1 /* write new block into device immediately */
#define NORMAL_WRITE 0 /* put new block into buffer */
/*mode of seek*/
#define SEEK_SET 0/*from the head of file*/
#define SEEK_CUR 1/*from current position*/
#define SEEK_END 2/*from the end of file*/
/*
* Type of pointer to Read/Write Function.
* Any device managed by file system should offer at least 2 functions
* (Read and Write) based this type. The functions will be saved in
* corresponding description structure of this device in the table
* 'device_dispcription[]'.
* Return Value:
* FS_OK : success
* FS_ERROR :
*/
typedef void (*DRVPOINTER)(unsigned char*,unsigned int,unsigned int);
/*
* Description of device:
* The structure is used to save physical infomation of device and
* description of its read-buffer. Size of read-buffer is decided
* by characteristic of device. For example, size of IC-CARD's
* read-buffer should be devided by its region size ( 256 bytes
* commonly ).
* Note, some device doesn't need read-buffer. for example, flash
* can be addressed directly, so it is not necessary to accelerate
* reading by buffer.
* Besides, because management of write-buffer is based on area,
* while not device, 'DEV_DSP_S' needn't to inclue information
* about write-buffer.
*/
typedef struct {
unsigned int devid; /* ID of this device */
unsigned int rbufsize; /* size of read-buffer */
unsigned char *rbuf; /* start address of read-buffer */
unsigned int start; /* physical start address of new data in read-buffer */
DRVPOINTER read; /* read function */
DRVPOINTER write; /* write function */
} DEV_DSP_S;
/* Definition of Device ID
* It is equal to the subscript variable where the device
* lies in the table 'device_dispcription[]'. */
#define FLASH_DEVID 0
#define ICCARD_DEVID 1
extern DEV_DSP_S device_dispcription[];
/*
* Description of area:
* In this file system, the whole storage space is splitted into
* many areas. Each area's physical information are saved in
* 'AREA_DSP_S'.
*/
typedef struct {
unsigned int devid; /* ID of the device this area belongs to */
unsigned int start; /* start address of area */
unsigned int size; /* size of area */
} AREA_DSP_S;
extern const AREA_DSP_S area_dispcription[];
/*
* Description of area in running time:
* The structure keeps running information of area in RAM.
* It includes this area's physical information, and uses
* a bitmap to save things about free blocks in this area.
* (Most importantly, the physical block storing info of
* 'bitmap' is assign as the first block of every area).
* Besides, it maintains the area's write-buffer. Every
* new block written in mode 'NORMAL_WRITE' will be added
* into the list whose head node is 'buf' below. While
* number of nodes in the list is up to 'max_nblknum', data
* in all nodes of the list should be written into device
* and the list will be cleared.
* Note, the value of 'max_nblknum' is decided by size of
* the area. Bigger area can have more nodes. It is a pity
* that more nodes do not mean more efficiency. The worst
* thing is to repeat writing small and closed data. So user
* should avoid such operation to get better performance.
*/
typedef struct {
unsigned int *blkbitmap; /* bitmap of free blocks in the area */
unsigned int blkfreenum; /* current number of free blocks */
DLIST_S buf; /* head node of the area's write-buffer list */
AREA_DSP_S phyinfo; /* physical information of the area */
unsigned int nblknum; /* current number of nodes in write-buffer list */
unsigned int max_nblknum; /* max number of nodes in write-buffer list */
} AREA_S;
/*
* AREA_S Relating Operatiing Macros
* NOTE: 'a' in below macros should be a pointer to 'AREA_S'
*/
/* Check area's write-buffer is full or not */
#define AREA_BUF_FULL(a) ((a)->nblknum >= (a)->max_nblknum )
/* Get pointer to head node of area's write-buffer list */
#define get_area_buf_listhead(a) (&(a)->buf)
/* Increase number of node in area's write-buffer list */
#define inc_newblock_num(a) ((a)->nblknum++)
/* Decrease number of node in area's write-buffer list */
#define dec_newblock_num(a) ((a)->nblknum--)
/* Get pointer to 'AREA_S' using pointer to 'AREA_S.buf'(pbuf) */
#define get_area_pointer(pbuf) (list_entry((pbuf), AREA_S, buf))
/* Get pointer to area's read function */
#define READ_DEV(a) (device_dispcription[(a)->phyinfo.devid].read)
/* Get pointer to area's write function */
#define WRITE_DEV(a) (device_dispcription[(a)->phyinfo.devid].write)
/* Get area's start address */
#define AREA_START_ADDR(a) ((a)->phyinfo.start)
/* Get area's size */
#define AREA_SIZE(a) ((a)->phyinfo.size)
/* Get size of area's read-buffer */
#define AREA_READ_BUFFER_SIZE(a) (device_dispcription[(a)->phyinfo.devid].rbufsize)
/* Get physical start address of data in read-buffer */
#define AREA_READ_BUFFER_START(a) (device_dispcription[(a)->phyinfo.devid].start)
/* Get start address of area's read-buffer */
#define AREA_READ_BUFFER(a) (device_dispcription[(a)->phyinfo.devid].rbuf)
/*
* Calculate start address of device's read-buffer by 'addr':
* When user reads area which belongs to a device through read-buffer,
* 'addr' figures start address of data user wants to read. But this
* address maybe can not be devided by 'AREA_READ_BUFFER_SIZE(a)'.
* So we should calculate an address which is closed to 'addr' and smaller
* than it. And the resulting address will be new physical start address
* of data in read-buffer. Read-buffer should refresh its data based on
* this address.
*/
#define get_rbuf_startaddr(addr,a) \
((addr)-((addr)-(AREA_START_ADDR(a)))%(AREA_READ_BUFFER_SIZE(a)))
extern AREA_S area[];
/*
* Buffer-Block Structure:
* Every write operation in 'NORMAL_WRITE' mode will be record in
* a node based on this structure. The node will be linked into
* two lists, one is for area ( head is 'AREA_S.buf' ), the other
* is for file( head is 'FILE.link' ).
*/
typedef struct {
DLIST_S link; /* list for file */
DLIST_S area; /* list for area */
unsigned int blkid; /* ID of block new data belongs to */
unsigned short start; /* start address of new data */
unsigned short size; /* size of new data */
unsigned char *data; /* pointer to new data */
#if 0
unsigned int reserved; /* not used now */
#endif
} BUF_BLK_S;
/*
* PARTITION Structure:
* In this file system, several closed areas compose a partition.
* Every file or direcory is located in a partition. It is some like
* DOS file sytem. Because 'AREA_S' and 'AREA_DSP_S' are all arranged
* in arrays, it is easy to use 'start' which is subscript variable
* of the starting area of this partition to find all the areas in it.
*/
typedef struct {
unsigned int start; /* subscript variable of beginning area */
unsigned int num; /* number of areas */
} PARTITION;
/* Global partition list */
extern const PARTITION Partition[];
/*
*
*/
typedef struct _subfcb_s {
char flag;
unsigned int magic;
unsigned int blkid;
struct _subfcb_s* nextfcb;
unsigned int nextblk;
char reserved[2];
} SUBFCB_S;
typedef struct{
char flag;
unsigned int magic;
unsigned int blkid;
SUBFCB_S* nextfcb;
unsigned int nextblk;
// PARTITION* partition;
int partition;
char file_name[NAME_MAX];
unsigned long file_length;
char reserved[2];
} FCB_S;
typedef struct{
unsigned char flag;
unsigned long curp;
unsigned int magic;
FCB_S* fcb;
DLIST_S link;//02-8-22 changed by Julias.change DLIST_S * to DLIST_S.
char path[80];
char use;
FCB_S* curfcb;
unsigned long curblkid;
} FILE_S;
typedef struct{
char flag;/*whether this node is used*/
DLIST_S child;/*point to child node tree*/
DLIST_S next;/*point to next node*/
unsigned char dir[BLOCKSIZE];/*data of FCB*/
} DIR_CACHE_NODE_S;
typedef struct{
DLIST_S treehead;/*point to the head node of search tree*/
unsigned int freenum;/*the num of free node*/
DIR_CACHE_NODE_S* freehead;/*point to the next node of current node*/
DIR_CACHE_NODE_S dir_cache_data[DIR_CACHE_NODE_MAX_NUM];/*array of node*/
} DIR_CACHE_S;
typedef struct{
unsigned int blkid;
char dirtype;
unsigned char dirname[NAME_MAX];
} DCB_S;
typedef struct
{
FCB_S curdir;
DCB_S subdir[MAX_DIR_NUM];
}DIR_S;
typedef struct {
char type;
char name[NAME_MAX];
}SIMPLE_INFO;
typedef struct{
int allnum;
SIMPLE_INFO siminfo[MAX_DIR_NUM];
}DIRINFO_S;
extern DIR_CACHE_S cache_data;
extern DIR_S RootDir[];
extern FILE_S filebuf[ ];
#endif /* _FS_H */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -