SPIFFS: flash access refactoring.
This commit is contained in:
parent
5d5f28a22f
commit
4b1568cbb9
6 changed files with 332 additions and 463 deletions
|
@ -11,7 +11,7 @@
|
|||
#include <stdbool.h>
|
||||
#include <esp/uart.h>
|
||||
#include <fcntl.h>
|
||||
#include "esp_spi_flash.h"
|
||||
#include "esp_spiffs_flash.h"
|
||||
|
||||
spiffs fs;
|
||||
|
||||
|
@ -31,113 +31,19 @@ static fs_buf_t cache_buf = {0};
|
|||
|
||||
#define ESP_SPIFFS_CACHE_PAGES 5
|
||||
|
||||
|
||||
/*
|
||||
* Flash addresses and size alignment is a rip-off of Arduino implementation.
|
||||
*/
|
||||
|
||||
static s32_t esp_spiffs_read(u32_t addr, u32_t size, u8_t *dst)
|
||||
{
|
||||
uint32_t result = SPIFFS_OK;
|
||||
uint32_t alignedBegin = (addr + 3) & (~3);
|
||||
uint32_t alignedEnd = (addr + size) & (~3);
|
||||
if (alignedEnd < alignedBegin) {
|
||||
alignedEnd = alignedBegin;
|
||||
if (esp_spiffs_flash_read(addr, dst, size) == ESP_SPIFFS_FLASH_ERROR) {
|
||||
return SPIFFS_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
if (addr < alignedBegin) {
|
||||
uint32_t nb = alignedBegin - addr;
|
||||
uint32_t tmp;
|
||||
if (esp_spi_flash_read(alignedEnd - 4, &tmp, 4) != SPI_FLASH_RESULT_OK) {
|
||||
printf("spi_flash_read failed\n");
|
||||
return SPIFFS_ERR_INTERNAL;
|
||||
}
|
||||
memcpy(dst, &tmp + 4 - nb, nb);
|
||||
}
|
||||
|
||||
if (alignedEnd != alignedBegin) {
|
||||
if (esp_spi_flash_read(alignedBegin,
|
||||
(uint32_t*) (dst + alignedBegin - addr),
|
||||
alignedEnd - alignedBegin) != SPI_FLASH_RESULT_OK) {
|
||||
printf("spi_flash_read failed\n");
|
||||
return SPIFFS_ERR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (addr + size > alignedEnd) {
|
||||
uint32_t nb = addr + size - alignedEnd;
|
||||
uint32_t tmp;
|
||||
if (esp_spi_flash_read(alignedEnd, &tmp, 4) != SPI_FLASH_RESULT_OK) {
|
||||
printf("spi_flash_read failed\n");
|
||||
return SPIFFS_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
memcpy(dst + size - nb, &tmp, nb);
|
||||
}
|
||||
|
||||
return result;
|
||||
return SPIFFS_OK;
|
||||
}
|
||||
|
||||
static const int UNALIGNED_WRITE_BUFFER_SIZE = 512;
|
||||
|
||||
static s32_t esp_spiffs_write(u32_t addr, u32_t size, u8_t *src)
|
||||
{
|
||||
uint32_t alignedBegin = (addr + 3) & (~3);
|
||||
uint32_t alignedEnd = (addr + size) & (~3);
|
||||
if (alignedEnd < alignedBegin) {
|
||||
alignedEnd = alignedBegin;
|
||||
}
|
||||
|
||||
if (addr < alignedBegin) {
|
||||
uint32_t ofs = alignedBegin - addr;
|
||||
uint32_t nb = (size < ofs) ? size : ofs;
|
||||
uint8_t tmp[4] __attribute__((aligned(4))) = {0xff, 0xff, 0xff, 0xff};
|
||||
memcpy(tmp + 4 - ofs, src, nb);
|
||||
if (esp_spi_flash_write(alignedBegin - 4, (uint32_t*) tmp, 4)
|
||||
!= SPI_FLASH_RESULT_OK) {
|
||||
printf("spi_flash_write failed\n");
|
||||
return SPIFFS_ERR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (alignedEnd != alignedBegin) {
|
||||
uint32_t* srcLeftover = (uint32_t*) (src + alignedBegin - addr);
|
||||
uint32_t srcAlign = ((uint32_t) srcLeftover) & 3;
|
||||
if (!srcAlign) {
|
||||
if (esp_spi_flash_write(alignedBegin, (uint32_t*) srcLeftover,
|
||||
alignedEnd - alignedBegin) != SPI_FLASH_RESULT_OK) {
|
||||
printf("spi_flash_write failed\n");
|
||||
return SPIFFS_ERR_INTERNAL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
uint8_t buf[UNALIGNED_WRITE_BUFFER_SIZE];
|
||||
for (uint32_t sizeLeft = alignedEnd - alignedBegin; sizeLeft; ) {
|
||||
size_t willCopy = sizeLeft < sizeof(buf) ? sizeLeft : sizeof(buf);
|
||||
memcpy(buf, srcLeftover, willCopy);
|
||||
|
||||
if (esp_spi_flash_write(alignedBegin, (uint32_t*) buf, willCopy)
|
||||
!= SPI_FLASH_RESULT_OK) {
|
||||
printf("spi_flash_write failed\n");
|
||||
return SPIFFS_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
sizeLeft -= willCopy;
|
||||
srcLeftover += willCopy;
|
||||
alignedBegin += willCopy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (addr + size > alignedEnd) {
|
||||
uint32_t nb = addr + size - alignedEnd;
|
||||
uint32_t tmp = 0xffffffff;
|
||||
memcpy(&tmp, src + size - nb, nb);
|
||||
|
||||
if (esp_spi_flash_write(alignedEnd, &tmp, 4) != SPI_FLASH_RESULT_OK) {
|
||||
printf("spi_flash_write failed\n");
|
||||
return SPIFFS_ERR_INTERNAL;
|
||||
}
|
||||
if (esp_spiffs_flash_write(addr, src, size) == ESP_SPIFFS_FLASH_ERROR) {
|
||||
return SPIFFS_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
return SPIFFS_OK;
|
||||
|
@ -145,19 +51,15 @@ static s32_t esp_spiffs_write(u32_t addr, u32_t size, u8_t *src)
|
|||
|
||||
static s32_t esp_spiffs_erase(u32_t addr, u32_t size)
|
||||
{
|
||||
if (addr % SPI_FLASH_SEC_SIZE) {
|
||||
printf("Unaligned erase addr=%x\n", addr);
|
||||
}
|
||||
if (size % SPI_FLASH_SEC_SIZE) {
|
||||
printf("Unaligned erase size=%d\n", size);
|
||||
uint32_t sectors = size / SPI_FLASH_SEC_SIZE;
|
||||
|
||||
for (uint32_t i = 0; i < sectors; i++) {
|
||||
if (esp_spiffs_flash_erase_sector(addr + (SPI_FLASH_SEC_SIZE * i))
|
||||
== ESP_SPIFFS_FLASH_ERROR) {
|
||||
return SPIFFS_ERR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
const uint32_t sector = addr / SPI_FLASH_SEC_SIZE;
|
||||
const uint32_t sectorCount = size / SPI_FLASH_SEC_SIZE;
|
||||
|
||||
for (uint32_t i = 0; i < sectorCount; ++i) {
|
||||
esp_spi_flash_erase(sector + i);
|
||||
}
|
||||
return SPIFFS_OK;
|
||||
}
|
||||
|
||||
|
@ -196,8 +98,8 @@ int32_t esp_spiffs_mount()
|
|||
printf("SPIFFS memory, work_buf_size=%d, fds_buf_size=%d, cache_buf_size=%d\n",
|
||||
work_buf.size, fds_buf.size, cache_buf.size);
|
||||
|
||||
int32_t err = SPIFFS_mount(&fs, &config, (uint8_t*)work_buf.buf,
|
||||
(uint8_t*)fds_buf.buf, fds_buf.size,
|
||||
int32_t err = SPIFFS_mount(&fs, &config, (uint8_t*)work_buf.buf,
|
||||
(uint8_t*)fds_buf.buf, fds_buf.size,
|
||||
cache_buf.buf, cache_buf.size, 0);
|
||||
|
||||
if (err != SPIFFS_OK) {
|
||||
|
@ -213,7 +115,7 @@ int32_t esp_spiffs_mount()
|
|||
long _write_r(struct _reent *r, int fd, const char *ptr, int len )
|
||||
{
|
||||
if(fd != r->_stdout->_file) {
|
||||
long ret = SPIFFS_write(&fs, (spiffs_file)(fd - FD_OFFSET),
|
||||
long ret = SPIFFS_write(&fs, (spiffs_file)(fd - FD_OFFSET),
|
||||
(char*)ptr, len);
|
||||
return ret;
|
||||
}
|
||||
|
@ -296,6 +198,6 @@ int _stat_r(struct _reent *r, const char *pathname, void *buf)
|
|||
}
|
||||
|
||||
off_t _lseek_r(struct _reent *r, int fd, off_t offset, int whence)
|
||||
{
|
||||
{
|
||||
return SPIFFS_lseek(&fs, (spiffs_file)(fd - FD_OFFSET), offset, whence);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue