assert(mFirstUsedEntry != INVALID_ENTRY);
const uint16_t count = size / ENTRY_SIZE;
- auto rc = spi_flash_write(getEntryAddress(mNextFreeEntry), data, size);
+ const uint8_t* buf = data;
+
+#ifdef ESP_PLATFORM
+ /* On the ESP32, data can come from DROM, which is not accessible by spi_flash_write
+ * function. To work around this, we copy the data to heap if it came from DROM.
+ * Hopefully this won't happen very often in practice. For data from DRAM, we should
+ * still be able to write it to flash directly.
+ * TODO: figure out how to make this platform-specific check nicer (probably by introducing
+ * a platform-specific flash layer).
+ */
+ if ((uint32_t) data < 0x3ff00000) {
+ buf = (uint8_t*) malloc(size);
+ if (!buf) {
+ return ESP_ERR_NO_MEM;
+ }
+ memcpy((void*)buf, data, size);
+ }
+#endif //ESP_PLATFORM
+ auto rc = spi_flash_write(getEntryAddress(mNextFreeEntry), buf, size);
+#ifdef ESP_PLATFORM
+ if (buf != data) {
+ free((void*)buf);
+ }
+#endif //ESP_PLATFORM
if (rc != ESP_OK) {
mState = PageState::INVALID;
return rc;
if (size % 4 != 0) {
return ESP_ERR_INVALID_SIZE;
}
+ if ((uint32_t) src < 0x3ff00000) {
+ // if source address is in DROM, we won't be able to read it
+ // from within SPIWrite
+ // TODO: consider buffering source data using heap and writing it anyway?
+ return ESP_ERR_INVALID_ARG;
+ }
// Out of bound writes are checked in ROM code, but we can give better
// error code here
if (dest_addr + size > g_rom_flashchip.chip_size) {
*
* @note Address in flash, dest, has to be 4-byte aligned.
* This is a temporary limitation which will be removed.
+ * @note If source address is in DROM, this function will return
+ * ESP_ERR_INVALID_ARG.
*
* @param dest destination address in Flash
* @param src pointer to the source buffer