Skip to content

Commit

Permalink
Merge #19079
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
bors[bot] and gschorcht authored Jan 18, 2023
2 parents c7ded01 + c21eb6b commit 7855aad
Show file tree
Hide file tree
Showing 25 changed files with 384 additions and 26 deletions.
3 changes: 3 additions & 0 deletions cpu/esp32/Kconfig.esp32
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions cpu/esp32/Kconfig.esp32c3
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions cpu/esp32/Kconfig.esp32s2
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions cpu/esp32/Kconfig.esp32s3
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion cpu/esp32/Makefile.dep
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
3 changes: 3 additions & 0 deletions cpu/esp32/Makefile.features
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
33 changes: 33 additions & 0 deletions cpu/esp32/Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion cpu/esp32/esp-idf/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
39 changes: 39 additions & 0 deletions cpu/esp32/include/cpu_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
#ifndef CPU_CONF_H
#define CPU_CONF_H

#if !defined(__ASSEMBLER__)
#include <stdint.h>
#endif

/**
* @name Stack size configuration
* @{
Expand Down Expand Up @@ -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"
Expand Down
27 changes: 27 additions & 0 deletions cpu/esp32/include/sdkconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

/**
Expand Down
7 changes: 7 additions & 0 deletions cpu/esp32/ld/esp32/memory.ld.in
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
12 changes: 11 additions & 1 deletion cpu/esp32/ld/esp32/sections.ld.in
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,6 @@ SECTIONS
. = ALIGN(ALIGNOF(.flash.rodata));
} >default_rodata_seg

_rodata_start = ABSOLUTE(.);
.flash.rodata : ALIGN(0x10)
{
_flash_rodata_start = ABSOLUTE(.);
Expand Down Expand Up @@ -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)),
Expand Down
7 changes: 7 additions & 0 deletions cpu/esp32/ld/esp32c3/memory.ld.in
Original file line number Diff line number Diff line change
Expand Up @@ -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

/**
Expand Down
10 changes: 10 additions & 0 deletions cpu/esp32/ld/esp32c3/sections.ld.in
Original file line number Diff line number Diff line change
Expand Up @@ -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)),
Expand Down
7 changes: 7 additions & 0 deletions cpu/esp32/ld/esp32s2/memory.ld.in
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
11 changes: 11 additions & 0 deletions cpu/esp32/ld/esp32s2/sections.ld.in
Original file line number Diff line number Diff line change
Expand Up @@ -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)),
Expand Down
7 changes: 7 additions & 0 deletions cpu/esp32/ld/esp32s3/memory.ld.in
Original file line number Diff line number Diff line change
Expand Up @@ -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

/**
Expand Down
11 changes: 11 additions & 0 deletions cpu/esp32/ld/esp32s3/sections.ld.in
Original file line number Diff line number Diff line change
Expand Up @@ -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)),
Expand Down
18 changes: 18 additions & 0 deletions cpu/esp32/periph/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Loading

0 comments on commit 7855aad

Please sign in to comment.