Ver Fonte

flash_ops: fix spi_flash_read with source buffer not from internal memory and size < 16

Closes https://github.com/espressif/esp-idf/issues/4010
Ajita Chavan há 6 anos atrás
pai
commit
622842a983

+ 10 - 0
components/spi_flash/flash_ops.c

@@ -522,7 +522,17 @@ esp_err_t IRAM_ATTR spi_flash_read(size_t src, void *dstv, size_t size)
             goto out;
         }
         COUNTER_ADD_BYTES(read, read_size);
+#ifdef ESP_PLATFORM
+        if (esp_ptr_external_ram(dstv)) {
+            spi_flash_guard_end();
+            memcpy(dstv, ((uint8_t *) t) + left_off, size);
+            spi_flash_guard_start();
+        } else {
+            memcpy(dstv, ((uint8_t *) t) + left_off, size);
+        }
+#else
         memcpy(dstv, ((uint8_t *) t) + left_off, size);
+#endif
         goto out;
     }
     uint8_t *dstc = (uint8_t *) dstv;

+ 34 - 1
components/spi_flash/test/test_read_write.c

@@ -29,6 +29,7 @@
 #include "soc/timer_group_reg.h"
 #include "esp_heap_caps.h"
 
+#define MIN_BLOCK_SIZE  12
 /* Base offset in flash for tests. */
 static size_t start;
 
@@ -265,4 +266,36 @@ TEST_CASE("spi_flash_write can write from external RAM buffer", "[spi_flash]")
     free(buf_int);
 }
 
-#endif // CONFIG_SPIRAM_SUPPORT
+TEST_CASE("spi_flash_read less than 16 bytes into buffer in external RAM", "[spi_flash]")
+{
+    uint8_t *buf_ext_8 = (uint8_t *) heap_caps_malloc(MIN_BLOCK_SIZE, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
+    TEST_ASSERT_NOT_NULL(buf_ext_8);
+
+    uint8_t *buf_int_8 = (uint8_t *) heap_caps_malloc(MIN_BLOCK_SIZE, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
+    TEST_ASSERT_NOT_NULL(buf_int_8);
+
+    uint8_t data_8[MIN_BLOCK_SIZE];
+    for (int i = 0; i < MIN_BLOCK_SIZE; i++) {
+        data_8[i] = i;
+    }
+
+    const esp_partition_t *part = get_test_data_partition();
+    TEST_ESP_OK(spi_flash_erase_range(part->address, SPI_FLASH_SEC_SIZE));
+    TEST_ESP_OK(spi_flash_write(part->address, data_8, MIN_BLOCK_SIZE));
+    TEST_ESP_OK(spi_flash_read(part->address, buf_ext_8, MIN_BLOCK_SIZE));
+    TEST_ESP_OK(spi_flash_read(part->address, buf_int_8, MIN_BLOCK_SIZE));
+
+    TEST_ASSERT_EQUAL(0, memcmp(buf_ext_8, data_8, MIN_BLOCK_SIZE));
+    TEST_ASSERT_EQUAL(0, memcmp(buf_int_8, data_8, MIN_BLOCK_SIZE));
+
+    if (buf_ext_8) {
+        free(buf_ext_8);
+        buf_ext_8 = NULL;
+    }
+    if (buf_int_8) {
+        free(buf_int_8);
+        buf_int_8 = NULL;
+    }
+}
+
+#endif // CONFIG_ESP32_SPIRAM_SUPPORT