]> granicus.if.org Git - esp-idf/commitdiff
implement review recomendations
authorme-no-dev <hristo@espressif.com>
Wed, 1 Feb 2017 15:55:25 +0000 (17:55 +0200)
committerme-no-dev <hristo@espressif.com>
Wed, 1 Feb 2017 15:55:25 +0000 (17:55 +0200)
components/fatfs/src/diskio.c
components/fatfs/src/diskio.h
components/fatfs/src/esp_vfs_fat.h
components/fatfs/src/vfs_fat.c
components/fatfs/src/vfs_fat_sdmmc.c

index 915bb8e2cf3cd47a6bc0d987edf1baf46ce071dd..c61702f51f7f936f707843212fc6e68da1fe8266 100644 (file)
@@ -27,15 +27,16 @@ PARTITION VolToPart[] = {
     {1, 0}     /* Logical drive 1 ==> Physical drive 1, auto detection */\r
 };\r
 \r
-BYTE ff_disk_getpdrv()\r
+esp_err_t ff_diskio_get_drive(BYTE* out_pdrv)\r
 {\r
     BYTE i;\r
     for(i=0; i<_VOLUMES; i++) {\r
         if (!s_impls[i]) {\r
-            return i;\r
+            *out_pdrv = i;\r
+            return ESP_OK;\r
         }\r
     }\r
-    return 0xFF;\r
+    return ESP_ERR_NOT_FOUND;\r
 }\r
 \r
 void ff_diskio_register(BYTE pdrv, const ff_diskio_impl_t* discio_impl)\r
index 2fd27a864a3056238262b4135c504a650f2131d3..64d5d5b8df1b33c44c4ad5bb55779fbca1550fb0 100644 (file)
@@ -58,16 +58,19 @@ typedef struct {
 } ff_diskio_impl_t;\r
 \r
 /**\r
- * Register diskio driver for given drive number.\r
+ * Register or unregister diskio driver for given drive number.\r
  *\r
  * When FATFS library calls one of disk_xxx functions for driver number pdrv,\r
  * corresponding function in discio_impl for given pdrv will be called.\r
  *\r
  * @param pdrv drive number\r
- * @param discio_impl  pointer to ff_diskio_impl_t structure with diskio functions\r
+ * @param discio_impl   pointer to ff_diskio_impl_t structure with diskio functions\r
+ *                      or NULL to unregister and free previously registered drive\r
  */\r
 void ff_diskio_register(BYTE pdrv, const ff_diskio_impl_t* discio_impl);\r
 \r
+#define ff_diskio_unregister(pdrv_) ff_diskio_register(pdrv_, NULL)\r
+\r
 /**\r
  * Register SD/MMC diskio driver\r
  *\r
@@ -79,9 +82,12 @@ void ff_diskio_register_sdmmc(BYTE pdrv, sdmmc_card_t* card);
 /**\r
  * Get next available drive number\r
  *\r
- * @return 0xFF on fail, else the drive number\r
+ * @param   out_pdrv            pointer to the byte to set if successful\r
+ *\r
+ * @return  ESP_OK              on success\r
+ *          ESP_ERR_NOT_FOUND   if all drives are attached\r
  */\r
-BYTE ff_disk_getpdrv();\r
+esp_err_t ff_diskio_get_drive(BYTE* out_pdrv);\r
 \r
 /* Disk Status Bits (DSTATUS) */\r
 \r
index 6dbef5cfb1ca753b8426abaff91ee88e156de333..9c39198da370bbc4dd5dc90f9d314422cc171383 100644 (file)
@@ -51,18 +51,24 @@ esp_err_t esp_vfs_fat_register(const char* base_path, const char* fat_drive,
  * @note FATFS structure returned by esp_vfs_fat_register is destroyed after
  *       this call. Make sure to call f_mount function to unmount it before
  *       calling esp_vfs_fat_unregister.
+ *       This function is left for compatibility and will be changed in
+ *       future versions to accept base_path and replace the method below
  * @return
  *      - ESP_OK on success
  *      - ESP_ERR_INVALID_STATE if FATFS is not registered in VFS
  */
-esp_err_t esp_vfs_fat_unregister();
+esp_err_t esp_vfs_fat_unregister() __attribute__((deprecated));
 
 /**
  * @brief Un-register FATFS from VFS
  *
  * @note FATFS structure returned by esp_vfs_fat_register is destroyed after
  *       this call. Make sure to call f_mount function to unmount it before
- *       calling esp_vfs_fat_unregister.
+ *       calling esp_vfs_fat_unregister_ctx.
+ *       Difference between this function and the one above is that this one
+ *       will release the correct drive, while the one above will release
+ *       the last registered one
+ *
  * @param base_path     path prefix where FATFS is registered. This is the same
  *                      used when esp_vfs_fat_register was called
  * @return
index e85666f1d3b4edbf6b8fbdd16eaa12fc0fa4dc3c..10e207482f2043afc2dc9bcd8419835e884f9b18 100644 (file)
@@ -65,12 +65,12 @@ static int vfs_fat_mkdir(void* ctx, const char* name, mode_t mode);
 static int vfs_fat_rmdir(void* ctx, const char* name);
 
 static vfs_fat_ctx_t* s_fat_ctxs[_VOLUMES] = { NULL, NULL };
-//compatibility
+//backwards-compatibility with esp_vfs_fat_unregister()
 static vfs_fat_ctx_t* s_fat_ctx = NULL;
 
-static unsigned char esp_vfs_fat_get_ctx(const char* base_path)
+static size_t find_context_index_by_path(const char* base_path)
 {
-    for(unsigned char i=0; i<_VOLUMES; i++) {
+    for(size_t i=0; i<_VOLUMES; i++) {
         if (s_fat_ctxs[i] && !strcmp(s_fat_ctxs[i]->base_path, base_path)) {
             return i;
         }
@@ -78,9 +78,9 @@ static unsigned char esp_vfs_fat_get_ctx(const char* base_path)
     return _VOLUMES;
 }
 
-static unsigned char esp_vfs_fat_get_empty_ctx()
+static size_t find_unused_context_index()
 {
-    for(unsigned char i=0; i<_VOLUMES; i++) {
+    for(size_t i=0; i<_VOLUMES; i++) {
         if (!s_fat_ctxs[i]) {
             return i;
         }
@@ -90,12 +90,12 @@ static unsigned char esp_vfs_fat_get_empty_ctx()
 
 esp_err_t esp_vfs_fat_register(const char* base_path, const char* fat_drive, size_t max_files, FATFS** out_fs)
 {
-    unsigned char ctx = esp_vfs_fat_get_ctx(base_path);
+    size_t ctx = find_context_index_by_path(base_path);
     if (ctx < _VOLUMES) {
         return ESP_ERR_INVALID_STATE;
     }
 
-    ctx = esp_vfs_fat_get_empty_ctx();
+    ctx = find_unused_context_index();
     if (ctx == _VOLUMES) {
         return ESP_ERR_NO_MEM;
     }
@@ -127,12 +127,8 @@ esp_err_t esp_vfs_fat_register(const char* base_path, const char* fat_drive, siz
         return ESP_ERR_NO_MEM;
     }
     fat_ctx->max_files = max_files;
-
-    strncpy(fat_ctx->fat_drive, fat_drive, sizeof(fat_ctx->fat_drive) - 1);
-    fat_ctx->fat_drive[sizeof(fat_ctx->fat_drive) - 1] = 0;
-
-    strncpy(fat_ctx->base_path, base_path, sizeof(fat_ctx->base_path) - 1);
-    fat_ctx->base_path[sizeof(fat_ctx->base_path) - 1] = 0;
+    strlcpy(fat_ctx->fat_drive, fat_drive, sizeof(fat_ctx->fat_drive) - 1);
+    strlcpy(fat_ctx->base_path, base_path, sizeof(fat_ctx->base_path) - 1);
 
     esp_err_t err = esp_vfs_register(base_path, &vfs, fat_ctx);
     if (err != ESP_OK) {
@@ -153,7 +149,7 @@ esp_err_t esp_vfs_fat_register(const char* base_path, const char* fat_drive, siz
 
 esp_err_t esp_vfs_fat_unregister_ctx(const char* base_path)
 {
-    unsigned char ctx = esp_vfs_fat_get_ctx(base_path);
+    size_t ctx = find_context_index_by_path(base_path);
     if (ctx == _VOLUMES) {
         return ESP_ERR_INVALID_STATE;
     }
@@ -249,14 +245,20 @@ static void file_cleanup(vfs_fat_ctx_t* ctx, int fd)
     memset(&ctx->files[fd], 0, sizeof(FIL));
 }
 
-#define vfs_fat_fix_path(ctx, path) \
-    char buf_ ## path[strlen(path)+strlen(((vfs_fat_ctx_t*)ctx)->fat_drive)+1]; \
-    sprintf(buf_ ## path,"%s%s", ((vfs_fat_ctx_t*)ctx)->fat_drive, path); \
-    path = (const char *)buf_ ## path;
+static void prepend_drive_to_path(void * ctx, const char * path, const char * path2){
+    static char buf[FILENAME_MAX+3];
+    static char buf2[FILENAME_MAX+3];
+    sprintf(buf, "%s%s", ((vfs_fat_ctx_t*)ctx)->fat_drive, path);
+    path = (const char *)buf;
+    if(path2){
+        sprintf(buf2, "%s%s", ((vfs_fat_ctx_t*)ctx)->fat_drive, path2);
+        path2 = (const char *)buf;
+    }
+}
 
 static int vfs_fat_open(void* ctx, const char * path, int flags, int mode)
 {
-    vfs_fat_fix_path(ctx, path);
+    prepend_drive_to_path(ctx, path, NULL);
     ESP_LOGV(TAG, "%s: path=\"%s\", flags=%x, mode=%x", __func__, path, flags, mode);
     vfs_fat_ctx_t* fat_ctx = (vfs_fat_ctx_t*) ctx;
     _lock_acquire(&fat_ctx->lock);
@@ -366,7 +368,7 @@ static int vfs_fat_fstat(void* ctx, int fd, struct stat * st)
 
 static int vfs_fat_stat(void* ctx, const char * path, struct stat * st)
 {
-    vfs_fat_fix_path(ctx, path);
+    prepend_drive_to_path(ctx, path, NULL);
     FILINFO info;
     FRESULT res = f_stat(path, &info);
     if (res != FR_OK) {
@@ -396,7 +398,7 @@ static int vfs_fat_stat(void* ctx, const char * path, struct stat * st)
 
 static int vfs_fat_unlink(void* ctx, const char *path)
 {
-    vfs_fat_fix_path(ctx, path);
+    prepend_drive_to_path(ctx, path, NULL);
     FRESULT res = f_unlink(path);
     if (res != FR_OK) {
         ESP_LOGD(TAG, "%s: fresult=%d", __func__, res);
@@ -408,8 +410,7 @@ static int vfs_fat_unlink(void* ctx, const char *path)
 
 static int vfs_fat_link(void* ctx, const char* n1, const char* n2)
 {
-    vfs_fat_fix_path(ctx, n1);
-    vfs_fat_fix_path(ctx, n2);
+    prepend_drive_to_path(ctx, n1, n2);
     const size_t copy_buf_size = 4096;
     void* buf = malloc(copy_buf_size);
     if (buf == NULL) {
@@ -464,8 +465,7 @@ fail1:
 
 static int vfs_fat_rename(void* ctx, const char *src, const char *dst)
 {
-    vfs_fat_fix_path(ctx, src);
-    vfs_fat_fix_path(ctx, dst);
+    prepend_drive_to_path(ctx, src, dst);
     FRESULT res = f_rename(src, dst);
     if (res != FR_OK) {
         ESP_LOGD(TAG, "%s: fresult=%d", __func__, res);
@@ -477,7 +477,7 @@ static int vfs_fat_rename(void* ctx, const char *src, const char *dst)
 
 static DIR* vfs_fat_opendir(void* ctx, const char* name)
 {
-    vfs_fat_fix_path(ctx, name);
+    prepend_drive_to_path(ctx, name, NULL);
     vfs_fat_dir_t* fat_dir = calloc(1, sizeof(vfs_fat_dir_t));
     if (!fat_dir) {
         errno = ENOMEM;
@@ -582,7 +582,7 @@ static void vfs_fat_seekdir(void* ctx, DIR* pdir, long offset)
 static int vfs_fat_mkdir(void* ctx, const char* name, mode_t mode)
 {
     (void) mode;
-    vfs_fat_fix_path(ctx, name);
+    prepend_drive_to_path(ctx, name, NULL);
     FRESULT res = f_mkdir(name);
     if (res != FR_OK) {
         ESP_LOGD(TAG, "%s: fresult=%d", __func__, res);
@@ -594,7 +594,7 @@ static int vfs_fat_mkdir(void* ctx, const char* name, mode_t mode)
 
 static int vfs_fat_rmdir(void* ctx, const char* name)
 {
-    vfs_fat_fix_path(ctx, name);
+    prepend_drive_to_path(ctx, name, NULL);
     FRESULT res = f_unlink(name);
     if (res != FR_OK) {
         ESP_LOGD(TAG, "%s: fresult=%d", __func__, res);
index f5e4c5099afc1107cd83c4dfa9fda15a1e7acdf2..16effdce27cdedf91e1fbd005c6fcb0612639da3 100644 (file)
@@ -13,6 +13,7 @@
 // limitations under the License.
 
 #include <stdlib.h>
+#include <string.h>
 #include "esp_log.h"
 #include "esp_vfs.h"
 #include "esp_vfs_fat.h"
@@ -23,6 +24,7 @@
 static const char* TAG = "vfs_fat_sdmmc";
 static sdmmc_card_t* s_card = NULL;
 static uint8_t s_pdrv = 0;
+static char * s_base_path = NULL;
 
 esp_err_t esp_vfs_fat_sdmmc_mount(const char* base_path,
     const sdmmc_host_t* host_config,
@@ -36,6 +38,20 @@ esp_err_t esp_vfs_fat_sdmmc_mount(const char* base_path,
     if (s_card != NULL) {
         return ESP_ERR_INVALID_STATE;
     }
+
+    // connect SDMMC driver to FATFS
+    BYTE pdrv = 0xFF;
+    if (ff_diskio_get_drive(&pdrv) != ESP_OK || pdrv == 0xFF) {
+        ESP_LOGD(TAG, "the maximum count of volumes is already mounted");
+        return ESP_ERR_NO_MEM;
+    }
+
+    s_base_path = strdup(base_path);
+    if(!s_base_path){
+        ESP_LOGD(TAG, "could not copy base_path");
+        return ESP_ERR_NO_MEM;
+    }
+
     // enable SDMMC
     sdmmc_host_init();
 
@@ -56,12 +72,6 @@ esp_err_t esp_vfs_fat_sdmmc_mount(const char* base_path,
         *out_card = s_card;
     }
 
-    // connect SDMMC driver to FATFS
-    BYTE pdrv = ff_disk_getpdrv();
-    if (pdrv == 0xFF) {
-        ESP_LOGD(TAG, "the maximum count of volumes is already mounted");
-        goto fail;
-    }
     ff_diskio_register_sdmmc(pdrv, s_card);
     s_pdrv = pdrv;
     char drv[3] = {(char)('0' + pdrv), ':', 0};
@@ -114,6 +124,7 @@ esp_err_t esp_vfs_fat_sdmmc_mount(const char* base_path,
 fail:
     free(workbuf);
     esp_vfs_fat_unregister_ctx(base_path);
+    ff_diskio_unregister(pdrv);
     free(s_card);
     s_card = NULL;
     return err;
@@ -128,8 +139,12 @@ esp_err_t esp_vfs_fat_sdmmc_unmount()
     char drv[3] = {(char)('0' + s_pdrv), ':', 0};
     f_mount(0, drv, 0);
     // release SD driver
+    ff_diskio_unregister(s_pdrv);
     free(s_card);
     s_card = NULL;
     sdmmc_host_deinit();
-    return esp_vfs_fat_unregister();
+    esp_err_t err = esp_vfs_fat_unregister_ctx(s_base_path);
+    free(s_base_path);
+    s_base_path = NULL;
+    return err;
 }