1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
19079: cpu/esp32: add periph_flashpage support r=kaspar030 a=gschorcht

### Contribution description

This PR provides the `periph_flashpage` support for ESP32x SoCs.

For byte-aligned read access to constant data in the flash, the MMU of all ESP32x SoCs allows to map a certain number of 64 kByte pages of the flash into the data address space of the CPU. This address space is called DROM. Normally the whole DROM address space is assigned to the section `.rodata`. The default flash layout used by all ESP32x SoCs is:
| Address in Flash | Content |
|:-----------------------|:-----------|
| `0x0000` or `0x1000` | bootloader |
| `0x8000` | parition table |
| `0x9000` | `nvs` parition with WiFi data |
| `0xf000`  | `phy_init` partition with RF data |
| `0x10000` | `factory` partition with the app image |

The factory partition consists of a number of 64 kByte pages for the sections `.text`, `.rodata`, `.bss` and others. The `.text` and `rodata` sections are page-aligned and are simply mapped into the instruction address space (IROM) and the data address space (DROM), respectively. All other sections are loaded into RAM.

If the `periph_flashpage` module is used, the `periph_flashpage` driver
- decreases the size of the `.rodata` section in DROM address space by `CONFIG_ESP_FLASHPAGE_CAPACITY`,
- adds a section `.flashpage.writable` of size `CONFIG_ESP_FLASHPAGE_CAPACITY` at the end of DROM address space that is mapped into data address space of the CPU,
- reserves a region of size `CONFIG_ESP_FLASHPAGE_CAPACITY` starting from `0x10000` in front of the image partition `factory` and
- moves the image partition `factory` by  `CONFIG_ESP_FLASHPAGE_CAPACITY` to address `0x10000 + CONFIG_ESP_FLASHPAGE_CAPACITY`. 

The new flash layout is then:
| Address in Flash | Content |
|:-----------------------|:-----------|
| `0x0000` or `0x1000` | bootloader |
| `0x8000` | parition table |
| `0x9000` | `nvs` parition with WiFi data |
| `0xf000`  | `phy_init` partition with RF data |
| `0x10000` | flashpage region |
| `0x10000 + CONFIG_ESP_FLASHPAGE_CAPACITY` | `factory` partition with the app image |

This guarantees that the flash pages are not overwritten if a new app image with changed size is flashed. `CONFIG_ESP_FLASHPAGE_CAPACITY` has to be a multiple of 64 kBytes.

~The PR includes PR #19077 and PR #19078 for the moment to be compilable.~

### Testing procedure

The following tests should pass.
```
USEMODULE='esp_log_startup ps shell_cmds_default' BOARD=esp32-wroom-32 make -j8 -C tests/periph_flashpage flash term
```
```
USEMODULE='esp_log_startup ps shell_cmds_default' BOARD=esp32-wroom-32 make -j8 -C tests/mtd_flashpage flash term
```

### Issues/PRs references

Depends on PR #19077
Depends on PR #19078 


Co-authored-by: Gunar Schorcht <gunar@schorcht.net>
This commit is contained in:
bors[bot] 2023-01-18 17:48:29 +00:00 committed by GitHub
commit 7855aad7e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 384 additions and 26 deletions

View File

@ -17,6 +17,9 @@ config CPU_FAM_ESP32
select HAS_ESP_BLE_ESP32
select HAS_ESP_HW_COUNTER
select HAS_ESP_WIFI_ENTERPRISE
select HAS_PERIPH_FLASHPAGE
select HAS_PERIPH_FLASHPAGE_IN_ADDRESS_SPACE
select HAS_PERIPH_FLASHPAGE_PAGEWISE
select HAS_PERIPH_GPIO_LL
select HAS_PERIPH_GPIO_LL_IRQ
select HAS_PERIPH_GPIO_LL_IRQ_LEVEL_TRIGGERED_HIGH

View File

@ -18,6 +18,9 @@ config CPU_FAM_ESP32C3
select HAS_ESP_BLE
select HAS_ESP_BLE_ESP32C3
select HAS_ESP_WIFI_ENTERPRISE
select HAS_PERIPH_FLASHPAGE
select HAS_PERIPH_FLASHPAGE_IN_ADDRESS_SPACE
select HAS_PERIPH_FLASHPAGE_PAGEWISE
select HAS_PERIPH_GPIO_LL
select HAS_PERIPH_GPIO_LL_IRQ
select HAS_PERIPH_GPIO_LL_IRQ_LEVEL_TRIGGERED_HIGH

View File

@ -13,6 +13,9 @@ config CPU_FAM_ESP32S2
select HAS_CPU_ESP32
select HAS_ESP_HW_COUNTER
select HAS_ESP_WIFI_ENTERPRISE
select HAS_PERIPH_FLASHPAGE
select HAS_PERIPH_FLASHPAGE_IN_ADDRESS_SPACE
select HAS_PERIPH_FLASHPAGE_PAGEWISE
select HAS_PERIPH_GPIO_LL
select HAS_PERIPH_GPIO_LL_IRQ
select HAS_PERIPH_GPIO_LL_IRQ_LEVEL_TRIGGERED_HIGH

View File

@ -19,6 +19,9 @@ config CPU_FAM_ESP32S3
select HAS_ESP_BLE_ESP32C3
select HAS_ESP_HW_COUNTER
select HAS_ESP_WIFI_ENTERPRISE
select HAS_PERIPH_FLASHPAGE
select HAS_PERIPH_FLASHPAGE_IN_ADDRESS_SPACE
select HAS_PERIPH_FLASHPAGE_PAGEWISE
select HAS_PERIPH_GPIO_LL
select HAS_PERIPH_GPIO_LL_IRQ
select HAS_PERIPH_GPIO_LL_IRQ_LEVEL_TRIGGERED_HIGH

View File

@ -128,7 +128,7 @@ ifneq (,$(filter esp_idf_heap,$(USEMODULE)))
USEPKG += tlsf
endif
ifneq (,$(filter mtd,$(USEMODULE)))
ifneq (,$(filter mtd periph_flashpage,$(USEMODULE)))
USEMODULE += esp_idf_spi_flash
endif

View File

@ -17,6 +17,9 @@ include $(RIOTCPU)/esp_common/Makefile.features
FEATURES_PROVIDED += arch_esp32
FEATURES_PROVIDED += esp_wifi_enterprise
FEATURES_PROVIDED += periph_flashpage
FEATURES_PROVIDED += periph_flashpage_in_address_space
FEATURES_PROVIDED += periph_flashpage_pagewise
FEATURES_PROVIDED += periph_gpio_ll
FEATURES_PROVIDED += periph_gpio_ll_irq
FEATURES_PROVIDED += periph_gpio_ll_irq_level_triggered_high

View File

@ -23,6 +23,38 @@ else ifneq (,$(filter esp32s2,$(CPU_FAM)))
else
$(error Unkwnown ESP32x SoC variant (family))
endif
ifneq (,$(filter periph_flashpage,$(USEMODULE)))
ifneq (,$(CONFIG_ESP_FLASHPAGE_CAPACITY_64K))
FLASHFILE_POS = 0x20000
FLASHPAGE_CAP = 0x10000
else ifneq (,$(CONFIG_ESP_FLASHPAGE_CAPACITY_128K))
FLASHFILE_POS = 0x30000
FLASHPAGE_CAP = 0x20000
else ifneq (,$(CONFIG_ESP_FLASHPAGE_CAPACITY_256K))
FLASHFILE_POS = 0x50000
FLASHPAGE_CAP = 0x40000
else ifneq (,$(CONFIG_ESP_FLASHPAGE_CAPACITY_512K))
FLASHFILE_POS = 0x90000
FLASHPAGE_CAP = 0x80000
else ifneq (,$(CONFIG_ESP_FLASHPAGE_CAPACITY_1M))
FLASHFILE_POS = 0x110000
FLASHPAGE_CAP = 0x100000
else ifneq (,$(CONFIG_ESP_FLASHPAGE_CAPACITY_2M))
FLASHFILE_POS = 0x210000
FLASHPAGE_CAP = 0x200000
else
# use 512 kByte for periph_flashpage by default
FLASHFILE_POS = 0x90000
FLASHPAGE_CAP = 0x80000
CFLAGS += -DCONFIG_ESP_FLASHPAGE_CAPACITY_512K
endif
FLASHPAGE_ADDR_START = 0x10000
FLASHPAGE_ADDR_END = $(FLASHFILE_POS)
CFLAGS += -DFLASHPAGE_ADDR_START=$(FLASHPAGE_ADDR_START)
CFLAGS += -DFLASHPAGE_ADDR_END=$(FLASHPAGE_ADDR_END)
endif
FLASHFILE_POS ?= 0x10000
ESPTOOL ?= $(RIOTTOOLS)/esptools/esptool_v3.2.py
@ -76,6 +108,7 @@ INCLUDES += -I$(ESP32_SDK_DIR)/components/log/include
INCLUDES += -I$(ESP32_SDK_DIR)/components/newlib/platform_include
INCLUDES += -I$(ESP32_SDK_DIR)/components/soc/include
INCLUDES += -I$(ESP32_SDK_DIR)/components/soc/$(CPU_FAM)/include
INCLUDES += -I$(ESP32_SDK_DIR)/components/spi_flash/include
ifneq (,$(filter riscv32%,$(TARGET_ARCH)))
INCLUDES += -I$(ESP32_SDK_DIR)/components/riscv/include

View File

@ -13,7 +13,7 @@ config MODULE_ESP_IDF
default y
select MODULE_ESP_IDF_COMMON
select MODULE_ESP_IDF_EFUSE
select MODULE_ESP_IDF_SPI_FLASH if MODULE_MTD
select MODULE_ESP_IDF_SPI_FLASH if MODULE_MTD || MODULE_PERIPH_FLASHPAGE
select MODULE_ESP_IDF_USB if MODULE_TINYUSB_PORTABLE_ESPRESSIF
help
Espressif IoT Development Framework.

View File

@ -22,6 +22,10 @@
#ifndef CPU_CONF_H
#define CPU_CONF_H
#if !defined(__ASSEMBLER__)
#include <stdint.h>
#endif
/**
* @name Stack size configuration
* @{
@ -60,6 +64,41 @@
*/
#define PUF_SRAM_ATTRIBUTES __attribute__((used, section(".noinit")))
/**
* @brief Support of unaligned access
*
* All ESP32x SoCs allow unaligned read/write access to the RAM as well as
* unaligned read access to the constant data in the flash, which is accessible
* via the data bus and mapped by the MMU into the data address space of
* the CPU.
*/
#define CPU_HAS_UNALIGNED_ACCESS 1
/**
* @name Flash page configuration
* @{
*/
#if !DOXYGEN && !defined(__ASSEMBLER__)
/* start address of flash pages in CPU address space as determined by the linker */
extern uint8_t _fp_mem_start;
#endif
#define FLASHPAGE_SIZE (4096U) /**< Size of pages (flash sectors) in bytes */
#define FLASHPAGE_WRITE_BLOCK_SIZE (4U) /**< Minimum write block size */
#define FLASHPAGE_WRITE_BLOCK_ALIGNMENT (4U) /**< Write block alignment */
/**
* @brief Number of pages
*/
#define FLASHPAGE_NUMOF (CONFIG_ESP_FLASHPAGE_CAPACITY / FLASHPAGE_SIZE)
/**
* @brief CPU base address for flash page access as determined by the linker
*/
#define CPU_FLASH_BASE ((uint32_t)&_fp_mem_start)
/** @} */
/* include ESP32x SoC specific compile time configurations */
#if defined(CPU_FAM_ESP32)
#include "cpu_conf_esp32.h"

View File

@ -206,6 +206,33 @@
#define CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE
#define CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER CONFIG_ESP_PHY_MAX_WIFI_TX_POWER
/**
* Flashpage configuration
*/
#ifndef CONFIG_ESP_FLASHPAGE_CAPACITY
#ifdef MODULE_PERIPH_FLASHPAGE
#if CONFIG_ESP_FLASHPAGE_CAPACITY_64K
#define CONFIG_ESP_FLASHPAGE_CAPACITY 0x10000
#elif CONFIG_ESP_FLASHPAGE_CAPACITY_128K
#define CONFIG_ESP_FLASHPAGE_CAPACITY 0x20000
#elif CONFIG_ESP_FLASHPAGE_CAPACITY_256K
#define CONFIG_ESP_FLASHPAGE_CAPACITY 0x40000
#elif CONFIG_ESP_FLASHPAGE_CAPACITY_512K
#define CONFIG_ESP_FLASHPAGE_CAPACITY 0x80000
#elif CONFIG_ESP_FLASHPAGE_CAPACITY_1M
#define CONFIG_ESP_FLASHPAGE_CAPACITY 0x100000
#elif CONFIG_ESP_FLASHPAGE_CAPACITY_2M
#define CONFIG_ESP_FLASHPAGE_CAPACITY 0x200000
#else
#define CONFIG_ESP_FLASHPAGE_CAPACITY 0x80000
#endif
#else /* MODULE_PERIPH_FLASHPAGE_IN_ADDRESS_SPACE */
#define CONFIG_ESP_FLASHPAGE_CAPACITY 0x0
#endif /* MODULE_PERIPH_FLASHPAGE_IN_ADDRESS_SPACE */
#endif /* !CONFIG_ESP_FLASHPAGE_CAPACITY */
#endif /* DOXYGEN */
/**

View File

@ -84,9 +84,16 @@ MEMORY
#ifdef CONFIG_APP_BUILD_USE_FLASH_SECTIONS
/* Flash mapped constant data */
#ifdef MODULE_PERIPH_FLASHPAGE
drom0_0_seg (R) : org = 0x3F400020,
len = 0x400000 - 0x20 - CONFIG_ESP_FLASHPAGE_CAPACITY
drom0_1_seg (R) : org = ORIGIN(drom0_0_seg) + LENGTH(drom0_0_seg),
len = CONFIG_ESP_FLASHPAGE_CAPACITY
#else
drom0_0_seg (R) : org = 0x3F400020, len = 0x400000-0x20
/* (See iram0_2_seg for meaning of 0x20 offset in the above.) */
#endif /* MODULE_PERIPH_FLASHPAGE */
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
/* RTC fast memory (executable). Persists over deep sleep.

View File

@ -466,7 +466,6 @@ SECTIONS
. = ALIGN(ALIGNOF(.flash.rodata));
} >default_rodata_seg
_rodata_start = ABSOLUTE(.);
.flash.rodata : ALIGN(0x10)
{
_flash_rodata_start = ABSOLUTE(.);
@ -617,6 +616,17 @@ SECTIONS
_heap_start = ABSOLUTE(.);
_sheap = ABSOLUTE(.);
} > dram0_0_seg
#ifdef MODULE_PERIPH_FLASHPAGE
.flash_writable (NOLOAD) : ALIGN(65536)
{
_fp_mem_start = . ;
KEEP(*(SORT(.flash_writable.*)))
_fp_mem_end = . ;
. = ALIGN(4096);
_end_fw = . ;
} > drom0_1_seg
#endif
}
ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)),

View File

@ -72,9 +72,16 @@ MEMORY
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
/* Flash mapped constant data */
#ifdef MODULE_PERIPH_FLASHPAGE
drom0_0_seg (R) : org = 0x3C000020,
len = 0x800000 - 0x20 - CONFIG_ESP_FLASHPAGE_CAPACITY
drom0_1_seg (R) : org = ORIGIN(drom0_0_seg) + LENGTH(drom0_0_seg),
len = CONFIG_ESP_FLASHPAGE_CAPACITY
#else
drom0_0_seg (R) : org = 0x3C000020, len = 0x800000-0x20
/* (See iram0_2_seg for meaning of 0x20 offset in the above.) */
#endif /* MODULE_PERIPH_FLASHPAGE */
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
/**

View File

@ -599,6 +599,16 @@ SECTIONS
} > dram0_0_seg
_eheap = phy_param_rom;
#ifdef MODULE_PERIPH_FLASHPAGE
.flash_writable (NOLOAD) : ALIGN(65536)
{
_fp_mem_start = . ;
KEEP(*(SORT(.flash_writable.*)))
_fp_mem_end = . ;
. = ALIGN(4096);
_end_fw = . ;
} > drom0_1_seg
#endif
}
ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)),

View File

@ -90,9 +90,16 @@ MEMORY
#ifdef CONFIG_APP_BUILD_USE_FLASH_SECTIONS
/* Flash mapped constant data */
#ifdef MODULE_PERIPH_FLASHPAGE
drom0_0_seg (R) : org = 0x3F000020,
len = 0x3f0000-0x20 - CONFIG_ESP_FLASHPAGE_CAPACITY
drom0_1_seg (R) : org = ORIGIN(drom0_0_seg) + LENGTH(drom0_0_seg),
len = CONFIG_ESP_FLASHPAGE_CAPACITY
#else
drom0_0_seg (R) : org = 0x3F000020, len = 0x3f0000-0x20
/* (See iram0_2_seg for meaning of 0x20 offset in the above.) */
#endif /* MODULE_PERIPH_FLASHPAGE */
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
/* RTC fast memory (executable). Persists over deep sleep.

View File

@ -592,6 +592,17 @@ SECTIONS
. = _heap_end;
_eheap = ABSOLUTE(.);
#ifdef MODULE_PERIPH_FLASHPAGE
.flash_writable (NOLOAD) : ALIGN(65536)
{
_fp_mem_start = . ;
KEEP(*(SORT(.flash_writable.*)))
_fp_mem_end = . ;
. = ALIGN(4096);
_end_fw = . ;
} > drom0_1_seg
#endif
}
ASSERT(((_iram_text_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)),

View File

@ -90,9 +90,16 @@ MEMORY
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
/* Flash mapped constant data */
#ifdef MODULE_PERIPH_FLASHPAGE
drom0_0_seg (R) : org = 0x3C000020,
len = 0x800000-0x20 - CONFIG_ESP_FLASHPAGE_CAPACITY
drom0_1_seg (R) : org = ORIGIN(drom0_0_seg) + LENGTH(drom0_0_seg),
len = CONFIG_ESP_FLASHPAGE_CAPACITY
#else
drom0_0_seg (R) : org = 0x3C000020, len = 0x800000-0x20
/* (See iram0_2_seg for meaning of 0x20 offset in the above.) */
#endif /* MODULE_PERIPH_FLASHPAGE */
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
/**

View File

@ -619,6 +619,17 @@ SECTIONS
. = _heap_end;
_eheap = ABSOLUTE(.);
#ifdef MODULE_PERIPH_FLASHPAGE
.flash_writable (NOLOAD) : ALIGN(65536)
{
_fp_mem_start = . ;
KEEP(*(SORT(.flash_writable.*)))
_fp_mem_end = . ;
. = ALIGN(4096);
_end_fw = . ;
} > drom0_1_seg
#endif
}
ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)),

View File

@ -31,4 +31,22 @@ config MODULE_ESP_HW_COUNTER
registers that can be used as low-level timer peripherals. Use this
option to enable these CCOUNT and CCOMPARE register as low-level timer.
choice ESP_FLASHPAGE_CAPACITY
bool "Flashpage capacity"
default ESP_FLASHPAGE_CAPACITY_512K
depends on MODULE_PERIPH_FLASHPAGE
config ESP_FLASHPAGE_CAPACITY_64K
bool "64 kByte"
config ESP_FLASHPAGE_CAPACITY_128K
bool "128 kByte"
config ESP_FLASHPAGE_CAPACITY_256K
bool "256 kByte"
config ESP_FLASHPAGE_CAPACITY_512K
bool "512 kByte"
config ESP_FLASHPAGE_CAPACITY_1M
bool "1 MByte"
config ESP_FLASHPAGE_CAPACITY_2M
bool "2 MByte"
endchoice
endif # TEST_KCONFIG

View File

@ -0,0 +1,161 @@
/*
* Copyright (C) 2022 Gunar Schorcht
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup cpu_esp32
* @{
*
* @file
* @brief Implementation of the peripheral flashpage interface
*
* @author Gunar Schorcht <gunar@schorcht.net>
* @}
*/
#include <assert.h>
#include "architecture.h"
#include "cpu.h"
#include "irq.h"
#include "periph/flashpage.h"
#include "irq.h"
#include "log.h"
#include "esp_flash_partitions.h"
#include "esp_spi_flash.h"
#include "rom/cache.h"
#include "rom/spi_flash.h"
#include "soc/mmu.h"
#include "soc/soc.h"
#define ENABLE_DEBUG 0
#include "debug.h"
#define ESP_PART_TABLE_ADDR 0x8000 /* TODO configurable as used in Makefile.include */
#define ESP_PART_TABLE_SIZE 0xC00
#define ESP_PART_ENTRY_SIZE 0x20
#define ESP_PART_ENTRY_MAGIC ESP_PARTITION_MAGIC
extern uint8_t _fp_mem_start; /* start address in CPU address space */
extern uint8_t _fp_mem_end;
extern uint8_t _end_fw;
static uint32_t _fp_flash_start; /* start address in flash */
void IRAM_ATTR esp_flashpage_init(void)
{
/* CONFIG_ESP_FLASHPAGE_CAPACITY has to be a multiple of SPI_FLASH_MMU_PAGE_SIZE */
assert((CONFIG_ESP_FLASHPAGE_CAPACITY % SPI_FLASH_MMU_PAGE_SIZE) == 0);
DEBUG("%s pages in CPU address space @0x%08"PRIx32"...0x%08"PRIx32"\n", __func__,
CPU_FLASH_BASE, CPU_FLASH_BASE + CONFIG_ESP_FLASHPAGE_CAPACITY - 1);
_fp_flash_start = FLASHPAGE_ADDR_START;
DEBUG("%s pages in flash @0x%08"PRIx32"...0x%08"PRIx32"\n", __func__,
_fp_flash_start, _fp_flash_start + CONFIG_ESP_FLASHPAGE_CAPACITY - 1);
uint32_t state = irq_disable();
uint32_t p_numof = CONFIG_ESP_FLASHPAGE_CAPACITY / SPI_FLASH_MMU_PAGE_SIZE;
uint32_t p_addr = FLASHPAGE_ADDR_START;
#if CPU_FAM_ESP32S2
/* ESP32-S2 requires special handling to enable the MMU pages in Cache
* explicitly */
uint32_t autoload = Cache_Suspend_ICache();
Cache_Invalidate_ICache_All();
int res = Cache_Ibus_MMU_Set(MMU_ACCESS_FLASH, (uint32_t)&_fp_mem_start,
p_addr, 64, p_numof, 0);
Cache_Resume_ICache(autoload);
DEBUG("%s DCache MMU set paddr=%08x vaddr=%08x size=%d n=%u\n", __func__,
p_addr, (uint32_t)&_fp_mem_start, CONFIG_ESP_FLASHPAGE_CAPACITY,
p_numof);
if (res != ESP_OK) {
LOG_TAG_ERROR("flashpage",
"Could not map MMU pages in DCache, error: %d\n", res);
}
#else
uint32_t p_mmu = ((uint32_t)&_fp_mem_start - SOC_DROM_LOW) / SPI_FLASH_MMU_PAGE_SIZE;
while (p_numof--) {
uint32_t p_flash = p_addr / SPI_FLASH_MMU_PAGE_SIZE;
DEBUG("%s map MMU page %"PRIu32" @0x%08"PRIx32" to "
"flash page %"PRIu32" @0x%08"PRIx32"\n", __func__,
p_mmu, (p_mmu * SPI_FLASH_MMU_PAGE_SIZE) + SOC_DROM_LOW,
p_flash, p_flash * SPI_FLASH_MMU_PAGE_SIZE);
SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE[p_mmu] = SOC_MMU_PAGE_IN_FLASH(p_flash);
p_addr += SPI_FLASH_MMU_PAGE_SIZE;
p_mmu++;
}
#endif
irq_restore(state);
if (IS_ACTIVE(ENABLE_DEBUG)) {
spi_flash_mmap_dump();
}
}
void flashpage_erase(unsigned page)
{
assert(page < FLASHPAGE_NUMOF);
uint32_t flash_addr = _fp_flash_start + (page * FLASHPAGE_SIZE);
DEBUG("%s erase page in flash @0x%08"PRIx32"\n", __func__, flash_addr);
int res = spi_flash_erase_range(flash_addr, FLASHPAGE_SIZE);
if (res != ESP_OK) {
LOG_TAG_ERROR("flashpage", "Could not erase page %u, error %d\n",
page, res);
}
}
void flashpage_write(void *target_addr, const void *data, size_t len)
{
DEBUG("%s write %u byte from @%p to @%p\n",
__func__, len, data, target_addr);
/* assert multiples of FLASHPAGE_WRITE_BLOCK_SIZE are written */
assert(!(len % FLASHPAGE_WRITE_BLOCK_SIZE));
/* ensure writes to flash are aligned */
assert(!((unsigned)target_addr % FLASHPAGE_WRITE_BLOCK_ALIGNMENT));
/* ensure the length doesn't exceed the actual flash size */
assert(((unsigned)target_addr + len) <=
(CPU_FLASH_BASE + (FLASHPAGE_SIZE * FLASHPAGE_NUMOF)));
uint32_t flash_addr = ((uint32_t)target_addr - (uint32_t)&_fp_mem_start) + _fp_flash_start;
DEBUG("%s write to CPU address @%p (flash @0x%08"PRIx32")\n",
__func__, target_addr, flash_addr);
int res = spi_flash_write(flash_addr, data, len);
if (res != ESP_OK) {
LOG_TAG_ERROR("flashpage", "Could not write to CPU address @%p "
"(flash @0x%08"PRIx32"), error %d\n",
target_addr, flash_addr, res);
}
}
unsigned flashpage_first_free(void)
{
/* _end_fw is page aligned */
return flashpage_page(&_end_fw);
}
unsigned flashpage_last_free(void)
{
// return flashpage_page((const void *)SOC_DROM_HIGH) - 1;
return flashpage_page((void *)(CPU_FLASH_BASE + CONFIG_ESP_FLASHPAGE_CAPACITY)) - 1;
}

View File

@ -289,6 +289,11 @@ static NORETURN void IRAM system_init (void)
print_board_config();
#endif
#if IS_USED(MODULE_PERIPH_FLASHPAGE)
extern void esp_flashpage_init(void);
esp_flashpage_init();
#endif
#if IS_USED(MODULE_MTD)
/* init flash drive */
extern void spi_flash_drive_init (void);

View File

@ -150,12 +150,22 @@ TEST_EXTRA_FILES += $(FLASHFILE) $(BINDIR)/partitions.bin $(BOOTLOADER_BIN)
# table setting PARTITION_TABLE_CSV.
PARTITION_TABLE_CSV ?= $(BINDIR)/partitions.csv
ifneq (,$(filter periph_flashpage_in_address_space,$(USEMODULE)))
$(BINDIR)/partitions.csv: $(FLASHFILE)
$(Q)printf "\n" > $(BINDIR)/partitions.csv
$(Q)printf "nvs, data, nvs, 0x9000, 0x6000\n" >> $@
$(Q)printf "phy_init, data, phy, 0xf000, 0x1000\n" >> $@
$(Q)printf "flashpage, data, phy, $(FLASHPAGE_ADDR_START), $(FLASHPAGE_CAP)\n" >> $@
$(Q)printf "factory, app, factory, $(FLASHFILE_POS), " >> $@
$(Q)ls -l $< | awk '{ print $$5 }' >> $@
else
$(BINDIR)/partitions.csv: $(FLASHFILE)
$(Q)printf "\n" > $(BINDIR)/partitions.csv
$(Q)printf "nvs, data, nvs, 0x9000, 0x6000\n" >> $@
$(Q)printf "phy_init, data, phy, 0xf000, 0x1000\n" >> $@
$(Q)printf "factory, app, factory, $(FLASHFILE_POS), " >> $@
$(Q)ls -l $< | awk '{ print $$5 }' >> $@
endif
$(BINDIR)/partitions.bin: $(PARTITION_TABLE_CSV)
$(Q)python3 $(RIOTTOOLS)/esptools/gen_esp32part.py --verify $< $@

View File

@ -7,6 +7,7 @@ FEATURES_OPTIONAL += periph_flashpage_pagewise
FEATURES_OPTIONAL += periph_flashpage_rwee
USEMODULE += od
USEMODULE += od_string
USEMODULE += shell
# avoid running Kconfig by default

View File

@ -1,5 +1,6 @@
# this file enables modules defined in Kconfig. Do not use this file for
# application configuration. This is only needed during migration.
CONFIG_MODULE_OD=y
CONFIG_MODULE_OD_STRING=y
CONFIG_MODULE_PERIPH_FLASHPAGE=y
CONFIG_MODULE_SHELL=y

View File

@ -81,31 +81,9 @@ static int getpage(const char *str)
}
#ifdef MODULE_PERIPH_FLASHPAGE_PAGEWISE
static void dumpchar(uint8_t mem)
{
if (mem >= ' ' && mem <= '~') {
printf(" %c ", mem);
}
else {
printf(" ?? ");
}
}
static void memdump(void *addr, size_t len)
{
unsigned pos = 0;
uint8_t *mem = (uint8_t *)addr;
while (pos < (unsigned)len) {
for (unsigned i = 0; i < LINE_LEN; i++) {
printf("0x%02x ", mem[pos + i]);
}
puts("");
for (unsigned i = 0; i < LINE_LEN; i++) {
dumpchar(mem[pos++]);
}
puts("");
}
od_hex_dump (addr, len, LINE_LEN);
}
static void dump_local(void)