1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-06-06 05:21:22 +03:00

Add flash read/write/erase APIs to ESPClass

This commit is contained in:
Ivan Grokhotkov 2015-08-18 23:38:23 +03:00
parent fac840b6a8
commit c355f626f2
4 changed files with 67 additions and 59 deletions

View File

@ -400,3 +400,26 @@ bool EspClass::updateSketch(Stream& in, uint32_t size, bool restartOnFail, bool
if(restartOnSuccess) ESP.restart(); if(restartOnSuccess) ESP.restart();
return true; return true;
} }
static const int FLASH_INT_MASK = ((B10 << 8) | B00111010);
bool EspClass::flashEraseSector(uint32_t sector) {
ets_isr_mask(FLASH_INT_MASK);
int rc = spi_flash_erase_sector(sector);
ets_isr_unmask(FLASH_INT_MASK);
return rc == 0;
}
bool EspClass::flashWrite(uint32_t offset, uint32_t *data, size_t size) {
ets_isr_mask(FLASH_INT_MASK);
int rc = spi_flash_write(offset, (uint32_t*) data, size);
ets_isr_unmask(FLASH_INT_MASK);
return rc == 0;
}
bool EspClass::flashRead(uint32_t offset, uint32_t *data, size_t size) {
ets_isr_mask(FLASH_INT_MASK);
int rc = spi_flash_read(offset, (uint32_t*) data, size);
ets_isr_unmask(FLASH_INT_MASK);
return rc == 0;
}

View File

@ -117,6 +117,10 @@ class EspClass {
FlashMode_t getFlashChipMode(); FlashMode_t getFlashChipMode();
uint32_t getFlashChipSizeByChipId(); uint32_t getFlashChipSizeByChipId();
bool flashEraseSector(uint32_t sector);
bool flashWrite(uint32_t offset, uint32_t *data, size_t size);
bool flashRead(uint32_t offset, uint32_t *data, size_t size);
uint32_t getSketchSize(); uint32_t getSketchSize();
uint32_t getFreeSketchSpace(); uint32_t getFreeSketchSpace();
bool updateSketch(Stream& in, uint32_t size, bool restartOnFail = false, bool restartOnSuccess = true); bool updateSketch(Stream& in, uint32_t size, bool restartOnFail = false, bool restartOnSuccess = true);

View File

@ -1,9 +1,13 @@
#include "Updater.h" #include "Updater.h"
#include "Arduino.h" #include "Arduino.h"
#include "eboot_command.h" #include "eboot_command.h"
//#define DEBUG_UPDATER Serial //#define DEBUG_UPDATER Serial
extern "C" {
#include "c_types.h"
#include "spi_flash.h"
}
extern "C" uint32_t _SPIFFS_start; extern "C" uint32_t _SPIFFS_start;
UpdaterClass::UpdaterClass() UpdaterClass::UpdaterClass()
@ -112,17 +116,11 @@ bool UpdaterClass::end(bool evenIfRemaining){
} }
bool UpdaterClass::_writeBuffer(){ bool UpdaterClass::_writeBuffer(){
noInterrupts();
int rc = SPIEraseSector(_currentAddress/FLASH_SECTOR_SIZE);
interrupts();
yield(); yield();
if(!rc){ bool result = ESP.flashEraseSector(_currentAddress/FLASH_SECTOR_SIZE) &&
noInterrupts(); ESP.flashWrite(_currentAddress, (uint32_t*) _buffer, _bufferLen);
rc = SPIWrite(_currentAddress, _buffer, _bufferLen);
interrupts(); if (!result) {
}
interrupts();
if (rc) {
_error = UPDATE_ERROR_WRITE; _error = UPDATE_ERROR_WRITE;
_currentAddress = (_startAddress + _size); _currentAddress = (_startAddress + _size);
#ifdef DEBUG_UPDATER #ifdef DEBUG_UPDATER

View File

@ -23,32 +23,11 @@
#include <algorithm> #include <algorithm>
#include "spiffs/spiffs.h" #include "spiffs/spiffs.h"
#include "debug.h" #include "debug.h"
#include "interrupts.h"
extern "C" { extern "C" {
#include "c_types.h" #include "c_types.h"
#include "spi_flash.h" #include "spi_flash.h"
} }
static int spi_flash_read_locked(uint32_t addr, uint32_t* dst, uint32_t size) {
optimistic_yield(10000);
AutoInterruptLock(5);
return spi_flash_read(addr, dst, size);
}
static int spi_flash_write_locked(uint32_t addr, const uint32_t* src, uint32_t size) {
optimistic_yield(10000);
AutoInterruptLock(5);
return spi_flash_write(addr, (uint32_t*) src, size);
}
static int spi_flash_erase_sector_locked(uint32_t sector) {
optimistic_yield(10000);
AutoInterruptLock(5);
return spi_flash_erase_sector(sector);
}
/* /*
spi_flash_read function requires flash address to be aligned on word boundary. spi_flash_read function requires flash address to be aligned on word boundary.
We take care of this by reading first and last words separately and memcpy We take care of this by reading first and last words separately and memcpy
@ -64,6 +43,8 @@ alignedEnd: ^
*/ */
int32_t spiffs_hal_read(uint32_t addr, uint32_t size, uint8_t *dst) { int32_t spiffs_hal_read(uint32_t addr, uint32_t size, uint8_t *dst) {
optimistic_yield(10000);
uint32_t result = SPIFFS_OK; uint32_t result = SPIFFS_OK;
uint32_t alignedBegin = (addr + 3) & (~3); uint32_t alignedBegin = (addr + 3) & (~3);
uint32_t alignedEnd = (addr + size) & (~3); uint32_t alignedEnd = (addr + size) & (~3);
@ -71,7 +52,7 @@ int32_t spiffs_hal_read(uint32_t addr, uint32_t size, uint8_t *dst) {
if (addr < alignedBegin) { if (addr < alignedBegin) {
uint32_t nb = alignedBegin - addr; uint32_t nb = alignedBegin - addr;
uint32_t tmp; uint32_t tmp;
if (spi_flash_read_locked(alignedBegin - 4, &tmp, 4) != SPI_FLASH_RESULT_OK) { if (!ESP.flashRead(alignedBegin - 4, &tmp, 4)) {
DEBUGV("_spif_read(%d) addr=%x size=%x ab=%x ae=%x\r\n", DEBUGV("_spif_read(%d) addr=%x size=%x ab=%x ae=%x\r\n",
__LINE__, addr, size, alignedBegin, alignedEnd); __LINE__, addr, size, alignedBegin, alignedEnd);
return SPIFFS_ERR_INTERNAL; return SPIFFS_ERR_INTERNAL;
@ -80,8 +61,8 @@ int32_t spiffs_hal_read(uint32_t addr, uint32_t size, uint8_t *dst) {
} }
if (alignedEnd != alignedBegin) { if (alignedEnd != alignedBegin) {
if (spi_flash_read_locked(alignedBegin, (uint32_t*) (dst + alignedBegin - addr), if (!ESP.flashRead(alignedBegin, (uint32_t*) (dst + alignedBegin - addr),
alignedEnd - alignedBegin) != SPI_FLASH_RESULT_OK) { alignedEnd - alignedBegin)) {
DEBUGV("_spif_read(%d) addr=%x size=%x ab=%x ae=%x\r\n", DEBUGV("_spif_read(%d) addr=%x size=%x ab=%x ae=%x\r\n",
__LINE__, addr, size, alignedBegin, alignedEnd); __LINE__, addr, size, alignedBegin, alignedEnd);
return SPIFFS_ERR_INTERNAL; return SPIFFS_ERR_INTERNAL;
@ -91,7 +72,7 @@ int32_t spiffs_hal_read(uint32_t addr, uint32_t size, uint8_t *dst) {
if (addr + size > alignedEnd) { if (addr + size > alignedEnd) {
uint32_t nb = addr + size - alignedEnd; uint32_t nb = addr + size - alignedEnd;
uint32_t tmp; uint32_t tmp;
if (spi_flash_read_locked(alignedEnd, &tmp, 4) != SPI_FLASH_RESULT_OK) { if (!ESP.flashRead(alignedEnd, &tmp, 4)) {
DEBUGV("_spif_read(%d) addr=%x size=%x ab=%x ae=%x\r\n", DEBUGV("_spif_read(%d) addr=%x size=%x ab=%x ae=%x\r\n",
__LINE__, addr, size, alignedBegin, alignedEnd); __LINE__, addr, size, alignedBegin, alignedEnd);
return SPIFFS_ERR_INTERNAL; return SPIFFS_ERR_INTERNAL;
@ -116,6 +97,8 @@ int32_t spiffs_hal_read(uint32_t addr, uint32_t size, uint8_t *dst) {
static const int UNALIGNED_WRITE_BUFFER_SIZE = 512; static const int UNALIGNED_WRITE_BUFFER_SIZE = 512;
int32_t spiffs_hal_write(uint32_t addr, uint32_t size, uint8_t *src) { int32_t spiffs_hal_write(uint32_t addr, uint32_t size, uint8_t *src) {
optimistic_yield(10000);
uint32_t alignedBegin = (addr + 3) & (~3); uint32_t alignedBegin = (addr + 3) & (~3);
uint32_t alignedEnd = (addr + size) & (~3); uint32_t alignedEnd = (addr + size) & (~3);
@ -123,7 +106,7 @@ int32_t spiffs_hal_write(uint32_t addr, uint32_t size, uint8_t *src) {
uint32_t nb = alignedBegin - addr; uint32_t nb = alignedBegin - addr;
uint32_t tmp = 0xffffffff; uint32_t tmp = 0xffffffff;
memcpy(((uint8_t* )&tmp) + 4 - nb, src, nb); memcpy(((uint8_t* )&tmp) + 4 - nb, src, nb);
if (spi_flash_write_locked(alignedBegin - 4, &tmp, 4) != SPI_FLASH_RESULT_OK) { if (!ESP.flashWrite(alignedBegin - 4, &tmp, 4)) {
DEBUGV("_spif_write(%d) addr=%x size=%x ab=%x ae=%x\r\n", DEBUGV("_spif_write(%d) addr=%x size=%x ab=%x ae=%x\r\n",
__LINE__, addr, size, alignedBegin, alignedEnd); __LINE__, addr, size, alignedBegin, alignedEnd);
return SPIFFS_ERR_INTERNAL; return SPIFFS_ERR_INTERNAL;
@ -134,8 +117,8 @@ int32_t spiffs_hal_write(uint32_t addr, uint32_t size, uint8_t *src) {
uint32_t* srcLeftover = (uint32_t*) (src + alignedBegin - addr); uint32_t* srcLeftover = (uint32_t*) (src + alignedBegin - addr);
uint32_t srcAlign = ((uint32_t) srcLeftover) & 3; uint32_t srcAlign = ((uint32_t) srcLeftover) & 3;
if (!srcAlign) { if (!srcAlign) {
if (spi_flash_write_locked(alignedBegin, (uint32_t*) srcLeftover, if (!ESP.flashWrite(alignedBegin, (uint32_t*) srcLeftover,
alignedEnd - alignedBegin) != SPI_FLASH_RESULT_OK) { alignedEnd - alignedBegin)) {
DEBUGV("_spif_write(%d) addr=%x size=%x ab=%x ae=%x\r\n", DEBUGV("_spif_write(%d) addr=%x size=%x ab=%x ae=%x\r\n",
__LINE__, addr, size, alignedBegin, alignedEnd); __LINE__, addr, size, alignedBegin, alignedEnd);
return SPIFFS_ERR_INTERNAL; return SPIFFS_ERR_INTERNAL;
@ -147,8 +130,7 @@ int32_t spiffs_hal_write(uint32_t addr, uint32_t size, uint8_t *src) {
size_t willCopy = std::min(sizeLeft, sizeof(buf)); size_t willCopy = std::min(sizeLeft, sizeof(buf));
memcpy(buf, srcLeftover, willCopy); memcpy(buf, srcLeftover, willCopy);
if (spi_flash_write_locked(alignedBegin, (uint32_t*) buf, if (!ESP.flashWrite(alignedBegin, (uint32_t*) buf, willCopy)) {
willCopy) != SPI_FLASH_RESULT_OK) {
DEBUGV("_spif_write(%d) addr=%x size=%x ab=%x ae=%x\r\n", DEBUGV("_spif_write(%d) addr=%x size=%x ab=%x ae=%x\r\n",
__LINE__, addr, size, alignedBegin, alignedEnd); __LINE__, addr, size, alignedBegin, alignedEnd);
return SPIFFS_ERR_INTERNAL; return SPIFFS_ERR_INTERNAL;
@ -166,7 +148,7 @@ int32_t spiffs_hal_write(uint32_t addr, uint32_t size, uint8_t *src) {
uint32_t tmp = 0xffffffff; uint32_t tmp = 0xffffffff;
memcpy(&tmp, src + size - nb, nb); memcpy(&tmp, src + size - nb, nb);
if (spi_flash_write_locked(alignedEnd, &tmp, 4) != SPI_FLASH_RESULT_OK) { if (!ESP.flashWrite(alignedEnd, &tmp, 4)) {
DEBUGV("_spif_write(%d) addr=%x size=%x ab=%x ae=%x\r\n", DEBUGV("_spif_write(%d) addr=%x size=%x ab=%x ae=%x\r\n",
__LINE__, addr, size, alignedBegin, alignedEnd); __LINE__, addr, size, alignedBegin, alignedEnd);
return SPIFFS_ERR_INTERNAL; return SPIFFS_ERR_INTERNAL;
@ -185,7 +167,8 @@ int32_t spiffs_hal_erase(uint32_t addr, uint32_t size) {
const uint32_t sector = addr / SPI_FLASH_SEC_SIZE; const uint32_t sector = addr / SPI_FLASH_SEC_SIZE;
const uint32_t sectorCount = size / SPI_FLASH_SEC_SIZE; const uint32_t sectorCount = size / SPI_FLASH_SEC_SIZE;
for (uint32_t i = 0; i < sectorCount; ++i) { for (uint32_t i = 0; i < sectorCount; ++i) {
if (spi_flash_erase_sector_locked(sector + i) != 0) { optimistic_yield(10000);
if (!ESP.flashEraseSector(sector + i)) {
DEBUGV("_spif_erase addr=%x size=%d i=%d\r\n", addr, size, i); DEBUGV("_spif_erase addr=%x size=%d i=%d\r\n", addr, size, i);
return SPIFFS_ERR_INTERNAL; return SPIFFS_ERR_INTERNAL;
} }