Browse Source

fixed bug: no release uffs_object_handler in dfs_uffs.c
function:dfs_uffs_open()

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1363 bbd45198-f89e-11dd-88c7-29a3b14d5316

iamyhw@gmail.com 14 years ago
parent
commit
8d77fe70dc

+ 34 - 29
components/dfs/filesystems/uffs/dfs_nand_if.c

@@ -10,6 +10,7 @@
  * \file nand flash interface example
  * \brief example for using nand flash driver and multiple partitions, with system memory allocator.
  * \author Ricky Zheng, created at 27 Nov, 2007
+ * \modify amsl, at 17 Jan, 2010 iamyhw@gmail.com 
  */
 
 #include <rtthread.h>
@@ -88,40 +89,42 @@ static int nand_is_badblock(uffs_Device *dev,u32 block)
 	return K9F2G08_Check_badblk(block);
 }
 
+/* The only uffs v1.3.2-4 can used. */
 static uffs_FlashOps nand_driver_ops = 
 {
-	nand_read_page_data,    //ReadPageData
-	nand_read_page_spare,   //ReadPageSpare
-	NULL,                	//ReadPageSpareWithLayout
-	nand_write_page_data,   //WritePageData
-	nand_write_page_spare,  //WritePageSpare
-	NULL,					//WriteFullPage		
-	nand_is_badblock,       //IsBadBlock
-	nand_mark_badblock,     //MarkBadBlock
-	nand_erase_block,       //EraseBlock
+	nand_read_page_data,    /* ReadPageData	*/
+	nand_read_page_spare,   /* ReadPageSpare */
+	NULL,                	/* ReadPageSpareWithLayout */
+	nand_write_page_data,   /* WritePageData */
+	nand_write_page_spare,  /* WritePageSpare */
+	NULL,					/* WriteFullPage */		
+	nand_is_badblock,       /* IsBadBlock */
+	nand_mark_badblock,     /* 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
-
 static struct uffs_StorageAttrSt flash_storage = {0};
 
 static int initDevice(uffs_Device *dev)
 {
 	dev->ops = &nand_driver_ops;
-	return RT_EOK;
+	return U_SUCC;
 }
 
 static int releaseDevice(uffs_Device *dev)
 {
-	return RT_EOK;
+	return U_SUCC;
 }
 
 #include <dfs_uffs.h>
 
 static uffs_Device uffs_device = {0};
-/* define mount table,UFFS FS private data */
-/* it is absolute accessing for uffs.*/
+
+/* 
+ * define mount table,UFFS FS private data
+ * it is absolute accessing for uffs.
+ * set struct data on the RT-Thread device 
+ */
 static uffs_MountTable uffs_mount_table = 
 {
 	&uffs_device, 
@@ -175,40 +178,42 @@ struct nand_flash_dev* nand_init(u8* buf)
 	return RT_NULL;
 }
 
-/* RT-Thread Device Driver Interface */
-/* UFFS FileSystem NandFlash InterFace */
-/* we don't use entity, let uffs autarky */
+/* 
+ * RT-Thread Device Driver Interface
+ * UFFS FileSystem NandFlash InterFace
+ * we don't use entity, let uffs autarky 
+ */
 
 struct rt_device nand_device;
 
 static rt_err_t rt_nand_init(rt_device_t dev)
 {
-	return 0;
+	return RT_EOK;
 }
 
 static rt_err_t rt_nand_open(rt_device_t dev, u16 oflag)
 {
-	return 0;
+	return RT_EOK;
 }
 
 static rt_err_t rt_nand_close(rt_device_t dev)
 {
-	return 0;
+	return RT_EOK;
 }
 
 static rt_err_t rt_nand_control(rt_device_t dev, u8 cmd, void *args)
 {
-	return 0;
+	return RT_EOK;
 }
 
 static rt_size_t rt_nand_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
 {	
-	return 0;
+	return RT_EOK;
 }
 
 static rt_size_t rt_nand_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
 {
-	return 0;
+	return RT_EOK;
 }
 
 void rt_hw_nand_init(void)
@@ -236,7 +241,7 @@ void rt_hw_nand_init(void)
 
 		/* about uffs codes */
 		entry = &uffs_mount_table;
-		//entry->lock = rt_sem_create("sem_nand0", 1, RT_IPC_FLAG_FIFO);//??it's lonely!how to do?
+		/* entry->lock = rt_sem_create("sem_nand0", 1, RT_IPC_FLAG_FIFO); */ /* it's lonely!how to do? */
 
 		uffs_MemSetupSystemAllocator(&(entry->dev->mem));
 		entry->dev->Init    = initDevice;
@@ -261,7 +266,7 @@ void rt_hw_nand_init(void)
 			extid >>= 2;
 			/* Calc blocksize. Blocksize is multiples of 64KiB */
 			chip->pages_per_block = ((64*1024)<<(extid & 0x03))/(chip->page_data_size);
-			/* The 5th id byte */
+			/* The 5th id byte,it is no use */
 			chip->total_blocks = (type->chipsize*1024*1024) / 
 								 chip->page_data_size / chip->pages_per_block;
 	
@@ -279,7 +284,7 @@ void rt_hw_nand_init(void)
 			chip->block_status_offs = NAND_SMALL_BADBLOCK_POS;
 		chip->ecc_opt    = UFFS_ECC_SOFT;    		/* ecc option, do not use ECC,debug */
 		chip->layout_opt = UFFS_LAYOUT_UFFS; 		/* let UFFS do the spare layout */
-#if (0)	//DEBUG trace facility 
+#if (0)	/* DEBUG trace facility */
 		rt_kprintf("page_data_size  = %d\n",chip->page_data_size);		
 		rt_kprintf("pages_per_block = %d\n",chip->pages_per_block);
 		rt_kprintf("spare_size      = %d\n",chip->spare_size);
@@ -289,5 +294,5 @@ void rt_hw_nand_init(void)
 	}
 }
 
-//end of file																				 
+/* end of file */																				 
 

+ 58 - 41
components/dfs/filesystems/uffs/dfs_uffs.c

@@ -37,36 +37,46 @@ int dfs_uffs_statfs(struct dfs_filesystem* fs, struct statfs *buf)
 }      
 
 int dfs_uffs_open(struct dfs_fd* fd)   
-{	
-	int ret=U_SUCC;
-
+{
 	if (fd->flags & DFS_O_DIRECTORY)
-	{//Îļþ¼Ð
-		uffs_DIR *dirp;
-		/* open directory */
+	{	/* directory */
+		uffs_DIR* dirp;
+		int oflag = UO_DIR;
+
+		if (fd->flags & DFS_O_CREAT) oflag |= UO_CREATE;
+		if (fd->flags & DFS_O_RDONLY) oflag |= UO_RDONLY;
+		if (fd->flags & DFS_O_WRONLY) oflag |= UO_WRONLY;
 		
-		if (fd->flags & DFS_O_CREAT)
-		{//´´½¨
-			ret = uffs_open(fd->path,UO_CREATE|UO_DIR);
-			if(ret != U_SUCC)
+		if (oflag & UO_CREATE)
+		{	/* create directory right now */
+			uffs_Object* fp = uffs_GetObject();
+			if(fp == NULL) 
+			{
+				uffs_set_error(-UEMFILE);
+				return U_FAIL;
+			}
+	
+			if(uffs_OpenObject(fp, fd->path, oflag) != U_SUCC)
 			{
 				return U_FAIL;
 			}
+			/* release object hander */
+			uffs_PutObject(fp);	
 		}
 
+		/* use directory handler */
 		dirp = uffs_opendir(fd->path);
 		if(dirp == NULL) 
 		{
 			uffs_set_error(-UEMFILE);
-			ret = U_FAIL;
+			return U_FAIL;
 		}
-
 		fd->data = dirp;
 
 		return U_SUCC;
 	}
 	else
-	{//Îļþ
+	{/* file */
 		uffs_Object *fp;
 		
 		int mode = UO_RDONLY;
@@ -80,17 +90,15 @@ int dfs_uffs_open(struct dfs_fd* fd)
 		/* 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 */
+		/* get an object hander */
 		fp = uffs_GetObject();
 		if(fp == NULL) 
 		{
 			uffs_set_error(-UEMFILE);
-			ret = U_FAIL;
+			return U_FAIL;
 		}
 
-		if(uffs_OpenObject(fp, fd->path, mode) == RT_EOK)
+		if(uffs_OpenObject(fp, fd->path, mode) == U_SUCC)
 		{
 			struct uffs_stat stat_buf;
 
@@ -104,20 +112,20 @@ int dfs_uffs_open(struct dfs_fd* fd)
 			{
 				fd->pos = uffs_SeekObject(fp, 0, USEEK_END);
 			}
-			ret = U_SUCC;
+			return U_SUCC;
 		}
 		else
 		{
 			/* open failed, return */
 			uffs_set_error(-uffs_GetObjectErr(fp));
+			/* release object hander */
 			uffs_PutObject(fp);
 			return U_FAIL;
 		}
-	}
-
-	return ret;  
+	} 
 }      
 
+
 int dfs_uffs_close(struct dfs_fd* fd)   
 {
 	int ret=U_SUCC;
@@ -125,21 +133,18 @@ int dfs_uffs_close(struct dfs_fd* fd)
 	if (fd->type == FT_DIRECTORY)
 	{
 		uffs_DIR* dirp;
-
 		dirp = (uffs_DIR*)(fd->data);
 		RT_ASSERT(dirp != RT_NULL);
 
-		uffs_closedir(dirp);
+		ret = uffs_closedir(dirp);
 	}
 	else if (fd->type == FT_REGULAR)
 	{
-		uffs_Object* fp;
-
-		fp = (uffs_Object*)(fd->data);
-
+		uffs_Object* fp = (uffs_Object*)(fd->data);
 		RT_ASSERT(fd != RT_NULL);
 
 		ret = uffs_CloseObject(fp);
+		/* release object hander */
 		uffs_PutObject(fp);
 	}
 
@@ -169,7 +174,7 @@ int dfs_uffs_read(struct dfs_fd* fd, void* buf, rt_size_t count)
 	RT_ASSERT(fd != RT_NULL);
 
 	/* update position */
-	fd->pos  = fp->pos;
+	fp->pos  = fd->pos;
 
 	return uffs_ReadObject(fp, buf, count);  
 }      
@@ -179,7 +184,7 @@ 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;
-
+rt_kprintf("count=%d\n",count);
 	if(fd->type == FT_DIRECTORY)
 	{
 		return -DFS_STATUS_EISDIR;
@@ -226,6 +231,11 @@ int dfs_uffs_getdents(struct dfs_fd* fd, struct dirent* dir, rt_uint32_t count)
 	rt_uint32_t index;
 	struct dirent* d;
 
+	if(fd->type != FT_DIRECTORY)
+	{
+		return -DFS_STATUS_EISDIR;
+	}
+
 	dirp = (uffs_DIR*)(fd->data);
 	RT_ASSERT(dirp != RT_NULL);
 
@@ -276,18 +286,25 @@ int dfs_uffs_stat(struct dfs_filesystem* fs, const char* path, struct stat* st)
 
 	if (ret == U_SUCC)
 	{
-		st->st_dev = 0;
-		//st->st_mode = stat_buf.st_mode;
+		rt_uint32_t mode=0;
+		st->st_dev = 0;
 		
-		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);
+		if(stat_buf.st_mode & US_IFREG)	mode |= DFS_S_IFREG; 
+		if(stat_buf.st_mode & US_IFDIR)	mode |= DFS_S_IFDIR; 
+		if(stat_buf.st_mode & US_IRWXU)	mode |= DFS_S_IRWXU; 
+		if(stat_buf.st_mode & US_IRUSR)	mode |= DFS_S_IRUSR; 
+		if(stat_buf.st_mode & US_IWUSR)	mode |= DFS_S_IWUSR; 
+		if(stat_buf.st_mode & US_IXUSR)	mode |= DFS_S_IXUSR; 
+		if(stat_buf.st_mode & US_IRWXG)	mode |= DFS_S_IRWXG; 
+		if(stat_buf.st_mode & US_IRGRP)	mode |= DFS_S_IRGRP; 
+		if(stat_buf.st_mode & US_IWGRP)	mode |= DFS_S_IWGRP; 
+		if(stat_buf.st_mode & US_IXGRP)	mode |= DFS_S_IXGRP; 
+		if(stat_buf.st_mode & US_IRWXO)	mode |= DFS_S_IRWXO; 
+		if(stat_buf.st_mode & US_IROTH)	mode |= DFS_S_IROTH; 
+		if(stat_buf.st_mode & US_IWOTH)	mode |= DFS_S_IWOTH; 
+		if(stat_buf.st_mode & US_IXOTH)	mode |= DFS_S_IXOTH; 
+
+		st->st_mode = mode;
 		st->st_size = stat_buf.st_size;
 		st->st_mtime= stat_buf.st_mtime;
 		st->st_blksize= stat_buf.st_blksize;

+ 1 - 0
components/dfs/filesystems/uffs/flash/K9F2G08.h

@@ -2,6 +2,7 @@
 #define __K9F2G08_H__
 
 #include <rtdef.h>
+#include <s3c24x0.h>
 #include <nand.h>
 
 void K9F2G08_Program(u32 blockIndex, u32 srcAddress, u32 fileSize);

+ 128 - 144
components/dfs/filesystems/uffs/flash/k9f2g08.c

@@ -1,10 +1,21 @@
-/**
- * 用户要自己实现这个文件中的接口函数,不一样的芯片会有不同的访问命令
- * 这个例程文件是关于Samsung k9f2g08芯片的,属于大页nandflash
+/*
+ * uffs/flash/k9f2g08.c
+ *
+ * COPYRIGHT (C) 2006 - 2011, 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
+ *
+ * Info:
+ *	Low hardware driver for samsung nandflash.
  */
+
+/* XXX UFFS XXX */
+#include <uffs/uffs_types.h>
+
 #include <nand.h>
 #include "s3c24x0.h" 
-
 #include <k9f2g08.h>
 
 #define nand_write_cmd(cmd)		(NFCMD  = (cmd))
@@ -17,51 +28,34 @@
 
 #define nand_wait()    	{while(!(NFSTAT&(1<<0)));} //wait tWB and check F_RNB pin. 
 
-//NAND Flash Command.support K9F2G08
-#define K9F2G08_CMD_READ0			0x00	//  Read0
-//#define K9F2G08_CMD_READ1			1		//  Read1,K9F2G08 don't support the command.
-#define K9F2G08_CMD_RANDOM_DATA_OUT	0x05	//  Random data output
-#define K9F2G08_CMD_PAGEPROG		0x10	//  Write phase 2
-#define K9F2G08_CMD_READ30			0x30	//  Read30
-#define K9F2G08_CMD_READ35			0x35	//  Read35
-//#define K9F2G08_CMD_READOOB			0x50	//  Read oob
-#define K9F2G08_CMD_ERASE1			0x60	//  Erase phase 1
-#define K9F2G08_CMD_STATUS			0x70	//  Status read
-#define K9F2G08_CMD_READ_EDC		0x7b	//  Read EDC Status
-#define K9F2G08_CMD_SEQIN			0x80	//  Write phase 1
-#define K9F2G08_CMD_RANDOM_DATA_IN	0x85	//  Random data input Copy-Back Program(0x85,0x10)
-#define K9F2G08_CMD_READID			0x90	//  ReadID,all-purpose command
-#define K9F2G08_CMD_ERASE2			0xd0	//  Erase phase 2
-#define K9F2G08_CMD_RESET			0xff	//  Reset
-
-#define BAD_CHECK	(0)
-#define ECC_CHECK	(0)
-
-
-//*************************************************
-//**           H/W dependent functions           **
-//************************************************* 
-
-// HCLK=100Mhz
-#define TACLS		1  //1clk(0ns) 
-#define TWRPH0		4  //3clk(25ns)
-#define TWRPH1		0  //1clk(10ns)  //TACLS+TWRPH0+TWRPH1>=50ns
-
-int read_nand_stats(void)	// R/B 未接好?
+/*
+*************************************************
+**           H/W dependent functions           **
+*************************************************
+*/ 
+
+/* HCLK=100Mhz */
+#define TACLS		1  /* 1clk(0ns)  */
+#define TWRPH0		4  /* 3clk(25ns) */
+#define TWRPH1		0  /* 1clk(10ns) */ /* TACLS+TWRPH0+TWRPH1>=50ns */
+
+int read_nand_stats(void)	/* R/B is fixed? */
 {
 	u8 stat;
 
-	nand_write_cmd(K9F2G08_CMD_STATUS);//0x70
+	nand_write_cmd(NAND_CMD_STATUS);
 
-	stat = nand_read();//读出返回的数据
+	stat = nand_read();/* read byte */
 
-	if(stat&1) return 1; // I/O0=1失败
-	else return 0; 		 // I/O0=0成功
+	if(stat&1) return 1; /* I/O0=1 successful */
+	else return 0; 		 /* I/O0=0 unsuccessful */
 }
 
-//擦除一个块
-//返回0,successful
-//返回1,error
+/*
+ *erase a block
+ *return 0,successful
+ *return 1,error
+ */
 int K9F2G08_EraseBlock(u32 block)
 {
 	int stat;
@@ -69,50 +63,55 @@ int K9F2G08_EraseBlock(u32 block)
     
     nand_cs_en();
     
-    nand_write_cmd(K9F2G08_CMD_ERASE1);   // Erase one block 1st command
+    nand_write_cmd(NAND_CMD_ERASE1);   /* Erase one block 1st command */
 
-    nand_write_addr(_page&0xff);	    // Page number=0
+    nand_write_addr(_page&0xff);	    /* Page number=0 */
     nand_write_addr((_page>>8)&0xff);   
     nand_write_addr((_page>>16)&0xff);
 
-    nand_write_cmd(K9F2G08_CMD_ERASE2);   // Erase one blcok 2nd command
+    nand_write_cmd(NAND_CMD_ERASE2);   /* Erase one blcok 2nd command */
     
-	nand_wait();    // Wait tBERS max 3ms.
+	nand_wait();    /* Wait tBERS max 3ms. */
 
     stat = read_nand_stats();
 	nand_cs_ds();
 	return stat;
 }
 
-//return 1 if it's a bad block, 0 if it's good.
-int K9F2G08_Check_badblk(u32 block)	//0:bad,1:good
+/*
+ * check block is bad?
+ * return 1 if it's a bad block, 0 if it's good.
+ */
+int K9F2G08_Check_badblk(u32 block)
 {
     u8 data;
-    u32 _page;//块的首页地址
+    u32 _page;/* frist page in block */
     
-    _page = block*PAGES_PER_BLOCK;	// For 2'nd cycle I/O[7:5] 
+    _page = block*PAGES_PER_BLOCK;	/* For 2'nd cycle I/O[7:5] */
     
     nand_cs_en();
 	    
-    nand_write_cmd(K9F2G08_CMD_READ0);		// Spare array read command
-    nand_write_addr(PAGE_DATA_SIZE&0xff);		// Read the mark of bad block in spare array(M addr=5)
+    nand_write_cmd(NAND_CMD_READ0);		  	/* Spare array read command	*/
+    nand_write_addr(PAGE_DATA_SIZE&0xff); 	/* Read the mark of bad block in spare array(M addr=5) */
 	nand_write_addr((PAGE_DATA_SIZE>>8)&0xff); 
-    nand_write_addr(_page&0xff);	// The mark of bad block is in 0 page
-    nand_write_addr((_page>>8)&0xff);   // For block number A[24:17]
-    nand_write_addr((_page>>16)&0xff);  // For block number A[25]
-	nand_write_cmd(K9F2G08_CMD_READ30);
+    nand_write_addr(_page&0xff);		  	/* The mark of bad block is in 0 page */
+    nand_write_addr((_page>>8)&0xff);   	/* For block number A[24:17] */
+    nand_write_addr((_page>>16)&0xff);  	/* For block number A[25] */
+	nand_write_cmd(NAND_CMD_READSTART);
 
-    nand_wait();	// Wait tR(max 12us)
+    nand_wait();	/* Wait tR(max 12us) */
     
     data=nand_read();
     nand_cs_ds();    
     if(data==0x00)
-    	return 1;//坏块
+    	return 1;/* bad */
     else
-    	return 0;//好块
+    	return 0;/* good */
 }
-
-//return 0 if ok, 1:fail
+/*
+ * mark a block is bad
+ * return 0 if ok, 1:fail
+ */
 int K9F2G08_Mark_badblk(u32 block)
 {
 	u8 stat;
@@ -120,20 +119,20 @@ int K9F2G08_Mark_badblk(u32 block)
     
     nand_cs_en(); 
 
-    nand_write_cmd(K9F2G08_CMD_SEQIN);   	// Write 1st command
+    nand_write_cmd(NAND_CMD_SEQIN);   	/* Write 1st command */
     
-    nand_write_addr(PAGE_DATA_SIZE & 0xff);		    // The mark of bad block
+    nand_write_addr(PAGE_DATA_SIZE & 0xff);/* The mark of bad block	*/
 	nand_write_addr((PAGE_DATA_SIZE>>8)&0xff);
-    nand_write_addr(_page&0xff);	    // marked 5th spare array 
-    nand_write_addr((_page>>8)&0xff);   // in the 1st page.
-    nand_write_addr((_page>>16)&0xff);  //
+    nand_write_addr(_page&0xff);	    /* marked 1th spare array */
+    nand_write_addr((_page>>8)&0xff);   /* in the 1st page. */
+    nand_write_addr((_page>>16)&0xff); 
     
-    nand_write(0x00);	//坏块标记
+    nand_write(0x00);	/* 0x00 is commendatory make of the bad block. */
 
-    nand_write_cmd(K9F2G08_CMD_PAGEPROG);   // Write 2nd command
+    nand_write_cmd(NAND_CMD_PAGEPROG);   /* Write 2nd command */
 
-    nand_wait();      // Wait tPROG(200~500us)
-    stat = read_nand_stats();//查询是否成功
+    nand_wait();      /* Wait tPROG(200~500us) */
+    stat = read_nand_stats();
 	nand_cs_ds();
 
     return stat;
@@ -145,23 +144,23 @@ int K9F2G08_ReadPage(u32 block, u32 page, u8 *buffer, int len, u8 *ecc)
     int i;
     u32 _page = block*PAGES_PER_BLOCK + page;
     
-//    NF_RSTECC();    // Initialize ECC
+	/* NF_RSTECC(); */ /* Initialize ECC*/
     
     nand_cs_en(); 
 	   
-    nand_write_cmd(K9F2G08_CMD_READ0);   // Read command
-    nand_write_addr(0x00);	// Column = 0
+    nand_write_cmd(NAND_CMD_READ0);   	/* Read command */
+    nand_write_addr(0x00);				/* Column = 0 */
 	nand_write_addr(0x00);
-    nand_write_addr(_page&0xff);	    //
-    nand_write_addr((_page>>8)&0xff);   // Block & Page num.
-    nand_write_addr((_page>>16)&0xff);  //
+    nand_write_addr(_page&0xff);
+    nand_write_addr((_page>>8)&0xff);
+    nand_write_addr((_page>>16)&0xff); 
 
-	nand_write_cmd(K9F2G08_CMD_READ30);
+	nand_write_cmd(NAND_CMD_READSTART);
     
-    nand_wait();    // Wait tR(max 12us)
+    nand_wait();    /* Wait tR(max 12us) */
     for(i=0;i<len;i++)
     {
-    	buffer[i] = nand_read();	// Read one page
+    	buffer[i] = nand_read();	/* Read one page */
     }
 
     nand_cs_ds();    
@@ -175,23 +174,23 @@ int K9F2G08_ReadTags(u32 block, u32 page, u8 *spare, int ofs, int len)
 
 	u32 _page = block*PAGES_PER_BLOCK + page;
 
-//    NF_RSTECC();    // Initialize ECC
+	/* NF_RSTECC(); */ /* Initialize ECC */
     
     nand_cs_en(); 
 	   
-    nand_write_cmd(K9F2G08_CMD_READ0);   // Read command
-    nand_write_addr((PAGE_DATA_SIZE+ofs)&0xff);	// Column = 0
+    nand_write_cmd(NAND_CMD_READ0);
+    nand_write_addr((PAGE_DATA_SIZE+ofs)&0xff);
 	nand_write_addr(((PAGE_DATA_SIZE+ofs)>>8)&0xff);
-    nand_write_addr(_page&0xff);	    //
-    nand_write_addr((_page>>8)&0xff);   // Block & Page num.
-    nand_write_addr((_page>>16)&0xff);  //
+    nand_write_addr(_page&0xff);
+    nand_write_addr((_page>>8)&0xff); 
+    nand_write_addr((_page>>16)&0xff);
 
-	nand_write_cmd(K9F2G08_CMD_READ30);
+	nand_write_cmd(NAND_CMD_READSTART);
     
-    nand_wait();    // Wait tR(max 12us)
+    nand_wait();    /* Wait tR(max 12us) */
     for(i=0;i<len;i++)
     {
-    	spare[i] = nand_read();	// Read one page
+    	spare[i] = nand_read();	/* Read one page */
     }
 
     nand_cs_ds();    
@@ -199,34 +198,36 @@ int K9F2G08_ReadTags(u32 block, u32 page, u8 *spare, int ofs, int len)
 	return 1;
 }
 
-//写一页数据
-//返回0,successful
-//返回1,error
+/*
+ * write one page data
+ * return 0,successful
+ * return 1,error
+ */
 int K9F2G08_WritePage(u32 block, u32 page, const u8 *buffer, int len, const u8 *ecc)
 {
     int i,stat;
 
 	u32 _page = block*PAGES_PER_BLOCK + page;
 
-    //nand_Init_ECC();    // Initialize ECC
+    /* nand_Init_ECC(); */  /* nitialize ECC */
     
     nand_cs_en(); 
 
-    nand_write_cmd(K9F2G08_CMD_SEQIN);   //0x80 Write 1st command
+    nand_write_cmd(NAND_CMD_SEQIN);
 	for(i=0;i<10;i++); 
-    nand_write_addr(0x00);			    // Column 0
+    nand_write_addr(0x00);			    /* Column 0	*/
 	nand_write_addr(0x00);
-    nand_write_addr(_page&0xff);	    //
-    nand_write_addr((_page>>8)&0xff);   // Block & page num.
-    nand_write_addr((_page>>16)&0xff);  //
+    nand_write_addr(_page&0xff);
+    nand_write_addr((_page>>8)&0xff);
+    nand_write_addr((_page>>16)&0xff);
 
     for(i=0;i<len;i++)
     {
-		nand_write(*buffer++);	// Write one page to NFM from buffer
+		nand_write(*buffer++);
     }  
-    nand_write_cmd(K9F2G08_CMD_PAGEPROG);   //0x10 Write 2nd command
+    nand_write_cmd(NAND_CMD_PAGEPROG);
 
-    nand_wait();    //wait tPROG 200~500us;
+    nand_wait();    /* wait tPROG 200~500us; */
  
 	stat = read_nand_stats();
     nand_cs_ds();
@@ -239,29 +240,29 @@ int K9F2G08_WriteTags(u32 block, u32 page, const u8 *spare, int ofs, int len)
     int i,stat;
 	u32 _page = block*PAGES_PER_BLOCK + page;
 
-    //nand_Init_ECC();    // Initialize ECC
+    /* nand_Init_ECC(); */  /* Initialize ECC */
     
     nand_cs_en(); 
 
-    nand_write_cmd(K9F2G08_CMD_SEQIN);   //0x80 Write 1st command
+    nand_write_cmd(NAND_CMD_SEQIN);
 	for(i=0;i<10;i++); 
-    nand_write_addr((PAGE_DATA_SIZE+ofs)&0xff);			    // Column 0
+    nand_write_addr((PAGE_DATA_SIZE+ofs)&0xff);
 	nand_write_addr(((PAGE_DATA_SIZE+ofs)>>8)&0xff);
-    nand_write_addr(_page&0xff);	    //
-    nand_write_addr((_page>>8)&0xff);   // Block & page num.
-    nand_write_addr((_page>>16)&0xff);  //
+    nand_write_addr(_page&0xff);
+    nand_write_addr((_page>>8)&0xff);
+    nand_write_addr((_page>>16)&0xff);
 
     for(i=0;i<len;i++)
     {
-		nand_write(*spare++);	// Write one page to NFM from buffer
+		nand_write(*spare++);
     }   
 
-    nand_write_cmd(K9F2G08_CMD_PAGEPROG);   //0x10 Write 2nd command
+    nand_write_cmd(NAND_CMD_PAGEPROG);
 
-    nand_wait();    //wait tPROG 200~500us;
+    nand_wait();    /* wait tPROG 200~500us; */
  
 	stat = read_nand_stats();
-    if(!stat) // Page write error
+    if(!stat) /* Page write error */
     {	
     	nand_cs_ds();
 		return 0;
@@ -273,38 +274,21 @@ int K9F2G08_WriteTags(u32 block, u32 page, const u8 *spare, int ofs, int len)
     }
 }
 
-//find frist shift bit
-//rt_inline int generic_ffs(int x)
-//{
-//	int r = 1;
-//
-//	if(!x)
-//		return 0;
-//
-//	if(!(x & 0xffff)) {x >>= 16;r += 16;}
-//	if(!(x & 0xff))   {x >>= 8;r += 8;}
-//	if(!(x & 0xf))    {x >>= 4;r += 4;}
-//	if(!(x & 3))      {x >>= 2;r += 2;}
-//	if(!(x & 1))      {x >>= 1;r += 1;}
-//
-//	return r;
-//}
-
 /* when all is true,read all byte */
 void K9F2G08_ReadChipID(u8* buf, UBOOL all)
 {
 	nand_cs_en();    
 
-	nand_write_cmd(K9F2G08_CMD_READID);	//0x90
-	nand_write_addr(K9F2G08_CMD_READ0);
+	nand_write_cmd(NAND_CMD_READID);
+	nand_write_addr(NAND_CMD_READ0);
 
-	buf[0] = nand_read();//制造商ID
-	buf[1] = nand_read();//芯片ID
+	buf[0] = nand_read();/* manufacturer ID */
+	buf[1] = nand_read();/* physical chip ID */
 	if(all)
 	{
 		buf[2] = nand_read();
 		buf[3] = nand_read();
-		//buf[4] = nand_read();	//有的芯片没有第5个字节
+		/* buf[4] = nand_read(); */	/* Some chips have no 5th byte */ 
 	}
 
 	nand_cs_ds();
@@ -315,17 +299,17 @@ void K9F2G08_Init(void)
     NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<0);
 	NFCONT = (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0);
 	NFSTAT = 0;	
-    // 1  1    1     1,   1      xxx,  r xxx,   r xxx        
-    // En 512B 4step ECCR nFCE=H tACLS   tWRPH0   tWRPH1
+    /* 1  1    1     1,   1      xxx,  r xxx,   r xxx  */      
+    /* En 512B 4step ECCR nFCE=H tACLS   tWRPH0   tWRPH1 */
 }
 
 void K9F2G08_Reset(void)
 {
     nand_cs_en();
 
-    nand_write_cmd(0xFF);	//reset command
+    nand_write_cmd(0xFF);	/* reset command */
 
-    nand_wait();      //wait 200~500us;
+    nand_wait();      /* wait 200~500us */
     nand_cs_ds();
 
 	K9F2G08_Init();
@@ -338,24 +322,24 @@ int K9F2G08_ReadChunk(u32 chunk, u8 *data, u8 *tags)
 
     nand_cs_en(); 
 	   
-    nand_write_cmd(K9F2G08_CMD_READ0);   // Read command
+    nand_write_cmd(NAND_CMD_READ0);
 	nand_write_addr(0x00);
 	nand_write_addr(0x00);
-    nand_write_addr(chunk & 0xff);	    //
-    nand_write_addr((chunk >> 8) & 0xff);   // Block & Page num.
+    nand_write_addr(chunk & 0xff);
+    nand_write_addr((chunk >> 8) & 0xff);
     nand_write_addr((chunk >> 16) & 0xff);  //
-	//nand_Init_ECC();
-	nand_write_cmd(K9F2G08_CMD_READ30);   // Read command
+	/* nand_Init_ECC(); */
+	nand_write_cmd(NAND_CMD_READ30);
 
-    nand_wait();    // Wait tR(max 12us)
+    nand_wait();    /* Wait tR(max 12us) */
 
     for(i = 0; i < PAGE_DATA_SIZE; i++)
 	{	
-    	data[i] = nand_read();	// Read one page
+    	data[i] = nand_read();	/* Read page data */
 	}
     for(i = 0; i < PAGE_SPARE_SIZE; i++)
 	{	
-    	tags[i] = nand_read();	// Read spare array
+    	tags[i] = nand_read();	/* Read spare array	*/
     }
 
     nand_cs_ds();    

+ 47 - 33
components/dfs/filesystems/uffs/flash/nand.h

@@ -1,24 +1,40 @@
-//
-// Copyright (c) Microsoft Corporation.  All rights reserved.
-//
-//
-// Use of this source code is subject to the terms of the Microsoft end-user
-// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
-// If you did not accept the terms of the EULA, you are not authorized to use
-// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
-// install media.
-//
-/*++
-THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
-ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
-PARTICULAR PURPOSE.
---*/
-#ifndef __NAND_H__
-#define __NAND_H__
+/*
+ * uffs/flash/nand.h
+ *
+ * COPYRIGHT (C) 2006 - 2011, 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
+ *
+ * Info:
+ *	Contains standard defines and IDs for NAND flash devices
+ */
+#ifndef __RTT_DFS_NAND_H__
+#define __RTT_DFS_NAND_H__
 
-#include <s3c24x0.h>
-#include <uffs/uffs_types.h>
+/*
+ * Standard NAND flash commands
+ */ 
+#define NAND_CMD_READ0				0		/* Read0 */
+#define NAND_CMD_READ1				1		/* Read1 */
+#define NAND_CMD_RNDOUT				5		/* Random data output */
+#define NAND_CMD_PAGEPROG			0x10	/* Write phase 2 */
+#define NAND_CMD_READOOB			0x50	/* Read oob	*/
+#define NAND_CMD_ERASE1				0x60	/* Erase phase 1 */
+#define NAND_CMD_STATUS				0x70	/* Status read */
+#define NAND_CMD_STATUS_MULTI		0x71								 
+#define NAND_CMD_SEQIN				0x80	/* Write phase 1 */
+#define NAND_CMD_RNDIN				0x85	/* Random data input */
+#define NAND_CMD_READID				0x90	/* ReadID,all-purpose command */
+#define NAND_CMD_ERASE2				0xd0	/* Erase phase 2 */
+#define NAND_CMD_RESET				0xff	/* Reset */
+
+/* Extended commands for large page devices */
+#define NAND_CMD_READSTART			0x30
+#define NAND_CMD_RNDOUTSTART		0xE0
+#define NAND_CMD_CACHEDPROG			0x15
+#define NAND_CMD_READ_EDC			0x7b	
 
 /* define low accessing value */
 #define TOTAL_BLOCKS    	2048							/* total block of whole chip */
@@ -28,9 +44,9 @@ PARTICULAR PURPOSE.
 #define PAGE_SIZE			(PAGE_DATA_SIZE+PAGE_SPARE_SIZE)/* max size per whole page */
 #define BLOCK_DATA_SIZE 	(PAGE_DATA_SIZE*PAGES_PER_BLOCK)/* max size per block' */
 
-//bad flags offset in the oob area. 
-#define NAND_SMALL_BADBLOCK_POS		5	//small page FLASH
-#define NAND_LARGE_BADBLOCK_POS		0	//large page FLASH
+/* bad flags offset in the oob area. */
+#define NAND_SMALL_BADBLOCK_POS		5	/* small page FLASH	*/
+#define NAND_LARGE_BADBLOCK_POS		0	/* large page FLASH	*/
 
 /* Option constants for bizarre disfunctionality and real
 *  features
@@ -56,16 +72,14 @@ PARTICULAR PURPOSE.
 #define NAND_SAMSUNG_LP_OPTIONS \
 	(NAND_NO_PADDING | NAND_CACHEPRG | NAND_COPYBACK)
 
-
-struct nand_flash_dev 
-
+struct nand_flash_dev 
 {
-	char 		  *name;	//chip name
-	int 		  id;		//chip ID
-	unsigned long pagesize;	//max pages
-	unsigned long chipsize;	//size of whole chip iMB
-	unsigned long blocksize;//size of block 
-	unsigned long options;	//option
+	char 		  *name;	/* chip name */
+	int 		  id;		/* chip ID */
+	unsigned long pagesize;	/* max pages */
+	unsigned long chipsize;	/* size of whole chip iMB */
+	unsigned long blocksize;/* size of block */
+	unsigned long options;	/* option */
 };
 
 struct nand_manufacturers 
@@ -74,4 +88,4 @@ struct nand_manufacturers
 	char * name;
 };
 
-#endif /*__NAND_H__*/
+#endif /*__RTT_DFS_NAND_H__*/

+ 15 - 15
components/dfs/filesystems/uffs/src/inc/uffs/uffs.h

@@ -37,25 +37,25 @@
 
 #ifndef _UFFS_H_
 #define _UFFS_H_
-#include <dfs_def.h>
+#include <rtthread.h>
 #include "uffs/uffs_types.h"
 
 #ifdef __cplusplus
 extern "C"{
 #endif
 
-#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_RDONLY		0x0000		/** read only */
+#define UO_WRONLY		0x0001		/** write only */
+#define UO_RDWR			0x0002		/** read and write */
+#define UO_APPEND		0x0008		/** append */
 
-#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_DIR			DFS_O_DIRECTORY	/** open a directory */
+#define UO_BINARY		0x0000		/** no used in uffs */
+
+#define UO_CREATE		0x0100
+#define UO_TRUNC		0x0200
+#define UO_EXCL			0x0400		
+
+#define UO_DIR			0x1000		/** open a directory */
 
 
 
@@ -85,9 +85,9 @@ extern "C"{
 #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* 从文件的结尾寻找 */
+#define USEEK_CUR		_SEEK_CUR
+#define USEEK_SET		_SEEK_SET
+#define USEEK_END		_SEEK_END
 
 
 

+ 532 - 531
components/dfs/filesystems/uffs/src/uffs/uffs_fd.c

@@ -1,531 +1,532 @@
-/*
-  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.
-*/
-
-#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: "
-
-
-#define FD_OFFSET		3	//!< just make file handler more like POSIX (0, 1, 2 for stdin/stdout/stderr)
-
-#define FD2OBJ(fd)	(((fd) >= FD_OFFSET && (fd) < MAX_DIR_HANDLE + FD_OFFSET) ? \
-						(uffs_Object *)uffs_PoolGetBufByIndex(uffs_GetObjectPool(), (fd) - FD_OFFSET) : NULL )
-
-#define OBJ2FD(obj)		(uffs_PoolGetIndex(uffs_GetObjectPool(), obj) + FD_OFFSET)
-
-#define CHK_OBJ(obj, ret)	do { \
-								if (uffs_PoolVerify(uffs_GetObjectPool(), (obj)) == U_FALSE || \
-										uffs_PoolCheckFreeList(uffs_GetObjectPool(), (obj)) == U_TRUE) { \
-									uffs_set_error(-UEBADF); \
-									return (ret); \
-								} \
-							} while(0)
-
-#define CHK_DIR(dirp, ret)	do { \
-								if (uffs_PoolVerify(&_dir_pool, (dirp)) == U_FALSE || \
-										uffs_PoolCheckFreeList(&_dir_pool, (dirp)) == U_TRUE) { \
-									uffs_set_error(-UEBADF); \
-									return (ret); \
-								} \
-							} while(0)
-
-#define CHK_DIR_VOID(dirp)	do { \
-								if (uffs_PoolVerify(&_dir_pool, (dirp)) == U_FALSE || \
-										uffs_PoolCheckFreeList(&_dir_pool, (dirp)) == U_TRUE) { \
-									uffs_set_error(-UEBADF); \
-									return; \
-								} \
-							} while(0)
-
-
-
-static int _dir_pool_data[sizeof(uffs_DIR) * MAX_DIR_HANDLE / sizeof(int)];
-static uffs_Pool _dir_pool;
-static int _uffs_errno = 0;
-
-/**
- * initialise uffs_DIR buffers, called by UFFS internal
- */
-int uffs_InitDirEntryBuf(void)
-{
-	return uffs_PoolInit(&_dir_pool, _dir_pool_data, sizeof(_dir_pool_data),
-			sizeof(uffs_DIR), MAX_DIR_HANDLE);
-}
-
-/**
- * Release uffs_DIR buffers, called by UFFS internal
- */
-int uffs_ReleaseDirEntryBuf(void)
-{
-	return uffs_PoolRelease(&_dir_pool);
-}
-
-uffs_Pool * uffs_GetDirEntryBufPool(void)
-{
-	return &_dir_pool;
-}
-
-static uffs_DIR * GetDirEntry(void)
-{
-	uffs_DIR *dirp = (uffs_DIR *) uffs_PoolGet(&_dir_pool);
-
-	if(dirp)
-		memset(dirp, 0, sizeof(uffs_DIR));
-
-	return dirp;
-}
-
-static void PutDirEntry(uffs_DIR *p)
-{
-	uffs_PoolPut(&_dir_pool, p);
-}
-
-
-/** get global errno
- */
-int uffs_get_error(void)
-{
-	return _uffs_errno;
-}
-
-/** set global errno
- */
-int uffs_set_error(int err)
-{
-	return (_uffs_errno = err);
-}
-
-/* POSIX compliant file system APIs */
-
-int uffs_open(const char *name, int oflag, ...)
-{
-	uffs_Object *obj;
-	int ret = 0;
-
-	obj = uffs_GetObject();
-	if (obj == NULL) {
-		uffs_set_error(-UEMFILE);
-		ret = -1;
-	}
-	else {
-		if (uffs_OpenObject(obj, name, oflag) == U_FAIL) {
-			uffs_set_error(-uffs_GetObjectErr(obj));
-			uffs_PutObject(obj);
-			ret = -1;
-		}
-		else {
-			ret = OBJ2FD(obj);
-		}
-	}
-
-	return ret;
-}
-
-int uffs_close(int fd)
-{
-	int ret = 0;
-	uffs_Object *obj = FD2OBJ(fd);
-
-	CHK_OBJ(obj, -1);
-
-	uffs_ClearObjectErr(obj);
-	if (uffs_CloseObject(obj) == U_FAIL) {
-		uffs_set_error(-uffs_GetObjectErr(obj));
-		ret = -1;
-	}
-	else {
-		uffs_PutObject(obj);
-		ret = 0;
-	}
-
-	return ret;
-}
-
-int uffs_read(int fd, void *data, int len)
-{
-	int ret;
-	uffs_Object *obj = FD2OBJ(fd);
-
-	CHK_OBJ(obj, -1);
-	uffs_ClearObjectErr(obj);
-	ret = uffs_ReadObject(obj, data, len);
-	uffs_set_error(-uffs_GetObjectErr(obj));
-
-	return ret;
-}
-
-int uffs_write(int fd, void *data, int len)
-{
-	int ret;
-	uffs_Object *obj = FD2OBJ(fd);
-
-	CHK_OBJ(obj, -1);
-	uffs_ClearObjectErr(obj);
-	ret = uffs_WriteObject(obj, data, len);
-	uffs_set_error(-uffs_GetObjectErr(obj));
-
-	return ret;
-}
-
-long uffs_seek(int fd, long offset, int origin)
-{
-	int ret;
-	uffs_Object *obj = FD2OBJ(fd);
-
-	CHK_OBJ(obj, -1);
-	uffs_ClearObjectErr(obj);
-	ret = uffs_SeekObject(obj, offset, origin);
-	uffs_set_error(-uffs_GetObjectErr(obj));
-	
-	return ret;
-}
-
-long uffs_tell(int fd)
-{
-	long ret;
-	uffs_Object *obj = FD2OBJ(fd);
-
-	CHK_OBJ(obj, -1);
-	uffs_ClearObjectErr(obj);
-	ret = (long) uffs_GetCurOffset(obj);
-	uffs_set_error(-uffs_GetObjectErr(obj));
-	
-	return ret;
-}
-
-int uffs_eof(int fd)
-{
-	int ret;
-	uffs_Object *obj = FD2OBJ(fd);
-
-	CHK_OBJ(obj, -1);
-	uffs_ClearObjectErr(obj);
-	ret = uffs_EndOfFile(obj);
-	uffs_set_error(-uffs_GetObjectErr(obj));
-	
-	return ret;
-}
-
-int uffs_flush(int fd)
-{
-	int ret;
-	uffs_Object *obj = FD2OBJ(fd);
-
-	CHK_OBJ(obj, -1);
-	uffs_ClearObjectErr(obj);
-	ret = (uffs_FlushObject(obj) == U_SUCC) ? 0 : -1;
-	uffs_set_error(-uffs_GetObjectErr(obj));
-	
-	return ret;
-}
-
-int uffs_rename(const char *old_name, const char *new_name)
-{
-	int err = 0;
-	int ret = 0;
-
-	ret = (uffs_RenameObject(old_name, new_name, &err) == U_SUCC) ? 0 : -1;
-	uffs_set_error(-err);
-
-	return ret;
-}
-
-int uffs_remove(const char *name)
-{
-	int err = 0;
-	int ret = 0;
-	struct uffs_stat st;
-
-	if (uffs_stat(name, &st) < 0) {
-		err = UENOENT;
-		ret = -1;
-	}
-	else if (st.st_mode & US_IFDIR) {
-		err = UEISDIR;
-		ret = -1;
-	}
-	else if (uffs_DeleteObject(name, &err) == U_SUCC) {
-		ret = 0;
-	}
-	else {
-		ret = -1;
-	}
-
-	uffs_set_error(-err);
-	return ret;
-}
-
-
-int uffs_truncate(int fd, long remain)
-{
-	int ret;
-	uffs_Object *obj = FD2OBJ(fd);
-
-	CHK_OBJ(obj, -1);
-	uffs_ClearObjectErr(obj);
-	ret = (uffs_TruncateObject(obj, remain) == U_SUCC) ? 0 : -1;
-	uffs_set_error(-uffs_GetObjectErr(obj));
-	
-	return ret;
-}
-
-static int do_stat(uffs_Object *obj, struct uffs_stat *buf)
-{
-	uffs_ObjectInfo info;
-	int ret = 0;
-	int err = 0;
-
-	if (uffs_GetObjectInfo(obj, &info, &err) == U_FAIL) {
-		ret = -1;
-	}
-	else {
-		buf->st_dev = obj->dev->dev_num;
-		buf->st_ino = info.serial;
-		buf->st_nlink = 0;
-		buf->st_uid = 0;
-		buf->st_gid = 0;
-		buf->st_rdev = 0;
-		buf->st_size = info.len;
-		buf->st_blksize = obj->dev->com.pg_data_size;
-		buf->st_blocks = 0;
-		buf->st_atime = info.info.last_modify;
-		buf->st_mtime = info.info.last_modify;
-		buf->st_ctime = info.info.create_time;
-		buf->st_mode = (info.info.attr & FILE_ATTR_DIR ? US_IFDIR : US_IFREG);
-		if (info.info.attr & FILE_ATTR_WRITE)
-			buf->st_mode |= US_IRWXU;
-	}
-
-	uffs_set_error(-err);
-	return ret;
-}
-
-int uffs_stat(const char *name, struct uffs_stat *buf)
-{
-	uffs_Object *obj;
-	int ret = 0;
-	int err = 0;
-	URET result;
-
-	obj = uffs_GetObject();
-	if (obj) {
-		if (*name && name[strlen(name) - 1] == '/') {
-			result = uffs_OpenObject(obj, name, UO_RDONLY | UO_DIR);
-		}
-		else {
-			if ((result = uffs_OpenObject(obj, name, UO_RDONLY)) != U_SUCC)	// try file
-				result = uffs_OpenObject(obj, name, UO_RDONLY | UO_DIR);	// then try dir
-		}
-		if (result == U_SUCC) {
-			ret = do_stat(obj, buf);
-			uffs_CloseObject(obj);
-		}
-		else {
-			err = uffs_GetObjectErr(obj);
-			ret = -1;
-		}
-		uffs_PutObject(obj);
-	}
-	else {
-		err = UENOMEM;
-		ret = -1;
-	}
-
-	uffs_set_error(-err);
-	return ret;
-}
-
-int uffs_lstat(const char *name, struct uffs_stat *buf)
-{
-	return uffs_stat(name, buf);
-}
-
-int uffs_fstat(int fd, struct uffs_stat *buf)
-{
-	uffs_Object *obj = FD2OBJ(fd);
-
-	CHK_OBJ(obj, -1);
-
-	return do_stat(obj, buf);
-}
-
-int uffs_closedir(uffs_DIR *dirp)
-{
-	CHK_DIR(dirp, -1);
-
-	uffs_FindObjectClose(&dirp->f);
-	if (dirp->obj) {
-		uffs_CloseObject(dirp->obj);
-		uffs_PutObject(dirp->obj);
-	}
-	PutDirEntry(dirp);
-
-	return 0;
-}
-
-uffs_DIR * uffs_opendir(const char *path)
-{
-	int err = 0;
-	uffs_DIR *ret = NULL;
-	uffs_DIR *dirp = GetDirEntry();
-
-	if (dirp) {
-		dirp->obj = uffs_GetObject();
-		if (dirp->obj) {
-			if (uffs_OpenObject(dirp->obj, path, UO_RDONLY | UO_DIR) == U_SUCC) {
-				if (uffs_FindObjectOpen(&dirp->f, dirp->obj) == U_SUCC) {
-					ret = dirp;
-					goto ext;
-				}
-				else {
-					uffs_CloseObject(dirp->obj);
-				}
-			}
-			else {
-				err = uffs_GetObjectErr(dirp->obj);
-			}
-			uffs_PutObject(dirp->obj);
-			dirp->obj = NULL;
-		}
-		else {
-			err = UEMFILE;
-		}
-		PutDirEntry(dirp);
-	}
-	else {
-		err = UEMFILE;
-	}
-ext:
-	uffs_set_error(-err);
-	return ret;
-}
-
-struct uffs_dirent* uffs_readdir(uffs_DIR *dirp)
-{
-	struct uffs_dirent *ent = &dirp->dirent;
-
-	//CHK_DIR(dirp, NULL);
-	if(dirp == NULL)
-		return NULL;
-	
-	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);
-		ent->d_name[ent->d_namelen] = 0;
-		ent->d_off = dirp->f.pos;
-		ent->d_reclen = sizeof(struct uffs_dirent);
-		ent->d_type = dirp->info.info.attr;
-
-		return ent;
-	}
-	else
-		return NULL;
-}
-
-void uffs_rewinddir(uffs_DIR *dirp)
-{
-	CHK_DIR_VOID(dirp);
-
-	uffs_FindObjectRewind(&dirp->f);	//fi(=)find info
-}
-
-/*
- * 函数功能: 创建一个文件夹
- * 输入参数: 文件夹名称,参数
- * 返回参数: 
- */
-int uffs_mkdir(const char *name, ...)
-{
-	uffs_Object *obj;
-	int ret = 0;
-	int err = 0;
-
-	obj = uffs_GetObject();
-	if (obj) {
-		if (uffs_CreateObject(obj, name, UO_CREATE|UO_DIR) != U_SUCC) {
-			err = obj->err;
-			ret = -1;
-		}
-		else {
-			uffs_CloseObject(obj);
-			ret = 0;
-		}
-		uffs_PutObject(obj);
-	}
-	else {
-		err = UEMFILE;
-		ret = -1;
-	}
-
-	uffs_set_error(-err);
-	return ret;
-}
-
-/*
- * 函数功能: 移除一个文件夹
- * 输入参数: 文件夹名称
- * 返回参数: 
- */
-int uffs_rmdir(const char *name)
-{
-	int err = 0;
-	int ret = 0;
-	struct uffs_stat st;
-
-	if (uffs_stat(name, &st) < 0) {
-		err = UENOENT;
-		ret = -1;
-	}
-	else if ((st.st_mode & US_IFDIR) == 0) {
-		err = UENOTDIR;
-		ret = -1;
-	}
-	else if (uffs_DeleteObject(name, &err) == U_SUCC) {
-		ret = 0;
-	}
-	else {
-		ret = -1;
-	}
-
-	uffs_set_error(-err);
-	return ret;
-}
-
+/*
+  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.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_fs.h"
+#include "uffs/uffs_fd.h"
+#define PFX "fd: "
+
+
+#define FD_OFFSET		3	//!< just make file handler more like POSIX (0, 1, 2 for stdin/stdout/stderr)
+
+#define FD2OBJ(fd)	(((fd) >= FD_OFFSET && (fd) < MAX_DIR_HANDLE + FD_OFFSET) ? \
+						(uffs_Object *)uffs_PoolGetBufByIndex(uffs_GetObjectPool(), (fd) - FD_OFFSET) : NULL )
+
+#define OBJ2FD(obj)		(uffs_PoolGetIndex(uffs_GetObjectPool(), obj) + FD_OFFSET)
+
+#define CHK_OBJ(obj, ret)	do { \
+								if (uffs_PoolVerify(uffs_GetObjectPool(), (obj)) == U_FALSE || \
+										uffs_PoolCheckFreeList(uffs_GetObjectPool(), (obj)) == U_TRUE) { \
+									uffs_set_error(-UEBADF); \
+									return (ret); \
+								} \
+							} while(0)
+
+#define CHK_DIR(dirp, ret)	do { \
+								if (uffs_PoolVerify(&_dir_pool, (dirp)) == U_FALSE || \
+										uffs_PoolCheckFreeList(&_dir_pool, (dirp)) == U_TRUE) { \
+									uffs_set_error(-UEBADF); \
+									return (ret); \
+								} \
+							} while(0)
+
+#define CHK_DIR_VOID(dirp)	do { \
+								if (uffs_PoolVerify(&_dir_pool, (dirp)) == U_FALSE || \
+										uffs_PoolCheckFreeList(&_dir_pool, (dirp)) == U_TRUE) { \
+									uffs_set_error(-UEBADF); \
+									return; \
+								} \
+							} while(0)
+
+
+
+static int _dir_pool_data[sizeof(uffs_DIR) * MAX_DIR_HANDLE / sizeof(int)];
+static uffs_Pool _dir_pool;
+static int _uffs_errno = 0;
+
+/**
+ * initialise uffs_DIR buffers, called by UFFS internal
+ */
+URET uffs_InitDirEntryBuf(void)
+{
+	return uffs_PoolInit(&_dir_pool, _dir_pool_data, sizeof(_dir_pool_data),
+			sizeof(uffs_DIR), MAX_DIR_HANDLE);
+}
+
+/**
+ * Release uffs_DIR buffers, called by UFFS internal
+ */
+URET uffs_ReleaseDirEntryBuf(void)
+{
+	return uffs_PoolRelease(&_dir_pool);
+}
+
+uffs_Pool * uffs_GetDirEntryBufPool(void)
+{
+	return &_dir_pool;
+}
+
+static uffs_DIR * GetDirEntry(void)
+{
+	uffs_DIR *dirp = (uffs_DIR *) uffs_PoolGet(&_dir_pool);
+
+	if (dirp)
+		memset(dirp, 0, sizeof(uffs_DIR));
+
+	return dirp;
+}
+
+static void PutDirEntry(uffs_DIR *p)
+{
+	uffs_PoolPut(&_dir_pool, p);
+}
+
+
+/** get global errno
+ */
+int uffs_get_error(void)
+{
+	return _uffs_errno;
+}
+
+/** set global errno
+ */
+int uffs_set_error(int err)
+{
+	return (_uffs_errno = err);
+}
+
+/* POSIX compliant file system APIs */
+
+int uffs_open(const char *name, int oflag, ...)
+{
+	uffs_Object *obj;
+	int ret = 0;
+
+	obj = uffs_GetObject();
+	if (obj == NULL) {
+		uffs_set_error(-UEMFILE);
+		ret = -1;
+	}
+	else {
+		if (uffs_OpenObject(obj, name, oflag) == U_FAIL) {
+			uffs_set_error(-uffs_GetObjectErr(obj));
+			uffs_PutObject(obj);
+			ret = -1;
+		}
+		else {
+			ret = OBJ2FD(obj);
+		}
+	}
+
+	return ret;
+}
+
+int uffs_close(int fd)
+{
+	int ret = 0;
+	uffs_Object *obj = FD2OBJ(fd);
+
+	CHK_OBJ(obj, -1);
+
+	uffs_ClearObjectErr(obj);
+	if (uffs_CloseObject(obj) == U_FAIL) {
+		uffs_set_error(-uffs_GetObjectErr(obj));
+		ret = -1;
+	}
+	else {
+		uffs_PutObject(obj);
+		ret = 0;
+	}
+
+	return ret;
+}
+
+int uffs_read(int fd, void *data, int len)
+{
+	int ret;
+	uffs_Object *obj = FD2OBJ(fd);
+
+	CHK_OBJ(obj, -1);
+	uffs_ClearObjectErr(obj);
+	ret = uffs_ReadObject(obj, data, len);
+	uffs_set_error(-uffs_GetObjectErr(obj));
+
+	return ret;
+}
+
+int uffs_write(int fd, void *data, int len)
+{
+	int ret;
+	uffs_Object *obj = FD2OBJ(fd);
+
+	CHK_OBJ(obj, -1);
+	uffs_ClearObjectErr(obj);
+	ret = uffs_WriteObject(obj, data, len);
+	uffs_set_error(-uffs_GetObjectErr(obj));
+
+	return ret;
+}
+
+long uffs_seek(int fd, long offset, int origin)
+{
+	int ret;
+	uffs_Object *obj = FD2OBJ(fd);
+
+	CHK_OBJ(obj, -1);
+	uffs_ClearObjectErr(obj);
+	ret = uffs_SeekObject(obj, offset, origin);
+	uffs_set_error(-uffs_GetObjectErr(obj));
+	
+	return ret;
+}
+
+long uffs_tell(int fd)
+{
+	long ret;
+	uffs_Object *obj = FD2OBJ(fd);
+
+	CHK_OBJ(obj, -1);
+	uffs_ClearObjectErr(obj);
+	ret = (long) uffs_GetCurOffset(obj);
+	uffs_set_error(-uffs_GetObjectErr(obj));
+	
+	return ret;
+}
+
+int uffs_eof(int fd)
+{
+	int ret;
+	uffs_Object *obj = FD2OBJ(fd);
+
+	CHK_OBJ(obj, -1);
+	uffs_ClearObjectErr(obj);
+	ret = uffs_EndOfFile(obj);
+	uffs_set_error(-uffs_GetObjectErr(obj));
+	
+	return ret;
+}
+
+int uffs_flush(int fd)
+{
+	int ret;
+	uffs_Object *obj = FD2OBJ(fd);
+
+	CHK_OBJ(obj, -1);
+	uffs_ClearObjectErr(obj);
+	ret = (uffs_FlushObject(obj) == U_SUCC) ? 0 : -1;
+	uffs_set_error(-uffs_GetObjectErr(obj));
+	
+	return ret;
+}
+
+int uffs_rename(const char *old_name, const char *new_name)
+{
+	int err = 0;
+	int ret = 0;
+
+	ret = (uffs_RenameObject(old_name, new_name, &err) == U_SUCC) ? 0 : -1;
+	uffs_set_error(-err);
+
+	return ret;
+}
+
+int uffs_remove(const char *name)
+{
+	int err = 0;
+	int ret = 0;
+	struct uffs_stat st;
+
+	if (uffs_stat(name, &st) < 0) {
+		err = UENOENT;
+		ret = -1;
+	}
+	else if (st.st_mode & US_IFDIR) {
+		err = UEISDIR;
+		ret = -1;
+	}
+	else if (uffs_DeleteObject(name, &err) == U_SUCC) {
+		ret = 0;
+	}
+	else {
+		ret = -1;
+	}
+
+	uffs_set_error(-err);
+	return ret;
+}
+
+int uffs_truncate(int fd, long remain)
+{
+	int ret;
+	uffs_Object *obj = FD2OBJ(fd);
+
+	CHK_OBJ(obj, -1);
+	uffs_ClearObjectErr(obj);
+	ret = (uffs_TruncateObject(obj, remain) == U_SUCC) ? 0 : -1;
+	uffs_set_error(-uffs_GetObjectErr(obj));
+	
+	return ret;
+}
+
+static int do_stat(uffs_Object *obj, struct uffs_stat *buf)
+{
+	uffs_ObjectInfo info;
+	int ret = 0;
+	int err = 0;
+
+	if (uffs_GetObjectInfo(obj, &info, &err) == U_FAIL) {
+		ret = -1;
+	}
+	else {
+		buf->st_dev = obj->dev->dev_num;
+		buf->st_ino = info.serial;
+		buf->st_nlink = 0;
+		buf->st_uid = 0;
+		buf->st_gid = 0;
+		buf->st_rdev = 0;
+		buf->st_size = info.len;
+		buf->st_blksize = obj->dev->com.pg_data_size;
+		buf->st_blocks = 0;
+		buf->st_atime = info.info.last_modify;
+		buf->st_mtime = info.info.last_modify;
+		buf->st_ctime = info.info.create_time;
+		buf->st_mode = (info.info.attr & FILE_ATTR_DIR ? US_IFDIR : US_IFREG);
+		if (info.info.attr & FILE_ATTR_WRITE)
+			buf->st_mode |= US_IRWXU;
+	}
+
+	uffs_set_error(-err);
+	return ret;
+}
+
+int uffs_stat(const char *name, struct uffs_stat *buf)
+{
+	uffs_Object *obj;
+	int ret = 0;
+	int err = 0;
+	URET result;
+
+	obj = uffs_GetObject();
+	if (obj) {
+		if (*name && name[strlen(name) - 1] == '/') {
+			result = uffs_OpenObject(obj, name, UO_RDONLY | UO_DIR);
+		}
+		else {
+			if ((result = uffs_OpenObject(obj, name, UO_RDONLY)) != U_SUCC)	// try file
+				result = uffs_OpenObject(obj, name, UO_RDONLY | UO_DIR);	// then try dir
+		}
+		if (result == U_SUCC) {
+			ret = do_stat(obj, buf);
+			uffs_CloseObject(obj);
+		}
+		else {
+			err = uffs_GetObjectErr(obj);
+			ret = -1;
+		}
+		uffs_PutObject(obj);
+	}
+	else {
+		err = UENOMEM;
+		ret = -1;
+	}
+
+	uffs_set_error(-err);
+	return ret;
+}
+
+int uffs_lstat(const char *name, struct uffs_stat *buf)
+{
+	return uffs_stat(name, buf);
+}
+
+int uffs_fstat(int fd, struct uffs_stat *buf)
+{
+	uffs_Object *obj = FD2OBJ(fd);
+
+	CHK_OBJ(obj, -1);
+
+	return do_stat(obj, buf);
+}
+
+int uffs_closedir(uffs_DIR *dirp)
+{
+	CHK_DIR(dirp, -1);
+
+	uffs_FindObjectClose(&dirp->f);
+	if (dirp->obj) {
+		uffs_CloseObject(dirp->obj);
+		uffs_PutObject(dirp->obj);
+	}
+	PutDirEntry(dirp);
+
+	return 0;
+}
+
+uffs_DIR * uffs_opendir(const char *path)
+{
+	int err = 0;
+	uffs_DIR *ret = NULL;
+	uffs_DIR *dirp = GetDirEntry();
+
+	if (dirp) {
+		dirp->obj = uffs_GetObject();
+		if (dirp->obj) {
+			if (uffs_OpenObject(dirp->obj, path, UO_RDONLY | UO_DIR) == U_SUCC) {
+				if (uffs_FindObjectOpen(&dirp->f, dirp->obj) == U_SUCC) {
+					ret = dirp;
+					goto ext;
+				}
+				else {
+					uffs_CloseObject(dirp->obj);
+				}
+			}
+			else {
+				err = uffs_GetObjectErr(dirp->obj);
+			}
+			uffs_PutObject(dirp->obj);
+			dirp->obj = NULL;
+		}
+		else {
+			err = UEMFILE;
+		}
+		PutDirEntry(dirp);
+	}
+	else {
+		err = UEMFILE;
+	}
+ext:
+	uffs_set_error(-err);
+	return ret;
+}
+
+struct uffs_dirent * uffs_readdir(uffs_DIR *dirp)
+{
+	struct uffs_dirent *ent;
+
+	CHK_DIR(dirp, NULL);
+
+	if (uffs_FindObjectNext(&dirp->info, &dirp->f) == U_SUCC) {
+		ent = &dirp->dirent;
+		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);
+		ent->d_name[ent->d_namelen] = 0;
+		ent->d_off = dirp->f.pos;
+		ent->d_reclen = sizeof(struct uffs_dirent);
+		ent->d_type = dirp->info.info.attr;
+
+		return ent;
+	}
+	else
+		return NULL;
+}
+
+void uffs_rewinddir(uffs_DIR *dirp)
+{
+	CHK_DIR_VOID(dirp);
+
+	uffs_FindObjectRewind(&dirp->f);
+}
+
+
+int uffs_mkdir(const char *name, ...)
+{
+	uffs_Object *obj;
+	int ret = 0;
+	int err = 0;
+
+	obj = uffs_GetObject();
+	if (obj) {
+		if (uffs_CreateObject(obj, name, UO_CREATE|UO_DIR) != U_SUCC) {
+			err = obj->err;
+			ret = -1;
+		}
+		else {
+			uffs_CloseObject(obj);
+			ret = 0;
+		}
+		uffs_PutObject(obj);
+	}
+	else {
+		err = UEMFILE;
+		ret = -1;
+	}
+
+	uffs_set_error(-err);
+	return ret;
+}
+
+int uffs_rmdir(const char *name)
+{
+	int err = 0;
+	int ret = 0;
+	struct uffs_stat st;
+
+	if (uffs_stat(name, &st) < 0) {
+		err = UENOENT;
+		ret = -1;
+	}
+	else if ((st.st_mode & US_IFDIR) == 0) {
+		err = UENOTDIR;
+		ret = -1;
+	}
+	else if (uffs_DeleteObject(name, &err) == U_SUCC) {
+		ret = 0;
+	}
+	else {
+		ret = -1;
+	}
+
+	uffs_set_error(-err);
+	return ret;
+}
+
+
+#if 0
+void uffs_seekdir(uffs_DIR *dirp, long loc)
+{
+	return ;
+}
+
+long uffs_telldir(uffs_DIR *dirp)
+{
+	return 0;
+}
+#endif

+ 1 - 1
components/dfs/filesystems/uffs/uffs_ext.c

@@ -19,7 +19,7 @@
 #include "uffs_ext.h"
 
 #include <dfs_posix.h>
-#include <filerw.h>
+#include <rtgui/filerw.h>
 
 #ifdef RT_USING_FINSH
 #include <finsh.h>