Index: EcnlProtoTool/trunk/ntshell/fatfs/ccsbcs.c
===================================================================
--- EcnlProtoTool/trunk/ntshell/fatfs/ccsbcs.c	(revision 278)
+++ EcnlProtoTool/trunk/ntshell/fatfs/ccsbcs.c	(revision 279)
@@ -266,5 +266,5 @@
 
 
-#if !_TBLDEF || !_USE_LFN
+#if _CODE_PAGE != 65001 && (!_TBLDEF || !_USE_LFN)
 #error This file is not needed at current configuration. Remove from the project.
 #endif
@@ -272,5 +272,5 @@
 
 
-
+#if _CODE_PAGE != 65001
 WCHAR ff_convert (	/* Converted character, Returns zero on error */
 	WCHAR	chr,	/* Character code to be converted */
@@ -298,5 +298,5 @@
 	return c;
 }
-
+#endif
 
 
Index: EcnlProtoTool/trunk/ntshell/fatfs/diskio.c
===================================================================
--- EcnlProtoTool/trunk/ntshell/fatfs/diskio.c	(revision 278)
+++ EcnlProtoTool/trunk/ntshell/fatfs/diskio.c	(revision 279)
@@ -15,5 +15,6 @@
 #define MAX_DRIVES	1	/* Max number of physical drives to be used */
 
-unsigned char RamDisk[SZ_RAMDISK * 1024];
+#define RamDisk _binary____webserver_httpd_fs_bin_start
+extern unsigned char RamDisk[];
 
 typedef struct {
Index: EcnlProtoTool/trunk/ntshell/fatfs/ff.c
===================================================================
--- EcnlProtoTool/trunk/ntshell/fatfs/ff.c	(revision 278)
+++ EcnlProtoTool/trunk/ntshell/fatfs/ff.c	(revision 279)
@@ -314,4 +314,92 @@
 #endif
 #define _DF1S	0
+
+#elif _CODE_PAGE == 65001 /* UTF-8 */
+#if _LFN_UNICODE
+#error Cannot use LFN_UNICODE feature without valid code page.
+#endif
+#define _DF1S	0
+
+void Utf16_to_Utf8(unsigned char *ret_code, int *ret_size, UINT chr)
+{
+	ret_code[0] = ret_code[1] = ret_code[2] = ret_code[3] = 0;
+
+	if (chr <= 0x7f) {  // ASCIIäºæ
+		ret_code[0] = chr;
+		*ret_size = 1;
+		return;
+	}
+
+	if (chr <= 0x7ff) {
+		ret_code[1] = (0x80 | (chr & 0x3f));
+		ret_code[0] = (0xc0 | (chr >> 6));
+		*ret_size = 2;
+		return;
+	}
+
+	if (chr <= 0xffff) {
+		ret_code[2] = (0x80 | (chr & 0x3f));
+		ret_code[1] = (0x80 | ((chr >> 6) & 0x3f));
+		ret_code[0] = (0xe0 | ((chr >> 12) & 0x0f));
+		*ret_size = 3;
+		return;
+	}
+
+	if (chr <= 0x1fffff) {
+		ret_code[3] = (0x80 | (chr & 0x3f));
+		ret_code[2] = (0x80 | ((chr >> 6) & 0x3f));
+		ret_code[1] = (0x80 | ((chr >> 12) & 0x3f));
+		ret_code[0] = (0xf0 | ((chr >> 18) & 0x07));
+		*ret_size = 4;
+		return;
+	}
+
+	if (chr <= 0x3ffffff) {
+		ret_code[4] = (0x80 | (chr & 0x3f));
+		ret_code[3] = (0x80 | ((chr >> 6) & 0x3f));
+		ret_code[2] = (0x80 | ((chr >> 12) & 0x3f));
+		ret_code[1] = (0x80 | ((chr >> 18) & 0x3f));
+		ret_code[0] = (0xf8 | ((chr >> 24) & 0x03));
+		*ret_size = 5;
+		return;
+	}
+
+	ret_code[5] = (0x80 | (chr & 0x3f));
+	ret_code[4] = (0x80 | ((chr >> 6) & 0x3f));
+	ret_code[3] = (0x80 | ((chr >> 12) & 0x3f));
+	ret_code[2] = (0x80 | ((chr >> 18) & 0x3f));
+	ret_code[1] = (0x80 | ((chr >> 24) & 0x3f));
+	ret_code[0] = (0xfc | ((chr >> 30) & 0x01));
+	*ret_size = 6;
+	return;
+}
+
+//2ãã¤ãã®UTF-16ã³ã¼ããå¾ããã
+WCHAR Utf8_to_Utf16(const char *src, int *code_size)
+{
+	int i;
+	unsigned int uc = 0;
+	unsigned char len = 0;
+
+	len = 0;
+	if ((src[0] & 0x80) == 0) { uc = src[0] & 0x7F; len = 0; }
+	else if ((src[0] & 0xE0) == 0xC0) { uc = src[0] & 0x1F; len = 1; }
+	else if ((src[0] & 0xF0) == 0xE0) { uc = src[0] & 0x0F; len = 2; }
+	else if ((src[0] & 0xF8) == 0xF0) { uc = src[0] & 0x07; len = 3; }
+	else if ((src[0] & 0xFC) == 0xF8) { uc = src[0] & 0x03; len = 4; }
+	else if ((src[0] & 0xFE) == 0xFC) { uc = src[0] & 0x01; len = 5; }
+
+	i = 1;
+	while ((i <= len) && ((src[i] & 0xC0) == 0x80)) {
+		uc = (uc << 6) | (src[i] & 0x3F);
+		i++;
+	}
+
+	//æ¶è²»æå­æ°è¨­å®
+	*code_size = i;
+
+	//ç¾ç¶ã2ãã¤ãéå®
+	return uc;
+}
 
 #else
@@ -1712,4 +1800,8 @@
 	WCHAR w, *lfn;
 #endif
+#if _CODE_PAGE == 65001
+	unsigned char utf8_code[6];
+	int code_size;
+#endif
 
 	p = fno->fname;
@@ -1748,4 +1840,11 @@
 			while ((w = *lfn++) != 0) {		/* Get an LFN character */
 #if !_LFN_UNICODE
+#if _CODE_PAGE == 65001
+				Utf16_to_Utf8(utf8_code, &code_size, w);
+				for (int j = 0; j < code_size - 1; j++) {
+					p[i++] = utf8_code[j];
+				}
+				w = utf8_code[code_size - 1];
+#else
 				w = ff_convert(w, 0);		/* Unicode -> OEM */
 				if (!w) { i = 0; break; }	/* No LFN if it could not be converted */
@@ -1753,4 +1852,5 @@
 					p[i++] = (TCHAR)(w >> 8);
 #endif
+#endif
 				if (i >= fno->lfsize - 1) { i = 0; break; }	/* No LFN if buffer overflow */
 				p[i++] = (TCHAR)w;
@@ -1778,8 +1878,14 @@
 
 #if !_LFN_UNICODE
+#if _CODE_PAGE == 65001
+	int code_size;
+	chr = Utf8_to_Utf16(*ptr, &code_size);
+	(*ptr) += code_size;
+#else
 	chr = (BYTE)*(*ptr)++;					/* Get a byte */
 	if (IsLower(chr)) chr -= 0x20;			/* To upper ASCII char */
 	if (IsDBCS1(chr) && IsDBCS2(**ptr))		/* Get DBC 2nd byte if needed */
 		chr = chr << 8 | (BYTE)*(*ptr)++;
+#endif
 #ifdef _EXCVT
 	if (chr >= 0x80) chr = ExCvt[chr - 0x80];	/* To upper SBCS extended char */
@@ -1851,5 +1957,8 @@
 	UINT i, ni, si, di;
 	const TCHAR *p;
-
+#if _CODE_PAGE == 65001
+	char utf8_code[6];
+	int code_size;
+#endif
 	/* Create LFN in Unicode */
 	for (p = *path; *p == '/' || *p == '\\'; p++) ;	/* Strip duplicated separator */
@@ -1862,4 +1971,8 @@
 			return FR_INVALID_NAME;
 #if !_LFN_UNICODE
+#if _CODE_PAGE == 65001
+		w = Utf8_to_Utf16(&p[si - 1], &code_size);
+		si += code_size - 1;
+#else
 		w &= 0xFF;
 		if (IsDBCS1(w)) {				/* Check if it is a DBC 1st byte (always false on SBCS cfg) */
@@ -1871,4 +1984,5 @@
 		w = ff_convert(w, 1);			/* Convert ANSI/OEM to Unicode */
 		if (!w) return FR_INVALID_NAME;	/* Reject invalid code */
+#endif
 #endif
 		if (w < 0x80 && chk_chr("\"*:<>\?|\x7F", w)) /* Reject illegal characters for LFN */
@@ -1925,9 +2039,43 @@
 			if (w) w = ExCvt[w - 0x80];	/* Convert extended character to upper (SBCS) */
 #else
+#if _CODE_PAGE == 65001
+			Utf16_to_Utf8(utf8_code, &code_size, ff_wtoupper(w));
+#else
 			w = ff_convert(ff_wtoupper(w), 0);	/* Upper converted Unicode -> OEM code */
 #endif
+#endif
 			cf |= NS_LFN;				/* Force create LFN entry */
 		}
-
+#if _CODE_PAGE == 65001
+		else
+			code_size = 1;
+#endif
+
+#if _CODE_PAGE == 65001
+		if (code_size > 1) {		/* Is this DBC? (always false at SBCS cfg) */
+			if (i >= ni - 1) {
+				cf |= NS_LOSS | NS_LFN; i = ni; continue;
+			}
+			for (int j = 0; j < code_size; j++) {
+				dp->fn[i++] = (BYTE)utf8_code[j];
+			}
+		}
+		else {						/* SBC */
+			if (!w || chk_chr("+,;=[]", w)) {	/* Replace illegal characters for SFN */
+				w = '_'; cf |= NS_LOSS | NS_LFN;/* Lossy conversion */
+			}
+			else {
+				if (IsUpper(w)) {		/* ASCII large capital */
+					b |= 2;
+				}
+				else {
+					if (IsLower(w)) {	/* ASCII small capital */
+						b |= 1; w -= 0x20;
+					}
+				}
+			}
+			dp->fn[i++] = (BYTE)w;
+		}
+#else
 		if (_DF1S && w >= 0x100) {		/* Is this DBC? (always false at SBCS cfg) */
 			if (i >= ni - 1) {
@@ -1949,4 +2097,5 @@
 		}
 		dp->fn[i++] = (BYTE)w;
+#endif
 	}
 
@@ -3178,5 +3327,17 @@
 }
 
-
+FRESULT f_seek(FIL* fp, DWORD ofs, BYTE mode)
+{
+  switch (mode) {
+  case F_SEEK_SET:
+    return f_lseek((fp), ofs);
+  case F_SEEK_CUR:
+    return f_lseek((fp), (fp)->fptr + ofs);
+  case F_SEEK_END:
+    return f_lseek((fp), (fp)->fsize - ofs);
+  default:
+    return FR_INVALID_PARAMETER;
+  }
+}
 
 #if _FS_MINIMIZE <= 1
@@ -3719,4 +3880,5 @@
 	DWORD dw;
 	DEFINE_NAMEBUF;
+	TCHAR *temp_new_path = 0;
 
 
@@ -3742,5 +3904,13 @@
 				else
 					res = FR_INVALID_DRIVE;
-				if (res == FR_OK) res = FR_EXIST;		/* The new object name is already existing */
+				if (res == FR_OK) {
+					res = FR_EXIST;		/* The new object name is already existing */
+					dir = djn.dir;
+					if (dir[DIR_Attr] & AM_DIR) {	/* The new object is a directory */
+						temp_new_path = (TCHAR *)ff_memalloc((_MAX_LFN + 1) * sizeof(WCHAR));
+						snprintf(temp_new_path, _MAX_LFN, "%s/%s", path_new, basename((char *)path_old));
+						res = follow_path(&djn, temp_new_path);
+					}
+				}
 				if (res == FR_NO_FILE) { 				/* It is a valid path and no name collision */
 					res = dir_register(&djn);			/* Register the new entry */
@@ -3777,4 +3947,6 @@
 	}
 
+	if (temp_new_path != 0)	ff_memfree(temp_new_path);
+
 	LEAVE_FF(djo.fs, res);
 }
@@ -3912,5 +4084,8 @@
 	WCHAR w;
 	DWORD tm;
-
+#if _CODE_PAGE == 65001
+	int code_size;
+	char utf8_code[6];
+#endif
 
 	/* Get logical drive number */
@@ -3925,4 +4100,13 @@
 		i = j = 0;
 		do {
+#if _CODE_PAGE == 65001
+			w = ff_wtoupper(Utf8_to_Utf16(&label[i], &code_size));
+			i += code_size;
+			Utf16_to_Utf8(utf8_code, &code_size, w);
+			if (!w || chk_chr("\"*+,.:;<=>\?[]|\x7F", w) || j >= sizeof(vn) - code_size) /* Reject invalid characters for volume label */
+				LEAVE_FF(dj.fs, FR_INVALID_NAME);
+			for (int k = 0; k < code_size; k++)
+				vn[j++] = utf8_code[k];
+#else
 #if _USE_LFN && _LFN_UNICODE
 			w = ff_convert(ff_wtoupper(label[i++]), 0);
@@ -3946,4 +4130,5 @@
 			if (w >= 0x100) vn[j++] = (BYTE)(w >> 8);
 			vn[j++] = (BYTE)w;
+#endif
 		} while (i < sl);
 		while (j < 11) vn[j++] = ' ';	/* Fill remaining name field */
Index: EcnlProtoTool/trunk/ntshell/fatfs/ff.h
===================================================================
--- EcnlProtoTool/trunk/ntshell/fatfs/ff.h	(revision 278)
+++ EcnlProtoTool/trunk/ntshell/fatfs/ff.h	(revision 279)
@@ -143,5 +143,5 @@
 /* Directory object structure (DIR) */
 
-typedef struct {
+typedef struct __dirstream {
 	FATFS*	fs;				/* Pointer to the owner file system object (**do not change order**) */
 	WORD	id;				/* Owner file system mount ID (**do not change order**) */
@@ -162,4 +162,5 @@
 	const TCHAR*	pat;	/* Pointer to the name matching pattern */
 #endif
+	struct dirent *dirent;
 } DIR;
 
@@ -252,22 +253,10 @@
 #define f_rewind(fp) f_lseek((fp), 0)
 #define f_rewinddir(dp) f_readdir((dp), 0)
-#define f_flush(fp)
+#define f_flush(fp) (FR_OK)
 
 #define F_SEEK_SET 1
 #define F_SEEK_CUR 2
 #define F_SEEK_END 3
-static FRESULT f_seek(FIL* fp, DWORD ofs, BYTE mode)
-{
-  switch (mode) {
-  case F_SEEK_SET:
-    return f_lseek((fp), ofs);
-  case F_SEEK_CUR:
-    return f_lseek((fp), (fp)->fptr + ofs);
-  case F_SEEK_END:
-    return f_lseek((fp), (fp)->fsize - ofs);
-  default:
-    return FR_INVALID_PARAMETER;
-  }
-}
+FRESULT f_seek(FIL* fp, DWORD ofs, BYTE mode);
 
 #ifndef EOF
Index: EcnlProtoTool/trunk/ntshell/fatfs/ffarch.c
===================================================================
--- EcnlProtoTool/trunk/ntshell/fatfs/ffarch.c	(revision 278)
+++ EcnlProtoTool/trunk/ntshell/fatfs/ffarch.c	(revision 279)
@@ -56,8 +56,7 @@
 #include <kernel.h>
 #include <stdlib.h>
-#include <errno.h>
-#include <sys/types.h>
 #include <string.h>
 #include "t_stdlib.h"
+#include "syssvc/serial.h"
 #include "syssvc/syslog.h"
 #include "kernel_cfg.h"
@@ -65,4 +64,16 @@
 #include "sdfs.h"
 #include "ff.h"
+#include "tlsf.h"
+#include "ntstdio.h"
+
+#define SIO_PORTID 1
+extern ntstdio_t ntstdio;
+
+static tlsf_t sys_tlsf;
+static pool_t sys_pool;
+
+uint32_t  __HeapBase;
+uint32_t  __HeapLimit;
+FATFS RomDisk;
 
 gpio_t ins;
@@ -70,12 +81,20 @@
 #define WP() false
 
-extern FATFS RomDisk;
-extern unsigned char RamDisk[SZ_RAMDISK * 1024];
-
+typedef struct SD {
+	DSTATUS dst;
+	BYTE type;
+	FATFS FatFs;
+} SD;
+SD Sd;
+
+void sys_init(void);
 bool_t romdisk_init();
+bool_t SD_begin();
 
 int mruby_arduino_init()
 {
 	int result = -1;
+
+	sys_init();
 
 	/* SD_CD */
@@ -85,26 +104,65 @@
 	sdfs_init(&sdfs, P8_5, P8_6, P8_3, P8_4, "sd");
 
-	SD_begin();
-
-	FIL fd;
-	UINT rlen = 0;
-	memset(&fd, 0, sizeof(fd));
-	if (f_open(&fd, "1:/httpd-fs.bin", FA_OPEN_EXISTING | FA_READ) == FR_OK) {
-		f_read(&fd, RamDisk, SZ_RAMDISK * 1024, &rlen);
-		f_close(&fd);
-		if (romdisk_init())
-			result = 0;
-	}
-
+	result = SD_begin() ? 0 : -1;
 	if (result == 0) {
-		syslog(LOG_NOTICE, "ramdisk ok!");
+		ntstdio_printf(&ntstdio, "SD card (1:) OK!\n");
 	}
 	else {
-		syslog(LOG_NOTICE, "ramdisk ng!");
-	}
-
-	arduino_init();
+		ntstdio_printf(&ntstdio, "SD card (1:) NG!\n");
+	}
+	sta_cyc(SDFS_CYC);
+
+	if (romdisk_init())
+		result = 0;
+
+	if (result == 0) {
+		ntstdio_printf(&ntstdio, "ROM disk (0:) OK!\n");
+	}
+	else {
+		ntstdio_printf(&ntstdio, "ROM disk (0:) NG!\n");
+	}
+
+	/* uploadãã£ã¬ã¯ããªãä½æãã¦ãã */
+	f_mkdir("1:/upload");
+
+	serial_ctl_por(SIO_PORTID, IOCTL_FCSND | IOCTL_FCRCV);
 
 	return result;
+}
+
+void sys_init(void)
+{
+	sys_tlsf = tlsf_create(&__HeapBase);
+	if (sys_tlsf == NULL)
+		return;
+
+	sys_pool = tlsf_add_pool(sys_tlsf, ((uint8_t *)&__HeapBase) + tlsf_size(), ((size_t)&__HeapLimit - (size_t)&__HeapBase) - tlsf_size());
+}
+
+void sys_fini(void)
+{
+	tlsf_destroy(sys_tlsf);
+}
+
+void *sys_malloc(size_t size)
+{
+	return tlsf_malloc(sys_tlsf, size);
+}
+
+void *sys_calloc(size_t size, size_t count)
+{
+	void *result = tlsf_malloc(sys_tlsf, count * size);
+	memset(result, 0, count * size);
+	return result;
+}
+
+void *sys_realloc(void *ptr, size_t size)
+{
+	return tlsf_realloc(sys_tlsf, ptr, size);
+}
+
+void sys_free(void *ptr)
+{
+	tlsf_free(sys_tlsf, ptr);
 }
 
@@ -122,4 +180,33 @@
 
 	if ((res = f_mount(&RomDisk, "0:", 1)) != FR_OK) {
+		return false;
+	}
+
+	return true;
+}
+
+bool_t SD_begin()
+{
+	DSTATUS dst;
+	FRESULT res;
+	BYTE pdrv = 1, type;
+
+	if (Sd.FatFs.fs_type != 0)
+		return true;
+
+	if ((dst = disk_initialize(pdrv)) != RES_OK) {
+		return false;
+	}
+
+	if ((dst = disk_ioctl(pdrv, MMC_GET_TYPE, &type)) != RES_OK) {
+		Sd.dst = dst;
+		Sd.type = 0;
+	}
+	else {
+		Sd.dst = RES_OK;
+		Sd.type = type;
+	}
+
+	if ((res = f_mount(&Sd.FatFs, "1:", 1)) != FR_OK) {
 		return false;
 	}
@@ -207,122 +294,33 @@
 }
 
-static int lock[TNUM_TSKID];
-static int stack_pos[TNUM_TSKID];
-
-void __malloc_lock(struct _reent *a)
-{
-	ID tskid;
+int ff_cre_syncobj(BYTE vol, _SYNC_t* sobj)
+{
+	return 1;
+}
+
+int ff_req_grant(_SYNC_t sobj)
+{
 	ER ret;
-	int count, sp;
-
-	ret = get_tid(&tskid);
-	if (ret != E_OK) {
-		/*syslog(LOG_DEBUG, "get_tid %s", itron_strerror(ret));*/
-		Asm("bkpt #0");
-	}
-
-	Asm("mov %0, sp" : "=r"(sp) :);
-	if ((stack_pos[tskid - 1] == 0) || (stack_pos[tskid - 1] < sp))
-		stack_pos[tskid - 1] = sp;
-
-	count = ++lock[tskid - 1];
-	if (count != 1)
-		return;
-
-	ret = wai_sem(SEM_MALLOC);
-	if (ret != E_OK) {
-		/*syslog(LOG_DEBUG, "wai_sem %s", itron_strerror(ret));*/
-		Asm("bkpt #0");
-	}
-}
-
-void __malloc_unlock(struct _reent *a)
-{
-	ID tskid;
-	ER ret;
-	int count;
-
-	ret = get_tid(&tskid);
-	if (ret != E_OK) {
-		/*syslog(LOG_DEBUG, "get_tid %s", itron_strerror(ret));*/
-		Asm("bkpt #0");
-	}
-
-	count = --lock[tskid - 1];
-	if(count != 0)
-		return;
-
-	ret = sig_sem(SEM_MALLOC);
-	if (ret != E_OK) {
-		/*syslog(LOG_DEBUG, "sig_sem %s", itron_strerror(ret));*/
-		Asm("bkpt #0");
-	}
-}
-
-// Provide implementation of _sbrk (low-level dynamic memory allocation
-// routine) for GCC_ARM which compares new heap pointer with MSP instead of
-// SP.  This make it compatible with RTX RTOS thread stacks.
-
-// Linker defined symbol used by _sbrk to indicate where heap should start.
-int __end__;
-uint32_t  __HeapLimit;
-
-// Turn off the errno macro and use actual global variable instead.
-#undef errno
-int errno;
-
-static unsigned char* heap = (unsigned char*)&__end__;
-
-// Dynamic memory allocation related syscall.
-caddr_t _sbrk(int incr) {
-	unsigned char*        prev_heap = heap;
-	unsigned char*        new_heap = heap + incr;
-
-	if (new_heap >= (unsigned char*)&__HeapLimit) {     /* __HeapLimit is end of heap section */
-		errno = ENOMEM;
-		return (caddr_t)-1;
-	}
-
-	heap = new_heap;
-	return (caddr_t) prev_heap;
-}
-
-void reset_heap()
-{
-	// .data
-	extern uint8_t __malloc_av_[0x408];
-	extern uint8_t __malloc_sbrk_base[0x4];
-	extern uint8_t __malloc_trim_threshold[0x4];
-	// .bss
-	extern uint8_t __malloc_top_pad[0x4];
-	extern uint8_t __malloc_current_mallinfo[0x28];
-	extern uint8_t __malloc_max_sbrked_mem[0x4];
-	extern uint8_t __malloc_max_total_mem[0x4];
-	//
-	extern void *__etext;
-	extern void *__data_start__;
-
-	int offset = (int)&__etext - (int)&__data_start__;
-
-	__malloc_lock(_REENT);
-
-	memcpy(__malloc_av_, &__malloc_av_[offset], sizeof(__malloc_av_));
-	memcpy(__malloc_sbrk_base, &__malloc_sbrk_base[offset], sizeof(__malloc_sbrk_base));
-	memcpy(__malloc_trim_threshold, &__malloc_trim_threshold[offset], sizeof(__malloc_trim_threshold));
-
-	memset(__malloc_top_pad, 0, sizeof(__malloc_top_pad));
-	memset(__malloc_current_mallinfo, 0, sizeof(__malloc_current_mallinfo));
-	memset(__malloc_max_sbrked_mem, 0, sizeof(__malloc_max_sbrked_mem));
-	memset(__malloc_max_total_mem, 0, sizeof(__malloc_max_total_mem));
-
-	heap = (unsigned char*)&__end__;
-
-	__malloc_unlock(_REENT);
-}
-
-void exit(int return_code) {
-	Asm("bkpt #0");
-	reset_heap();
-	ext_tsk();
-	for(;;);
-}
+	ret = wai_sem(SEM_FILESYSTEM);
+	return ret == E_OK;
+}
+
+void ff_rel_grant(_SYNC_t sobj)
+{
+	sig_sem(SEM_FILESYSTEM);
+}
+
+int ff_del_syncobj(_SYNC_t sobj)
+{
+	return 1;
+}
+
+void* ff_memalloc (UINT msize)
+{
+	return sys_malloc(msize);
+}
+
+void ff_memfree (void* mblock)
+{
+	sys_free(mblock);
+}
Index: EcnlProtoTool/trunk/ntshell/fatfs/ffarch.cfg
===================================================================
--- EcnlProtoTool/trunk/ntshell/fatfs/ffarch.cfg	(revision 278)
+++ EcnlProtoTool/trunk/ntshell/fatfs/ffarch.cfg	(revision 279)
@@ -51,7 +51,7 @@
  */
 
-#include "mruby_arduino.h"
+#include "ffarch.h"
 
-CRE_CYC(SDFS_CYC, { TA_NULL, { TNFY_HANDLER, 0, sdfs_cychdr }, 1000, 0 });
+CRE_CYC(SDFS_CYC, { TA_NULL, { TNFY_HANDLER, 0, sdfs_cychdr }, 1000000, 0 });
 
 CRE_SEM(SEM_MALLOC, { TA_TPRI, 1, 1 });
Index: EcnlProtoTool/trunk/ntshell/fatfs/ffarch.h
===================================================================
--- EcnlProtoTool/trunk/ntshell/fatfs/ffarch.h	(revision 278)
+++ EcnlProtoTool/trunk/ntshell/fatfs/ffarch.h	(revision 279)
@@ -54,5 +54,4 @@
 
 int mruby_arduino_init();
-void reset_heap();
 void sdfs_cychdr(intptr_t exinf);
 
Index: EcnlProtoTool/trunk/ntshell/fatfs/ffconf.h
===================================================================
--- EcnlProtoTool/trunk/ntshell/fatfs/ffconf.h	(revision 278)
+++ EcnlProtoTool/trunk/ntshell/fatfs/ffconf.h	(revision 279)
@@ -62,5 +62,5 @@
 /---------------------------------------------------------------------------*/
 
-#define _CODE_PAGE 437
+#define _CODE_PAGE 65001
 /* This option specifies the OEM code page to be used on the target system.
 /  Incorrect setting of the code page can cause a file open failure.
@@ -91,5 +91,5 @@
 
 
-#define	_USE_LFN	1
+#define	_USE_LFN	3
 #define	_MAX_LFN	255
 /* The _USE_LFN option switches the LFN feature.
@@ -227,7 +227,7 @@
 
 
-#define _FS_REENTRANT	0
+#define _FS_REENTRANT	1
 #define _FS_TIMEOUT		1000
-#define	_SYNC_t			HANDLE
+#define	_SYNC_t			unsigned int
 /* The _FS_REENTRANT option switches the re-entrancy (thread safe) of the FatFs
 /  module itself. Note that regardless of this option, file access to different
Index: EcnlProtoTool/trunk/ntshell/fatfs/time.c
===================================================================
--- EcnlProtoTool/trunk/ntshell/fatfs/time.c	(revision 279)
+++ EcnlProtoTool/trunk/ntshell/fatfs/time.c	(revision 279)
@@ -0,0 +1,269 @@
+/* musl-1.1.12/src/time/*.c */
+/* musl as a whole is licensed under the following standard MIT license:
+*
+* ----------------------------------------------------------------------
+* Copyright (C) 2005-2014 Rich Felker, et al.
+*
+* Permission is hereby granted, free of charge, to any person obtaining
+* a copy of this software and associated documentation files (the
+* "Software"), to deal in the Software without restriction, including
+* without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to
+* permit persons to whom the Software is furnished to do so, subject to
+* the following conditions:
+*
+* The above copyright notice and this permission notice shall be
+* included in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+* ----------------------------------------------------------------------*/
+#include <string.h>
+#include <limits.h>
+#include <time.h>
+#include <errno.h>
+#include "ff.h"
+
+/* 2000-03-01 (mod 400 year, immediately after feb29 */
+#define LEAPOCH (946684800LL + 86400*(31+29))
+
+#define DAYS_PER_400Y (365*400 + 97)
+#define DAYS_PER_100Y (365*100 + 24)
+#define DAYS_PER_4Y   (365*4   + 1)
+
+int __secs_to_tm(long long t, struct tm* tm)
+{
+	long long days, secs, years;
+	int remdays, remsecs, remyears;
+	int qc_cycles, c_cycles, q_cycles;
+	int months;
+	int wday, yday, leap;
+	static const char days_in_month[] = {31,30,31,30,31,31,30,31,30,31,31,29};
+
+	/* Reject time_t values whose year would overflow int */
+	if (t < INT_MIN * 31622400LL || t > INT_MAX * 31622400LL)
+		return -1;
+
+	secs = t - LEAPOCH;
+	days = secs / 86400;
+	remsecs = secs % 86400;
+	if (remsecs < 0) {
+		remsecs += 86400;
+		days--;
+	}
+
+	wday = (3 + days) % 7;
+	if (wday < 0) wday += 7;
+
+	qc_cycles = days / DAYS_PER_400Y;
+	remdays = days % DAYS_PER_400Y;
+	if (remdays < 0) {
+		remdays += DAYS_PER_400Y;
+		qc_cycles--;
+	}
+
+	c_cycles = remdays / DAYS_PER_100Y;
+	if (c_cycles == 4) c_cycles--;
+	remdays -= c_cycles * DAYS_PER_100Y;
+
+	q_cycles = remdays / DAYS_PER_4Y;
+	if (q_cycles == 25) q_cycles--;
+	remdays -= q_cycles * DAYS_PER_4Y;
+
+	remyears = remdays / 365;
+	if (remyears == 4) remyears--;
+	remdays -= remyears * 365;
+
+	leap = !remyears && (q_cycles || !c_cycles);
+	yday = remdays + 31 + 28 + leap;
+	if (yday >= 365 + leap) yday -= 365 + leap;
+
+	years = remyears + 4 * q_cycles + 100 * c_cycles + 400LL * qc_cycles;
+
+	for (months = 0; days_in_month[months] <= remdays; months++)
+		remdays -= days_in_month[months];
+
+	if (years + 100 > INT_MAX || years + 100 < INT_MIN)
+		return -1;
+
+	tm->tm_year = years + 100;
+	tm->tm_mon = months + 2;
+	if (tm->tm_mon >= 12) {
+		tm->tm_mon -= 12;
+		tm->tm_year++;
+	}
+	tm->tm_mday = remdays + 1;
+	tm->tm_wday = wday;
+	tm->tm_yday = yday;
+
+	tm->tm_hour = remsecs / 3600;
+	tm->tm_min = remsecs / 60 % 60;
+	tm->tm_sec = remsecs % 60;
+
+	return 0;
+}
+
+long long __year_to_secs(long long year, int *is_leap)
+{
+	if (year - 2ULL <= 136) {
+		int y = year;
+		int leaps = (y - 68) >> 2;
+		if (!((y - 68) & 3)) {
+			leaps--;
+			if (is_leap) *is_leap = 1;
+		}
+		else if (is_leap) *is_leap = 0;
+		return 31536000 * (y - 70) + 86400 * leaps;
+	}
+
+	int cycles, centuries, leaps, rem;
+
+	if (!is_leap) is_leap = &(int) { 0 };
+	cycles = (year - 100) / 400;
+	rem = (year - 100) % 400;
+	if (rem < 0) {
+		cycles--;
+		rem += 400;
+	}
+	if (!rem) {
+		*is_leap = 1;
+		centuries = 0;
+		leaps = 0;
+	}
+	else {
+		if (rem >= 200) {
+			if (rem >= 300) centuries = 3, rem -= 300;
+			else centuries = 2, rem -= 200;
+		}
+		else {
+			if (rem >= 100) centuries = 1, rem -= 100;
+			else centuries = 0;
+		}
+		if (!rem) {
+			*is_leap = 0;
+			leaps = 0;
+		}
+		else {
+			leaps = rem / 4U;
+			rem %= 4U;
+			*is_leap = !rem;
+		}
+	}
+
+	leaps += 97 * cycles + 24 * centuries - *is_leap;
+
+	return (year - 100) * 31536000LL + leaps * 86400LL + 946684800 + 86400;
+}
+
+int __month_to_secs(int month, int is_leap)
+{
+	static const int secs_through_month[] = {
+		0, 31 * 86400, 59 * 86400, 90 * 86400,
+		120 * 86400, 151 * 86400, 181 * 86400, 212 * 86400,
+		243 * 86400, 273 * 86400, 304 * 86400, 334 * 86400};
+	int t = secs_through_month[month];
+	if (is_leap && month >= 2) t += 86400;
+	return t;
+}
+
+long long __tm_to_secs(const struct tm *tm)
+{
+	int is_leap;
+	long long year = tm->tm_year;
+	int month = tm->tm_mon;
+	if (month >= 12 || month < 0) {
+		int adj = month / 12;
+		month %= 12;
+		if (month < 0) {
+			adj--;
+			month += 12;
+		}
+		year += adj;
+	}
+	long long t = __year_to_secs(year, &is_leap);
+	t += __month_to_secs(month, is_leap);
+	t += 86400LL * (tm->tm_mday - 1);
+	t += 3600LL * tm->tm_hour;
+	t += 60LL * tm->tm_min;
+	t += tm->tm_sec;
+	return t;
+}
+
+struct tm *localtime_r(const time_t *t, struct tm *tm)
+{
+	/* Reject time_t values whose year would overflow int because
+	* __secs_to_zone cannot safely handle them. */
+	if (*t < INT_MIN * 31622400LL || *t > INT_MAX * 31622400LL) {
+		errno = EOVERFLOW;
+		return 0;
+	}
+	//TODO:__secs_to_zone(*t, 0, &tm->tm_isdst, &tm->__tm_gmtoff, 0, &tm->__tm_zone);
+	if (__secs_to_tm((long long)*t /*+ tm->__tm_gmtoff*/, tm) < 0) {
+		errno = EOVERFLOW;
+		return 0;
+	}
+	return tm;
+}
+
+struct tm *localtime(const time_t *time)
+{
+	static struct tm tm;
+	return localtime_r(time, &tm);
+}
+
+struct tm *gmtime_r(const time_t *t, struct tm *tm)
+{
+	if (__secs_to_tm(*t, tm) < 0) {
+		errno = EOVERFLOW;
+		return 0;
+	}
+	tm->tm_isdst = 0;
+	/*tm->__tm_gmtoff = 0;
+	tm->__tm_zone = NULL;//__gmt;*/
+	return tm;
+}
+
+/* There is no other implemented value than TIME_UTC; all other values
+ * are considered erroneous. */
+/*int timespec_get(struct timespec * ts, int base)
+{
+	if (base != TIME_UTC) return 0;
+	int ret = __clock_gettime(CLOCK_REALTIME, ts);
+	return ret < 0 ? 0 : base;
+}*/
+time_t mktime(struct tm *tm)
+{
+	struct tm new;
+	long opp;
+	long long t = __tm_to_secs(tm);
+
+	if (__secs_to_tm(t, &new) < 0) goto error;
+
+	*tm = new;
+	return t;
+
+error:
+	errno = EOVERFLOW;
+	return -1;
+}
+
+DWORD get_fattime(void)
+{
+	time_t temp;
+	struct tm _tm;
+
+	time(&temp);
+	gmtime_r(&temp, &_tm);
+
+	return	  ((DWORD)(_tm.tm_year - 1980) << 25)
+		| ((DWORD)_tm.tm_mon << 21)
+		| ((DWORD)_tm.tm_mday << 16)
+		| ((DWORD)_tm.tm_hour << 11)
+		| ((DWORD)_tm.tm_min << 5)
+		| ((DWORD)_tm.tm_sec >> 1);
+}
