提交 0030a2d3 编写于 作者: I iamyhw@gmail.com

add support uffs interface

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1243 bbd45198-f89e-11dd-88c7-29a3b14d5316
上级 dede5414
#include <rtthread.h>
#include <dfs.h>
#include <rtthread.h>
#include <dfs_def.h>
#include <dfs_fs.h>
#include "uffs/uffs_fs.h"
#include "uffs/uffs_mtb.h"
#include "uffs/uffs_fd.h"
#include "uffs_ext.h"
/* mount and unmount file system */
static int dfs_uffs_mount(struct dfs_filesystem* fs, unsigned long rwflag, const void* data)
/* mount and unmount file system */
int dfs_uffs_mount(struct dfs_filesystem* fs, unsigned long rwflag, const void* data)
{
}
return ((uffs_InitMountTable() == U_SUCC) ? 0 : -1);
}
static int dfs_uffs_unmount(struct dfs_filesystem* fs)
int dfs_uffs_unmount(struct dfs_filesystem* fs)
{
}
uffs_ReleaseObjectBuf();
return uffs_ReleaseMountTable();
}
static int dfs_uffs_mkfs(const char* device_name)
{
return -DFS_STATUS_EIO;
}
int dfs_uffs_mkfs(const char* device_name)
{
return uffs_format(NULL);
}
static int dfs_uffs_statfs(struct dfs_filesystem* fs, struct _statfs *buf)
int dfs_uffs_statfs(struct dfs_filesystem* fs, struct statfs *buf)
{
}
int ret = U_SUCC;
uffs_MountTable *entry = (uffs_MountTable*)(fs->dev_id->user_data);
struct uffs_StorageAttrSt *attr = entry->dev->attr;
static int dfs_uffs_open(struct dfs_fd* fd)
{
}
buf->f_bsize = attr->page_data_size * attr->pages_per_block;
buf->f_blocks = attr->total_blocks;
buf->f_bfree = 0;
static int dfs_uffs_close(struct dfs_fd* fd)
{
}
return ret;
}
static int dfs_uffs_ioctl(struct dfs_fd* fd, int cmd, void *args)
{
}
int dfs_uffs_open(struct dfs_fd* fd)
{
int ret=U_SUCC;
if (fd->flags & DFS_O_DIRECTORY)
{//ļ
uffs_DIR *dirp;
/* open directory */
if (fd->flags & DFS_O_CREAT)
{//
ret = uffs_open(fd->path,UO_CREATE|UO_DIR);
if(ret != U_SUCC)
{
return U_FAIL;
}
}
dirp = uffs_opendir(fd->path);
if(dirp == NULL)
{
uffs_set_error(-UEMFILE);
ret = U_FAIL;
}
fd->data = dirp;
return U_SUCC;
}
else
{//ļ
uffs_Object *fp;
int mode = UO_RDONLY;
if (fd->flags & DFS_O_WRONLY) mode |= UO_WRONLY;
if ((fd->flags & DFS_O_ACCMODE) & DFS_O_RDWR) mode |= UO_WRONLY;
/* Opens the file, if it is existing. If not, a new file is created. */
if (fd->flags & DFS_O_CREAT) mode |= UO_CREATE;
/* Creates a new file. If the file is existing, it is truncated and overwritten. */
if (fd->flags & DFS_O_TRUNC) mode |= UO_TRUNC;
/* Creates a new file. The function fails if the file is already existing. */
if (fd->flags & DFS_O_EXCL) mode |= UO_EXCL;
/* allocate a fd */
/* open directory */
fp = uffs_GetObject();
if(fp == NULL)
{
uffs_set_error(-UEMFILE);
ret = U_FAIL;
}
if(uffs_OpenObject(fp, fd->path, mode) == RT_EOK)
{
struct uffs_stat stat_buf;
uffs_stat(fd->path, &stat_buf);
fd->pos = fp->pos;
fd->size = stat_buf.st_size;
fd->data = fp;
if(fd->flags & DFS_O_APPEND)
{
fd->pos = uffs_SeekObject(fp, 0, USEEK_END);
}
ret = U_SUCC;
}
else
{
/* open failed, return */
uffs_set_error(-uffs_GetObjectErr(fp));
uffs_PutObject(fp);
return U_FAIL;
}
}
static int dfs_uffs_read(struct dfs_fd* fd, void* buf, rt_size_t count)
return ret;
}
int dfs_uffs_close(struct dfs_fd* fd)
{
}
int ret=U_SUCC;
if (fd->type == FT_DIRECTORY)
{
uffs_DIR* dirp;
dirp = (uffs_DIR*)(fd->data);
RT_ASSERT(dirp != RT_NULL);
uffs_closedir(dirp);
}
else if (fd->type == FT_REGULAR)
{
uffs_Object* fp;
fp = (uffs_Object*)(fd->data);
RT_ASSERT(fd != RT_NULL);
ret = uffs_CloseObject(fp);
uffs_PutObject(fp);
}
static int dfs_uffs_write(struct dfs_fd* fd, const void* buf, rt_size_t count)
return ret;
}
int dfs_uffs_ioctl(struct dfs_fd* fd, int cmd, void *args)
{
}
return -DFS_STATUS_ENOSYS;
}
static int dfs_uffs_flush(struct dfs_fd* fd)
int dfs_uffs_read(struct dfs_fd* fd, void* buf, rt_size_t count)
{
}
uffs_Object* fp;
uffs_DIR* dirp;
if (fd->type == FT_DIRECTORY)
{
dirp = (uffs_DIR*)(fd->data);
fp = dirp->obj;
}
else
{
fp = (uffs_Object*)(fd->data);
}
RT_ASSERT(fd != RT_NULL);
/* update position */
fd->pos = fp->pos;
static int dfs_uffs_lseek(struct dfs_fd* fd, rt_off_t offset)
return uffs_ReadObject(fp, buf, count);
}
int dfs_uffs_write(struct dfs_fd* fd, const void* buf, rt_size_t count)
{
}
uffs_Object* fp;
u32 byte_write;
struct uffs_stat stat_buf;
if(fd->type == FT_DIRECTORY)
{
return -DFS_STATUS_EISDIR;
}
fp = (uffs_Object*)(fd->data);
RT_ASSERT(fp != RT_NULL);
static int dfs_uffs_getdents(struct dfs_fd* fd, struct _dirent* dirp, rt_uint32_t count)
byte_write = uffs_WriteObject(fp, buf, count);
/* update position and file size */
fd->pos = fp->pos;
uffs_stat(fp->name, &stat_buf);
fd->size = stat_buf.st_size;
return byte_write;
}
int dfs_uffs_flush(struct dfs_fd* fd)
{
}
uffs_Object* fp;
static int dfs_uffs_unlink(struct dfs_filesystem* fs, const char* pathname)
fp = (uffs_Object*)(fd->data);
RT_ASSERT(fp != RT_NULL);
return uffs_FlushObject(fp);
}
int dfs_uffs_lseek(struct dfs_fd* fd, rt_off_t offset)
{
}
uffs_Object* fp;
fp = (uffs_Object*)(fd->data);
RT_ASSERT(fp != RT_NULL);
static int dfs_uffs_stat(struct dfs_filesystem* fs, const char* filename, struct _stat* buf)
return uffs_SeekObject(fp, USEEK_SET, offset);
}
int dfs_uffs_getdents(struct dfs_fd* fd, struct dirent* dir, rt_uint32_t count)
{
}
uffs_DIR* dirp;
struct uffs_dirent *ent;
rt_uint32_t index;
struct dirent* d;
dirp = (uffs_DIR*)(fd->data);
RT_ASSERT(dirp != RT_NULL);
/* make integer count */
count = (count / sizeof(struct dirent)) * sizeof(struct dirent);
if ( count == 0 ) return -DFS_STATUS_EINVAL;
index = 0;
while (1)
{
d = dir + index;
ent = uffs_readdir(dirp);
if(ent == RT_NULL)break;
d->d_type = DFS_DT_DIR;
static int dfs_uffs_rename(struct dfs_filesystem* fs, const char* oldpath, const char* newpath)
d->d_namlen = ent->d_namelen;
d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
rt_strncpy(d->d_name, ent->d_name, rt_strlen(ent->d_name) + 1);
index ++;
if ( index * sizeof(struct dirent) >= count )
break;
}
return index * sizeof(struct dirent);
}
//Delete a File or Directory
int dfs_uffs_unlink(struct dfs_filesystem* fs, const char* path)
{
}
int ret;
int err = 0;
ret = uffs_DeleteObject(path, &err);
uffs_set_error(-err);
return ret;
}
static const struct dfs_filesystem_operation _uffs =
int dfs_uffs_stat(struct dfs_filesystem* fs, const char* path, struct stat* st)
{
"uffs",
dfs_uffs_mount,
dfs_uffs_unmount,
dfs_uffs_mkfs,
dfs_uffs_statfs,
dfs_uffs_open,
dfs_uffs_close,
dfs_uffs_ioctl,
dfs_uffs_read,
dfs_uffs_write,
dfs_uffs_flush,
dfs_uffs_lseek,
dfs_uffs_getdents,
dfs_uffs_unlink,
dfs_uffs_stat,
dfs_uffs_rename,
};
int dfs_uffs_init(void)
int ret=U_SUCC;
struct uffs_stat stat_buf;
ret = uffs_stat(path, &stat_buf);
if (ret == U_SUCC)
{
st->st_dev = 0;
//st->st_mode = stat_buf.st_mode;
st->st_mode = DFS_S_IFREG | DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH |
DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH;
if (stat_buf.st_mode & US_IFDIR)
{
st->st_mode &= ~DFS_S_IFREG;
st->st_mode |= DFS_S_IFDIR | DFS_S_IXUSR | DFS_S_IXGRP | DFS_S_IXOTH;
}
if (stat_buf.st_mode & US_IREAD)
st->st_mode &= ~(DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH);
st->st_size = stat_buf.st_size;
st->st_mtime= stat_buf.st_mtime;
st->st_blksize= stat_buf.st_blksize;
return U_SUCC;
}
return U_FAIL;
}
int dfs_uffs_rename(struct dfs_filesystem* fs, const char* oldpath, const char* newpath)
{
/* register UFFS file system */
return dfs_register(&_uffs);
}
int ret;
int err = 0;
ret = uffs_RenameObject(oldpath, newpath, &err);
uffs_set_error(-err);
return ret;
}
struct dfs_filesystem_operation _uffs =
{
"uffs",
dfs_uffs_mount,
dfs_uffs_unmount,
dfs_uffs_mkfs,
dfs_uffs_statfs,
dfs_uffs_open,
dfs_uffs_close,
dfs_uffs_ioctl,
dfs_uffs_read,
dfs_uffs_write,
dfs_uffs_flush,
dfs_uffs_lseek,
dfs_uffs_getdents,
dfs_uffs_unlink,
dfs_uffs_stat,
dfs_uffs_rename,
};
int dfs_uffs_init(void)
{
/* register UFFS file system */
return dfs_register(&_uffs);
}
/*
* File : dfs_uffs.h
* This file is part of Device File System in RT-Thread RTOS
* COPYRIGHT (C) 2004-2010, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE.
*
* Change Logs:
* Date Author Notes
* 2010-09-02 Bernard The first version.
*/
+------------------------------------------------------------------------------
| Project : Device Filesystem
+------------------------------------------------------------------------------
| Copyright 2010
| All rights reserved.
|------------------------------------------------------------------------------
| File : dfs_uffs.h
|------------------------------------------------------------------------------
| Chang Logs:
| Date Author Notes
| 2010-12-24 amsl Add dfs_uffs_init function declaration
+------------------------------------------------------------------------------
*/
#ifndef __DFS_UFFS_H__
#define __DFS_UFFS_H__
#ifdef __cplusplus
extern "C" {
#endif
int dfs_uffs_init(void);
#ifdef __cplusplus
}
#endif
#endif
......@@ -57,7 +57,7 @@ struct cli_commandset {
const char * cli_getparam(const char *tail, const char **next);
void cli_add_commandset(struct cli_commandset *cmds);
void cliInterpret(const char *line);
void cliMain();
void cliMain(void);
#endif
......
......@@ -37,7 +37,7 @@
*/
#include "uffs/uffs_os.h"
#include "uffs/uffs_public.h"
#include <memory.h>
//#include <memory.h>
#include <stdlib.h>
#include <time.h>
......@@ -98,7 +98,7 @@ unsigned int uffs_GetCurDateTime(void)
// or just return 0 if you don't care about file time.
time_t tvalue;
tvalue = time(NULL);
tvalue = 0;//time(NULL);
return (unsigned int)tvalue;
}
INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/inc)
INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/emu)
LINK_DIRECTORIES(${uffs_BINARY_DIR}/src/emu)
LINK_DIRECTORIES(${uffs_BINARY_DIR}/src/uffs)
SET(static_mem_SRCS static-mem-allocate.c)
SET(flash_if_SRCS flash-interface-example.c)
ADD_EXECUTABLE(static-mem-example ${static_mem_SRCS})
ADD_EXECUTABLE(flash-if-example ${flash_if_SRCS})
TARGET_LINK_LIBRARIES(static-mem-example emu uffs emu)
TARGET_LINK_LIBRARIES(flash-if-example emu uffs emu)
INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/inc)
INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/emu)
LINK_DIRECTORIES(${uffs_BINARY_DIR}/src/emu)
LINK_DIRECTORIES(${uffs_BINARY_DIR}/src/uffs)
SET(static_mem_SRCS static-mem-allocate.c)
SET(flash_if_SRCS flash-interface-example.c)
ADD_EXECUTABLE(static-mem-example ${static_mem_SRCS})
ADD_EXECUTABLE(flash-if-example ${flash_if_SRCS})
TARGET_LINK_LIBRARIES(static-mem-example emu uffs emu)
TARGET_LINK_LIBRARIES(flash-if-example emu uffs emu)
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file static-mem-allocate.c
* \brief demostrate how to use static memory allocation. This example use
* file emulated NAND flash.
* \author Ricky Zheng
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "uffs/uffs_config.h"
#include "uffs/uffs_public.h"
#include "uffs/uffs_fs.h"
#include "uffs/uffs_utils.h"
#include "uffs/uffs_core.h"
#include "uffs/uffs_mtb.h"
#include "cmdline.h"
#include "uffs_fileem.h"
#define PFX "static-example: "
#if CONFIG_USE_STATIC_MEMORY_ALLOCATOR == 0
int main()
{
uffs_Perror(UFFS_ERR_NORMAL, "This example need CONFIG_USE_STATIC_MEMORY_ALLOCATOR = 1");
return 0;
}
#else
extern struct cli_commandset * get_helper_cmds(void);
#define DEFAULT_EMU_FILENAME "uffsemfile.bin"
#define PAGE_DATA_SIZE 512
#define PAGE_SPARE_SIZE 16
#define PAGES_PER_BLOCK 32
#define TOTAL_BLOCKS 128
#define PAGE_SIZE (PAGE_DATA_SIZE + PAGE_SPARE_SIZE)
#define BLOCK_DATA_SIZE (PAGES_PER_BLOCK * PAGE_DATA_SIZE)
#define TOTAL_DATA_SIZE (TOTAL_BLOCKS * BLOCK_DATA_SIZE)
#define BLOCK_SIZE (PAGES_PER_BLOCK * PAGE_SIZE)
#define TOTAL_SIZE (BLOCK_SIZE * TOTAL_BLOCKS)
#define MAX_MOUNT_TABLES 10
#define MAX_MOUNT_POINT_NAME 32
static uffs_Device demo_device = {0};
static struct uffs_MountTableEntrySt demo_mount = {
&demo_device,
0, /* start from block 0 */
-1, /* use whole chip */
"/", /* mount point */
NULL
};
static struct uffs_StorageAttrSt emu_storage = {0};
static struct uffs_FileEmuSt emu_private = {0};
/* static alloc the memory */
static int static_buffer_pool[UFFS_STATIC_BUFF_SIZE(PAGES_PER_BLOCK, PAGE_SIZE, TOTAL_BLOCKS) / sizeof(int)];
static void setup_emu_storage(struct uffs_StorageAttrSt *attr)
{
attr->total_blocks = TOTAL_BLOCKS; /* total blocks */
attr->page_data_size = PAGE_DATA_SIZE; /* page data size */
attr->spare_size = PAGE_SPARE_SIZE; /* page spare size */
attr->pages_per_block = PAGES_PER_BLOCK; /* pages per block */
attr->block_status_offs = 4; /* block status offset is 5th byte in spare */
attr->ecc_opt = UFFS_ECC_SOFT; /* ecc option */
attr->layout_opt = UFFS_LAYOUT_UFFS; /* let UFFS do the spare layout */
}
static void setup_emu_private(uffs_FileEmu *emu)
{
memset(emu, 0, sizeof(uffs_FileEmu));
emu->emu_filename = DEFAULT_EMU_FILENAME;
}
static int init_uffs_fs(void)
{
struct uffs_MountTableEntrySt *mtbl = &demo_mount;
/* setup emu storage */
setup_emu_storage(&emu_storage);
setup_emu_private(&emu_private);
emu_storage._private = &emu_private;
mtbl->dev->attr = &emu_storage;
/* setup memory allocator */
uffs_MemSetupStaticAllocator(&mtbl->dev->mem, static_buffer_pool, sizeof(static_buffer_pool));
/* setup device */
uffs_fileem_setup_device(mtbl->dev);
/* register mount table */
uffs_RegisterMountTable(mtbl);
return uffs_InitMountTable() == U_SUCC ? 0 : -1;
}
static int release_uffs_fs(void)
{
return uffs_ReleaseMountTable();
}
int main(int argc, char *argv[])
{
int ret;
ret = init_uffs_fs();
if (ret != 0) {
printf ("Init file system fail: %d\n", ret);
return -1;
}
cli_add_commandset(get_helper_cmds());
cliMain();
release_uffs_fs();
return 0;
}
#endif
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file static-mem-allocate.c
* \brief demostrate how to use static memory allocation. This example use
* file emulated NAND flash, one partition only.
* \author Ricky Zheng
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "uffs/uffs_config.h"
#include "uffs/uffs_public.h"
#include "uffs/uffs_fs.h"
#include "uffs/uffs_utils.h"
#include "uffs/uffs_core.h"
#include "uffs/uffs_mtb.h"
#include "cmdline.h"
#include "uffs_fileem.h"
#define PFX "static-example: "
#if CONFIG_USE_STATIC_MEMORY_ALLOCATOR == 0
int main()
{
uffs_Perror(UFFS_ERR_NORMAL, "This example need CONFIG_USE_STATIC_MEMORY_ALLOCATOR = 1");
return 0;
}
#else
extern struct cli_commandset * get_helper_cmds(void);
#define PAGE_DATA_SIZE 512
#define PAGE_SPARE_SIZE 16
#define PAGES_PER_BLOCK 32
#define TOTAL_BLOCKS 128
#define PAGE_SIZE (PAGE_DATA_SIZE + PAGE_SPARE_SIZE)
#define BLOCK_DATA_SIZE (PAGES_PER_BLOCK * PAGE_DATA_SIZE)
#define TOTAL_DATA_SIZE (TOTAL_BLOCKS * BLOCK_DATA_SIZE)
#define BLOCK_SIZE (PAGES_PER_BLOCK * PAGE_SIZE)
#define TOTAL_SIZE (BLOCK_SIZE * TOTAL_BLOCKS)
#define MAX_MOUNT_TABLES 10
#define MAX_MOUNT_POINT_NAME 32
static uffs_Device demo_device = {0};
static struct uffs_MountTableEntrySt demo_mount = {
&demo_device,
0, /* start from block 0 */
-1, /* use whole chip */
"/", /* mount point */
NULL
};
/* static alloc the memory */
static int static_buffer_pool[UFFS_STATIC_BUFF_SIZE(PAGES_PER_BLOCK, PAGE_SIZE, TOTAL_BLOCKS) / sizeof(int)];
static void setup_storage(struct uffs_StorageAttrSt *attr)
{
attr->total_blocks = TOTAL_BLOCKS; /* total blocks */
attr->page_data_size = PAGE_DATA_SIZE; /* page data size */
attr->spare_size = PAGE_SPARE_SIZE; /* page spare size */
attr->pages_per_block = PAGES_PER_BLOCK; /* pages per block */
attr->block_status_offs = 4; /* block status offset is 5th byte in spare */
attr->ecc_opt = UFFS_ECC_SOFT; /* use UFFS software ecc */
attr->layout_opt = UFFS_LAYOUT_UFFS; /* let UFFS do the spare layout */
}
static void setup_device(uffs_Device *dev)
{
// using file emulator device
dev->Init = femu_InitDevice;
dev->Release = femu_ReleaseDevice;
dev->attr = femu_GetStorage();
}
static int init_uffs_fs(void)
{
struct uffs_MountTableEntrySt *mtbl = &demo_mount;
/* setup flash storage attributes */
setup_storage(femu_GetStorage());
/* setup memory allocator */
uffs_MemSetupStaticAllocator(&mtbl->dev->mem, static_buffer_pool, sizeof(static_buffer_pool));
/* setup device: init, release, attr */
setup_device(mtbl->dev);
/* register mount table */
uffs_RegisterMountTable(mtbl);
return uffs_InitMountTable() == U_SUCC ? 0 : -1;
}
static int release_uffs_fs(void)
{
return uffs_ReleaseMountTable();
}
int main(int argc, char *argv[])
{
int ret;
ret = init_uffs_fs();
if (ret != 0) {
printf ("Init file system fail: %d\n", ret);
return -1;
}
cli_add_commandset(get_helper_cmds());
cli_add_commandset(get_test_cmds());
cliMain();
release_uffs_fs();
return 0;
}
#endif
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs.h
......@@ -37,98 +37,98 @@
#ifndef _UFFS_H_
#define _UFFS_H_
#include <dfs_def.h>
#include "uffs/uffs_types.h"
#ifdef __cplusplus
extern "C"{
#endif
#endif
#define UO_RDONLY 0x0000 /** read only */
#define UO_WRONLY 0x0001 /** write only */
#define UO_RDWR 0x0002 /** read and write */
#define UO_APPEND 0x0008 /** append */
#define UO_RDONLY DFS_O_RDONLY /** read only */
#define UO_WRONLY DFS_O_WRONLY /** write only */
#define UO_RDWR DFS_O_RDWR /** read and write */
#define UO_APPEND DFS_O_APPEND /** append */
#define UO_BINARY 0x0000 /** no used in uffs */
#define UO_BINARY 0x0000 /** no used in uffs */
#define UO_CREATE DFS_O_CREAT
#define UO_TRUNC DFS_O_TRUNC
#define UO_EXCL DFS_O_EXCL
#define UO_CREATE 0x0100
#define UO_TRUNC 0x0200
#define UO_EXCL 0x0400
#define UO_DIR DFS_O_DIRECTORY /** open a directory */
#define UO_DIR 0x1000 /** open a directory */
#define UENOERR 0 /** no error */
#define UEACCES 1 /** Tried to open read-only file
for writing, or files sharing mode
does not allow specified operations,
or given path is directory */
#define UENOERR 0 /** no error */
#define UEACCES 1 /** Tried to open read-only file
for writing, or files sharing mode
does not allow specified operations,
or given path is directory */
#define UEEXIST 2 /** _O_CREAT and _O_EXCL flags specified,
#define UEEXIST 2 /** _O_CREAT and _O_EXCL flags specified,
but filename already exists */
#define UEINVAL 3 /** Invalid oflag or pmode argument */
#define UEMFILE 4 /** No more file handles available
(too many open files) */
#define UENOENT 5 /** file or path not found */
#define UETIME 6 /** can't set file time */
#define UEBADF 9 /** invalid file handle */
#define UENOMEM 10 /** no enough memory */
#define UEIOERR 11 /** I/O error from lower level flash operation */
#define UENOTDIR 12 /** Not a directory */
#define UEISDIR 13 /** Is a directory */
#define UEUNKNOWN 100 /** unknown error */
#define _SEEK_CUR 0 /** seek from current position */
#define _SEEK_SET 1 /** seek from beginning of file */
#define _SEEK_END 2 /** seek from end of file */
#define USEEK_CUR _SEEK_CUR
#define USEEK_SET _SEEK_SET
#define USEEK_END _SEEK_END
/**
* \def MAX_FILENAME_LENGTH
* \note Be careful: it's part of the physical format (see: uffs_FileInfoSt.name)
* !!DO NOT CHANGE IT AFTER FILE SYSTEM IS FORMATED!!
*/
#define MAX_FILENAME_LENGTH 32
/** \note 8-bits attr goes to uffs_dirent::d_type */
#define FILE_ATTR_DIR (1 << 7) //!< attribute for directory
#define FILE_ATTR_WRITE (1 << 0) //!< writable
/**
* \structure uffs_FileInfoSt
* \brief file/dir entry info in physical storage format
*/
struct uffs_FileInfoSt {
u32 attr; //!< file/dir attribute
u32 create_time;
u32 last_modify;
u32 access;
u32 reserved;
u32 name_len; //!< length of file/dir name
char name[MAX_FILENAME_LENGTH];
};
typedef struct uffs_FileInfoSt uffs_FileInfo;
/**
* \struct uffs_ObjectInfoSt
* \brief object info
*/
typedef struct uffs_ObjectInfoSt {
uffs_FileInfo info;
u32 len; //!< length of file
u16 serial; //!< object serial num
} uffs_ObjectInfo;
#define UEINVAL 3 /** Invalid oflag or pmode argument */
#define UEMFILE 4 /** No more file handles available
(too many open files) */
#define UENOENT 5 /** file or path not found */
#define UETIME 6 /** can't set file time */
#define UEBADF 9 /** invalid file handle */
#define UENOMEM 10 /** no enough memory */
#define UEIOERR 11 /** I/O error from lower level flash operation */
#define UENOTDIR 12 /** Not a directory */
#define UEISDIR 13 /** Is a directory */
#define UEUNKNOWN 100 /** unknown error */
#define _SEEK_CUR 0 /** seek from current position */
#define _SEEK_SET 1 /** seek from beginning of file */
#define _SEEK_END 2 /** seek from end of file */
#define USEEK_SET DFS_SEEK_SET /*0* 从当前点寻找 */
#define USEEK_CUR DFS_SEEK_CUR /*1* 从文件的开始寻找 */
#define USEEK_END DFS_SEEK_END /*2* 从文件的结尾寻找 */
/**
* \def MAX_FILENAME_LENGTH
* \note Be careful: it's part of the physical format (see: uffs_FileInfoSt.name)
* !!DO NOT CHANGE IT AFTER FILE SYSTEM IS FORMATED!!
*/
#define MAX_FILENAME_LENGTH 32
/** \note 8-bits attr goes to uffs_dirent::d_type */
#define FILE_ATTR_DIR (1 << 7) //!< attribute for directory
#define FILE_ATTR_WRITE (1 << 0) //!< writable
/*
* \structure uffs_FileInfoSt
* \brief file/dir entry info in physical storage format
*/
struct uffs_FileInfoSt {
u32 attr; //!< file/dir attribute
u32 create_time;
u32 last_modify;
u32 access;
u32 reserved;
u32 name_len; //!< length of file/dir name
char name[MAX_FILENAME_LENGTH];
};
typedef struct uffs_FileInfoSt uffs_FileInfo;
/**
* \struct uffs_ObjectInfoSt
* \brief object info
*/
typedef struct uffs_ObjectInfoSt {
uffs_FileInfo info;
u32 len; //!< length of file
u16 serial; //!< object serial num
} uffs_ObjectInfo;
#ifdef __cplusplus
}
......
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs_badblock.h
* \brief bad block management
* \author Ricky Zheng
*/
#ifndef _UFFS_BADBLOCK_H_
#define _UFFS_BADBLOCK_H_
#include "uffs/uffs_public.h"
#include "uffs/uffs_device.h"
#include "uffs/uffs_core.h"
#ifdef __cplusplus
extern "C"{
#endif
#define HAVE_BADBLOCK(dev) (dev->bad.block != UFFS_INVALID_BLOCK)
/** initialize bad block management data structures for uffs device */
void uffs_BadBlockInit(uffs_Device *dev);
/** processing bad block: erase bad block, mark it as 'bad' and put it to bad block list */
void uffs_BadBlockProcess(uffs_Device *dev, TreeNode *node);
/** try to recover data from a new discovered bad block */
void uffs_BadBlockRecover(uffs_Device *dev);
/** put a new block to the bad block waiting list */
void uffs_BadBlockAdd(uffs_Device *dev, int block);
#ifdef __cplusplus
}
#endif
#endif
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs_badblock.h
* \brief bad block management
* \author Ricky Zheng
*/
#ifndef _UFFS_BADBLOCK_H_
#define _UFFS_BADBLOCK_H_
#include "uffs/uffs_public.h"
#include "uffs/uffs_device.h"
#include "uffs/uffs_core.h"
#ifdef __cplusplus
extern "C"{
#endif
#define HAVE_BADBLOCK(dev) (dev->bad.block != UFFS_INVALID_BLOCK)
/** initialize bad block management data structures for uffs device */
void uffs_BadBlockInit(uffs_Device *dev);
/** processing bad block: erase bad block, mark it as 'bad' and put it to bad block list */
void uffs_BadBlockProcess(uffs_Device *dev, TreeNode *node);
/** try to recover data from a new discovered bad block */
void uffs_BadBlockRecover(uffs_Device *dev);
/** put a new block to the bad block waiting list */
void uffs_BadBlockAdd(uffs_Device *dev, int block);
#ifdef __cplusplus
}
#endif
#endif
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs_blockinfo.h
* \brief data structure for operating block information
* \author Ricky Zheng
*/
#ifndef _UFFS_BLOCKINFO_H_
#define _UFFS_BLOCKINFO_H_
#include "uffs/uffs_types.h"
#include "uffs/uffs_public.h"
#include "uffs/uffs_core.h"
#ifdef __cplusplus
extern "C"{
#endif
/**
* \struct uffs_PageSpareSt
* \brief this structure is for storing uffs tag and more.
*/
struct uffs_PageSpareSt {
uffs_Tags tag; //!< page tag
u8 expired:1;
};
/**
* \struct uffs_BlockInfoSt
* \brief block information data. Block info is frequently accessed,
UFFS use a cache system to speed up block info access.
*/
struct uffs_BlockInfoSt {
struct uffs_BlockInfoSt *next;
struct uffs_BlockInfoSt *prev;
u16 block; //!< block number
struct uffs_PageSpareSt *spares; //!< page spare info array
int expired_count; //!< how many pages expired in this block ?
int ref_count; //!< reference counter, it's safe to reuse this block memory when the counter is 0.
};
/** get tag from block info */
#define GET_TAG(bc, page) (&(bc)->spares[page].tag)
/** initialize block info caches */
URET uffs_BlockInfoInitCache(uffs_Device *dev, int maxCachedBlocks);
/** release block info caches */
URET uffs_BlockInfoReleaseCache(uffs_Device *dev);
/** load page spare to block info cache */
URET uffs_BlockInfoLoad(uffs_Device *dev, uffs_BlockInfo *work, int page);
/** find block info cache */
uffs_BlockInfo * uffs_BlockInfoFindInCache(uffs_Device *dev, int block);
/** get block info cache, load it on demand */
uffs_BlockInfo * uffs_BlockInfoGet(uffs_Device *dev, int block);
/** put info cache back to pool, should be called with #uffs_BlockInfoGet in pairs. */
void uffs_BlockInfoPut(uffs_Device *dev, uffs_BlockInfo *p);
/** explicitly expire a block info cache */
void uffs_BlockInfoExpire(uffs_Device *dev, uffs_BlockInfo *p, int page);
/** no one hold any block info cache ? safe to release block info caches */
UBOOL uffs_BlockInfoIsAllFree(uffs_Device *dev);
/** explicitly expire all block info caches */
void uffs_BlockInfoExpireAll(uffs_Device *dev);
#ifdef __cplusplus
}
#endif
#endif
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs_blockinfo.h
* \brief data structure for operating block information
* \author Ricky Zheng
*/
#ifndef _UFFS_BLOCKINFO_H_
#define _UFFS_BLOCKINFO_H_
#include "uffs/uffs_types.h"
#include "uffs/uffs_public.h"
#include "uffs/uffs_core.h"
#ifdef __cplusplus
extern "C"{
#endif
/**
* \struct uffs_PageSpareSt
* \brief this structure is for storing uffs tag and more.
*/
struct uffs_PageSpareSt {
uffs_Tags tag; //!< page tag
u8 expired:1;
};
/**
* \struct uffs_BlockInfoSt
* \brief block information data. Block info is frequently accessed,
UFFS use a cache system to speed up block info access.
*/
struct uffs_BlockInfoSt {
struct uffs_BlockInfoSt *next;
struct uffs_BlockInfoSt *prev;
u16 block; //!< block number
struct uffs_PageSpareSt *spares; //!< page spare info array
int expired_count; //!< how many pages expired in this block ?
int ref_count; //!< reference counter, it's safe to reuse this block memory when the counter is 0.
};
/** get tag from block info */
#define GET_TAG(bc, page) (&(bc)->spares[page].tag)
/** initialize block info caches */
URET uffs_BlockInfoInitCache(uffs_Device *dev, int maxCachedBlocks);
/** release block info caches */
URET uffs_BlockInfoReleaseCache(uffs_Device *dev);
/** load page spare to block info cache */
URET uffs_BlockInfoLoad(uffs_Device *dev, uffs_BlockInfo *work, int page);
/** find block info cache */
uffs_BlockInfo * uffs_BlockInfoFindInCache(uffs_Device *dev, int block);
/** get block info cache, load it on demand */
uffs_BlockInfo * uffs_BlockInfoGet(uffs_Device *dev, int block);
/** put info cache back to pool, should be called with #uffs_BlockInfoGet in pairs. */
void uffs_BlockInfoPut(uffs_Device *dev, uffs_BlockInfo *p);
/** explicitly expire a block info cache */
void uffs_BlockInfoExpire(uffs_Device *dev, uffs_BlockInfo *p, int page);
/** no one hold any block info cache ? safe to release block info caches */
UBOOL uffs_BlockInfoIsAllFree(uffs_Device *dev);
/** explicitly expire all block info caches */
void uffs_BlockInfoExpireAll(uffs_Device *dev);
#ifdef __cplusplus
}
#endif
#endif
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs_buf.h
* \brief page buffers
* \author Ricky Zheng
*/
#ifndef UFFS_BUF_H
#define UFFS_BUF_H
#include "uffs/uffs_types.h"
#include "uffs/uffs_device.h"
#include "uffs/uffs_tree.h"
#include "uffs/uffs_core.h"
#ifdef __cplusplus
extern "C"{
#endif
#define CLONE_BUF_MARK 0xffff //!< set uffs_BufSt::ref_count to this for a 'cloned' buffer
/** for uffs_BufSt::mark */
#define UFFS_BUF_EMPTY 0 //!< buffer is empty
#define UFFS_BUF_VALID 1 //!< buffer is holding valid data
#define UFFS_BUF_DIRTY 2 //!< buffer data is modified
/** for uffs_BufSt::ext_mark */
#define UFFS_BUF_EXT_MARK_TRUNC_TAIL 1 //!<
/** uffs page buffer */
struct uffs_BufSt{
struct uffs_BufSt *next; //!< link to next buffer
struct uffs_BufSt *prev; //!< link to previous buffer
struct uffs_BufSt *next_dirty; //!< link to next dirty buffer
struct uffs_BufSt *prev_dirty; //!< link to previous dirty buffer
u8 type; //!< #UFFS_TYPE_DIR or #UFFS_TYPE_FILE or #UFFS_TYPE_DATA
u16 parent; //!< parent serial
u16 serial; //!< serial
u16 page_id; //!< page id
u16 mark; //!< #UFFS_BUF_EMPTY or #UFFS_BUF_VALID, or #UFFS_BUF_DIRTY ?
u16 ref_count; //!< reference counter, or #CLONE_BUF_MARK for a cloned buffer
u16 data_len; //!< length of data
u16 check_sum; //!< checksum field
u8 * data; //!< data buffer
u8 * header; //!< header
int ext_mark; //!< extension mark.
};
#define uffs_BufIsFree(buf) (buf->ref_count == 0 ? U_TRUE : U_FALSE)
/** initialize page buffers */
URET uffs_BufInit(struct uffs_DeviceSt *dev, int buf_max, int dirty_buf_max);
/** release page buffers */
URET uffs_BufReleaseAll(struct uffs_DeviceSt *dev);
/** find the page buffer, move to link list head if found */
uffs_Buf * uffs_BufGet(struct uffs_DeviceSt *dev, u16 parent, u16 serial, u16 page_id);
uffs_Buf *uffs_BufGetEx(struct uffs_DeviceSt *dev, u8 type, TreeNode *node, u16 page_id);
/** alloc a new page buffer */
uffs_Buf *uffs_BufNew(struct uffs_DeviceSt *dev, u8 type, u16 parent, u16 serial, u16 page_id);
/** find the page buffer (not affect the reference counter) */
uffs_Buf * uffs_BufFind(uffs_Device *dev, u16 parent, u16 serial, u16 page_id);
/** put page buffer back to pool, called in pair with #uffs_Get,#uffs_GetEx or #uffs_BufNew */
URET uffs_BufPut(uffs_Device *dev, uffs_Buf *buf);
/** increase buffer references */
void uffs_BufIncRef(uffs_Buf *buf);
/** decrease buffer references */
void uffs_BufDecRef(uffs_Buf *buf);
/** write data to a page buffer */
URET uffs_BufWrite(struct uffs_DeviceSt *dev, uffs_Buf *buf, void *data, u32 ofs, u32 len);
/** read data from a page buffer */
URET uffs_BufRead(struct uffs_DeviceSt *dev, uffs_Buf *buf, void *data, u32 ofs, u32 len);
/** mark buffer as #UFFS_BUF_EMPTY if ref_count == 0, and discard all data it holds */
void uffs_BufMarkEmpty(uffs_Device *dev, uffs_Buf *buf);
/** if there is no free dirty group slot, flush the most dirty group */
URET uffs_BufFlush(struct uffs_DeviceSt *dev);
URET uffs_BufFlushEx(struct uffs_DeviceSt *dev, UBOOL force_block_recover);
/** flush dirty group */
URET uffs_BufFlushGroup(struct uffs_DeviceSt *dev, u16 parent, u16 serial);
URET uffs_BufFlushGroupEx(struct uffs_DeviceSt *dev, u16 parent, u16 serial, UBOOL force_block_recover);
/** find free dirty group slot */
int uffs_BufFindFreeGroupSlot(struct uffs_DeviceSt *dev);
/** find the dirty group slot */
int uffs_BufFindGroupSlot(struct uffs_DeviceSt *dev, u16 parent, u16 serial);
/** lock dirty group */
URET uffs_BufLockGroup(struct uffs_DeviceSt *dev, int slot);
/** unlock dirty group */
URET uffs_BufUnLockGroup(struct uffs_DeviceSt *dev, int slot);
/** flush most dirty group */
URET uffs_BufFlushMostDirtyGroup(struct uffs_DeviceSt *dev);
/** flush all groups under the same parent number */
URET uffs_BufFlushGroupMatchParent(struct uffs_DeviceSt *dev, u16 parent);
/** flush all page buffers */
URET uffs_BufFlushAll(struct uffs_DeviceSt *dev);
/** no one holding any page buffer ? safe to release page buffers */
UBOOL uffs_BufIsAllFree(struct uffs_DeviceSt *dev);
/** are all page buffer marked with #UFFS_BUF_EMPTY ? */
UBOOL uffs_BufIsAllEmpty(struct uffs_DeviceSt *dev);
/** mark all page buffer as #UFFS_BUF_EMPTY */
URET uffs_BufSetAllEmpty(struct uffs_DeviceSt *dev);
/** clone a page buffer */
uffs_Buf * uffs_BufClone(struct uffs_DeviceSt *dev, uffs_Buf *buf);
/** release a cloned page buffer, call in pair with #uffs_BufClone */
URET uffs_BufFreeClone(uffs_Device *dev, uffs_Buf *buf);
/** load physical storage data to page buffer */
URET uffs_BufLoadPhyData(uffs_Device *dev, uffs_Buf *buf, u32 block, u32 page);
/** load physical storage data to page buffer withouth checking ECC */
URET uffs_LoadPhyDataToBufEccUnCare(uffs_Device *dev, uffs_Buf *buf, u32 block, u32 page);
/** showing page buffers info, for debug only */
void uffs_BufInspect(uffs_Device *dev);
#ifdef __cplusplus
}
#endif
#endif
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs_buf.h
* \brief page buffers
* \author Ricky Zheng
*/
#ifndef UFFS_BUF_H
#define UFFS_BUF_H
#include "uffs/uffs_types.h"
#include "uffs/uffs_device.h"
#include "uffs/uffs_tree.h"
#include "uffs/uffs_core.h"
#ifdef __cplusplus
extern "C"{
#endif
#define CLONE_BUF_MARK 0xffff //!< set uffs_BufSt::ref_count to this for a 'cloned' buffer
/** for uffs_BufSt::mark */
#define UFFS_BUF_EMPTY 0 //!< buffer is empty
#define UFFS_BUF_VALID 1 //!< buffer is holding valid data
#define UFFS_BUF_DIRTY 2 //!< buffer data is modified
/** for uffs_BufSt::ext_mark */
#define UFFS_BUF_EXT_MARK_TRUNC_TAIL 1 //!<
/** uffs page buffer */
struct uffs_BufSt{
struct uffs_BufSt *next; //!< link to next buffer
struct uffs_BufSt *prev; //!< link to previous buffer
struct uffs_BufSt *next_dirty; //!< link to next dirty buffer
struct uffs_BufSt *prev_dirty; //!< link to previous dirty buffer
u8 type; //!< #UFFS_TYPE_DIR or #UFFS_TYPE_FILE or #UFFS_TYPE_DATA
u16 parent; //!< parent serial
u16 serial; //!< serial
u16 page_id; //!< page id
u16 mark; //!< #UFFS_BUF_EMPTY or #UFFS_BUF_VALID, or #UFFS_BUF_DIRTY ?
u16 ref_count; //!< reference counter, or #CLONE_BUF_MARK for a cloned buffer
u16 data_len; //!< length of data
u16 check_sum; //!< checksum field
u8 * data; //!< data buffer
u8 * header; //!< header
int ext_mark; //!< extension mark.
};
#define uffs_BufIsFree(buf) (buf->ref_count == 0 ? U_TRUE : U_FALSE)
/** initialize page buffers */
URET uffs_BufInit(struct uffs_DeviceSt *dev, int buf_max, int dirty_buf_max);
/** release page buffers */
URET uffs_BufReleaseAll(struct uffs_DeviceSt *dev);
/** find the page buffer, move to link list head if found */
uffs_Buf * uffs_BufGet(struct uffs_DeviceSt *dev, u16 parent, u16 serial, u16 page_id);
uffs_Buf *uffs_BufGetEx(struct uffs_DeviceSt *dev, u8 type, TreeNode *node, u16 page_id);
/** alloc a new page buffer */
uffs_Buf *uffs_BufNew(struct uffs_DeviceSt *dev, u8 type, u16 parent, u16 serial, u16 page_id);
/** find the page buffer (not affect the reference counter) */
uffs_Buf * uffs_BufFind(uffs_Device *dev, u16 parent, u16 serial, u16 page_id);
/** put page buffer back to pool, called in pair with #uffs_Get,#uffs_GetEx or #uffs_BufNew */
URET uffs_BufPut(uffs_Device *dev, uffs_Buf *buf);
/** increase buffer references */
void uffs_BufIncRef(uffs_Buf *buf);
/** decrease buffer references */
void uffs_BufDecRef(uffs_Buf *buf);
/** write data to a page buffer */
URET uffs_BufWrite(struct uffs_DeviceSt *dev, uffs_Buf *buf, void *data, u32 ofs, u32 len);
/** read data from a page buffer */
URET uffs_BufRead(struct uffs_DeviceSt *dev, uffs_Buf *buf, void *data, u32 ofs, u32 len);
/** mark buffer as #UFFS_BUF_EMPTY if ref_count == 0, and discard all data it holds */
void uffs_BufMarkEmpty(uffs_Device *dev, uffs_Buf *buf);
/** if there is no free dirty group slot, flush the most dirty group */
URET uffs_BufFlush(struct uffs_DeviceSt *dev);
URET uffs_BufFlushEx(struct uffs_DeviceSt *dev, UBOOL force_block_recover);
/** flush dirty group */
URET uffs_BufFlushGroup(struct uffs_DeviceSt *dev, u16 parent, u16 serial);
URET uffs_BufFlushGroupEx(struct uffs_DeviceSt *dev, u16 parent, u16 serial, UBOOL force_block_recover);
/** find free dirty group slot */
int uffs_BufFindFreeGroupSlot(struct uffs_DeviceSt *dev);
/** find the dirty group slot */
int uffs_BufFindGroupSlot(struct uffs_DeviceSt *dev, u16 parent, u16 serial);
/** lock dirty group */
URET uffs_BufLockGroup(struct uffs_DeviceSt *dev, int slot);
/** unlock dirty group */
URET uffs_BufUnLockGroup(struct uffs_DeviceSt *dev, int slot);
/** flush most dirty group */
URET uffs_BufFlushMostDirtyGroup(struct uffs_DeviceSt *dev);
/** flush all groups under the same parent number */
URET uffs_BufFlushGroupMatchParent(struct uffs_DeviceSt *dev, u16 parent);
/** flush all page buffers */
URET uffs_BufFlushAll(struct uffs_DeviceSt *dev);
/** no one holding any page buffer ? safe to release page buffers */
UBOOL uffs_BufIsAllFree(struct uffs_DeviceSt *dev);
/** are all page buffer marked with #UFFS_BUF_EMPTY ? */
UBOOL uffs_BufIsAllEmpty(struct uffs_DeviceSt *dev);
/** mark all page buffer as #UFFS_BUF_EMPTY */
URET uffs_BufSetAllEmpty(struct uffs_DeviceSt *dev);
/** clone a page buffer */
uffs_Buf * uffs_BufClone(struct uffs_DeviceSt *dev, uffs_Buf *buf);
/** release a cloned page buffer, call in pair with #uffs_BufClone */
URET uffs_BufFreeClone(uffs_Device *dev, uffs_Buf *buf);
/** load physical storage data to page buffer */
URET uffs_BufLoadPhyData(uffs_Device *dev, uffs_Buf *buf, u32 block, u32 page);
/** load physical storage data to page buffer withouth checking ECC */
URET uffs_LoadPhyDataToBufEccUnCare(uffs_Device *dev, uffs_Buf *buf, u32 block, u32 page);
/** showing page buffers info, for debug only */
void uffs_BufInspect(uffs_Device *dev);
#ifdef __cplusplus
}
#endif
#endif
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs_config.h
* \brief basic configuration of uffs
* \author Ricky Zheng
*/
#ifndef _UFFS_CONFIG_H_
#define _UFFS_CONFIG_H_
/**
* \def UFFS_MAX_PAGE_SIZE
* \note maximum page size UFFS support
*/
#define UFFS_MAX_PAGE_SIZE 2048
/**
* \def UFFS_MAX_SPARE_SIZE
*/
#define UFFS_MAX_SPARE_SIZE ((UFFS_MAX_PAGE_SIZE / 256) * 8)
/**
* \def MAX_CACHED_BLOCK_INFO
* \note uffs cache the block info for opened directories and files,
* a practical value is 5 ~ MAX_OBJECT_HANDLE
*/
#define MAX_CACHED_BLOCK_INFO 10
/**
* \def MAX_PAGE_BUFFERS
* \note the bigger value will bring better read/write performance.
* but few writing performance will be improved when this
* value is become larger than 'max pages per block'
*/
#define MAX_PAGE_BUFFERS 10
/**
* \def CLONE_BUFFER_THRESHOLD
* \note reserve buffers for clone. 1 or 2 should be enough.
*/
#define CLONE_BUFFERS_THRESHOLD 2
/**
* \def MAX_SPARE_BUFFERS
* \note spare buffers are used for lower level flash operations, 5 should be enough.
*/
#define MAX_SPARE_BUFFERS 5
/**
* \def MAX_DIRTY_PAGES_IN_A_BLOCK
* \note this value should be between '2' and the lesser of 'max pages per block' and (MAX_PAGE_BUFFERS - CLONE_BUFFERS_THRESHOLD - 1).
* the smaller the value the frequently the buffer will be flushed.
*/
#define MAX_DIRTY_PAGES_IN_A_BLOCK 7
/**
* \def MAX_DIRTY_BUF_GROUPS
*/
#define MAX_DIRTY_BUF_GROUPS 3
/**
* \def CONFIG_USE_STATIC_MEMORY_ALLOCATOR
* \note uffs will use static memory allocator if this is defined.
* to use static memory allocator, you need to provide memory
* buffer when creating uffs_Device.
*
* use UFFS_STATIC_BUFF_SIZE() to calculate memory buffer size.
*/
#define CONFIG_USE_STATIC_MEMORY_ALLOCATOR 0
/**
* \def CONFIG_USE_NATIVE_MEMORY_ALLOCATOR
* \note the native memory allocator should only be used for
* tracking memory leak bugs or tracking memory consuming.
* In your final product, you either disable the native memory
* allocator or use the system heap as the memory pool for the
* native memory allocator.
*/
#define CONFIG_USE_NATIVE_MEMORY_ALLOCATOR 0
/**
* \def CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR
* \note using system platform's 'malloc' and 'free'.
*/
#define CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR 1
/**
* \def CONFIG_FLUSH_BUF_AFTER_WRITE
* \note UFFS will write all data directly into flash in
* each 'write' call if you enable this option.
* (which means lesser data lost when power failue but
* pooer writing performance).
* It's not recommented to open this define for normal applications.
*/
//#define CONFIG_FLUSH_BUF_AFTER_WRITE
/**
* \def CONFIG_TREE_NODE_USE_DOUBLE_LINK
* \note: enable double link tree node will speed up insert/delete operation,
*/
#define CONFIG_TREE_NODE_USE_DOUBLE_LINK
/**
* \def MAX_OBJECT_HANDLE
* maximum number of object handle
*/
#define MAX_OBJECT_HANDLE 10
/**
* \def MAX_DIR_HANDLE
* maximum number of uffs_DIR
*/
#define MAX_DIR_HANDLE 5
/**
* \def MINIMUN_ERASED_BLOCK
* UFFS will not allow appending or creating new files when the free/erased block
* is lower then MINIMUN_ERASED_BLOCK.
*/
#define MINIMUN_ERASED_BLOCK 2
/**
* \def CONFIG_CHANGE_MODIFY_TIME
* \note If defined, closing a file which is opened for writing/appending will
* update the file's modify time as well. Disable this feature will save a
* lot of writing activities if you frequently open files for write and close it.
*/
//#define CONFIG_CHANGE_MODIFY_TIME
/**
* \def CONFIG_ENABLE_BAD_BLOCK_VERIFY
* \note allow erase and verify block marked as 'bad' when format UFFS partition.
* it's not recommented for most NAND flash.
*/
#define CONFIG_ENABLE_BAD_BLOCK_VERIFY
/**
* \def CONFIG_ERASE_BLOCK_BEFORE_MARK_BAD
* \note erase block again before mark bad block
*/
#define CONFIG_ERASE_BLOCK_BEFORE_MARK_BAD
/**
* \def CONFIG_PAGE_WRITE_VERIFY
* \note verify page data after write, for extra safe data storage.
*/
#define CONFIG_PAGE_WRITE_VERIFY
/**
* \def CONFIG_BAD_BLOCK_POLICY_STRICT
* \note If this is enabled, UFFS will report the block as 'bad' if any bit-flips found;
* otherwise, UFFS report bad block only when ECC failed or reported by low level flash driver.
*
* \note Enable this will ensure your data always be stored on completly good blocks.
*/
#define CONFIG_BAD_BLOCK_POLICY_STRICT
/** micros for calculating buffer sizes */
/**
* \def UFFS_BLOCK_INFO_BUFFER_SIZE
* \brief calculate memory bytes for block info caches
*/
#define UFFS_BLOCK_INFO_BUFFER_SIZE(n_pages_per_block) \
( \
( \
sizeof(uffs_BlockInfo) + \
sizeof(uffs_PageSpare) * n_pages_per_block \
) * MAX_CACHED_BLOCK_INFO \
)
/**
* \def UFFS_PAGE_BUFFER_SIZE
* \brief calculate memory bytes for page buffers
*/
#define UFFS_PAGE_BUFFER_SIZE(n_page_size) \
( \
( \
sizeof(uffs_Buf) + n_page_size \
) * MAX_PAGE_BUFFERS \
)
/**
* \def UFFS_TREE_BUFFER_SIZE
* \brief calculate memory bytes for tree nodes
*/
#define UFFS_TREE_BUFFER_SIZE(n_blocks) (sizeof(TreeNode) * n_blocks)
#define UFFS_SPARE_BUFFER_SIZE (MAX_SPARE_BUFFERS * UFFS_MAX_SPARE_SIZE)
/**
* \def UFFS_STATIC_BUFF_SIZE
* \brief calculate total memory usage of uffs system
*/
#define UFFS_STATIC_BUFF_SIZE(n_pages_per_block, n_page_size, n_blocks) \
( \
UFFS_BLOCK_INFO_BUFFER_SIZE(n_pages_per_block) + \
UFFS_PAGE_BUFFER_SIZE(n_page_size) + \
UFFS_TREE_BUFFER_SIZE(n_blocks) + \
UFFS_SPARE_BUFFER_SIZE \
)
/* config check */
#if (MAX_PAGE_BUFFERS - CLONE_BUFFERS_THRESHOLD) < 3
#error "MAX_PAGE_BUFFERS is too small"
#endif
#if (MAX_DIRTY_PAGES_IN_A_BLOCK < 2)
#error "MAX_DIRTY_PAGES_IN_A_BLOCK should >= 2"
#endif
#if (MAX_PAGE_BUFFERS - CLONE_BUFFERS_THRESHOLD - 1 < MAX_DIRTY_PAGES_IN_A_BLOCK)
#error "MAX_DIRTY_PAGES_IN_A_BLOCK should < (MAX_PAGE_BUFFERS - CLONE_BUFFERS_THRESHOLD)"
#endif
#if defined(CONFIG_PAGE_WRITE_VERIFY) && (CLONE_BUFFERS_THRESHOLD < 2)
#error "CLONE_BUFFERS_THRESHOLD should >= 2 when CONFIG_PAGE_WRITE_VERIFY is enabled."
#endif
#if CONFIG_USE_STATIC_MEMORY_ALLOCATOR + CONFIG_USE_NATIVE_MEMORY_ALLOCATOR + CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR > 1
#error "Please enable ONLY one memory allocator"
#endif
#if CONFIG_USE_STATIC_MEMORY_ALLOCATOR + CONFIG_USE_NATIVE_MEMORY_ALLOCATOR + CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR == 0
#error "Please enable ONE of memory allocators"
#endif
#ifdef WIN32
# pragma warning(disable : 4996)
#endif
#endif
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs_config.h
* \brief basic configuration of uffs
* \author Ricky Zheng
*/
#ifndef _UFFS_CONFIG_H_
#define _UFFS_CONFIG_H_
/**
* \def UFFS_MAX_PAGE_SIZE
* \note maximum page size UFFS support
*/
#define UFFS_MAX_PAGE_SIZE 2048
/**
* \def UFFS_MAX_SPARE_SIZE
*/
#define UFFS_MAX_SPARE_SIZE ((UFFS_MAX_PAGE_SIZE / 256) * 8)
/**
* \def MAX_CACHED_BLOCK_INFO
* \note uffs cache the block info for opened directories and files,
* a practical value is 5 ~ MAX_OBJECT_HANDLE
*/
#define MAX_CACHED_BLOCK_INFO 10
/**
* \def MAX_PAGE_BUFFERS
* \note the bigger value will bring better read/write performance.
* but few writing performance will be improved when this
* value is become larger than 'max pages per block'
*/
#define MAX_PAGE_BUFFERS 10
/**
* \def CLONE_BUFFER_THRESHOLD
* \note reserve buffers for clone. 1 or 2 should be enough.
*/
#define CLONE_BUFFERS_THRESHOLD 2
/**
* \def MAX_SPARE_BUFFERS
* \note spare buffers are used for lower level flash operations, 5 should be enough.
*/
#define MAX_SPARE_BUFFERS 5
/**
* \def MAX_DIRTY_PAGES_IN_A_BLOCK
* \note this value should be between '2' and the lesser of 'max pages per block' and (MAX_PAGE_BUFFERS - CLONE_BUFFERS_THRESHOLD - 1).
* the smaller the value the frequently the buffer will be flushed.
*/
#define MAX_DIRTY_PAGES_IN_A_BLOCK 7
/**
* \def MAX_DIRTY_BUF_GROUPS
*/
#define MAX_DIRTY_BUF_GROUPS 3
/**
* \def CONFIG_USE_STATIC_MEMORY_ALLOCATOR
* \note uffs will use static memory allocator if this is defined.
* to use static memory allocator, you need to provide memory
* buffer when creating uffs_Device.
*
* use UFFS_STATIC_BUFF_SIZE() to calculate memory buffer size.
*/
#define CONFIG_USE_STATIC_MEMORY_ALLOCATOR 0
/**
* \def CONFIG_USE_NATIVE_MEMORY_ALLOCATOR
* \note the native memory allocator should only be used for
* tracking memory leak bugs or tracking memory consuming.
* In your final product, you either disable the native memory
* allocator or use the system heap as the memory pool for the
* native memory allocator.
*/
#define CONFIG_USE_NATIVE_MEMORY_ALLOCATOR 0
/**
* \def CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR
* \note using system platform's 'malloc' and 'free'.
*/
#define CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR 1
/**
* \def CONFIG_FLUSH_BUF_AFTER_WRITE
* \note UFFS will write all data directly into flash in
* each 'write' call if you enable this option.
* (which means lesser data lost when power failue but
* pooer writing performance).
* It's not recommented to open this define for normal applications.
*/
//#define CONFIG_FLUSH_BUF_AFTER_WRITE
/**
* \def CONFIG_TREE_NODE_USE_DOUBLE_LINK
* \note: enable double link tree node will speed up insert/delete operation,
*/
#define CONFIG_TREE_NODE_USE_DOUBLE_LINK
/**
* \def MAX_OBJECT_HANDLE
* maximum number of object handle
*/
#define MAX_OBJECT_HANDLE 10
/**
* \def MAX_DIR_HANDLE
* maximum number of uffs_DIR
*/
#define MAX_DIR_HANDLE 5
/**
* \def MINIMUN_ERASED_BLOCK
* UFFS will not allow appending or creating new files when the free/erased block
* is lower then MINIMUN_ERASED_BLOCK.
*/
#define MINIMUN_ERASED_BLOCK 2
/**
* \def CONFIG_CHANGE_MODIFY_TIME
* \note If defined, closing a file which is opened for writing/appending will
* update the file's modify time as well. Disable this feature will save a
* lot of writing activities if you frequently open files for write and close it.
*/
//#define CONFIG_CHANGE_MODIFY_TIME
/**
* \def CONFIG_ENABLE_BAD_BLOCK_VERIFY
* \note allow erase and verify block marked as 'bad' when format UFFS partition.
* it's not recommented for most NAND flash.
*/
#define CONFIG_ENABLE_BAD_BLOCK_VERIFY
/**
* \def CONFIG_ERASE_BLOCK_BEFORE_MARK_BAD
* \note erase block again before mark bad block
*/
#define CONFIG_ERASE_BLOCK_BEFORE_MARK_BAD
/**
* \def CONFIG_PAGE_WRITE_VERIFY
* \note verify page data after write, for extra safe data storage.
*/
#define CONFIG_PAGE_WRITE_VERIFY
/**
* \def CONFIG_BAD_BLOCK_POLICY_STRICT
* \note If this is enabled, UFFS will report the block as 'bad' if any bit-flips found;
* otherwise, UFFS report bad block only when ECC failed or reported by low level flash driver.
*
* \note Enable this will ensure your data always be stored on completly good blocks.
*/
//#define CONFIG_BAD_BLOCK_POLICY_STRICT
/** micros for calculating buffer sizes */
/**
* \def UFFS_BLOCK_INFO_BUFFER_SIZE
* \brief calculate memory bytes for block info caches
*/
#define UFFS_BLOCK_INFO_BUFFER_SIZE(n_pages_per_block) \
( \
( \
sizeof(uffs_BlockInfo) + \
sizeof(uffs_PageSpare) * n_pages_per_block \
) * MAX_CACHED_BLOCK_INFO \
)
/**
* \def UFFS_PAGE_BUFFER_SIZE
* \brief calculate memory bytes for page buffers
*/
#define UFFS_PAGE_BUFFER_SIZE(n_page_size) \
( \
( \
sizeof(uffs_Buf) + n_page_size \
) * MAX_PAGE_BUFFERS \
)
/**
* \def UFFS_TREE_BUFFER_SIZE
* \brief calculate memory bytes for tree nodes
*/
#define UFFS_TREE_BUFFER_SIZE(n_blocks) (sizeof(TreeNode) * n_blocks)
#define UFFS_SPARE_BUFFER_SIZE (MAX_SPARE_BUFFERS * UFFS_MAX_SPARE_SIZE)
/**
* \def UFFS_STATIC_BUFF_SIZE
* \brief calculate total memory usage of uffs system
*/
#define UFFS_STATIC_BUFF_SIZE(n_pages_per_block, n_page_size, n_blocks) \
( \
UFFS_BLOCK_INFO_BUFFER_SIZE(n_pages_per_block) + \
UFFS_PAGE_BUFFER_SIZE(n_page_size) + \
UFFS_TREE_BUFFER_SIZE(n_blocks) + \
UFFS_SPARE_BUFFER_SIZE \
)
/* config check */
#if (MAX_PAGE_BUFFERS - CLONE_BUFFERS_THRESHOLD) < 3
#error "MAX_PAGE_BUFFERS is too small"
#endif
#if (MAX_DIRTY_PAGES_IN_A_BLOCK < 2)
#error "MAX_DIRTY_PAGES_IN_A_BLOCK should >= 2"
#endif
#if (MAX_PAGE_BUFFERS - CLONE_BUFFERS_THRESHOLD - 1 < MAX_DIRTY_PAGES_IN_A_BLOCK)
#error "MAX_DIRTY_PAGES_IN_A_BLOCK should < (MAX_PAGE_BUFFERS - CLONE_BUFFERS_THRESHOLD)"
#endif
#if defined(CONFIG_PAGE_WRITE_VERIFY) && (CLONE_BUFFERS_THRESHOLD < 2)
#error "CLONE_BUFFERS_THRESHOLD should >= 2 when CONFIG_PAGE_WRITE_VERIFY is enabled."
#endif
#if CONFIG_USE_STATIC_MEMORY_ALLOCATOR + CONFIG_USE_NATIVE_MEMORY_ALLOCATOR + CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR > 1
#error "Please enable ONLY one memory allocator"
#endif
#if CONFIG_USE_STATIC_MEMORY_ALLOCATOR + CONFIG_USE_NATIVE_MEMORY_ALLOCATOR + CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR == 0
#error "Please enable ONE of memory allocators"
#endif
#ifdef WIN32
# pragma warning(disable : 4996)
#endif
#endif
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
#ifndef _UFFS_CORE_H_
#define _UFFS_CORE_H_
#ifdef __cplusplus
extern "C"{
#endif
/** \typedef uffs_Device */
typedef struct uffs_DeviceSt uffs_Device;
/** \typedef uffs_FlashOps */
typedef struct uffs_FlashOpsSt uffs_FlashOps;
typedef struct uffs_BlockInfoSt uffs_BlockInfo;
typedef struct uffs_PageSpareSt uffs_PageSpare;
typedef struct uffs_TagsSt uffs_Tags; //!< UFFS page tags
typedef struct uffs_TagStoreSt uffs_TagStore; //!< UFFS page tags physical store structure
typedef struct uffs_BufSt uffs_Buf;
#ifdef __cplusplus
}
#endif
#endif
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
#ifndef _UFFS_CORE_H_
#define _UFFS_CORE_H_
#ifdef __cplusplus
extern "C"{
#endif
/** \typedef uffs_Device */
typedef struct uffs_DeviceSt uffs_Device;
/** \typedef uffs_FlashOps */
typedef struct uffs_FlashOpsSt uffs_FlashOps;
typedef struct uffs_BlockInfoSt uffs_BlockInfo;
typedef struct uffs_PageSpareSt uffs_PageSpare;
typedef struct uffs_TagsSt uffs_Tags; //!< UFFS page tags
typedef struct uffs_TagStoreSt uffs_TagStore; //!< UFFS page tags physical store structure
typedef struct uffs_BufSt uffs_Buf;
#ifdef __cplusplus
}
#endif
#endif
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs_device.h
* \brief uffs device structures definition
* \author Ricky Zheng
*/
#ifndef UFFS_DEVICE_H
#define UFFS_DEVICE_H
#include "uffs/uffs_types.h"
#include "uffs/uffs_config.h"
#include "uffs/uffs_buf.h"
#include "uffs/uffs_blockinfo.h"
#include "uffs/uffs_pool.h"
#include "uffs/uffs_tree.h"
#include "uffs/uffs_mem.h"
#include "uffs/uffs_core.h"
#include "uffs/uffs_flash.h"
#ifdef __cplusplus
extern "C"{
#endif
/**
* \struct uffs_BlockInfoCacheSt
* \brief block information structure, used to manager block information caches
*/
struct uffs_BlockInfoCacheSt {
uffs_BlockInfo *head; //!< buffer head of block info(spares)
uffs_BlockInfo *tail; //!< buffer tail
void *mem_pool; //!< internal memory pool, used for release whole buffer
};
/**
* \struct uffs_PartitionSt
* \brief partition basic information
*/
struct uffs_PartitionSt {
u16 start; //!< start block number of partition
u16 end; //!< end block number of partiton
};
/**
* \struct uffs_LockSt
* \brief lock stuffs
*/
struct uffs_LockSt {
int sem;
int task_id;
int counter;
};
/**
* \struct uffs_DirtyGroupSt
* \brief manager dirty page buffers
*/
struct uffs_DirtyGroupSt {
int count; //!< dirty buffers count
int lock; //!< dirty group lock (0: unlocked, >0: locked)
uffs_Buf *dirty; //!< dirty buffer list
};
/**
* \struct uffs_PageBufDescSt
* \brief uffs page buffers descriptor
*/
struct uffs_PageBufDescSt {
uffs_Buf *head; //!< head of buffers
uffs_Buf *tail; //!< tail of buffers
struct uffs_DirtyGroupSt dirtyGroup[MAX_DIRTY_BUF_GROUPS]; //!< dirty buffer groups
int buf_max; //!< maximum buffers
int dirty_buf_max; //!< maximum dirty buffer allowed
void *pool; //!< memory pool for buffers
};
/**
* \struct uffs_PageCommInfoSt
* \brief common data for device, should be initialized at early
* \note it is possible that pg_size is smaller than physical page size, but normally they are the same.
* \note page data layout: [HEADER] + [DATA]
*/
struct uffs_PageCommInfoSt {
u16 pg_data_size; //!< page data size
u16 header_size; //!< header size
u16 pg_size; //!< page size
};
/**
* \struct uffs_NewBadBlockSt
* \brief holding new discovered bad block
*/
struct uffs_NewBadBlockSt {
u16 block; //!< bad block, FIX ME to process more than one bad block
};
/**
* \struct uffs_FlashStatSt
* \typedef uffs_FlashStat
* \brief statistic data of flash read/write/erase activities
*/
typedef struct uffs_FlashStatSt {
int block_erase_count;
int page_write_count;
int page_read_count;
int page_header_read_count;
int spare_write_count;
int spare_read_count;
} uffs_FlashStat;
/**
* \struct uffs_DeviceSt
* \brief The core data structure of UFFS, all information needed by manipulate UFFS object
* \note one partition corresponding one uffs device.
*/
struct uffs_DeviceSt {
URET (*Init)(uffs_Device *dev); //!< low level initialization
URET (*Release)(uffs_Device *dev); //!< low level release
void *_private; //!< private data for device
struct uffs_StorageAttrSt *attr; //!< storage attribute
struct uffs_PartitionSt par; //!< partition information
struct uffs_FlashOpsSt *ops; //!< flash operations
struct uffs_BlockInfoCacheSt bc; //!< block info cache
struct uffs_LockSt lock; //!< lock data structure
struct uffs_PageBufDescSt buf; //!< page buffers
struct uffs_PageCommInfoSt com; //!< common information
struct uffs_TreeSt tree; //!< tree list of block
struct uffs_NewBadBlockSt bad; //!< new discovered bad block
struct uffs_FlashStatSt st; //!< statistic (counters)
struct uffs_memAllocatorSt mem; //!< uffs native memory allocator
u32 ref_count; //!< device reference count
int dev_num; //!< device number (partition number)
};
/** create the lock for uffs device */
URET uffs_DeviceInitLock(uffs_Device *dev);
/** delete the lock of uffs device */
URET uffs_DeviceReleaseLock(uffs_Device *dev);
/** lock uffs device */
URET uffs_DeviceLock(uffs_Device *dev);
/** unlock uffs device */
URET uffs_DeviceUnLock(uffs_Device *dev);
#ifdef __cplusplus
}
#endif
#endif
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs_device.h
* \brief uffs device structures definition
* \author Ricky Zheng
*/
#ifndef UFFS_DEVICE_H
#define UFFS_DEVICE_H
#include "uffs/uffs_types.h"
#include "uffs/uffs_config.h"
#include "uffs/uffs_buf.h"
#include "uffs/uffs_blockinfo.h"
#include "uffs/uffs_pool.h"
#include "uffs/uffs_tree.h"
#include "uffs/uffs_mem.h"
#include "uffs/uffs_core.h"
#include "uffs/uffs_flash.h"
#ifdef __cplusplus
extern "C"{
#endif
/**
* \struct uffs_BlockInfoCacheSt
* \brief block information structure, used to manager block information caches
*/
struct uffs_BlockInfoCacheSt {
uffs_BlockInfo *head; //!< buffer head of block info(spares)
uffs_BlockInfo *tail; //!< buffer tail
void *mem_pool; //!< internal memory pool, used for release whole buffer
};
/**
* \struct uffs_PartitionSt
* \brief partition basic information
*/
struct uffs_PartitionSt {
u16 start; //!< start block number of partition
u16 end; //!< end block number of partiton
};
/**
* \struct uffs_LockSt
* \brief lock stuffs
*/
struct uffs_LockSt {
int sem;
int task_id;
int counter;
};
/**
* \struct uffs_DirtyGroupSt
* \brief manager dirty page buffers
*/
struct uffs_DirtyGroupSt {
int count; //!< dirty buffers count
int lock; //!< dirty group lock (0: unlocked, >0: locked)
uffs_Buf *dirty; //!< dirty buffer list
};
/**
* \struct uffs_PageBufDescSt
* \brief uffs page buffers descriptor
*/
struct uffs_PageBufDescSt {
uffs_Buf *head; //!< head of buffers
uffs_Buf *tail; //!< tail of buffers
struct uffs_DirtyGroupSt dirtyGroup[MAX_DIRTY_BUF_GROUPS]; //!< dirty buffer groups
int buf_max; //!< maximum buffers
int dirty_buf_max; //!< maximum dirty buffer allowed
void *pool; //!< memory pool for buffers
};
/**
* \struct uffs_PageCommInfoSt
* \brief common data for device, should be initialized at early
* \note it is possible that pg_size is smaller than physical page size, but normally they are the same.
* \note page data layout: [HEADER] + [DATA]
*/
struct uffs_PageCommInfoSt {
u16 pg_data_size; //!< page data size
u16 header_size; //!< header size
u16 pg_size; //!< page size
};
/**
* \struct uffs_NewBadBlockSt
* \brief holding new discovered bad block
*/
struct uffs_NewBadBlockSt {
u16 block; //!< bad block, FIX ME to process more than one bad block
};
/**
* \struct uffs_FlashStatSt
* \typedef uffs_FlashStat
* \brief statistic data of flash read/write/erase activities
*/
typedef struct uffs_FlashStatSt {
int block_erase_count;
int page_write_count;
int page_read_count;
int page_header_read_count;
int spare_write_count;
int spare_read_count;
} uffs_FlashStat;
/**
* \struct uffs_DeviceSt
* \brief The core data structure of UFFS, all information needed by manipulate UFFS object
* \note one partition corresponding one uffs device.
*/
struct uffs_DeviceSt {
URET (*Init)(uffs_Device *dev); //!< low level initialization
URET (*Release)(uffs_Device *dev); //!< low level release
void *_private; //!< private data for device
struct uffs_StorageAttrSt *attr; //!< storage attribute
struct uffs_PartitionSt par; //!< partition information
struct uffs_FlashOpsSt *ops; //!< flash operations
struct uffs_BlockInfoCacheSt bc; //!< block info cache
struct uffs_LockSt lock; //!< lock data structure
struct uffs_PageBufDescSt buf; //!< page buffers
struct uffs_PageCommInfoSt com; //!< common information
struct uffs_TreeSt tree; //!< tree list of block
struct uffs_NewBadBlockSt bad; //!< new discovered bad block
struct uffs_FlashStatSt st; //!< statistic (counters)
struct uffs_memAllocatorSt mem; //!< uffs native memory allocator
u32 ref_count; //!< device reference count
int dev_num; //!< device number (partition number)
};
/** create the lock for uffs device */
URET uffs_DeviceInitLock(uffs_Device *dev);
/** delete the lock of uffs device */
URET uffs_DeviceReleaseLock(uffs_Device *dev);
/** lock uffs device */
URET uffs_DeviceLock(uffs_Device *dev);
/** unlock uffs device */
URET uffs_DeviceUnLock(uffs_Device *dev);
#ifdef __cplusplus
}
#endif
#endif
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs_ecc.h
* \brief file handle operations
* \author Ricky Zheng, created 8th Jun, 2005
*/
#ifndef _UFFS_ECC_H_
#define _UFFS_ECC_H_
#include <string.h>
#include "uffs/uffs_fs.h"
#include "uffs/uffs_config.h"
#include "uffs/uffs_core.h"
#ifdef __cplusplus
extern "C"{
#endif
#define MAX_ECC_LENGTH 24 //!< 2K page ecc length is 24 bytes.
/**
* calculate ECC
* \return length of generated ECC. (3 bytes ECC per 256 data)
*/
int uffs_EccMake(void *data, int data_len, void *ecc);
/**
* correct data by ECC.
*
* return: 0 -- no error
* -1 -- can not be corrected
* >0 -- how many bits are corrected
*/
int uffs_EccCorrect(void *data, int data_len, void *read_ecc, const void *test_ecc);
/**
* generate 12 bit ecc for maximum 8 bytes data
*/
u16 uffs_EccMake8(void *data, int data_len);
/**
* correct maximum 8 bytes data from 12 bits ECC
*
* return: 0 -- no error
* -1 -- can not be corrected
* >0 -- how many bits are corrected
*/
int uffs_EccCorrect8(void *data, u16 read_ecc, u16 test_ecc, int errtop);
#ifdef __cplusplus
}
#endif
#endif
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs_ecc.h
* \brief file handle operations
* \author Ricky Zheng, created 8th Jun, 2005
*/
#ifndef _UFFS_ECC_H_
#define _UFFS_ECC_H_
#include <string.h>
#include "uffs/uffs_fs.h"
#include "uffs/uffs_config.h"
#include "uffs/uffs_core.h"
#ifdef __cplusplus
extern "C"{
#endif
#define MAX_ECC_LENGTH 24 //!< 2K page ecc length is 24 bytes.
/**
* calculate ECC
* \return length of generated ECC. (3 bytes ECC per 256 data)
*/
int uffs_EccMake(void *data, int data_len, void *ecc);
/**
* correct data by ECC.
*
* return: 0 -- no error
* -1 -- can not be corrected
* >0 -- how many bits are corrected
*/
int uffs_EccCorrect(void *data, int data_len, void *read_ecc, const void *test_ecc);
/**
* generate 12 bit ecc for maximum 8 bytes data
*/
u16 uffs_EccMake8(void *data, int data_len);
/**
* correct maximum 8 bytes data from 12 bits ECC
*
* return: 0 -- no error
* -1 -- can not be corrected
* >0 -- how many bits are corrected
*/
int uffs_EccCorrect8(void *data, u16 read_ecc, u16 test_ecc, int errtop);
#ifdef __cplusplus
}
#endif
#endif
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs_fd.h
* \brief PISIX like file operations
* \author Ricky Zheng, created 8th Jun, 2005
*/
#include "uffs/uffs_config.h"
#include "uffs/uffs_core.h"
#include "uffs/uffs_fs.h"
#include "uffs/uffs.h"
#include "uffs/uffs_find.h"
#include <string.h>
/**
* \brief definitions for uffs_stat::st_mode
*/
#define US_IFMT 0xF000 /* file type make */
#define US_IFREG 0x8000 /* regular */
#define US_IFLNK 0xA000 /* symbolic link */
#define US_IFDIR 0x4000 /* directory */
#define US_IREAD 00400 /* read permission */
#define US_IWRITE 00200 /* write permission */
#define US_IRWXU 00700 /* RWX owner */
#define US_IRUSR 00400 /* R owner */
#define US_IWUSR 00200 /* W owner */
#define US_IXUSR 00100 /* X owner */
#define US_IRWXG 00070 /* RWX group */
#define US_IRGRP 00040 /* R group */
#define US_IWGRP 00020 /* W group */
#define US_IXGRP 00010 /* X group */
#define US_IRWXO 00007 /* RWX other */
#define US_IROTH 00004 /* R other */
#define US_IWOTH 00002 /* W other */
#define US_IXOTH 00001 /* X other */
/**
* \brief POSIX dirent
*/
struct uffs_dirent {
int d_ino; /* inode number (serial number or this record) */
char d_name[MAX_FILENAME_LENGTH]; /* name of this record */
int d_off; /* offset to this dirent */
unsigned short int d_reclen; /* length of this uffs_dirent */
unsigned short int d_namelen; /* length of this d_name */
unsigned char d_type; /* type of this record */
};
/**
* \brief POSIX DIR
*/
typedef struct uffs_dirSt {
struct uffs_ObjectSt *obj; /* dir object */
struct uffs_FindInfoSt f; /* find info */
struct uffs_ObjectInfoSt info; /* object info */
struct uffs_dirent dirent; /* dir entry */
} uffs_DIR;
/**
* \brief POSIX stat
*/
struct uffs_stat {
int st_dev; /* ID of device containing file */
int st_ino; /* inode number */
int st_mode; /* protection */
int st_nlink; /* number of hard links */
int st_uid; /* user ID of owner */
int st_gid; /* group ID of owner */
int st_rdev; /* device ID (if special file) */
long st_size; /* total size, in bytes */
int st_blksize; /* blocksize for filesystem I/O */
int st_blocks; /* number of blocks allocated */
u32 st_atime; /* time of last access */
u32 st_mtime; /* time of last modification */
u32 st_ctime; /* time of last status change */
};
URET uffs_InitDirEntryBuf(void);
URET uffs_ReleaseDirEntryBuf(void);
uffs_Pool * uffs_GetDirEntryBufPool(void);
/* POSIX compliant file system APIs */
int uffs_open(const char *name, int oflag, ...);
int uffs_close(int fd);
int uffs_read(int fd, void *data, int len);
int uffs_write(int fd, void *data, int len);
long uffs_seek(int fd, long offset, int origin);
long uffs_tell(int fd);
int uffs_eof(int fd);
int uffs_flush(int fd);
int uffs_rename(const char *old_name, const char *new_name);
int uffs_remove(const char *name);
int uffs_truncate(int fd, long remain);
int uffs_mkdir(const char *name, ...);
int uffs_rmdir(const char *name);
int uffs_stat(const char *name, struct uffs_stat *buf);
int uffs_lstat(const char *name, struct uffs_stat *buf);
int uffs_fstat(int fd, struct uffs_stat *buf);
int uffs_closedir(uffs_DIR *dirp);
uffs_DIR * uffs_opendir(const char *path);
struct uffs_dirent * uffs_readdir(uffs_DIR *dirp);
void uffs_rewinddir(uffs_DIR *dirp);
#if 0
void uffs_seekdir(uffs_DIR *dirp, long loc);
long uffs_telldir(uffs_DIR *dirp);
#endif
int uffs_get_error(void);
int uffs_set_error(int err);
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs_fd.h
* \brief PISIX like file operations
* \author Ricky Zheng, created 8th Jun, 2005
*/
#include "uffs/uffs_config.h"
#include "uffs/uffs_core.h"
#include "uffs/uffs_fs.h"
#include "uffs/uffs.h"
#include "uffs/uffs_find.h"
#include <string.h>
/**
* \brief definitions for uffs_stat::st_mode
*/
#define US_IFMT 0xF000 /* file type make */
#define US_IFREG 0x8000 /* regular */
#define US_IFLNK 0xA000 /* symbolic link */
#define US_IFDIR 0x4000 /* directory */
#define US_IREAD 00400 /* read permission */
#define US_IWRITE 00200 /* write permission */
#define US_IRWXU 00700 /* RWX owner */
#define US_IRUSR 00400 /* R owner */
#define US_IWUSR 00200 /* W owner */
#define US_IXUSR 00100 /* X owner */
#define US_IRWXG 00070 /* RWX group */
#define US_IRGRP 00040 /* R group */
#define US_IWGRP 00020 /* W group */
#define US_IXGRP 00010 /* X group */
#define US_IRWXO 00007 /* RWX other */
#define US_IROTH 00004 /* R other */
#define US_IWOTH 00002 /* W other */
#define US_IXOTH 00001 /* X other */
/**
* \brief POSIX dirent
*/
struct uffs_dirent
{
int d_ino; /* inode number (serial number or this record) */
char d_name[MAX_FILENAME_LENGTH]; /* name of this record */
int d_off; /* offset to this dirent */
u16 d_reclen; /* length of this uffs_dirent */
u16 d_namelen; /* length of this d_name */
u32 d_type; /* type of this record ,Ҫinfo.attrͱһ*/
};
/**
* \brief POSIX DIR
*/
typedef struct uffs_dirSt
{
struct uffs_ObjectSt *obj; /* dir object */
struct uffs_FindInfoSt f; /* find info */
struct uffs_ObjectInfoSt info; /* object info */
struct uffs_dirent dirent; /* dir entry */
}uffs_DIR;
/**
* \brief POSIX stat
*/
struct uffs_stat
{
int st_dev; /* ID of device containing file */
int st_ino; /* inode number */
int st_mode; /* protection */
int st_nlink; /* number of hard links */
int st_uid; /* user ID of owner */
int st_gid; /* group ID of owner */
int st_rdev; /* device ID (if special file) */
long st_size; /* total size, in bytes */
int st_blksize; /* blocksize for filesystem I/O */
int st_blocks; /* number of blocks allocated */
u32 st_atime; /* time of last access */
u32 st_mtime; /* time of last modification */
u32 st_ctime; /* time of last status change */
};
int uffs_InitDirEntryBuf(void);
int uffs_ReleaseDirEntryBuf(void);
uffs_Pool * uffs_GetDirEntryBufPool(void);
/* POSIX compliant file system APIs */
int uffs_open(const char *name, int oflag, ...);
int uffs_close(int fd);
int uffs_read(int fd, void *data, int len);
int uffs_write(int fd, void *data, int len);
long uffs_seek(int fd, long offset, int origin);
long uffs_tell(int fd);
int uffs_eof(int fd);
int uffs_flush(int fd);
int uffs_rename(const char *old_name, const char *new_name);
int uffs_remove(const char *name);
int uffs_truncate(int fd, long remain);
int uffs_mkdir(const char *name, ...);
int uffs_rmdir(const char *name);
int uffs_stat(const char *name, struct uffs_stat *buf);
int uffs_lstat(const char *name, struct uffs_stat *buf);
int uffs_fstat(int fd, struct uffs_stat *buf);
int uffs_closedir(uffs_DIR *dirp);
uffs_DIR * uffs_opendir(const char *path);
struct uffs_dirent * uffs_readdir(uffs_DIR *dirp);
void uffs_rewinddir(uffs_DIR *dirp);
#if 0
void uffs_seekdir(uffs_DIR *dirp, long loc);
long uffs_telldir(uffs_DIR *dirp);
#endif
int uffs_get_error(void);
int uffs_set_error(int err);
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs_find.h
* \brief find objects under dir
* \author Ricky Zheng
*/
#ifndef _UFFS_FIND_H_
#define _UFFS_FIND_H_
#include "uffs/uffs_fs.h"
#ifdef __cplusplus
extern "C"{
#endif
typedef struct uffs_FindInfoSt {
uffs_Device *dev; //!< the device to be searched
u16 serial; //!< the dir serial number
int step; //!< step: 0 - working on dir entries, 1 - working on file entries, 2 - stoped.
int hash; //!< hash entry, internal used
TreeNode *work; //!< working node, internal used.
int pos; //!< current position
} uffs_FindInfo;
URET uffs_GetObjectInfo(uffs_Object *obj, uffs_ObjectInfo *info, int *err);
URET uffs_FindObjectOpen(uffs_FindInfo *find_handle, uffs_Object *dir);
URET uffs_FindObjectOpenEx(uffs_FindInfo *f, uffs_Device *dev, int dir);
URET uffs_FindObjectFirst(uffs_ObjectInfo *info, uffs_FindInfo *find_handle);
URET uffs_FindObjectNext(uffs_ObjectInfo *info, uffs_FindInfo *find_handle);
URET uffs_FindObjectRewind(uffs_FindInfo *find_handle);
URET uffs_FindObjectClose(uffs_FindInfo * find_handle);
#ifdef __cplusplus
}
#endif
#endif
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs_find.h
* \brief find objects under dir
* \author Ricky Zheng
*/
#ifndef _UFFS_FIND_H_
#define _UFFS_FIND_H_
#include "uffs/uffs_fs.h"
#ifdef __cplusplus
extern "C"{
#endif
typedef struct uffs_FindInfoSt {
uffs_Device *dev; //!< the device to be searched
u16 serial; //!< the dir serial number
int step; //!< step: 0 - working on dir entries, 1 - working on file entries, 2 - stoped.
int hash; //!< hash entry, internal used
TreeNode *work; //!< working node, internal used.
int pos; //!< current position
} uffs_FindInfo;
URET uffs_GetObjectInfo(uffs_Object *obj, uffs_ObjectInfo *info, int *err);
URET uffs_FindObjectOpen(uffs_FindInfo *find_handle, uffs_Object *dir);
URET uffs_FindObjectOpenEx(uffs_FindInfo *f, uffs_Device *dev, int dir);
URET uffs_FindObjectFirst(uffs_ObjectInfo *info, uffs_FindInfo *find_handle);
URET uffs_FindObjectNext(uffs_ObjectInfo *info, uffs_FindInfo *find_handle);
URET uffs_FindObjectRewind(uffs_FindInfo *find_handle);
URET uffs_FindObjectClose(uffs_FindInfo * find_handle);
#ifdef __cplusplus
}
#endif
#endif
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs_public.h
* \brief flash interface for UFFS
* \author Ricky Zheng
*/
#ifndef _UFFS_FLASH_H_
#define _UFFS_FLASH_H_
#include "uffs/uffs_types.h"
#include "uffs/uffs_config.h"
#include "uffs/uffs_core.h"
#include "uffs/uffs_device.h"
#ifdef __cplusplus
extern "C"{
#endif
/** ECC options (uffs_StorageAttrSt.ecc_opt) */
#define UFFS_ECC_NONE 0 //!< do not use ECC
#define UFFS_ECC_SOFT 1 //!< UFFS calculate the ECC
#define UFFS_ECC_HW 2 //!< Flash driver(or by hardware) calculate the ECC
#define UFFS_ECC_HW_AUTO 3 //!< Hardware calculate the ECC and automatically write to spare.
/** spare layout options (uffs_StorageAttrSt.layout_opt) */
#define UFFS_LAYOUT_UFFS 0 //!< do layout by dev->attr information
#define UFFS_LAYOUT_FLASH 1 //!< flash driver do the layout
#define UFFS_SPARE_LAYOUT_SIZE 6 //!< maximum spare layout array size, 2 segments
/** flash operation return code */
#define UFFS_FLASH_NO_ERR 0 //!< no error
#define UFFS_FLASH_ECC_OK 1 //!< bit-flip found, but corrected by ECC
#define UFFS_FLASH_IO_ERR -1 //!< I/O error
#define UFFS_FLASH_ECC_FAIL -2 //!< ECC failed
#define UFFS_FLASH_BAD_BLK -3 //!< bad block
#define UFFS_FLASH_UNKNOWN_ERR -100 //!< unkown error?
#define UFFS_FLASH_HAVE_ERR(e) ((e) < 0)
#if defined(CONFIG_BAD_BLOCK_POLICY_STRICT)
# define UFFS_FLASH_IS_BAD_BLOCK(e) ((e) == UFFS_FLASH_ECC_FAIL || (e) == UFFS_FLASH_ECC_OK || (e) == UFFS_FLASH_BAD_BLK)
#else
# define UFFS_FLASH_IS_BAD_BLOCK(e) ((e) == UFFS_FLASH_ECC_FAIL || (e) == UFFS_FLASH_BAD_BLK)
#endif
/** defines for page info (data length and data sum) */
#define UFFS_PAGE_INFO_CLEAN 0xFFFFFFFF
#define UFFS_PAGE_INFO_IOERR 0xDEADFFFF
#define UFFS_PAGE_GET_LEN(info) (info & 0xFFFF)
#define UFFS_PAGE_GET_DSUM(info) (info >> 16)
#define UFFS_PAGE_MAKE_INFO(d_len, d_sum) ((d_sum << 16) | d_len)
/**
* \struct uffs_StorageAttrSt
* \brief uffs device storage attribute, provide by nand specific file
*/
struct uffs_StorageAttrSt {
u32 total_blocks; //!< total blocks in this chip
u16 page_data_size; //!< page data size (physical page data size, e.g. 512)
u16 pages_per_block; //!< pages per block
u8 spare_size; //!< page spare size (physical page spare size, e.g. 16)
u8 block_status_offs; //!< block status byte offset in spare
int ecc_opt; //!< ecc option ( #UFFS_ECC_[NONE|SOFT|HW|HW_AUTO] )
int layout_opt; //!< layout option (#UFFS_LAYOUT_UFFS or #UFFS_LAYOUT_FLASH)
const u8 *ecc_layout; //!< page data ECC layout: [ofs1, size1, ofs2, size2, ..., 0xFF, 0]
const u8 *data_layout; //!< spare data layout: [ofs1, size1, ofs2, size2, ..., 0xFF, 0]
u8 _uffs_ecc_layout[UFFS_SPARE_LAYOUT_SIZE]; //!< uffs spare ecc layout
u8 _uffs_data_layout[UFFS_SPARE_LAYOUT_SIZE]; //!< uffs spare data layout
void *_private; //!< private data for storage attribute
};
/**
* \struct uffs_FlashOpsSt
* \brief low level flash operations, should be implement in flash driver
*/
struct uffs_FlashOpsSt {
/**
* Read page data.
*
* if ecc_opt is UFFS_ECC_HW, flash driver must calculate and return ecc (if ecc != NULL).
*
* if ecc_opt is UFFS_ECC_HW_AUTO, flash driver do ecc correction aganist ecc in spare area.
*
* \return #UFFS_FLASH_NO_ERR: success and/or has no flip bits.
* #UFFS_FLASH_IO_ERR: I/O error, expect retry ?
* #UFFS_FLASH_ECC_FAIL: page data has flip bits and ecc correct failed.
* #UFFS_FLASH_ECC_OK: page data has flip bits and corrected by ecc.
*
* \note pad 0xFF for calculating ECC if len < page_data_size
*/
int (*ReadPageData)(uffs_Device *dev, u32 block, u32 page, u8 *data, int len, u8 *ecc);
/**
* Read page spare [len] bytes from [ofs].
*
* \note flash driver must privide this function.
*
* \return #UFFS_FLASH_NO_ERR: success
* #UFFS_FLASH_IO_ERR: I/O error, expect retry ?
*
* \note flash driver DO NOT need to do ecc correction for spare data,
* UFFS will take care of spare data ecc.
*/
int (*ReadPageSpare)(uffs_Device *dev, u32 block, u32 page, u8 *spare, int ofs, int len);
/**
* Read page spare, unload to tag and ecc.
*
* \note flash driver must provide this function if layout_opt is UFFS_LAYOUT_FLASH.
* UFFS will use this function (if exist) prio to 'ReadPageSpare()'
*
* \return #UFFS_FLASH_NO_ERR: success
* #UFFS_FLASH_IO_ERR: I/O error, expect retry ?
*
* \note flash driver DO NOT need to do ecc correction for spare data,
* UFFS will take care of spare data ecc.
*/
int (*ReadPageSpareWithLayout)(uffs_Device *dev, u32 block, u32 page, u8 *tag, int len, u8 *ecc);
/**
* Write page data.
*
* if ecc_opt is UFFS_ECC_HW, flash driver must calculate and return the ecc.
* if ecc_opt is UFFS_ECC_HW_AUTO, do not need to return ecc.
*
* \return #UFFS_FLASH_NO_ERR: success
* #UFFS_FLASH_IO_ERR: I/O error, expect retry ?
* #UFFS_FLASH_BAD_BLK: a bad block detected.
*
* \note pad 0xFF for calculating ECC if len < page_data_size
*/
int (*WritePageData)(uffs_Device *dev, u32 block, u32 page, const u8 *data, int len, u8 *ecc);
/**
* Write [len] bytes to page spare from [ofs].
*
* \note flash driver must privide this function.
*
* \return #UFFS_FLASH_NO_ERR: success
* #UFFS_FLASH_IO_ERR: I/O error, expect retry ?
* #UFFS_FLASH_BAD_BLK: a bad block detected.
*/
int (*WritePageSpare)(uffs_Device *dev, u32 block, u32 page, const u8 *spare, int ofs, int len, UBOOL eod);
/**
* Write full page, include page data and spare.
*
* you need to pack spare within nand driver.
*
* \note if layout_opt is UFFS_LAYOUT_FLASH, flash driver must implement this function.
* UFFS will use this function (if provided) prio to 'WritePageData() + WritePageSpare()'
*
* \return #UFFS_FLASH_NO_ERR: success
* #UFFS_FLASH_IO_ERR: I/O error, expect retry ?
* #UFFS_FLASH_BAD_BLK: a bad block detected.
*/
int (*WriteFullPage)(uffs_Device *dev, u32 block, u32 page, const u8* data, int len, const u8 *ts, int ts_len, const u8 *ecc);
/**
* check block status.
*
* \note flash driver may maintain a bad block table to speed up bad block checking or
* it will require one or two read spare I/O to check block status.
*
* \note if this function is not provided, UFFS check the block_status byte in spare.
*
* \return 1 if it's a bad block, 0 if it's not.
*/
int (*IsBadBlock)(uffs_Device *dev, u32 block);
/**
* Mark a new bad block.
*
* \return 0 if success, otherwise return -1.
*/
int (*MarkBadBlock)(uffs_Device *dev, u32 block);
/**
* Erase a block.
*
* \return #UFFS_FLASH_NO_ERR: success
* #UFFS_FLASH_IO_ERR: I/O error, expect retry ?
* #UFFS_FLASH_BAD_BLK: a bad block detected.
*/
int (*EraseBlock)(uffs_Device *dev, u32 block);
};
/** make spare from tag store and ecc */
void uffs_FlashMakeSpare(uffs_Device *dev, uffs_TagStore *ts, const u8 *ecc, u8* spare);
/** read page spare, fill tag and ECC */
int uffs_FlashReadPageSpare(uffs_Device *dev, int block, int page, uffs_Tags *tag, u8 *ecc);
/** read page data to page buf and do ECC correct */
int uffs_FlashReadPage(uffs_Device *dev, int block, int page, uffs_Buf *buf);
/** write page data and spare */
int uffs_FlashWritePageCombine(uffs_Device *dev, int block, int page, uffs_Buf *buf, uffs_Tags *tag);
/** Mark this block as bad block */
int uffs_FlashMarkBadBlock(uffs_Device *dev, int block);
/** Is this block a bad block ? */
UBOOL uffs_FlashIsBadBlock(uffs_Device *dev, int block);
/** Erase flash block */
int uffs_FlashEraseBlock(uffs_Device *dev, int block);
/* mark a clean page as 'dirty' (and 'invalid') */
int uffs_FlashMarkDirtyPage(uffs_Device *dev, int block, int page);
/**
* get page head info
*
* \return #UFFS_PAGE_INFO_IOERR if I/O error, otherwise return page info
*/
u32 uffs_FlashGetPageInfo(uffs_Device *dev, int block, int page);
/** load uffs_FileInfo from flash storage */
URET uffs_FlashReadFileinfoPhy(uffs_Device *dev, int block, int page, uffs_FileInfo *info);
/**
* Initialize UFFS flash interface
*/
URET uffs_FlashInterfaceInit(uffs_Device *dev);
/**
* Release UFFS flash interface
*/
URET uffs_FlashInterfaceRelease(uffs_Device *dev);
#ifdef __cplusplus
}
#endif
#endif
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs_public.h
* \brief flash interface for UFFS
* \author Ricky Zheng
*/
#ifndef _UFFS_FLASH_H_
#define _UFFS_FLASH_H_
#include "uffs/uffs_types.h"
#include "uffs/uffs_config.h"
#include "uffs/uffs_core.h"
#include "uffs/uffs_device.h"
#ifdef __cplusplus
extern "C"{
#endif
/** ECC options (uffs_StorageAttrSt.ecc_opt) */
#define UFFS_ECC_NONE 0 //!< do not use ECC
#define UFFS_ECC_SOFT 1 //!< UFFS calculate the ECC
#define UFFS_ECC_HW 2 //!< Flash driver(or by hardware) calculate the ECC
#define UFFS_ECC_HW_AUTO 3 //!< Hardware calculate the ECC and automatically write to spare.
/** spare layout options (uffs_StorageAttrSt.layout_opt) */
#define UFFS_LAYOUT_UFFS 0 //!< do layout by dev->attr information
#define UFFS_LAYOUT_FLASH 1 //!< flash driver do the layout
#define UFFS_SPARE_LAYOUT_SIZE 6 //!< maximum spare layout array size, 2 segments
/** flash operation return code */
#define UFFS_FLASH_NO_ERR 0 //!< no error
#define UFFS_FLASH_ECC_OK 1 //!< bit-flip found, but corrected by ECC
#define UFFS_FLASH_IO_ERR -1 //!< I/O error
#define UFFS_FLASH_ECC_FAIL -2 //!< ECC failed
#define UFFS_FLASH_BAD_BLK -3 //!< bad block
#define UFFS_FLASH_UNKNOWN_ERR -100 //!< unkown error?
#define UFFS_FLASH_HAVE_ERR(e) ((e) < 0)
#if defined(CONFIG_BAD_BLOCK_POLICY_STRICT)
# define UFFS_FLASH_IS_BAD_BLOCK(e) ((e) == UFFS_FLASH_ECC_FAIL || (e) == UFFS_FLASH_ECC_OK || (e) == UFFS_FLASH_BAD_BLK)
#else
# define UFFS_FLASH_IS_BAD_BLOCK(e) ((e) == UFFS_FLASH_ECC_FAIL || (e) == UFFS_FLASH_BAD_BLK)
#endif
/** defines for page info (data length and data sum) */
#define UFFS_PAGE_INFO_CLEAN 0xFFFFFFFF
#define UFFS_PAGE_INFO_IOERR 0xDEADFFFF
#define UFFS_PAGE_GET_LEN(info) (info & 0xFFFF)
#define UFFS_PAGE_GET_DSUM(info) (info >> 16)
#define UFFS_PAGE_MAKE_INFO(d_len, d_sum) ((d_sum << 16) | d_len)
/**
* \struct uffs_StorageAttrSt
* \brief uffs device storage attribute, provide by nand specific file
*/
struct uffs_StorageAttrSt {
u32 total_blocks; //!< total blocks in this chip
u16 page_data_size; //!< page data size (physical page data size, e.g. 512)
u16 pages_per_block; //!< pages per block
u8 spare_size; //!< page spare size (physical page spare size, e.g. 16)
u8 block_status_offs; //!< block status byte offset in spare
int ecc_opt; //!< ecc option ( #UFFS_ECC_[NONE|SOFT|HW|HW_AUTO] )
int layout_opt; //!< layout option (#UFFS_LAYOUT_UFFS or #UFFS_LAYOUT_FLASH)
const u8 *ecc_layout; //!< page data ECC layout: [ofs1, size1, ofs2, size2, ..., 0xFF, 0]
const u8 *data_layout; //!< spare data layout: [ofs1, size1, ofs2, size2, ..., 0xFF, 0]
u8 _uffs_ecc_layout[UFFS_SPARE_LAYOUT_SIZE]; //!< uffs spare ecc layout
u8 _uffs_data_layout[UFFS_SPARE_LAYOUT_SIZE]; //!< uffs spare data layout
void *_private; //!< private data for storage attribute
};
/**
* \struct uffs_FlashOpsSt
* \brief low level flash operations, should be implement in flash driver
*/
struct uffs_FlashOpsSt {
/**
* Read page data.
*
* if ecc_opt is UFFS_ECC_HW, flash driver must calculate and return ecc (if ecc != NULL).
*
* if ecc_opt is UFFS_ECC_HW_AUTO, flash driver do ecc correction aganist ecc in spare area.
*
* \return #UFFS_FLASH_NO_ERR: success and/or has no flip bits.
* #UFFS_FLASH_IO_ERR: I/O error, expect retry ?
* #UFFS_FLASH_ECC_FAIL: page data has flip bits and ecc correct failed.
* #UFFS_FLASH_ECC_OK: page data has flip bits and corrected by ecc.
*
* \note pad 0xFF for calculating ECC if len < page_data_size
*/
int (*ReadPageData)(uffs_Device *dev, u32 block, u32 page, u8 *data, int len, u8 *ecc);
/**
* Read page spare [len] bytes from [ofs].
*
* \note flash driver must privide this function.
*
* \return #UFFS_FLASH_NO_ERR: success
* #UFFS_FLASH_IO_ERR: I/O error, expect retry ?
*
* \note flash driver DO NOT need to do ecc correction for spare data,
* UFFS will take care of spare data ecc.
*/
int (*ReadPageSpare)(uffs_Device *dev, u32 block, u32 page, u8 *spare, int ofs, int len);
/**
* Read page spare, unload to tag and ecc.
*
* \note flash driver must provide this function if layout_opt is UFFS_LAYOUT_FLASH.
* UFFS will use this function (if exist) prio to 'ReadPageSpare()'
*
* \return #UFFS_FLASH_NO_ERR: success
* #UFFS_FLASH_IO_ERR: I/O error, expect retry ?
*
* \note flash driver DO NOT need to do ecc correction for spare data,
* UFFS will take care of spare data ecc.
*/
int (*ReadPageSpareWithLayout)(uffs_Device *dev, u32 block, u32 page, u8 *tag, int len, u8 *ecc);
/**
* Write page data.
*
* if ecc_opt is UFFS_ECC_HW, flash driver must calculate and return the ecc.
* if ecc_opt is UFFS_ECC_HW_AUTO, do not need to return ecc.
*
* \return #UFFS_FLASH_NO_ERR: success
* #UFFS_FLASH_IO_ERR: I/O error, expect retry ?
* #UFFS_FLASH_BAD_BLK: a bad block detected.
*
* \note pad 0xFF for calculating ECC if len < page_data_size
*/
int (*WritePageData)(uffs_Device *dev, u32 block, u32 page, const u8 *data, int len, u8 *ecc);
/**
* Write [len] bytes to page spare from [ofs].
*
* \note flash driver must privide this function.
*
* \return #UFFS_FLASH_NO_ERR: success
* #UFFS_FLASH_IO_ERR: I/O error, expect retry ?
* #UFFS_FLASH_BAD_BLK: a bad block detected.
*/
int (*WritePageSpare)(uffs_Device *dev, u32 block, u32 page, const u8 *spare, int ofs, int len, UBOOL eod);
/**
* Write full page, include page data and spare.
*
* you need to pack spare within nand driver.
*
* \note if layout_opt is UFFS_LAYOUT_FLASH, flash driver must implement this function.
* UFFS will use this function (if provided) prio to 'WritePageData() + WritePageSpare()'
*
* \return #UFFS_FLASH_NO_ERR: success
* #UFFS_FLASH_IO_ERR: I/O error, expect retry ?
* #UFFS_FLASH_BAD_BLK: a bad block detected.
*/
int (*WriteFullPage)(uffs_Device *dev, u32 block, u32 page, const u8* data, int len, const u8 *ts, int ts_len, const u8 *ecc);
/**
* check block status.
*
* \note flash driver may maintain a bad block table to speed up bad block checking or
* it will require one or two read spare I/O to check block status.
*
* \note if this function is not provided, UFFS check the block_status byte in spare.
*
* \return 1 if it's a bad block, 0 if it's not.
*/
int (*IsBadBlock)(uffs_Device *dev, u32 block);
/**
* Mark a new bad block.
*
* \return 0 if success, otherwise return -1.
*/
int (*MarkBadBlock)(uffs_Device *dev, u32 block);
/**
* Erase a block.
*
* \return #UFFS_FLASH_NO_ERR: success
* #UFFS_FLASH_IO_ERR: I/O error, expect retry ?
* #UFFS_FLASH_BAD_BLK: a bad block detected.
*/
int (*EraseBlock)(uffs_Device *dev, u32 block);
};
/** make spare from tag store and ecc */
void uffs_FlashMakeSpare(uffs_Device *dev, uffs_TagStore *ts, const u8 *ecc, u8* spare);
/** read page spare, fill tag and ECC */
int uffs_FlashReadPageSpare(uffs_Device *dev, int block, int page, uffs_Tags *tag, u8 *ecc);
/** read page data to page buf and do ECC correct */
int uffs_FlashReadPage(uffs_Device *dev, int block, int page, uffs_Buf *buf);
/** write page data and spare */
int uffs_FlashWritePageCombine(uffs_Device *dev, int block, int page, uffs_Buf *buf, uffs_Tags *tag);
/** Mark this block as bad block */
int uffs_FlashMarkBadBlock(uffs_Device *dev, int block);
/** Is this block a bad block ? */
UBOOL uffs_FlashIsBadBlock(uffs_Device *dev, int block);
/** Erase flash block */
int uffs_FlashEraseBlock(uffs_Device *dev, int block);
/* mark a clean page as 'dirty' (and 'invalid') */
int uffs_FlashMarkDirtyPage(uffs_Device *dev, int block, int page);
/**
* get page head info
*
* \return #UFFS_PAGE_INFO_IOERR if I/O error, otherwise return page info
*/
u32 uffs_FlashGetPageInfo(uffs_Device *dev, int block, int page);
/** load uffs_FileInfo from flash storage */
URET uffs_FlashReadFileinfoPhy(uffs_Device *dev, int block, int page, uffs_FileInfo *info);
/**
* Initialize UFFS flash interface
*/
URET uffs_FlashInterfaceInit(uffs_Device *dev);
/**
* Release UFFS flash interface
*/
URET uffs_FlashInterfaceRelease(uffs_Device *dev);
#ifdef __cplusplus
}
#endif
#endif
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs_fs.h
* \brief uffs basic file operations
* \author Ricky Zheng
*/
#ifndef _UFFS_FS_H_
#define _UFFS_FS_H_
#include "uffs/uffs_types.h"
#include "uffs/uffs.h"
#include "uffs/uffs_public.h"
#include "uffs/uffs_core.h"
#ifdef __cplusplus
extern "C"{
#endif
/** file object */
struct uffs_ObjectSt {
/******* objects manager ********/
int dev_lock_count;
int dev_get_count;
/******** init level 0 ********/
const char * name; //!< pointer to the start of name, for open or create
u32 name_len; //!< name length
u16 sum; //!< sum of name
uffs_Device *dev; //!< uffs device
u32 oflag;
u8 type;
u16 head_pages; //!< data pages on file head block
u16 parent;
/******* init level 1 ********/
TreeNode *node; //!< file entry node in tree
u16 serial;
/******* output ******/
int err; //!< error number
/******* current *******/
u32 pos; //!< current position in file
/***** others *******/
UBOOL attr_loaded; //!< attributes loaded ?
UBOOL open_succ; //!< U_TRUE or U_FALSE
};
typedef struct uffs_ObjectSt uffs_Object;
#define uffs_GetObjectErr(obj) ((obj)->err)
#define uffs_ClearObjectErr(obj) do { (obj)->err = UENOERR; } while (0)
uffs_Pool * uffs_GetObjectPool(void);
URET uffs_InitObjectBuf(void);
URET uffs_ReleaseObjectBuf(void);
uffs_Object * uffs_GetObject(void);
void uffs_PutObject(uffs_Object *obj);
int uffs_GetObjectIndex(uffs_Object *obj);
uffs_Object * uffs_GetObjectByIndex(int idx);
/**
* Re-initialize an object.
* should call this function if you want to re-use an object.
*/
URET uffs_ReInitObject(uffs_Object *obj);
URET uffs_ParseObject(uffs_Object *obj, const char *name);
URET uffs_CreateObjectEx(uffs_Object *obj, uffs_Device *dev,
int dir, const char *name, int name_len, int oflag);
URET uffs_OpenObjectEx(uffs_Object *obj, uffs_Device *dev,
int dir, const char *name, int name_len, int oflag);
URET uffs_OpenObject(uffs_Object *obj, const char *fullname, int oflag);
URET uffs_TruncateObject(uffs_Object *obj, u32 remain);
URET uffs_CreateObject(uffs_Object *obj, const char *fullname, int oflag);
URET uffs_CloseObject(uffs_Object *obj);
int uffs_WriteObject(uffs_Object *obj, const void *data, int len);
int uffs_ReadObject(uffs_Object *obj, void *data, int len);
long uffs_SeekObject(uffs_Object *obj, long offset, int origin);
int uffs_GetCurOffset(uffs_Object *obj);
int uffs_EndOfFile(uffs_Object *obj);
URET uffs_FlushObject(uffs_Object *obj);
URET uffs_RenameObject(const char *old_name, const char *new_name, int *err);
URET uffs_DeleteObject(const char * name, int *err);
#ifdef __cplusplus
}
#endif
#endif
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs_fs.h
* \brief uffs basic file operations
* \author Ricky Zheng
*/
#ifndef _UFFS_FS_H_
#define _UFFS_FS_H_
#include "uffs/uffs_types.h"
#include "uffs/uffs.h"
#include "uffs/uffs_public.h"
#include "uffs/uffs_core.h"
#ifdef __cplusplus
extern "C"{
#endif
/** file object */
struct uffs_ObjectSt {
/******* objects manager ********/
int dev_lock_count;
int dev_get_count;
/******** init level 0 ********/
const char * name; //!< pointer to the start of name, for open or create
u32 name_len; //!< name length
u16 sum; //!< sum of name
uffs_Device *dev; //!< uffs device
u32 oflag;
u8 type;
u16 head_pages; //!< data pages on file head block
u16 parent;
/******* init level 1 ********/
TreeNode *node; //!< file entry node in tree
u16 serial;
/******* output ******/
int err; //!< error number
/******* current *******/
u32 pos; //!< current position in file
/***** others *******/
UBOOL attr_loaded; //!< attributes loaded ?
UBOOL open_succ; //!< U_TRUE or U_FALSE
};
typedef struct uffs_ObjectSt uffs_Object;
#define uffs_GetObjectErr(obj) ((obj)->err)
#define uffs_ClearObjectErr(obj) do { (obj)->err = UENOERR; } while (0)
uffs_Pool * uffs_GetObjectPool(void);
URET uffs_InitObjectBuf(void);
URET uffs_ReleaseObjectBuf(void);
uffs_Object * uffs_GetObject(void);
void uffs_PutObject(uffs_Object *obj);
int uffs_GetObjectIndex(uffs_Object *obj);
uffs_Object * uffs_GetObjectByIndex(int idx);
/**
* Re-initialize an object.
* should call this function if you want to re-use an object.
*/
URET uffs_ReInitObject(uffs_Object *obj);
URET uffs_ParseObject(uffs_Object *obj, const char *name);
URET uffs_CreateObjectEx(uffs_Object *obj, uffs_Device *dev,
int dir, const char *name, int name_len, int oflag);
URET uffs_OpenObjectEx(uffs_Object *obj, uffs_Device *dev,
int dir, const char *name, int name_len, int oflag);
URET uffs_OpenObject(uffs_Object *obj, const char *fullname, int oflag);
URET uffs_TruncateObject(uffs_Object *obj, u32 remain);
URET uffs_CreateObject(uffs_Object *obj, const char *fullname, int oflag);
URET uffs_CloseObject(uffs_Object *obj);
int uffs_WriteObject(uffs_Object *obj, const void *data, int len);
int uffs_ReadObject(uffs_Object *obj, void *data, int len);
long uffs_SeekObject(uffs_Object *obj, long offset, int origin);
int uffs_GetCurOffset(uffs_Object *obj);
int uffs_EndOfFile(uffs_Object *obj);
URET uffs_FlushObject(uffs_Object *obj);
URET uffs_RenameObject(const char *old_name, const char *new_name, int *err);
URET uffs_DeleteObject(const char * name, int *err);
#ifdef __cplusplus
}
#endif
#endif
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册