提交 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 <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)
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)
int dfs_uffs_mkfs(const char* device_name)
{
return -DFS_STATUS_EIO;
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;
buf->f_bsize = attr->page_data_size * attr->pages_per_block;
buf->f_blocks = attr->total_blocks;
buf->f_bfree = 0;
return ret;
}
static int dfs_uffs_open(struct dfs_fd* fd)
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;
}
}
return ret;
}
static int dfs_uffs_close(struct dfs_fd* fd)
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);
}
return ret;
}
static int dfs_uffs_ioctl(struct dfs_fd* fd, int cmd, void *args)
int dfs_uffs_ioctl(struct dfs_fd* fd, int cmd, void *args)
{
return -DFS_STATUS_ENOSYS;
}
static int dfs_uffs_read(struct dfs_fd* fd, void* buf, rt_size_t count)
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;
return uffs_ReadObject(fp, buf, count);
}
static int dfs_uffs_write(struct dfs_fd* fd, const void* buf, rt_size_t 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);
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;
}
static int dfs_uffs_flush(struct dfs_fd* fd)
int dfs_uffs_flush(struct dfs_fd* fd)
{
uffs_Object* fp;
fp = (uffs_Object*)(fd->data);
RT_ASSERT(fp != RT_NULL);
return uffs_FlushObject(fp);
}
static int dfs_uffs_lseek(struct dfs_fd* fd, rt_off_t offset)
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);
return uffs_SeekObject(fp, USEEK_SET, offset);
}
static int dfs_uffs_getdents(struct dfs_fd* fd, struct _dirent* dirp, rt_uint32_t count)
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;
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);
}
static int dfs_uffs_unlink(struct dfs_filesystem* fs, const char* pathname)
//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 int dfs_uffs_stat(struct dfs_filesystem* fs, const char* filename, struct _stat* buf)
int dfs_uffs_stat(struct dfs_filesystem* fs, const char* path, struct stat* st)
{
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;
}
static int dfs_uffs_rename(struct dfs_filesystem* fs, const char* oldpath, const char* newpath)
int dfs_uffs_rename(struct dfs_filesystem* fs, const char* oldpath, const char* newpath)
{
int ret;
int err = 0;
ret = uffs_RenameObject(oldpath, newpath, &err);
uffs_set_error(-err);
return ret;
}
static const struct dfs_filesystem_operation _uffs =
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,
......@@ -90,3 +334,4 @@ 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;
}
......@@ -44,6 +44,50 @@
#define PFX "nand-drv:"
struct my_nand_chip {
void *IOR_ADDR;
void *IOW_ADDR;
UBOOL inited;
// ...
};
/*
* Standard NAND flash commands
*/
#define NAND_CMD_READ0 0
#define NAND_CMD_READ1 1
#define NAND_CMD_RNDOUT 5
#define NAND_CMD_PAGEPROG 0x10
#define NAND_CMD_READOOB 0x50
#define NAND_CMD_ERASE1 0x60
#define NAND_CMD_STATUS 0x70
#define NAND_CMD_STATUS_MULTI 0x71
#define NAND_CMD_SEQIN 0x80
#define NAND_CMD_RNDIN 0x85
#define NAND_CMD_READID 0x90
#define NAND_CMD_ERASE2 0xd0
#define NAND_CMD_RESET 0xff
/* impelent the following functions for your NAND flash */
#define CHIP_SET_CLE(chip) {}
#define CHIP_CLR_CLE(chip) {}
#define CHIP_SET_ALE(chip) {}
#define CHIP_CLR_ALE(chip) {}
#define CHIP_SET_NCS(chip) {}
#define CHIP_CLR_NCS(chip) {}
#define CHIP_BUSY(chip) {}
#define CHIP_READY(chip) {}
#define WRITE_COMMAND(chip, cmd) {}
#define WRITE_DATA_ADDR(chip, block, page, offset) {}
#define WRITE_ERASE_ADDR(chip, block) {}
#define WRITE_DATA(chip, data, len) {}
#define READ_DATA(chip, data, len) {}
#define PARSE_STATUS(v) (UFFS_FLASH_NO_ERR) // parse status to UFFS_FLASH_NO_ERR or UFFS_FLASH_BAD_BLK
#if CONFIG_USE_STATIC_MEMORY_ALLOCATOR == 0
int main()
{
......@@ -53,165 +97,207 @@ int main()
#else
#define USE_SINGLE_WRITE_FUN
#ifdef USE_SINGLE_WRITE_FUN
static int nand_write_full_page(uffs_Device *dev, u32 block, u32 pageNum, const u8 *page, int len, const u8 *tag, int tag_len, const u8 *ecc);
#else
static int nand_write_page_data(uffs_Device *dev, u32 block, u32 pageNum, const u8 *page, int len, u8 *ecc);
static int nand_write_page_spare(uffs_Device *dev, u32 block, u32 pageNum, const u8 *spare, int ofs, int len, UBOOL eod);
#endif
static int nand_read_page_data(uffs_Device *dev, u32 block, u32 pageNum, u8 *page, int len, u8 *ecc);
static int nand_read_page_spare(uffs_Device *dev, u32 block, u32 pageNum, u8 *spare, int ofs, int len);
static int nand_erase_block(uffs_Device *dev, u32 blockNumber);
static URET nand_init_device(uffs_Device *dev);
#ifdef USE_SINGLE_WRITE_FUN
// if you want to optimize nand flash driver, or use special nand hardware controller,
// or use other NAND driver (for example, eCos NAND lib), you shoud do layout in nand driver.
static int nand_write_full_page(uffs_Device *dev, u32 block, u32 pageNum, const u8 *page, int len, const u8 *tag, int tag_len, const u8 *ecc)
static int nand_read_page(uffs_Device *dev, u32 block, u32 page, u8 *data, int data_len, u8 *ecc,
u8 *spare, int spare_len)
{
#define SPOOL(dev) &((dev)->mem.spare_pool)
u8 *spare_buf = NULL;
spare_buf = (u8 *) uffs_PoolGet(SPOOL(dev)); // alloc a spare buffer
// ... START WRITE COMMAND ...
// ...
if (page) {
// WRITE page data
// ....
if (dev->attr->ecc_opt == UFFS_ECC_HW) {
// read ECC from hardware controller to ecc buf,
// ...
}
u8 val = 0;
int ret = UFFS_FLASH_NO_ERR;
struct my_nand_chip *chip = (struct my_nand_chip *) dev->attr->_private;
CHIP_CLR_NCS(chip);
if (data && data_len > 0) {
CHIP_SET_CLE(chip);
WRITE_COMMAND(chip, NAND_CMD_READ0);
CHIP_CLR_CLE(chip);
CHIP_SET_ALE(chip);
WRITE_DATA_ADDR(chip, block, page, 0);
CHIP_CLR_ALE(chip);
READ_DATA(chip, data, data_len);
// for now, we return all 0xFF to pass UFFS mount, you should remove this at your driver
memset(data, 0xFF, data_len);
}
if (tag && tag_len > 0) {
// now, you can use UFFS's layout function
uffs_FlashMakeSpare(dev, (uffs_TagStore *)tag, ecc, spare_buf);
// or, do your own layout
// ....
// WRITE spare_buf to page spare ...
// ...
if (spare && spare_len > 0) {
CHIP_SET_CLE(chip);
WRITE_COMMAND(chip, NAND_CMD_READOOB);
CHIP_CLR_CLE(chip);
CHIP_SET_ALE(chip);
WRITE_DATA_ADDR(chip, block, page, dev->attr->page_data_size);
CHIP_CLR_ALE(chip);
READ_DATA(chip, spare, spare_len);
// for now, we return all 0xFF to pass UFFS mount, you should remove this at your driver
memset(spare, 0xFF, spare_len);
}
// FINISH write command ...
// ...
// read program status ...
// ...
if (page)
dev->st.page_write_count++;
if (tag)
dev->st.spare_write_count++;
if (spare_buf)
uffs_PoolPut(SPOOL(dev), spare_buf); // release spare buffer
return UFFS_FLASH_NO_ERR;
}
#else
static int nand_write_page_data(uffs_Device *dev, u32 block, u32 pageNum, const u8 *page, int len, u8 *ecc)
{
// send WRITE command
if (data == NULL && spare == NULL) {
// read bad block mark
CHIP_SET_CLE(chip);
WRITE_COMMAND(chip, NAND_CMD_READOOB);
CHIP_CLR_CLE(chip);
CHIP_SET_ALE(chip);
WRITE_DATA_ADDR(chip, block, page, dev->attr->page_data_size + attr->block_status_offs);
CHIP_CLR_ALE(chip);
READ_DATA(chip, &val, 1);
ret = (val == 0xFF ? UFFS_FLASH_NO_ERR : UFFS_FLASH_BAD_BLK);
// for now, we return UFFS_FLASH_NO_ERR to pass UFFS mount, you should remove this at your driver
ret = UFFS_FLASH_NO_ERR;
}
// ... transfer data ...
CHIP_SET_NCS(chip);
dev->st.page_write_count++;
return UFFS_FLASH_NO_ERR;
return ret;
}
static int nand_write_page_spare(uffs_Device *dev, u32 block, u32 pageNum, const u8 *spare, int ofs, int len, UBOOL eod)
static int nand_write_page(uffs_Device *dev, u32 block, u32 page,
const u8 *data, int data_len, const u8 *spare, int spare_len)
{
if (eod == U_FALSE) {
// send WRITE command
}
u8 val = 0;
int ret = UFFS_FLASH_NO_ERR;
UBOOL fall_through = FALSE;
struct my_nand_chip *chip = (struct my_nand_chip *) dev->attr->_private;
CHIP_CLR_NCS(chip);
if (data && data_len > 0) {
CHIP_SET_CLE(chip);
WRITE_COMMAND(chip, NAND_CMD_READ0);
WRITE_COMMAND(chip, NAND_CMD_SEQIN);
CHIP_CLR_CLE(chip);
CHIP_SET_ALE(chip);
WRITE_DATA_ADDR(chip, block, page, 0);
CHIP_CLR_ALE(chip);
CHIP_BUSY(chip);
WRITE_DATA(chip, data, data_len);
if (data_len == dev->attr->page_data_size)
fall_through = U_TRUE;
else {
// do not need to send WRITE command if eod == U_FALSE because 'nand_write_page_data' is called before.
CHIP_SET_CLE(chip);
WRITE_COMMAND(chip, NAND_CMD_PAGEPROG);
WRITE_COMMAND(chip, NAND_CMD_STATUS);
CHIP_CLR_CLE(chip);
CHIP_READY(chip);
READ_DATA(chip, &val, 1);
ret = PARSE_STATUS(val);
}
}
// ... transfer data ...
if (ret != UFFS_FLASH_NO_ERR)
goto ext;
if (spare && spare_len > 0) {
if (!fall_through) {
CHIP_SET_CLE(chip);
WRITE_COMMAND(chip, NAND_CMD_READOOB);
WRITE_COMMAND(chip, NAND_CMD_SEQIN);
CHIP_CLR_CLE(chip);
CHIP_SET_ALE(chip);
WRITE_DATA_ADDR(chip, block, page, dev->attr->page_data_size);
CHIP_CLR_ALE(chip);
CHIP_BUSY(chip);
}
WRITE_DATA(chip, spare, spare_len);
CHIP_SET_CLE(chip);
WRITE_COMMAND(chip, NAND_CMD_PAGEPROG);
WRITE_COMMAND(chip, NAND_CMD_STATUS);
CHIP_CLR_CLE(chip);
CHIP_READY(chip);
READ_DATA(chip, &val, 1);
ret = PARSE_STATUS(val);
}
// send COMMIT command
if (data == NULL && spare == NULL) {
// mark bad block
CHIP_SET_CLE(chip);
WRITE_COMMAND(chip, NAND_CMD_READOOB);
WRITE_COMMAND(chip, NAND_CMD_SEQIN);
CHIP_CLR_CLE(chip);
CHIP_SET_ALE(chip);
WRITE_DATA_ADDR(chip, block, page, dev->attr->page_data_size + attr->block_status_offs);
CHIP_CLR_ALE(chip);
CHIP_BUSY(chip);
val = 0;
WRITE_DATA(chip, &val, 1);
CHIP_SET_CLE(chip);
WRITE_COMMAND(chip, NAND_CMD_PAGEPROG);
WRITE_COMMAND(chip, NAND_CMD_STATUS);
CHIP_CLR_CLE(chip);
CHIP_READY(chip);
READ_DATA(chip, &val, 1);
ret = PARSE_STATUS(val);
}
// read STATUS
ext:
CHIP_SET_NCS(chip);
dev->st.spare_write_count++;
return UFFS_FLASH_NO_ERR;
return ret;
}
#endif
static int nand_read_page_data(uffs_Device *dev, u32 block, u32 pageNum, u8 *page, int len, u8 *ecc)
static int nand_erase_block(uffs_Device *dev, u32 block)
{
// send READ command
// ... transfer data ...
// read STATUS
dev->st.page_read_count++;
return UFFS_FLASH_NO_ERR;
u8 val;
struct my_nand_chip *chip = (struct my_nand_chip *) dev->attr->_private;
CHIP_CLR_NCS(chip);
CHIP_SET_CLE(chip);
WRITE_COMMAND(chip, NAND_CMD_ERASE1);
CHIP_CLR_CLE(chip);
CHIP_SET_ALE(chip);
WRITE_ERASE_ADDR(chip, blcok);
CHIP_CLR_ALE(chip);
CHIP_SET_CLE(chip);
WRITE_COMMAND(chip, NAND_CMD_ERASE2);
WRITE_COMMAND(chip, NAND_CMD_STATUS);
CHIP_CLR_CLE(chip);
CHIP_READY(chip);
READ_DATA(chip, &val, 1);
CHIP_SET_NCS(chip);
return PARSE_STATUS(val);
}
static int nand_read_page_spare(uffs_Device *dev, u32 block, u32 pageNum, u8 *spare, int ofs, int len)
{
// send READ command
// ... transfer data ...
// read STATUS
dev->st.spare_read_count++;
return UFFS_FLASH_NO_ERR;
static int nand_init_flash(uffs_Device *dev)
{
// initialize your hardware here ...
struct my_nand_chip *chip = (struct my_nand_chip *) dev->attr->_private;
if (!chip->inited) {
// setup chip I/O address, setup NAND flash controller ... etc.
// chip->IOR_ADDR = 0xF0000000
// chip->IOW_ADDR = 0xF0000000
chip->inited = U_TRUE;
}
return 0;
}
static int nand_erase_block(uffs_Device *dev, u32 blockNumber)
static int nand_release_flash(uffs_Device *dev)
{
// insert your nand driver codes here ...
// release your hardware here
struct my_nand_chip *chip = (struct my_nand_chip *) dev->attr->_private;
dev->st.block_erase_count++;
return UFFS_FLASH_NO_ERR;
return 0;
}
static uffs_FlashOps g_my_nand_ops = {
nand_init_flash, // InitFlash()
nand_release_flash, // ReleaseFlash()
nand_read_page, // ReadPage()
NULL, // ReadPageWithLayout
nand_write_page, // WritePage()
NULL, // WirtePageWithLayout
NULL, // IsBadBlock(), let UFFS take care of it.
NULL, // MarkBadBlock(), let UFFS take care of it.
nand_erase_block, // EraseBlock()
};
/////////////////////////////////////////////////////////////////////////////////
static struct uffs_FlashOpsSt my_nand_driver_ops = {
nand_read_page_data, //ReadPageData
nand_read_page_spare, //ReadPageSpare
NULL, //ReadPageSpareWithLayout
#ifdef USE_SINGLE_WRITE_FUN
NULL,
NULL,
nand_write_full_page, //WriteFullPages
#else
nand_write_page_data, //WritePageData
nand_write_page_spare, //WritePageSpare
NULL,
#endif
NULL, //IsBadBlock
NULL, //MarkBadBlock
nand_erase_block, //EraseBlock
};
// change these parameters to fit your nand flash specification
#define MAN_ID MAN_ID_SAMSUNG // simulate Samsung's NAND flash
#define TOTAL_BLOCKS 1024
#define PAGE_DATA_SIZE 512
......@@ -224,13 +310,27 @@ static struct uffs_FlashOpsSt my_nand_driver_ops = {
#define PAR_1_BLOCKS 100 /* partition 1 */
#define PAR_2_BLOCKS (TOTAL_BLOCKS - PAR_1_BLOCKS) /* partition 2 */
static struct uffs_StorageAttrSt flash_storage = {0};
struct my_nand_chip g_nand_chip = {0};
static struct uffs_StorageAttrSt g_my_flash_storage = {0};
/* static alloc the memory for each partition */
/* define mount table */
static uffs_Device demo_device_1 = {0};
static uffs_Device demo_device_2 = {0};
static uffs_MountTable demo_mount_table[] = {
{ &demo_device_1, 0, PAR_1_BLOCKS - 1, "/data/" },
{ &demo_device_2, PAR_1_BLOCKS, PAR_1_BLOCKS + PAR_2_BLOCKS - 1, "/" },
{ NULL, 0, 0, NULL }
};
/* static alloc the memory for each partition */
static int static_buffer_par1[UFFS_STATIC_BUFF_SIZE(PAGES_PER_BLOCK, PAGE_SIZE, PAR_1_BLOCKS) / sizeof(int)];
static int static_buffer_par2[UFFS_STATIC_BUFF_SIZE(PAGES_PER_BLOCK, PAGE_SIZE, PAR_2_BLOCKS) / sizeof(int)];;
static void init_nand_chip(struct my_nand_chip *chip)
{
// init chip IO address, etc.
}
static void setup_flash_storage(struct uffs_StorageAttrSt *attr)
{
......@@ -245,35 +345,27 @@ static void setup_flash_storage(struct uffs_StorageAttrSt *attr)
attr->layout_opt = UFFS_LAYOUT_UFFS; /* let UFFS do the spare layout */
}
static URET my_initDevice(uffs_Device *dev)
static URET my_InitDevice(uffs_Device *dev)
{
dev->ops = &my_nand_driver_ops;
dev->attr = &g_my_flash_storage;
dev->attr->_private = (void *) &g_nand_chip; // hook nand_chip data structure to attr->_private
dev->ops = &g_my_nand_ops;
return U_SUCC;
}
static URET my_releaseDevice(uffs_Device *dev)
static URET my_ReleaseDevice(uffs_Device *dev)
{
return U_SUCC;
}
/* define mount table */
static uffs_Device demo_device_1 = {0};
static uffs_Device demo_device_2 = {0};
static uffs_MountTable demo_mount_table[] = {
{ &demo_device_1, 0, PAR_1_BLOCKS - 1, "/data/" },
{ &demo_device_2, PAR_1_BLOCKS, PAR_1_BLOCKS + PAR_2_BLOCKS - 1, "/" },
{ NULL, 0, 0, NULL }
};
static int my_init_filesystem(void)
{
uffs_MountTable *mtbl = &(demo_mount_table[0]);
/* setup nand storage attributes */
setup_flash_storage(&flash_storage);
setup_flash_storage(&g_my_flash_storage);
/* setup memory allocator */
uffs_MemSetupStaticAllocator(&demo_device_1.mem, static_buffer_par1, sizeof(static_buffer_par1));
......@@ -281,9 +373,9 @@ static int my_init_filesystem(void)
/* register mount table */
while(mtbl->dev) {
mtbl->dev->Init = my_initDevice;
mtbl->dev->Release = my_releaseDevice;
mtbl->dev->attr = &flash_storage;
// setup device init/release entry
mtbl->dev->Init = my_InitDevice;
mtbl->dev->Release = my_ReleaseDevice;
uffs_RegisterMountTable(mtbl);
mtbl++;
}
......
......@@ -33,7 +33,7 @@
/**
* \file static-mem-allocate.c
* \brief demostrate how to use static memory allocation. This example use
* file emulated NAND flash.
* file emulated NAND flash, one partition only.
* \author Ricky Zheng
*/
......@@ -61,8 +61,6 @@ int main()
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
......@@ -86,46 +84,41 @@ static struct uffs_MountTableEntrySt demo_mount = {
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)
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; /* ecc option */
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_emu_private(uffs_FileEmu *emu)
static void setup_device(uffs_Device *dev)
{
memset(emu, 0, sizeof(uffs_FileEmu));
emu->emu_filename = DEFAULT_EMU_FILENAME;
// 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 emu storage */
setup_emu_storage(&emu_storage);
setup_emu_private(&emu_private);
emu_storage._private = &emu_private;
mtbl->dev->attr = &emu_storage;
/* 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 */
uffs_fileem_setup_device(mtbl->dev);
/* setup device: init, release, attr */
setup_device(mtbl->dev);
/* register mount table */
uffs_RegisterMountTable(mtbl);
......@@ -150,6 +143,7 @@ int main(int argc, char *argv[])
}
cli_add_commandset(get_helper_cmds());
cli_add_commandset(get_test_cmds());
cliMain();
release_uffs_fs();
......
......@@ -37,25 +37,25 @@
#ifndef _UFFS_H_
#define _UFFS_H_
#include <dfs_def.h>
#include "uffs/uffs_types.h"
#ifdef __cplusplus
extern "C"{
#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_CREATE 0x0100
#define UO_TRUNC 0x0200
#define UO_EXCL 0x0400
#define UO_CREATE DFS_O_CREAT
#define UO_TRUNC DFS_O_TRUNC
#define UO_EXCL DFS_O_EXCL
#define UO_DIR 0x1000 /** open a directory */
#define UO_DIR DFS_O_DIRECTORY /** open a directory */
......@@ -81,14 +81,14 @@ extern "C"{
#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
#define USEEK_SET DFS_SEEK_SET /*0* 从当前点寻找 */
#define USEEK_CUR DFS_SEEK_CUR /*1* 从文件的开始寻找 */
#define USEEK_END DFS_SEEK_END /*2* 从文件的结尾寻找 */
......@@ -104,7 +104,7 @@ extern "C"{
#define FILE_ATTR_WRITE (1 << 0) //!< writable
/**
/*
* \structure uffs_FileInfoSt
* \brief file/dir entry info in physical storage format
*/
......
......@@ -191,7 +191,7 @@
*
* \note Enable this will ensure your data always be stored on completly good blocks.
*/
#define CONFIG_BAD_BLOCK_POLICY_STRICT
//#define CONFIG_BAD_BLOCK_POLICY_STRICT
......
......@@ -69,30 +69,32 @@
/**
* \brief POSIX dirent
*/
struct uffs_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 */
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 {
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;
}uffs_DIR;
/**
* \brief POSIX stat
*/
struct uffs_stat {
struct uffs_stat
{
int st_dev; /* ID of device containing file */
int st_ino; /* inode number */
int st_mode; /* protection */
......@@ -109,8 +111,8 @@ struct uffs_stat {
};
URET uffs_InitDirEntryBuf(void);
URET uffs_ReleaseDirEntryBuf(void);
int uffs_InitDirEntryBuf(void);
int uffs_ReleaseDirEntryBuf(void);
uffs_Pool * uffs_GetDirEntryBufPool(void);
/* POSIX compliant file system APIs */
......
......@@ -151,7 +151,7 @@ UBOOL uffs_IsSrcNewerThanObj(int src, int obj);
#define TENDSTR "\n"
//#define UFFS_DBG_LEVEL UFFS_ERR_NORMAL
#define UFFS_DBG_LEVEL UFFS_ERR_NOISY
#define UFFS_DBG_LEVEL UFFS_ERR_DEAD
void uffs_DebugMessage(int level, const char *prefix, const char *suffix, const char *errFmt, ...);
......
......@@ -146,6 +146,8 @@ typedef int URET;
#endif // _UBASE_
/* RT-Thread info */
#define memset rt_memset
#ifdef __cplusplus
}
......
......@@ -40,7 +40,8 @@
#include "uffs/uffs_config.h"
#include "uffs/uffs_ecc.h"
#include "uffs/uffs_badblock.h"
#include <string.h>
#include <rtthread.h>
#define PFX "bbl: "
......@@ -49,7 +50,6 @@ void uffs_BadBlockInit(uffs_Device *dev)
dev->bad.block = UFFS_INVALID_BLOCK;
}
/**
* \brief process bad block: erase bad block, mark it as 'bad' and put the node to bad block list.
* \param[in] dev uffs device
......@@ -196,7 +196,7 @@ void uffs_BadBlockRecover(uffs_Device *dev)
dev->ops->EraseBlock(dev, good->u.list.block);
uffs_TreeInsertToErasedListTail(dev, good); //put back to erased list
}
type = type;
uffs_BlockInfoPut(dev, bc);
}
......
......@@ -40,9 +40,9 @@
#include "uffs/uffs_public.h"
#include "uffs/uffs_os.h"
#include <string.h>
#include <rtthread.h>
#define PFX "bc : "
#define PFX "bc: "
#define UFFS_CLONE_BLOCK_INFO_NEXT ((uffs_BlockInfo *)(-2))
......@@ -52,8 +52,8 @@
* \param[in] dev uffs device
* \param[in] maxCachedBlocks maximum cache buffers to be allocated
* \return result of initialization
* \retval U_SUCC successful
* \retval U_FAIL failed
* \retval RT_EOK successful
* \retval RT_ERROR failed
*/
URET uffs_BlockInfoInitCache(uffs_Device *dev, int maxCachedBlocks)
{
......@@ -195,11 +195,11 @@ static void _MoveBcToTail(uffs_Device *dev, uffs_BlockInfo *bc)
* \brief load page spare data to given block info structure with given page number
* \param[in] dev uffs device
* \param[in] work given block info to be filled with
* \param[in] page given page number to be read from, if #UFFS_ALL_PAGES is presented, it will read
* \param[in] page given page number to be read from, if#UFFS_ALL_PAGES is presented, it will read
* all pages, otherwise it will read only one given page.
* \return load result
* \retval U_SUCC successful
* \retval U_FAIL fail to load
* \retval RT_EOK successful
* \retval RT_ERROR fail to load
* \note work->block must be set before load block info
*/
URET uffs_BlockInfoLoad(uffs_Device *dev, uffs_BlockInfo *work, int page)
......@@ -330,7 +330,7 @@ void uffs_BlockInfoPut(uffs_Device *dev, uffs_BlockInfo *p)
* \brief make the given pages expired in given block info buffer
* \param[in] dev uffs device
* \param[in] p pointer of block info buffer
* \param[in] page given page number. if #UFFS_ALL_PAGES presented, all pages in the block should be made expired.
* \param[in] page given page number. if#UFFS_ALL_PAGES presented, all pages in the block should be made expired.
*/
void uffs_BlockInfoExpire(uffs_Device *dev, uffs_BlockInfo *p, int page)
{
......
......@@ -577,7 +577,7 @@ static URET uffs_BufFlush_Exist_With_BlockCover(
UBOOL succRecover; //U_TRUE: recover successful, erase old block,
//U_FALSE: fail to recover, erase new block
UBOOL flash_op_err;
u16 data_sum;
u16 data_sum=0;
type = dev->buf.dirtyGroup[slot].dirty->type;
parent = dev->buf.dirtyGroup[slot].dirty->parent;
......
......@@ -71,7 +71,7 @@ void uffs_DebugMessage(int level, const char *prefix, const char *suffix, const
if (strlen(errFmt) > 800) {
// dangerous!!
printf("uffs_Perror buffer is not enough !");
rt_kprintf("uffs_Perror buffer is not enough !");
return;
}
......@@ -96,7 +96,7 @@ void uffs_DebugMessage(int level, const char *prefix, const char *suffix, const
fclose(fp);
}
#else
printf("%s", buf);
rt_kprintf("%s", buf);
#endif
}
#endif //ENABLE_DEBUG
......@@ -139,6 +139,6 @@ void uffs_Perror( int level, const char *errFmt, ...)
*/
void uffs_AssertCall(const char *file, int line, const char *msg)
{
printf("ASSERT %s:%d - msg:%s\n", file, line, msg);
rt_kprintf("ASSERT %s:%d - msg:%s\n", file, line, msg);
while (1);
}
......@@ -30,16 +30,15 @@
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs_fd.c
* \brief POSIX like, hight level file operations
* \author Ricky Zheng, created 8th Jun, 2005
*/
#include <string.h>
#include "uffs/uffs_config.h"
#include "uffs/uffs_device.h"
#include "uffs/uffs_mtb.h"
#include "uffs/uffs_utils.h"
#include "uffs/uffs_fs.h"
#include "uffs/uffs_fd.h"
#define PFX "fd: "
......@@ -83,7 +82,7 @@ static int _uffs_errno = 0;
/**
* initialise uffs_DIR buffers, called by UFFS internal
*/
URET uffs_InitDirEntryBuf(void)
int uffs_InitDirEntryBuf(void)
{
return uffs_PoolInit(&_dir_pool, _dir_pool_data, sizeof(_dir_pool_data),
sizeof(uffs_DIR), MAX_DIR_HANDLE);
......@@ -92,7 +91,7 @@ URET uffs_InitDirEntryBuf(void)
/**
* Release uffs_DIR buffers, called by UFFS internal
*/
URET uffs_ReleaseDirEntryBuf(void)
int uffs_ReleaseDirEntryBuf(void)
{
return uffs_PoolRelease(&_dir_pool);
}
......@@ -106,7 +105,7 @@ static uffs_DIR * GetDirEntry(void)
{
uffs_DIR *dirp = (uffs_DIR *) uffs_PoolGet(&_dir_pool);
if (dirp)
if(dirp)
memset(dirp, 0, sizeof(uffs_DIR));
return dirp;
......@@ -292,6 +291,7 @@ int uffs_remove(const char *name)
return ret;
}
int uffs_truncate(int fd, long remain)
{
int ret;
......@@ -436,14 +436,16 @@ ext:
return ret;
}
struct uffs_dirent * uffs_readdir(uffs_DIR *dirp)
struct uffs_dirent* uffs_readdir(uffs_DIR *dirp)
{
struct uffs_dirent *ent;
struct uffs_dirent *ent = &dirp->dirent;
CHK_DIR(dirp, NULL);
//CHK_DIR(dirp, NULL);
if(dirp == NULL)
return NULL;
if (uffs_FindObjectNext(&dirp->info, &dirp->f) == U_SUCC) {
ent = &dirp->dirent;
if(uffs_FindObjectNext(&dirp->info, &dirp->f) == RT_EOK)
{
ent->d_ino = dirp->info.serial;
ent->d_namelen = dirp->info.info.name_len;
memcpy(ent->d_name, dirp->info.info.name, ent->d_namelen);
......@@ -462,10 +464,14 @@ void uffs_rewinddir(uffs_DIR *dirp)
{
CHK_DIR_VOID(dirp);
uffs_FindObjectRewind(&dirp->f);
uffs_FindObjectRewind(&dirp->f); //fi(=)find info
}
/*
* 函数功能: 创建一个文件夹
* 输入参数: 文件夹名称,参数
* 返回参数:
*/
int uffs_mkdir(const char *name, ...)
{
uffs_Object *obj;
......@@ -493,6 +499,11 @@ int uffs_mkdir(const char *name, ...)
return ret;
}
/*
* 函数功能: 移除一个文件夹
* 输入参数: 文件夹名称
* 返回参数:
*/
int uffs_rmdir(const char *name)
{
int err = 0;
......@@ -518,15 +529,3 @@ int uffs_rmdir(const char *name)
return ret;
}
#if 0
void uffs_seekdir(uffs_DIR *dirp, long loc)
{
return ;
}
long uffs_telldir(uffs_DIR *dirp)
{
return 0;
}
#endif
......@@ -167,10 +167,13 @@ static URET do_FindObject(uffs_FindInfo *f, uffs_ObjectInfo *info, u16 x)
TreeNode *node;
uffs_Device *dev = f->dev;
if (f->step == 0) { //!< working on dirs
while (x != EMPTY_NODE) {
if (f->step == 0)
{ //!< working on dirs
while (x != EMPTY_NODE)
{
node = FROM_IDX(x, TPOOL(dev));
if (node->u.dir.parent == f->serial) {
if (node->u.dir.parent == f->serial)
{
f->work = node;
f->pos++;
if (info)
......@@ -182,11 +185,14 @@ static URET do_FindObject(uffs_FindInfo *f, uffs_ObjectInfo *info, u16 x)
f->hash++; //come to next hash entry
for (; f->hash < DIR_NODE_ENTRY_LEN; f->hash++) {
for (; f->hash < DIR_NODE_ENTRY_LEN; f->hash++)
{
x = dev->tree.dir_entry[f->hash];
while (x != EMPTY_NODE) {
while (x != EMPTY_NODE)
{
node = FROM_IDX(x, TPOOL(dev));
if (node->u.dir.parent == f->serial) {
if (node->u.dir.parent == f->serial)
{
f->work = node;
f->pos++;
if (info)
......@@ -203,11 +209,14 @@ static URET do_FindObject(uffs_FindInfo *f, uffs_ObjectInfo *info, u16 x)
x = EMPTY_NODE;
}
if (f->step == 1) {
if (f->step == 1)
{
while (x != EMPTY_NODE) {
while (x != EMPTY_NODE)
{
node = FROM_IDX(x, TPOOL(dev));
if (node->u.file.parent == f->serial) {
if (node->u.file.parent == f->serial)
{
f->work = node;
f->pos++;
if (info)
......@@ -219,11 +228,14 @@ static URET do_FindObject(uffs_FindInfo *f, uffs_ObjectInfo *info, u16 x)
f->hash++; //come to next hash entry
for (; f->hash < FILE_NODE_ENTRY_LEN; f->hash++) {
for (; f->hash < FILE_NODE_ENTRY_LEN; f->hash++)
{
x = dev->tree.file_entry[f->hash];
while (x != EMPTY_NODE) {
while (x != EMPTY_NODE)
{
node = FROM_IDX(x, TPOOL(dev));
if (node->u.file.parent == f->serial) {
if (node->u.file.parent == f->serial)
{
f->work = node;
f->pos++;
if (info)
......
......@@ -295,7 +295,7 @@ static void UnloadSpare(uffs_Device *dev, const u8 *spare, uffs_Tags *tag, u8 *e
int uffs_FlashReadPageSpare(uffs_Device *dev, int block, int page, uffs_Tags *tag, u8 *ecc)
{
uffs_FlashOps *ops = dev->ops;
struct uffs_StorageAttrSt *attr = dev->attr;
// struct uffs_StorageAttrSt *attr = dev->attr;
u8 * spare_buf;
int ret = UFFS_FLASH_UNKNOWN_ERR;
UBOOL is_bad = U_FALSE;
......
......@@ -243,18 +243,22 @@ URET uffs_CreateObjectEx(uffs_Object *obj, uffs_Device *dev,
obj->name = name;
obj->name_len = name_len;
if (obj->type == UFFS_TYPE_DIR) {
if (obj->type == UFFS_TYPE_DIR)
{
if (name[obj->name_len - 1] == '/')
obj->name_len--;
}
else {
if (name[obj->name_len - 1] == '/') {
else
{
if (name[obj->name_len - 1] == '/')
{
obj->err = UENOENT;
goto ext;
}
}
if (obj->name_len == 0) {
if (obj->name_len == 0)
{
obj->err = UENOENT;
goto ext;
}
......@@ -263,28 +267,34 @@ URET uffs_CreateObjectEx(uffs_Object *obj, uffs_Device *dev,
uffs_ObjectDevLock(obj);
if (obj->type == UFFS_TYPE_DIR) {
if (obj->type == UFFS_TYPE_DIR)
{
//find out whether have file with the same name
node = uffs_TreeFindFileNodeByName(obj->dev, obj->name, obj->name_len, obj->sum, obj->parent);
if (node != NULL) {
if (node != NULL)
{
obj->err = UEEXIST; // we can't create a dir has the same name with exist file.
goto ext_1;
}
obj->node = uffs_TreeFindDirNodeByName(obj->dev, obj->name, obj->name_len, obj->sum, obj->parent);
if (obj->node != NULL) {
if (obj->node != NULL)
{
obj->err = UEEXIST; // we can't create a dir already exist.
goto ext_1;
}
}
else {
else
{
//find out whether have dir with the same name
node = uffs_TreeFindDirNodeByName(obj->dev, obj->name, obj->name_len, obj->sum, obj->parent);
if (node != NULL) {
if (node != NULL)
{
obj->err = UEEXIST;
goto ext_1;
}
obj->node = uffs_TreeFindFileNodeByName(obj->dev, obj->name, obj->name_len, obj->sum, obj->parent);
if (obj->node) {
if (obj->node)
{
/* file already exist, truncate it to zero length */
obj->serial = GET_OBJ_NODE_SERIAL(obj);
obj->open_succ = U_TRUE; // set open_succ to U_TRUE before call do_TruncateObject()
......@@ -296,20 +306,23 @@ URET uffs_CreateObjectEx(uffs_Object *obj, uffs_Device *dev,
/* dir|file does not exist, create a new one */
obj->serial = uffs_FindFreeFsnSerial(obj->dev);
if (obj->serial == INVALID_UFFS_SERIAL) {
if (obj->serial == INVALID_UFFS_SERIAL)
{
uffs_Perror(UFFS_ERR_SERIOUS, "No free serial num!");
obj->err = UENOMEM;
goto ext_1;
}
if (obj->dev->tree.erased_count < MINIMUN_ERASED_BLOCK) {
if (obj->dev->tree.erased_count < MINIMUN_ERASED_BLOCK)
{
uffs_Perror(UFFS_ERR_NOISY, "insufficient block in create obj");
obj->err = UENOMEM;
goto ext_1;
}
buf = uffs_BufNew(obj->dev, obj->type, obj->parent, obj->serial, 0);
if (buf == NULL) {
if (buf == NULL)
{
uffs_Perror(UFFS_ERR_SERIOUS, "Can't create new buffer when create obj!");
goto ext_1;
}
......@@ -338,7 +351,8 @@ URET uffs_CreateObjectEx(uffs_Object *obj, uffs_Device *dev,
else
obj->node = uffs_TreeFindFileNode(obj->dev, obj->serial);
if (obj->node == NULL) {
if (obj->node == NULL)
{
uffs_Perror(UFFS_ERR_NOISY, "Can't find the node in the tree ?");
obj->err = UEIOERR;
goto ext_1;
......@@ -609,7 +623,7 @@ static URET do_FlushObject(uffs_Object *obj)
URET uffs_FlushObject(uffs_Object *obj)
{
uffs_Device *dev;
dev = dev;
if(obj->dev == NULL || obj->open_succ != U_TRUE) {
obj->err = UEBADF;
goto ext;
......@@ -640,7 +654,7 @@ URET uffs_CloseObject(uffs_Object *obj)
uffs_Buf *buf;
uffs_FileInfo fi;
#endif
dev = dev;
if(obj->dev == NULL || obj->open_succ != U_TRUE) {
obj->err = UEBADF;
goto ext;
......@@ -1406,17 +1420,20 @@ URET uffs_DeleteObject(const char * name, int *err)
uffs_ObjectDevLock(obj);
dev = obj->dev;
if (obj->type == UFFS_TYPE_DIR) {
if (obj->type == UFFS_TYPE_DIR)
{
// if the dir is not empty, can't delete it.
node = uffs_TreeFindDirNodeWithParent(dev, obj->serial);
if (node != NULL) {
if (node != NULL)
{
if (err)
*err = UEACCES;
goto err; //have sub dirs ?
}
node = uffs_TreeFindFileNodeWithParent(dev, obj->serial);
if (node != NULL) {
if (node != NULL)
{
if (err)
*err = UEACCES;
goto err; //have sub files ?
......
......@@ -96,16 +96,19 @@ URET uffs_InitMountTable(void)
}
work->dev->par.start = work->start_block;
if (work->end_block < 0) {
if (work->end_block < 0)
{
work->dev->par.end = work->dev->attr->total_blocks + work->end_block;
}
else {
else
{
work->dev->par.end = work->end_block;
}
uffs_Perror(UFFS_ERR_NOISY, "mount partiton: %d,%d",
work->dev->par.start, work->dev->par.end);
if (uffs_InitDevice(work->dev) != U_SUCC) {
if (uffs_InitDevice(work->dev) != U_SUCC)
{
uffs_Perror(UFFS_ERR_SERIOUS, "init device fail !");
return U_FAIL;
}
......
......@@ -229,7 +229,7 @@ int uffs_PoolPutLocked(uffs_Pool *pool, void *p)
void *uffs_PoolGetBufByIndex(uffs_Pool *pool, u32 index)
{
uffs_Assert(pool, "pool missing");
uffs_Assert(index >= 0 && index < pool->num_bufs, "index out of range");
uffs_Assert(index < pool->num_bufs, "index out of range");
return (u8 *) pool->mem + index * pool->buf_size;
}
......
......@@ -74,14 +74,17 @@ URET uffs_TreeInit(uffs_Device *dev)
pool = &(dev->mem.tree_pool);
if (dev->mem.tree_nodes_pool_size == 0) {
if (dev->mem.malloc) {
if (dev->mem.tree_nodes_pool_size == 0)
{
if (dev->mem.malloc)
{
dev->mem.tree_nodes_pool_buf = dev->mem.malloc(dev, size * num);
if (dev->mem.tree_nodes_pool_buf)
dev->mem.tree_nodes_pool_size = size * num;
}
}
if (size * num > dev->mem.tree_nodes_pool_size) {
if (size * num > dev->mem.tree_nodes_pool_size)
{
uffs_Perror(UFFS_ERR_DEAD, "Tree buffer require %d but only %d available.", size * num, dev->mem.tree_nodes_pool_size);
memset(pool, 0, sizeof(uffs_Pool));
return U_FAIL;
......@@ -96,15 +99,18 @@ URET uffs_TreeInit(uffs_Device *dev)
dev->tree.bad = NULL;
dev->tree.bad_count = 0;
for (i = 0; i < DIR_NODE_ENTRY_LEN; i++) {
for (i = 0; i < DIR_NODE_ENTRY_LEN; i++)
{
dev->tree.dir_entry[i] = EMPTY_NODE;
}
for (i = 0; i < FILE_NODE_ENTRY_LEN; i++) {
for (i = 0; i < FILE_NODE_ENTRY_LEN; i++)
{
dev->tree.file_entry[i] = EMPTY_NODE;
}
for (i = 0; i < DATA_NODE_ENTRY_LEN; i++) {
for (i = 0; i < DATA_NODE_ENTRY_LEN; i++)
{
dev->tree.data_entry[i] = EMPTY_NODE;
}
......@@ -121,7 +127,8 @@ URET uffs_TreeRelease(uffs_Device *dev)
uffs_Pool *pool;
pool = &(dev->mem.tree_pool);
if (pool->mem && dev->mem.free) {
if (pool->mem && dev->mem.free)
{
dev->mem.free(dev, pool->mem);
pool->mem = NULL;
dev->mem.tree_nodes_pool_size = 0;
......@@ -1003,7 +1010,7 @@ TreeNode * uffs_TreeGetErasedNode(uffs_Device *dev)
static void _InsertToEntry(uffs_Device *dev, u16 *entry, int hash, TreeNode *node)
{
struct uffs_TreeSt *tree = &(dev->tree);
/* struct uffs_TreeSt *tree = &(dev->tree); */
node->hash_next = entry[hash];
#ifdef CONFIG_TREE_NODE_USE_DOUBLE_LINK
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册