Caching issues with mmap'ed flash
Posted: Thu Jun 28, 2018 4:17 pm
I'm calling esp_partition_mmap() to memory-map a flash partition, and then esp_partition_erase_range() and esp_partition_write() to write to it. Most of the time (95%?) this works fine, but intermittently I see errors where, after a write, part of the mapped memory is still filled with FF instead of the data I wrote.
I thought this might be a race condition with the flash controller (maybe the write takes longer than it indicates and sometimes it hasn't finished by the time the read occurs) so I added a 100ms delay after the write; that seems to help somewhat, but it's not a complete fix.
My only other hypothesis is that this is due to CPU cache coherency, but the spi_flash code looks like it's careful to disable/enable caches. I'm not familiar with the ESP32's cache system, but I assume it's doing the equivalent of a memory-barrier.
Any ideas?
Here's some rough code showing the kind of thing I do:
I thought this might be a race condition with the flash controller (maybe the write takes longer than it indicates and sometimes it hasn't finished by the time the read occurs) so I added a 100ms delay after the write; that seems to help somewhat, but it's not a complete fix.
My only other hypothesis is that this is due to CPU cache coherency, but the spi_flash code looks like it's careful to disable/enable caches. I'm not familiar with the ESP32's cache system, but I assume it's doing the equivalent of a memory-barrier.
Any ideas?
Here's some rough code showing the kind of thing I do:
Code: Select all
void *mapped;
esp_partition_mmap(partition, 0, partition_size, SPI_FLASH_MMAP_DATA, &mapped, &handle);
...
esp_partition_erase_range(partition, 0, 4096);
esp_partition_write(partition, 0, data, dataLength);
...
assert(memcmp(data, mapped, dataLength) == 0); // sometimes fails