esp8266-std/ESP8266_RTOS_SDK/third_party/spiffs/esp_spiffs.c

293 lines
6.3 KiB
C
Raw Normal View History

2018-11-23 01:43:17 +00:00
#include "esp_common.h"
#include <fcntl.h>
#include <stdio.h>
#define NUM_SYS_FD 3
static spiffs fs;
static u8_t *spiffs_work_buf;
static u8_t *spiffs_fd_buf;
static u8_t *spiffs_cache_buf;
#define FLASH_UNIT_SIZE 4
static s32_t esp_spiffs_readwrite(u32_t addr, u32_t size, u8_t *p, int write)
{
/*
* With proper configurarion spiffs never reads or writes more than
* LOG_PAGE_SIZE
*/
if (size > fs.cfg.log_page_size) {
printf("Invalid size provided to read/write (%d)\n\r", (int) size);
return SPIFFS_ERR_NOT_CONFIGURED;
}
char tmp_buf[fs.cfg.log_page_size + FLASH_UNIT_SIZE * 2];
u32_t aligned_addr = addr & (-FLASH_UNIT_SIZE);
u32_t aligned_size =
((size + (FLASH_UNIT_SIZE - 1)) & -FLASH_UNIT_SIZE) + FLASH_UNIT_SIZE;
int res = spi_flash_read(aligned_addr, (u32_t *) tmp_buf, aligned_size);
if (res != 0) {
printf("spi_flash_read failed: %d (%d, %d)\n\r", res, (int) aligned_addr,
(int) aligned_size);
return res;
}
if (!write) {
memcpy(p, tmp_buf + (addr - aligned_addr), size);
return SPIFFS_OK;
}
memcpy(tmp_buf + (addr - aligned_addr), p, size);
res = spi_flash_write(aligned_addr, (u32_t *) tmp_buf, aligned_size);
if (res != 0) {
// printf("spi_flash_write failed: %d (%d, %d)\n\r", res,
// (int) aligned_addr, (int) aligned_size);
return res;
}
return SPIFFS_OK;
}
static s32_t esp_spiffs_read(u32_t addr, u32_t size, u8_t *dst)
{
return esp_spiffs_readwrite(addr, size, dst, 0);
}
static s32_t esp_spiffs_write(u32_t addr, u32_t size, u8_t *src)
{
return esp_spiffs_readwrite(addr, size, src, 1);
}
static s32_t esp_spiffs_erase(u32_t addr, u32_t size)
{
/*
* With proper configurarion spiffs always
* provides here sector address & sector size
*/
if (size != fs.cfg.phys_erase_block || addr % fs.cfg.phys_erase_block != 0) {
printf("Invalid size provided to esp_spiffs_erase (%d, %d)\n\r",
(int) addr, (int) size);
return SPIFFS_ERR_NOT_CONFIGURED;
}
return spi_flash_erase_sector(addr / fs.cfg.phys_erase_block);
}
s32_t esp_spiffs_init(struct esp_spiffs_config *config)
{
if (SPIFFS_mounted(&fs)) {
return -1;
}
spiffs_config cfg;
s32_t ret;
cfg.phys_size = config->phys_size;
cfg.phys_addr = config->phys_addr;
cfg.phys_erase_block = config->phys_erase_block;
cfg.log_block_size = config->log_block_size;
cfg.log_page_size = config->log_page_size;
cfg.hal_read_f = esp_spiffs_read;
cfg.hal_write_f = esp_spiffs_write;
cfg.hal_erase_f = esp_spiffs_erase;
if (spiffs_work_buf != NULL) {
free(spiffs_work_buf);
spiffs_work_buf = NULL;
}
spiffs_work_buf = malloc(config->log_page_size * 2);
if (spiffs_work_buf == NULL) {
return -1;
}
if (spiffs_fd_buf != NULL) {
free(spiffs_fd_buf);
spiffs_fd_buf = NULL;
}
spiffs_fd_buf = malloc(config->fd_buf_size);
if (spiffs_fd_buf == NULL) {
free(spiffs_work_buf);
return -1;
}
if (spiffs_cache_buf != NULL) {
free(spiffs_cache_buf);
spiffs_cache_buf = NULL;
}
spiffs_cache_buf = malloc(config->cache_buf_size);
if (spiffs_cache_buf == NULL) {
free(spiffs_work_buf);
free(spiffs_fd_buf);
return -1;
}
ret = SPIFFS_mount(&fs, &cfg, spiffs_work_buf,
spiffs_fd_buf, config->fd_buf_size,
spiffs_cache_buf, config->cache_buf_size,
0);
if (ret == -1) {
free(spiffs_work_buf);
free(spiffs_fd_buf);
free(spiffs_cache_buf);
}
return ret;
}
void esp_spiffs_deinit(u8_t format)
{
if (SPIFFS_mounted(&fs)) {
SPIFFS_unmount(&fs);
free(spiffs_work_buf);
free(spiffs_fd_buf);
free(spiffs_cache_buf);
if (format) {
SPIFFS_format(&fs);
}
}
}
int _open_r(struct _reent *r, const char *filename, int flags, int mode)
{
spiffs_mode sm = 0;
int res;
int rw = (flags & 3);
if (rw == O_RDONLY || rw == O_RDWR) {
sm |= SPIFFS_RDONLY;
}
if (rw == O_WRONLY || rw == O_RDWR) {
sm |= SPIFFS_WRONLY;
}
if (flags & O_CREAT) {
sm |= SPIFFS_CREAT;
}
if (flags & O_TRUNC) {
sm |= SPIFFS_TRUNC;
}
if (flags & O_APPEND) {
sm |= SPIFFS_APPEND;
}
/* Supported in newer versions of SPIFFS. */
/* if (flags && O_EXCL) sm |= SPIFFS_EXCL; */
/* if (flags && O_DIRECT) sm |= SPIFFS_DIRECT; */
res = SPIFFS_open(&fs, (char *) filename, sm, 0);
if (res >= 0) {
res += NUM_SYS_FD;
}
return res;
}
_ssize_t _read_r(struct _reent *r, int fd, void *buf, size_t len)
{
ssize_t res;
if (fd < NUM_SYS_FD) {
res = -1;
} else {
res = SPIFFS_read(&fs, fd - NUM_SYS_FD, buf, len);
}
return res;
}
_ssize_t _write_r(struct _reent *r, int fd, void *buf, size_t len)
{
if (fd < NUM_SYS_FD) {
return -1;
}
int res = SPIFFS_write(&fs, fd - NUM_SYS_FD, (char *) buf, len);
return res;
}
_off_t _lseek_r(struct _reent *r, int fd, _off_t where, int whence)
{
ssize_t res;
if (fd < NUM_SYS_FD) {
res = -1;
} else {
res = SPIFFS_lseek(&fs, fd - NUM_SYS_FD, where, whence);
}
return res;
}
int _close_r(struct _reent *r, int fd)
{
if (fd < NUM_SYS_FD) {
return -1;
}
SPIFFS_close(&fs, fd - NUM_SYS_FD);
return 0;
}
int _rename_r(struct _reent *r, const char *from, const char *to)
{
int res = SPIFFS_rename(&fs, (char *) from, (char *) to);
return res;
}
int _unlink_r(struct _reent *r, const char *filename)
{
int res = SPIFFS_remove(&fs, (char *) filename);
return res;
}
int _fstat_r(struct _reent *r, int fd, struct stat *s)
{
int res;
spiffs_stat ss;
memset(s, 0, sizeof(*s));
if (fd < NUM_SYS_FD) {
s->st_ino = fd;
s->st_rdev = fd;
s->st_mode = S_IFCHR | 0666;
return 0;
}
res = SPIFFS_fstat(&fs, fd - NUM_SYS_FD, &ss);
if (res < 0) {
return res;
}
s->st_ino = ss.obj_id;
s->st_mode = 0666;
s->st_nlink = 1;
s->st_size = ss.size;
return 0;
}