Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ea69f97

Browse files
committed
Merge branch 'feature/fix_spiflash_write_unaligned_flash_addr' into 'master'
Add feature to support flash address and memory address no align writing See merge request sdk/ESP8266_RTOS_SDK!285
2 parents cb0c5ee + a4be553 commit ea69f97

File tree

4 files changed

+359
-47
lines changed

4 files changed

+359
-47
lines changed

components/spi_flash/include/spi_flash.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ extern "C" {
3030

3131
#define SPI_FLASH_SEC_SIZE 4096 /**< SPI Flash sector size */
3232

33+
#define SPI_READ_BUF_MAX 64
34+
3335
#ifdef CONFIG_ENABLE_FLASH_MMAP
3436
/**
3537
* @brief Enumeration which specifies memory space requested in an mmap call

components/spi_flash/src/spi_flash.c

Lines changed: 94 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@
100100

101101
#define FLASH_ALIGN_BYTES 4
102102
#define FLASH_ALIGN(addr) ((((size_t)addr) + (FLASH_ALIGN_BYTES - 1)) & (~(FLASH_ALIGN_BYTES - 1)))
103+
#define FLASH_ALIGN_BEFORE(addr) (FLASH_ALIGN(addr) - 4)
104+
#define NOT_ALIGN(addr) (((size_t)addr) & (FLASH_ALIGN_BYTES - 1))
105+
#define IS_ALIGN(addr) (NOT_ALIGN(addr) == 0)
103106

104107
enum GD25Q32C_status {
105108
GD25Q32C_STATUS1=0,
@@ -129,6 +132,7 @@ extern uint32_t esp_get_time();
129132
bool IRAM_ATTR spi_user_cmd(spi_cmd_dir_t mode, spi_cmd_t *p_cmd);
130133
bool special_flash_read_status(uint8_t command, uint32_t* status, int len);
131134
bool special_flash_write_status(uint8_t command, uint32_t status, int len, bool write_en);
135+
esp_err_t spi_flash_read(size_t src_addr, void *dest, size_t size);
132136
uint8_t en25q16x_read_sfdp();
133137

134138
extern void pp_soft_wdt_feed(void);
@@ -148,7 +152,7 @@ uint8_t FlashIsOnGoing = 0;
148152

149153
const char *TAG = "spi_flash";
150154

151-
static esp_err_t IRAM_ATTR SPIWrite(uint32_t target, uint32_t *src_addr, size_t len)
155+
esp_err_t IRAM_ATTR SPIWrite(uint32_t target, uint32_t *src_addr, size_t len)
152156
{
153157
uint32_t page_size;
154158
uint32_t pgm_len, pgm_num;
@@ -481,17 +485,30 @@ static esp_err_t IRAM_ATTR spi_flash_write_raw(size_t dest_addr, const void *src
481485

482486
esp_err_t IRAM_ATTR spi_flash_write(size_t dest_addr, const void *src, size_t size)
483487
{
488+
#undef FLASH_WRITE
484489
#define FLASH_WRITE(dest, src, size) \
485490
{ \
486491
ret = spi_flash_write_raw(dest, src, size); \
487492
pp_soft_wdt_feed(); \
488-
if (ret) \
489-
goto exit; \
493+
if (ret) { \
494+
return ret; \
495+
} \
496+
}
497+
498+
#undef FLASH_READ
499+
#define FLASH_READ(dest, src, size) \
500+
{ \
501+
ret = spi_flash_read(dest, src, size); \
502+
if (ret) { \
503+
return ret; \
504+
} \
490505
}
491506

492507
esp_err_t ret = ESP_ERR_FLASH_OP_FAIL;
493-
uint32_t *tmp;
494-
size_t before_wbytes, align_wbytes;
508+
uint8_t *tmp = (uint8_t *)src;
509+
510+
if (!size)
511+
return ESP_OK;
495512

496513
if (src == NULL) {
497514
return ESP_ERR_FLASH_OP_FAIL;
@@ -501,41 +518,54 @@ esp_err_t IRAM_ATTR spi_flash_write(size_t dest_addr, const void *src, size_t si
501518
return ESP_ERR_FLASH_OP_FAIL;
502519
}
503520

504-
if (IS_FLASH(src)) {
505-
tmp = wifi_malloc(size, OSI_MALLOC_CAP_32BIT);
506-
if (!tmp) {
507-
return ESP_ERR_NO_MEM;
521+
if (NOT_ALIGN(dest_addr)
522+
|| NOT_ALIGN(tmp)
523+
|| NOT_ALIGN(size)
524+
|| IS_FLASH(src)) {
525+
uint8_t buf[SPI_READ_BUF_MAX];
526+
527+
if (NOT_ALIGN(dest_addr)) {
528+
size_t r_addr = FLASH_ALIGN_BEFORE(dest_addr);
529+
size_t c_off = dest_addr - r_addr;
530+
size_t wbytes = FLASH_ALIGN_BYTES - c_off;
531+
532+
wbytes = wbytes > size ? size : wbytes;
533+
534+
FLASH_READ(r_addr, buf, FLASH_ALIGN_BYTES);
535+
memcpy(&buf[c_off], tmp, wbytes);
536+
FLASH_WRITE(r_addr, buf, FLASH_ALIGN_BYTES);
537+
538+
dest_addr += wbytes;
539+
tmp += wbytes;
540+
size -= wbytes;
508541
}
509-
memcpy(tmp, src, size);
510-
} else
511-
tmp = (uint32_t *)src;
512542

513-
before_wbytes = FLASH_ALIGN(tmp) == (size_t)tmp ? 0 : FLASH_ALIGN(tmp) - (size_t)tmp;
514-
align_wbytes = size - before_wbytes;
543+
while (size > 0) {
544+
size_t len = size >= SPI_READ_BUF_MAX ? SPI_READ_BUF_MAX : size;
545+
size_t wlen = FLASH_ALIGN(len);
515546

516-
if (before_wbytes) {
517-
uint8_t load_buf[FLASH_ALIGN_BYTES];
547+
if (wlen != len) {
548+
size_t l_b = wlen - FLASH_ALIGN_BYTES;
518549

519-
memcpy(load_buf, tmp, before_wbytes);
520-
FLASH_WRITE(dest_addr, load_buf, FLASH_ALIGN_BYTES);
521-
}
550+
FLASH_READ(dest_addr + l_b, &buf[l_b], FLASH_ALIGN_BYTES);
551+
}
522552

523-
if (align_wbytes) {
524-
void *align_addr = (void *)FLASH_ALIGN(tmp);
553+
memcpy(buf, tmp, len);
525554

526-
if (align_wbytes % FLASH_ALIGN_BYTES)
527-
align_wbytes = (align_wbytes / FLASH_ALIGN_BYTES + 1) * FLASH_ALIGN_BYTES;
555+
FLASH_WRITE(dest_addr, buf, wlen);
528556

529-
FLASH_WRITE(dest_addr + before_wbytes, align_addr, align_wbytes);
557+
dest_addr += len;
558+
tmp += len;
559+
size -= len;
560+
}
561+
} else {
562+
FLASH_WRITE(dest_addr, src, size);
530563
}
531564

532-
exit:
533-
if (IS_FLASH(src))
534-
wifi_free(tmp);
535-
536565
return ret;
537566
}
538567

568+
539569
/******************************************************************************
540570
* FunctionName : spi_flash_read_raw
541571
* Description : a
@@ -568,42 +598,59 @@ static esp_err_t IRAM_ATTR spi_flash_read_raw(size_t src_addr, void *dest, size_
568598

569599
esp_err_t IRAM_ATTR spi_flash_read(size_t src_addr, void *dest, size_t size)
570600
{
601+
#undef FLASH_READ
571602
#define FLASH_READ(addr, dest, size) \
572603
{ \
573-
ret = spi_flash_read_raw(src_addr, dest, size); \
604+
ret = spi_flash_read_raw(addr, dest, size); \
574605
pp_soft_wdt_feed(); \
575606
if (ret) \
576607
return ret; \
577608
}
578609

579610
esp_err_t ret;
580-
uint8_t load_buf[FLASH_ALIGN_BYTES];
581-
size_t before_rbytes, after_rbytes, align_rbytes;
611+
uint8_t *tmp = (uint8_t *)dest;
612+
613+
if (!size)
614+
return ESP_OK;
582615

583-
if (dest == NULL) {
616+
if (tmp == NULL) {
584617
return ESP_ERR_FLASH_OP_FAIL;
585618
}
586619

587-
before_rbytes = FLASH_ALIGN(dest) == (size_t)dest ? 0 : FLASH_ALIGN(dest) - (size_t)dest;
588-
after_rbytes = (size - before_rbytes) & (FLASH_ALIGN_BYTES - 1);
589-
align_rbytes = size - before_rbytes - after_rbytes;
620+
if (NOT_ALIGN(src_addr)
621+
|| NOT_ALIGN(tmp)
622+
|| NOT_ALIGN(size)) {
623+
uint8_t buf[SPI_READ_BUF_MAX];
590624

591-
if (before_rbytes) {
592-
FLASH_READ(src_addr, load_buf, FLASH_ALIGN_BYTES);
593-
memcpy(dest, &load_buf[FLASH_ALIGN_BYTES - before_rbytes], before_rbytes);
594-
}
625+
if (NOT_ALIGN(src_addr)) {
626+
size_t r_addr = FLASH_ALIGN_BEFORE(src_addr);
627+
size_t c_off = src_addr - r_addr;
628+
size_t wbytes = FLASH_ALIGN_BYTES - c_off;
595629

596-
if (align_rbytes) {
597-
void *align_addr = (void *)FLASH_ALIGN(dest);
630+
wbytes = wbytes > size ? size : wbytes;
598631

599-
FLASH_READ(src_addr + before_rbytes, align_addr, align_rbytes);
600-
}
632+
FLASH_READ(r_addr, buf, FLASH_ALIGN_BYTES);
633+
memcpy(tmp, &buf[c_off], wbytes);
601634

602-
if (after_rbytes) {
603-
void *after_addr = (void *)FLASH_ALIGN((char *)dest + size - after_rbytes);
635+
tmp += wbytes;
636+
src_addr += wbytes;
637+
size -= wbytes;
638+
}
604639

605-
FLASH_READ(src_addr + before_rbytes + align_rbytes, load_buf, FLASH_ALIGN_BYTES);
606-
memcpy(after_addr, load_buf, after_rbytes);
640+
while (size) {
641+
size_t len = size >= SPI_READ_BUF_MAX ? SPI_READ_BUF_MAX : size;
642+
size_t wlen = FLASH_ALIGN(len);
643+
644+
FLASH_READ(src_addr, buf, wlen);
645+
646+
memcpy(tmp, buf, len);
647+
648+
src_addr += len;
649+
tmp += len;
650+
size -= len;
651+
}
652+
} else {
653+
FLASH_READ(src_addr, tmp, size);
607654
}
608655

609656
return ESP_OK;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#
2+
#Component Makefile
3+
#
4+
5+
COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive

0 commit comments

Comments
 (0)