ソースを参照

add: 添加fatfs-vfs,挂载sdcard到vfs也测试ok了, 扩展006fatfs测试用例

Wendal Chen 4 年 前
コミット
281697b5fc

+ 1 - 0
bsp/win32/CMakeLists.txt

@@ -94,6 +94,7 @@ add_library(fatfs   ${TOPROOT}/luat/packages/fatfs/ff.c
                     ${TOPROOT}/luat/packages/fatfs/diskio_impl.c
                     ${TOPROOT}/luat/packages/fatfs/diskio_ramdisk.c
                     ${TOPROOT}/luat/packages/fatfs/diskio_spitf.c
+                    ${TOPROOT}/luat/vfs/luat_fs_fatfs.c
                     ${TOPROOT}/luat/packages/fatfs/luat_lib_fatfs.c)
 
 #-----------------------

+ 14 - 0
bsp/win32/module_test/006fatfs.lua

@@ -18,6 +18,20 @@ sys.taskInit(function ()
         else
             log.info("fatfs", "ramdisk", "err", err)
         end
+        -- fatfs 在vfs中的前缀总是/sdcard
+        local f = io.open("/sdcard/abc.txt", "w")
+        assert(f ~= nil, "fatfs io error")
+        if f then
+            f:write("Hi, from LuatOS")
+            f:close()
+        end
+        f = io.open("/sdcard/abc.txt", "r")
+        assert(f ~= nil, "fatfs io error")
+        if f then
+            local data = f:read("a")
+            log.info("from fatfs-vfs", data)
+            assert(data == "Hi, from LuatOS", "fatfs r/w error")
+        end
     end
     os.exit(0)
 end)

+ 24 - 7
luat/packages/fatfs/luat_lib_fatfs.c

@@ -4,6 +4,7 @@
 #include "luat_timer.h"
 #include "luat_gpio.h"
 #include "luat_malloc.h"
+#include "luat_fs.h"
 
 #include "ff.h"			/* Obtains integer types */
 #include "diskio.h"		/* Declarations of disk functions */
@@ -19,6 +20,10 @@ extern BYTE FATFS_SPI_CS; // GPIO 3
 DRESULT diskio_open_ramdisk(BYTE pdrv, size_t len);
 DRESULT diskio_open_spitf(BYTE pdrv, BYTE id, BYTE cs);
 
+#ifdef LUAT_USE_FS_VFS
+extern const struct luat_vfs_filesystem vfs_fs_fatfs;
+#endif
+
 static int fatfs_mount(lua_State *L)
 {
 	if (FATFS_DEBUG)
@@ -41,12 +46,21 @@ static int fatfs_mount(lua_State *L)
 		diskio_open_spitf(0, FATFS_SPI_ID, FATFS_SPI_CS);
 	}
 
-	DRESULT re = f_mount(fs, mount_point, 0);
+	FRESULT re = f_mount(fs, "", 0);
 	
 	lua_pushinteger(L, re);
 	if (re == FR_OK) {
 		if (FATFS_DEBUG)
 			LLOGD("[FatFS]fatfs_init success");
+		#ifdef LUAT_USE_FS_VFS
+              luat_fs_conf_t conf2 = {
+		            .busname = (char*)fs,
+		            .type = "fatfs",
+		            .filesystem = "fatfs",
+		            .mount_point = "/sdcard/",
+	            };
+	            luat_fs_mount(&conf2);
+		#endif
 	}
 	else {
 		if (FATFS_DEBUG)
@@ -95,7 +109,7 @@ static int fatfs_getfree(lua_State *L)
 	// 挂载点
 	const char *mount_point = luaL_optstring(L, 1, "");
 	FATFS *fs2;
-	DRESULT re2 = f_getfree(mount_point, &fre_clust, &fs2);
+	FRESULT re2 = f_getfree(mount_point, &fre_clust, &fs2);
 	if (re2) {
 		lua_pushnil(L);
 		lua_pushinteger(L, re2);
@@ -157,7 +171,7 @@ static int fatfs_lsdir(lua_State *L)
 	char dirname[len+1];
 	memcpy(dirname, buf, len);
 	dirname[len] = 0x00;
-	DRESULT re = f_opendir(&dir, dirname);
+	FRESULT re = f_opendir(&dir, dirname);
 	if (re != FR_OK) {
 		lua_pushinteger(L, re);
 		return 1;
@@ -194,7 +208,7 @@ static int fatfs_lsdir(lua_State *L)
 		lua_settable(L, -3);
 	}
 	f_closedir(&dir);
-	LLOGD("[FatFS] lua_gettop=%d", lua_gettop(L));
+	//LLOGD("[FatFS] lua_gettop=%d", lua_gettop(L));
     return 2;
 }
 
@@ -261,7 +275,7 @@ static int fatfs_open(lua_State *L) {
 
 	if (FATFS_DEBUG)
 		LLOGD("[FatFS]open %s %0X", path, flag);
-	DRESULT re = f_open(fil, path, (BYTE)flag);
+	FRESULT re = f_open(fil, path, (BYTE)flag);
 	if (re != FR_OK) {
 		lua_remove(L, -1);
 		lua_pushnil(L);
@@ -342,7 +356,7 @@ static int fatfs_write(lua_State *L) {
     luaType = lua_type( L, 2 );
     int len;
     char* buf;
-	int re = -1;
+	FRESULT re = FR_OK;
     
     if(luaType == LUA_TSTRING )
     {
@@ -409,7 +423,7 @@ static int fatfs_readfile(lua_State *L) {
 	}
 	FIL fil;
 
-	DRESULT re = f_open(&fil, lua_tostring(L, 1), FA_READ);
+	FRESULT re = f_open(&fil, lua_tostring(L, 1), FA_READ);
 	if (re != FR_OK) {
 		lua_pushinteger(L, re);
 		return 1;
@@ -520,5 +534,8 @@ static const rotable_Reg reg_fatfs[] =
 int luaopen_fatfs( lua_State *L )
 {
   luat_newlib(L, reg_fatfs);
+  #ifdef LUAT_USE_FS_VFS
+  luat_vfs_reg(&vfs_fs_fatfs);
+  #endif
   return 1;
 }

+ 108 - 33
luat/vfs/luat_fs_fatfs.c

@@ -1,77 +1,150 @@
 
 #include "luat_base.h"
 #include "luat_fs.h"
+#include "luat_malloc.h"
 
-#ifdef LUAT_VFS_USE_FATFS
+#define LUAT_LOG_TAG "fatfs"
+#include "luat_log.h"
 
-#error "no complete yet"
-// 参考 luat_lib_fatfs 里面操作fatfs的方法, 实现vfs封装.
+#ifdef LUAT_USE_FS_VFS
 
 #include "ff.h"
 #include "diskio.h"
 
-extern FATFS *fs;
-
 FILE* luat_vfs_fatfs_fopen(void* userdata, const char *filename, const char *mode) {
-    //LLOGD("fopen %s %s", filename + (filename[0] == '/' ? 1 : 0), mode);
-    return fopen(filename + (filename[0] == '/' ? 1 : 0), mode);
+    LLOGD("f_open %s %s", filename, mode);
+    FATFS *fs = (FATFS*)userdata;
+    FIL* fp = luat_heap_malloc(sizeof(FIL));
+    int flag = 0;
+    for (size_t i = 0; i < strlen(mode); i++)
+    {
+        char m = *(mode + i);
+        switch (m)
+        {
+        case 'r':
+            flag |= FA_READ;
+            break;
+        case 'w':
+            flag |= FA_WRITE | FA_CREATE_NEW;
+            break;
+        case 'a':
+            flag |= FA_OPEN_APPEND;
+            break;
+        case '+':
+            flag |= FA_OPEN_APPEND;
+            break;
+        
+        default:
+            break;
+        }
+    }
+    FRESULT ret = f_open(fp, filename, flag);
+    if (ret != FR_OK) {
+        LLOGD("f_open %s %d", filename, ret);
+        luat_heap_free(fp);
+        return 0; 
+    }
+    return (FILE*)fp;
 }
 
 int luat_vfs_fatfs_getc(void* userdata, FILE* stream) {
-    //LLOGD("posix_getc %p", stream);
-    return getc(stream);
+    FATFS *fs = (FATFS*)userdata;
+    FIL* fp = (FIL*)stream;
+    char buff = 0;
+    UINT result = 0;
+    FRESULT ret = f_read(fp, (void*)&buff, 1, &result);
+    if (ret == FR_OK) {
+        return buff;
+    }
+    return -1;
 }
 
 int luat_vfs_fatfs_fseek(void* userdata, FILE* stream, long int offset, int origin) {
-    return fseek(stream, offset, origin);
+    FATFS *fs = (FATFS*)userdata;
+    FIL* fp = (FIL*)stream;
+    int npos = f_tell(fp);
+    if (origin == SEEK_SET) {
+        npos = offset;
+    } else if (origin == SEEK_CUR) {
+        npos += offset;
+    } else if (origin == SEEK_END) {
+        npos = f_size(fp);
+    }
+    FRESULT ret = f_lseek(fp, npos);
+    if (ret == FR_OK) {
+        return f_tell(fp);
+    }
+    return -1;
 }
 
 int luat_vfs_fatfs_ftell(void* userdata, FILE* stream) {
-    return ftell(stream);
+    FATFS *fs = (FATFS*)userdata;
+    FIL* fp = (FIL*)stream;
+    return f_tell(fp);
 }
 
 int luat_vfs_fatfs_fclose(void* userdata, FILE* stream) {
-    return fclose(stream);
+    FATFS *fs = (FATFS*)userdata;
+    FIL* fp = (FIL*)stream;
+    if (fp != NULL) {
+        f_close(fp);
+        luat_heap_free(fp);
+    }
+    return 0;
 }
 int luat_vfs_fatfs_feof(void* userdata, FILE* stream) {
-    return feof(stream);
+    FATFS *fs = (FATFS*)userdata;
+    FIL* fp = (FIL*)stream;
+    return f_eof(fp);
 }
 int luat_vfs_fatfs_ferror(void* userdata, FILE *stream) {
-    return ferror(stream);
+    FATFS *fs = (FATFS*)userdata;
+    FIL* fp = (FIL*)stream;
+    return f_error(fp);
 }
 size_t luat_vfs_fatfs_fread(void* userdata, void *ptr, size_t size, size_t nmemb, FILE *stream) {
-    
-    return fread(ptr, size, nmemb, stream);
+    FATFS *fs = (FATFS*)userdata;
+    FIL* fp = (FIL*)stream;
+    int result = 0;
+    FRESULT ret = f_read(fp, ptr, size*nmemb, &result);
+    if (ret == FR_OK) {
+        return result;
+    }
+    return 0;
 }
 size_t luat_vfs_fatfs_fwrite(void* userdata, const void *ptr, size_t size, size_t nmemb, FILE *stream) {
-    return fwrite(ptr, size, nmemb, stream);
+    FATFS *fs = (FATFS*)userdata;
+    FIL* fp = (FIL*)stream;
+    int result = 0;
+    FRESULT ret = f_write(fp, ptr, size*nmemb, &result);
+    if (ret == FR_OK) {
+        return result;
+    }
+    return 0;
 }
 int luat_vfs_fatfs_remove(void* userdata, const char *filename) {
-    return remove(filename + (filename[0] == '/' ? 1 : 0));
+    return f_unlink(filename);
 }
 int luat_vfs_fatfs_rename(void* userdata, const char *old_filename, const char *new_filename) {
-    return rename(old_filename + (old_filename[0] == '/' ? 1 : 0), new_filename + (new_filename[0] == '/' ? 1 : 0));
+    return f_rename(old_filename + (old_filename[0] == '/' ? 1 : 0), new_filename + (new_filename[0] == '/' ? 1 : 0));
 }
 
 int luat_vfs_fatfs_fexist(void* userdata, const char *filename) {
-    FILE* fd = luat_vfs_fatfs_fopen(userdata, filename, "rb");
-    if (fd) {
-        luat_vfs_fatfs_fclose(userdata, fd);
+    FILINFO fno = {0};
+    FRESULT ret = f_stat(filename, &fno);
+    if (ret == FR_OK) {
         return 1;
     }
     return 0;
 }
 
 size_t luat_vfs_fatfs_fsize(void* userdata, const char *filename) {
-    FILE *fd;
-    size_t size = 0;
-    fd = luat_vfs_fatfs_fopen(userdata, filename, "rb");
-    if (fd) {
-        luat_vfs_fatfs_fseek(userdata, fd, 0, SEEK_END);
-        size = luat_vfs_fatfs_ftell(userdata, fd); 
-        luat_vfs_fatfs_fclose(userdata, fd);
+    FILINFO fno = {0};
+    FRESULT ret = f_stat(filename, &fno);
+    if (ret == FR_OK) {
+        return fno.fsize;
     }
-    return size;
+    return 0;
 }
 
 int luat_vfs_fatfs_mkfs(void* userdata, luat_fs_conf_t *conf) {
@@ -79,7 +152,7 @@ int luat_vfs_fatfs_mkfs(void* userdata, luat_fs_conf_t *conf) {
     return -1;
 }
 int luat_vfs_fatfs_mount(void** userdata, luat_fs_conf_t *conf) {
-    //LLOGE("not support yet : mount");
+    *userdata = (void*)conf->busname;
     return 0;
 }
 int luat_vfs_fatfs_umount(void* userdata, luat_fs_conf_t *conf) {
@@ -88,10 +161,12 @@ int luat_vfs_fatfs_umount(void* userdata, luat_fs_conf_t *conf) {
 }
 
 int luat_vfs_fatfs_mkdir(void* userdata, char const* _DirName) {
-    return mkdir(_DirName);
+    LLOGE("not support yet : mkdir");
+    return -1;
 }
 int luat_vfs_fatfs_rmdir(void* userdata, char const* _DirName) {
-    return rmdir(_DirName);
+    LLOGE("not support yet : rmdir");
+    return -1;
 }
 
 #define T(name) .name = luat_vfs_fatfs_##name