pellepl / spiffs

Wear-leveled SPI flash file system for embedded devices
MIT License
1.52k stars 402 forks source link

Hardfault writing to work buffer pages #290

Open berkutta opened 2 years ago

berkutta commented 2 years ago

I'm currently trying to implement SPIFFS into a project running on a RP2040. This is a Cortex M0+ 32-Bit MCU.

My work buffer is created according to the implementation guide:

#define LOG_PAGE_SIZE       256

static u8_t spiffs_work_buf[LOG_PAGE_SIZE*2];
static u8_t spiffs_fds[32*4];
static u8_t spiffs_cache_buf[(LOG_PAGE_SIZE+32)*4];

After implementing the HAL functions, I tried to test everything with the test_spiffs() function from the implementation guide. Unfortunately, I got a hard fault while running the function. It crashed somewhere in the SPIFFS_close() function.

A bit of debugging revealed that the crash is happening on this line: https://github.com/pellepl/spiffs/blob/master/src/spiffs_nucleus.c#L1392

The reason for the crash seems to be that the work buffer is stored in an address utilizing the 32-Bit Address Space. Thus casting it to a (u8_t *) results writing in another forbidden area. For testing, I changed this cast to (u32_t *) which fixed the crash on this line. Unfortunately, the same issue is at many other places.

This is my current diff to get the test_spiffs() running.

Am I doing something horribly wrong in my implementation, or is this a real issue with SPIFFS?

diff --git a/src/spiffs_nucleus.c b/src/spiffs_nucleus.c
index ab5cde1..db0011b 100644
--- a/src/spiffs_nucleus.c
+++ b/src/spiffs_nucleus.c
@@ -1389,13 +1389,13 @@ s32_t spiffs_object_append(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) {
     // update memory representation of object index page with new data page
     if (cur_objix_spix == 0) {
       // update object index header page
-      ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix] = data_page;
+      ((spiffs_page_ix*)((u32_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix] = data_page;
       SPIFFS_DBG("append: "_SPIPRIid" wrote page "_SPIPRIpg" to objix_hdr entry "_SPIPRIsp" in mem\n", fd->obj_id
           , data_page, data_spix);
       objix_hdr->size = offset+written;
     } else {
       // update object index page
-      ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)] = data_page;
+      ((spiffs_page_ix*)((u32_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)] = data_page;
       SPIFFS_DBG("append: "_SPIPRIid" wrote page "_SPIPRIpg" to objix entry "_SPIPRIsp" in mem\n", fd->obj_id
           , data_page, (spiffs_span_ix)SPIFFS_OBJ_IX_ENTRY(fs, data_spix));
     }
@@ -1829,12 +1829,12 @@ s32_t spiffs_object_truncate(

     if (cur_objix_spix == 0) {
       // get data page from object index header page
-      data_pix = ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix];
-      ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix] = SPIFFS_OBJ_ID_FREE;
+      data_pix = ((spiffs_page_ix*)((u32_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix];
+      ((spiffs_page_ix*)((u32_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix] = SPIFFS_OBJ_ID_FREE;
     } else {
       // get data page from object index page
-      data_pix = ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)];
-      ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)] = SPIFFS_OBJ_ID_FREE;
+      data_pix = ((spiffs_page_ix*)((u32_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)];
+      ((spiffs_page_ix*)((u32_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)] = SPIFFS_OBJ_ID_FREE;
     }

     SPIFFS_DBG("truncate: got data pix "_SPIPRIpg"\n", data_pix);
@@ -2029,10 +2029,10 @@ s32_t spiffs_object_read(

       if (cur_objix_spix == 0) {
         // get data page from object index header page
-        data_pix = ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix];
+        data_pix = ((spiffs_page_ix*)((u32_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix];
       } else {
         // get data page from object index page
-        data_pix = ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)];
+        data_pix = ((spiffs_page_ix*)((u32_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)];
       }
 #if SPIFFS_IX_MAP
     }