Fix ESP32 flashwrites

This commit is contained in:
Theo Arends 2020-11-22 17:35:04 +01:00
parent 4c4c082769
commit f5ad07fe5e
2 changed files with 123 additions and 12 deletions

View File

@ -75,6 +75,17 @@ void ESP_Restart(void) {
ESP.reset();
}
uint32_t FlashWriteStartSector(void) {
return (ESP.getSketchSize() / SPI_FLASH_SEC_SIZE) + 2; // Stay on the safe side
}
uint32_t FlashWriteMaxSector(void) {
return (((uint32_t)&_FS_end - 0x40200000) / SPI_FLASH_SEC_SIZE) - 2;
}
uint8_t* FlashDirectAccess(void) {
return (uint8_t*)(0x40200000 + (FlashWriteStartSector() * SPI_FLASH_SEC_SIZE));
}
#endif
/*********************************************************************************************\
@ -190,6 +201,76 @@ void NvsInfo(void) {
nvs_stats.used_entries, nvs_stats.free_entries, nvs_stats.total_entries, nvs_stats.namespace_count);
}
//
// Flash memory mapping
//
#include "Esp.h"
#include "rom/spi_flash.h"
#include "esp_spi_flash.h"
#include <memory>
#include <soc/soc.h>
#include <soc/efuse_reg.h>
#include <esp_partition.h>
extern "C" {
#include "esp_ota_ops.h"
#include "esp_image_format.h"
}
uint32_t EspFlashBaseAddress(void) {
const esp_partition_t* partition = esp_ota_get_next_update_partition(nullptr);
if (!partition) { return 0; }
return partition->address; // For tasmota 0x00010000 or 0x00200000
}
uint32_t EspFlashBaseEndAddress(void) {
const esp_partition_t* partition = esp_ota_get_next_update_partition(nullptr);
if (!partition) { return 0; }
return partition->address + partition->size; // For tasmota 0x00200000 or 0x003F0000
}
uint8_t* EspFlashMmap(uint32_t address) {
static spi_flash_mmap_handle_t handle = 0;
if (handle) {
spi_flash_munmap(handle);
handle = 0;
}
const uint8_t* data;
int32_t err = spi_flash_mmap(address, 5 * SPI_FLASH_MMU_PAGE_SIZE, SPI_FLASH_MMAP_DATA, (const void **)&data, &handle);
/*
AddLog_P(LOG_LEVEL_DEBUG, PSTR("DBG: Spi_flash_map %d"), err);
spi_flash_mmap_dump();
*/
return (uint8_t*)data;
}
/*
int32_t EspPartitionMmap(uint32_t action) {
static spi_flash_mmap_handle_t handle;
int32_t err = 0;
if (1 == action) {
const esp_partition_t *partition = esp_ota_get_running_partition();
// const esp_partition_t* partition = esp_ota_get_next_update_partition(nullptr);
if (!partition) { return 0; }
err = esp_partition_mmap(partition, 0, 4 * SPI_FLASH_MMU_PAGE_SIZE, SPI_FLASH_MMAP_DATA, (const void **)&TasmotaGlobal_mmap_data, &handle);
AddLog_P(LOG_LEVEL_DEBUG, PSTR("DBG: Partition start 0x%08X, Partition end 0x%08X, Mmap data 0x%08X"), partition->address, partition->size, TasmotaGlobal_mmap_data);
} else {
spi_flash_munmap(handle);
handle = 0;
}
return err;
}
*/
//
// Crash stuff
//
@ -262,7 +343,7 @@ String ESP32GetResetReason(uint32_t cpu_no) {
case RTCWDT_CPU_RESET : return F("RTC Watch dog Reset CPU"); // 13
case EXT_CPU_RESET : return F("or APP CPU, reseted by PRO CPU"); // 14
case RTCWDT_BROWN_OUT_RESET : return F("Reset when the vdd voltage is not stable"); // 15
case RTCWDT_RTC_RESET : return F("RTC Watch dog reset digital core and rtc module"); // 16
case RTCWDT_RTC_RESET : return F("RTC Watch dog reset digital core and rtc module"); // 16
}
return F("No meaning"); // 0 and undefined
}
@ -313,4 +394,33 @@ void ESP_Restart(void) {
ESP.restart();
}
uint32_t FlashWriteStartSector(void) {
// Needs to be on SPI_FLASH_MMU_PAGE_SIZE (= 0x10000) alignment for mmap usage
uint32_t aligned_address = ((EspFlashBaseAddress() + (2 * SPI_FLASH_MMU_PAGE_SIZE)) / SPI_FLASH_MMU_PAGE_SIZE) * SPI_FLASH_MMU_PAGE_SIZE;
return aligned_address / SPI_FLASH_SEC_SIZE;
}
uint32_t FlashWriteMaxSector(void) {
// Needs to be on SPI_FLASH_MMU_PAGE_SIZE (= 0x10000) alignment for mmap usage
uint32_t aligned_end_address = (EspFlashBaseEndAddress() / SPI_FLASH_MMU_PAGE_SIZE) * SPI_FLASH_MMU_PAGE_SIZE;
return aligned_end_address / SPI_FLASH_SEC_SIZE;
}
uint8_t* FlashDirectAccess(void) {
uint32_t address = FlashWriteStartSector() * SPI_FLASH_SEC_SIZE;
uint8_t* data = EspFlashMmap(address);
/*
AddLog_P(LOG_LEVEL_DEBUG, PSTR("DBG: Flash start address 0x%08X, Mmap address 0x%08X"), address, data);
uint8_t buf[32];
memcpy(buf, data, sizeof(buf));
AddLogBuffer(LOG_LEVEL_DEBUG, (uint8_t*)&buf, 32);
memcpy(buf, data, sizeof(buf));
AddLogBuffer(LOG_LEVEL_DEBUG, (uint8_t*)&buf + , 32);
*/
return data;
}
#endif // ESP32

View File

@ -2575,14 +2575,10 @@ struct {
bool ready;
} BUpload;
uint32_t BUploadStartSector(void) {
return (ESP.getSketchSize() / SPI_FLASH_SEC_SIZE) + 2; // Stay on the safe side
}
void BUploadInit(uint32_t file_type) {
Web.upload_file_type = file_type;
BUpload.spi_hex_size = 0;
BUpload.spi_sector_counter = BUploadStartSector();
BUpload.spi_sector_counter = FlashWriteStartSector();
BUpload.spi_sector_cursor = 0;
BUpload.active = true;
BUpload.ready = false;
@ -2590,15 +2586,19 @@ void BUploadInit(uint32_t file_type) {
uint32_t BUploadWriteBuffer(uint8_t *buf, size_t size) {
if (0 == BUpload.spi_sector_cursor) { // Starting a new sector write so we need to erase it first
ESP.flashEraseSector(BUpload.spi_sector_counter);
if (!ESP.flashEraseSector(BUpload.spi_sector_counter)) {
return 7; // Upload aborted - flash failed
}
}
BUpload.spi_sector_cursor++;
ESP.flashWrite((BUpload.spi_sector_counter * SPI_FLASH_SEC_SIZE) + ((BUpload.spi_sector_cursor -1) * 2048), (uint32_t*)buf, size);
if (!ESP.flashWrite((BUpload.spi_sector_counter * SPI_FLASH_SEC_SIZE) + ((BUpload.spi_sector_cursor -1) * 2048), (uint32_t*)buf, size)) {
return 7; // Upload aborted - flash failed
}
BUpload.spi_hex_size += size;
if (2 == BUpload.spi_sector_cursor) { // The web upload sends 2048 bytes at a time so keep track of the cursor position to reset it for the next flash sector erase
BUpload.spi_sector_cursor = 0;
BUpload.spi_sector_counter++;
if (BUpload.spi_sector_counter > (SPIFFS_END -2)) {
if (BUpload.spi_sector_counter > FlashWriteMaxSector()) {
return 9; // File too large - Not enough free space
}
}
@ -2660,7 +2660,7 @@ void HandleUploadDone(void)
if ((UPL_EFR32 == Web.upload_file_type) && !Web.upload_error && BUpload.ready) {
BUpload.ready = false; // Make sure not to follow thru again
// GUI xmodem
ZigbeeUploadStep1Done(BUploadStartSector(), BUpload.spi_hex_size);
ZigbeeUploadStep1Done(FlashWriteStartSector(), BUpload.spi_hex_size);
HandleZigbeeXfer();
return;
}
@ -2886,7 +2886,8 @@ void HandleUploadLoop(void)
AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_UPLOAD "Transfer %u bytes"), upload.totalSize);
uint8_t* data = (uint8_t*)(0x40200000 + (BUploadStartSector() * SPI_FLASH_SEC_SIZE));
// uint8_t* data = (uint8_t*)(0x40200000 + (FlashWriteStartSector() * SPI_FLASH_SEC_SIZE));
uint8_t* data = FlashDirectAccess();
// uint32_t* values = (uint32_t*)(data); // Only 4-byte access allowed
// AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_UPLOAD "Head 0x%08X"), values[0]);
@ -2899,7 +2900,7 @@ void HandleUploadLoop(void)
#endif // USE_RF_FLASH
#ifdef USE_TASMOTA_CLIENT
if (UPL_TASMOTACLIENT == Web.upload_file_type) {
error = TasmotaClient_Flash(BUploadStartSector() * SPI_FLASH_SEC_SIZE, BUpload.spi_hex_size);
error = TasmotaClient_Flash(FlashWriteStartSector() * SPI_FLASH_SEC_SIZE, BUpload.spi_hex_size);
}
#endif // USE_TASMOTA_CLIENT
#ifdef SHELLY_FW_UPGRADE