mirror of
https://github.com/arendst/Tasmota.git
synced 2025-08-01 15:07:42 +00:00
Fix ESP32 flashwrites
This commit is contained in:
parent
4c4c082769
commit
f5ad07fe5e
@ -75,6 +75,17 @@ void ESP_Restart(void) {
|
|||||||
ESP.reset();
|
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
|
#endif
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
@ -190,6 +201,76 @@ void NvsInfo(void) {
|
|||||||
nvs_stats.used_entries, nvs_stats.free_entries, nvs_stats.total_entries, nvs_stats.namespace_count);
|
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
|
// Crash stuff
|
||||||
//
|
//
|
||||||
@ -313,4 +394,33 @@ void ESP_Restart(void) {
|
|||||||
ESP.restart();
|
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
|
#endif // ESP32
|
||||||
|
@ -2575,14 +2575,10 @@ struct {
|
|||||||
bool ready;
|
bool ready;
|
||||||
} BUpload;
|
} BUpload;
|
||||||
|
|
||||||
uint32_t BUploadStartSector(void) {
|
|
||||||
return (ESP.getSketchSize() / SPI_FLASH_SEC_SIZE) + 2; // Stay on the safe side
|
|
||||||
}
|
|
||||||
|
|
||||||
void BUploadInit(uint32_t file_type) {
|
void BUploadInit(uint32_t file_type) {
|
||||||
Web.upload_file_type = file_type;
|
Web.upload_file_type = file_type;
|
||||||
BUpload.spi_hex_size = 0;
|
BUpload.spi_hex_size = 0;
|
||||||
BUpload.spi_sector_counter = BUploadStartSector();
|
BUpload.spi_sector_counter = FlashWriteStartSector();
|
||||||
BUpload.spi_sector_cursor = 0;
|
BUpload.spi_sector_cursor = 0;
|
||||||
BUpload.active = true;
|
BUpload.active = true;
|
||||||
BUpload.ready = false;
|
BUpload.ready = false;
|
||||||
@ -2590,15 +2586,19 @@ void BUploadInit(uint32_t file_type) {
|
|||||||
|
|
||||||
uint32_t BUploadWriteBuffer(uint8_t *buf, size_t size) {
|
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
|
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++;
|
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;
|
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
|
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_cursor = 0;
|
||||||
BUpload.spi_sector_counter++;
|
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
|
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) {
|
if ((UPL_EFR32 == Web.upload_file_type) && !Web.upload_error && BUpload.ready) {
|
||||||
BUpload.ready = false; // Make sure not to follow thru again
|
BUpload.ready = false; // Make sure not to follow thru again
|
||||||
// GUI xmodem
|
// GUI xmodem
|
||||||
ZigbeeUploadStep1Done(BUploadStartSector(), BUpload.spi_hex_size);
|
ZigbeeUploadStep1Done(FlashWriteStartSector(), BUpload.spi_hex_size);
|
||||||
HandleZigbeeXfer();
|
HandleZigbeeXfer();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2886,7 +2886,8 @@ void HandleUploadLoop(void)
|
|||||||
|
|
||||||
AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_UPLOAD "Transfer %u bytes"), upload.totalSize);
|
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
|
// 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]);
|
// 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
|
#endif // USE_RF_FLASH
|
||||||
#ifdef USE_TASMOTA_CLIENT
|
#ifdef USE_TASMOTA_CLIENT
|
||||||
if (UPL_TASMOTACLIENT == Web.upload_file_type) {
|
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
|
#endif // USE_TASMOTA_CLIENT
|
||||||
#ifdef SHELLY_FW_UPGRADE
|
#ifdef SHELLY_FW_UPGRADE
|
||||||
|
Loading…
x
Reference in New Issue
Block a user