You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2021/09/28 01:22:37 UTC
[incubator-nuttx] 02/04: risc-v/esp32c3: Enable booting from
MCUboot bootloader
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit 3c63cb522ca310da61602a14f6f00afc84b3a489
Author: Gustavo Henrique Nihei <gu...@espressif.com>
AuthorDate: Fri Sep 10 13:29:22 2021 -0300
risc-v/esp32c3: Enable booting from MCUboot bootloader
Signed-off-by: Gustavo Henrique Nihei <gu...@espressif.com>
---
arch/risc-v/src/esp32c3/Kconfig | 158 +++++++++--
arch/risc-v/src/esp32c3/esp32c3_start.c | 174 +++++++++++-
.../src/esp32c3/hardware/esp32c3_cache_memory.h | 110 ++++++++
arch/risc-v/src/esp32c3/hardware/extmem_reg.h | 23 +-
.../esp32c3/esp32c3-devkit/scripts/Make.defs | 6 +-
.../esp32c3-devkit/scripts/esp32c3.template.ld | 70 ++++-
.../esp32c3-devkit/scripts/esp32c3_mcuboot.ld | 308 +++++++++++++++++++++
.../esp32c3/esp32c3-devkit/scripts/esp32c3_rom.ld | 6 +-
.../esp32c3/esp32c3-devkit/src/esp32c3_spiflash.c | 112 ++++++++
tools/esp32c3/Config.mk | 108 ++++++--
10 files changed, 1010 insertions(+), 65 deletions(-)
diff --git a/arch/risc-v/src/esp32c3/Kconfig b/arch/risc-v/src/esp32c3/Kconfig
index f91e39d..f307375 100644
--- a/arch/risc-v/src/esp32c3/Kconfig
+++ b/arch/risc-v/src/esp32c3/Kconfig
@@ -516,13 +516,6 @@ config ESP32C3_UART1_CTSPIN
endif # ESP32C3_UART1
-config ESP32C3_PARTITION
- bool "ESP32-C3 Partition"
- default n
- select ESP32C3_SPIFLASH
- ---help---
- Decode partition file and initialize partition as MTD.
-
endmenu
menu "Real-Time Timer"
@@ -760,7 +753,8 @@ config ESP32C3_WIFI_FS_MOUNTPT
config ESP32C3_WIFI_MTD_OFFSET
hex "Wi-Fi MTD partition offset"
- default 0x280000
+ default 0x280000 if !ESP32C3_HAVE_OTA_PARTITION
+ default 0x350000 if ESP32C3_HAVE_OTA_PARTITION
depends on ESP32C3_WIFI_SAVE_PARAM
---help---
This is the base address of the Wi-Fi MTD partition.
@@ -840,9 +834,50 @@ endmenu # BLE Configuration
menu "SPI Flash configuration"
depends on ESP32C3_SPIFLASH
+if ESP32C3_HAVE_OTA_PARTITION
+
+comment "Application Image OTA Update support"
+
+config ESP32C3_OTA_PRIMARY_SLOT_OFFSET
+ hex "Application image primary slot offset"
+ default "0x10000"
+
+config ESP32C3_OTA_PRIMARY_SLOT_DEVPATH
+ string "Application image primary slot device path"
+ default "/dev/ota0"
+
+config ESP32C3_OTA_SECONDARY_SLOT_OFFSET
+ hex "Application image secondary slot offset"
+ default "0x110000"
+
+config ESP32C3_OTA_SECONDARY_SLOT_DEVPATH
+ string "Application image secondary slot device path"
+ default "/dev/ota1"
+
+config ESP32C3_OTA_SLOT_SIZE
+ hex "Application image slot size (in bytes)"
+ default "0x100000"
+
+config ESP32C3_OTA_SCRATCH_OFFSET
+ hex "Scratch partition offset"
+ default "0x210000"
+
+config ESP32C3_OTA_SCRATCH_SIZE
+ hex "Scratch partition size"
+ default "0x40000"
+
+config ESP32C3_OTA_SCRATCH_DEVPATH
+ string "Scratch partition device path"
+ default "/dev/otascratch"
+
+endif
+
+comment "General MTD configuration"
+
config ESP32C3_MTD_OFFSET
hex "MTD base address in SPI Flash"
- default 0x180000
+ default 0x180000 if !ESP32C3_HAVE_OTA_PARTITION
+ default 0x250000 if ESP32C3_HAVE_OTA_PARTITION
---help---
MTD base address in SPI Flash.
@@ -860,20 +895,7 @@ config ESP32C3_SPIFLASH_DEBUG
If this option is enabled, SPI Flash driver read and write functions
will output input parameters and return values (if applicable).
-endmenu # ESP32C3_SPIFLASH
-
-menu "Partition Configuration"
- depends on ESP32C3_PARTITION
-
-config ESP32C3_PARTITION_OFFSET
- hex "Partition offset"
- default "0x8000"
-
-config ESP32C3_PARTITION_MOUNT
- string "Partition mount point"
- default "/dev/esp/partition/"
-
-endmenu # ESP32C3_PARTITION
+endmenu # SPI Flash configuration
menu "GDMA Configuration"
depends on ESP32C3_DMA
@@ -909,6 +931,96 @@ config ESP32C3_TICKLESS
select ARCH_HAVE_TICKLESS
select SCHED_TICKLESS
+config ESP32C3_HAVE_OTA_PARTITION
+ bool
+ default n
+
+menu "Application Image Configuration"
+
+choice
+ prompt "Application Image Format"
+ default ESP32C3_APP_FORMAT_LEGACY
+ ---help---
+ Depending on the chosen 2nd stage bootloader, the application may
+ be required to be perform a specific startup routine. Furthermore,
+ the image binary must be formatted according to the definition from
+ the 2nd stage bootloader.
+
+config ESP32C3_APP_FORMAT_LEGACY
+ bool "Legacy format"
+ ---help---
+ This is the legacy application image format, as supported by the ESP-IDF
+ 2nd stage bootloader.
+
+config ESP32C3_APP_FORMAT_MCUBOOT
+ bool "MCUboot-bootable format"
+ select ESP32C3_HAVE_OTA_PARTITION
+ depends on EXPERIMENTAL
+ ---help---
+ The Espressif port of MCUboot supports the loading of unsegmented firmware
+ images.
+
+comment "MCUboot support depends on CONFIG_EXPERIMENTAL"
+ depends on !EXPERIMENTAL
+
+endchoice # Application Image Format
+
+choice
+ prompt "Target slot for image flashing"
+ default ESP32C3_ESPTOOL_TARGET_PRIMARY
+ depends on ESP32C3_HAVE_OTA_PARTITION
+ ---help---
+ Slot to which ESPTOOL will flash the generated binary image.
+
+config ESP32C3_ESPTOOL_TARGET_PRIMARY
+ bool "Application image primary slot"
+ ---help---
+ This assumes that the generated image is already pre-validated.
+ This is the recommended option for the initial stages of the
+ application firmware image development.
+
+config ESP32C3_ESPTOOL_TARGET_SECONDARY
+ bool "Application image secondary slot"
+ ---help---
+ The application needs to confirm the generated image as valid,
+ otherwise the bootloader may consider it invalid and perform the
+ rollback of the update after a reset.
+ This is the choice most suitable for the development and verification
+ of a secure firmware update workflow.
+
+endchoice
+
+config ESP32C3_APP_MCUBOOT_HEADER_SIZE
+ int "Application image header size (in bytes)"
+ default 32
+ depends on ESP32C3_APP_FORMAT_MCUBOOT
+
+endmenu # Application Image Configuration
+
+if ESP32C3_APP_FORMAT_LEGACY
+
+config ESP32C3_PARTITION
+ bool "ESP32-C3 Partition"
+ default n
+ select ESP32C3_SPIFLASH
+ ---help---
+ Decode partition file and initialize partition as MTD.
+
+menu "Partition Configuration"
+ depends on ESP32C3_PARTITION
+
+config ESP32C3_PARTITION_OFFSET
+ hex "Partition offset"
+ default "0x8000"
+
+config ESP32C3_PARTITION_MOUNT
+ string "Partition mount point"
+ default "/dev/esp/partition/"
+
+endmenu # Partition Configuration
+
+endif
+
menu "AES accelerator"
depends on ESP32C3_AES_ACCELERATOR
diff --git a/arch/risc-v/src/esp32c3/esp32c3_start.c b/arch/risc-v/src/esp32c3/esp32c3_start.c
index d83cf82..07e7016 100644
--- a/arch/risc-v/src/esp32c3/esp32c3_start.c
+++ b/arch/risc-v/src/esp32c3/esp32c3_start.c
@@ -35,17 +35,83 @@
#include "esp32c3_lowputc.h"
#include "esp32c3_start.h"
#include "esp32c3_wdt.h"
+#include "hardware/esp32c3_cache_memory.h"
+#include "hardware/extmem_reg.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_DEBUG_FEATURES
-# define showprogress(c) riscv_lowputc(c)
+# define showprogress(c) riscv_lowputc(c)
#else
# define showprogress(c)
#endif
+#ifdef CONFIG_ESP32C3_APP_FORMAT_MCUBOOT
+
+#define PRIMARY_SLOT_OFFSET CONFIG_ESP32C3_OTA_PRIMARY_SLOT_OFFSET
+
+#define HDR_ATTR __attribute__((section(".entry_addr"))) \
+ __attribute__((used))
+
+/* Cache MMU block size */
+
+#define MMU_BLOCK_SIZE 0x00010000 /* 64 KB */
+
+/* Cache MMU address mask (MMU tables ignore bits which are zero) */
+
+#define MMU_FLASH_MASK (~(MMU_BLOCK_SIZE - 1))
+
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP32C3_APP_FORMAT_MCUBOOT
+extern uint32_t _image_irom_vma;
+extern uint32_t _image_irom_lma;
+extern uint32_t _image_irom_size;
+
+extern uint32_t _image_drom_vma;
+extern uint32_t _image_drom_lma;
+extern uint32_t _image_drom_size;
+#endif
+
+/****************************************************************************
+ * ROM Function Prototypes
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP32C3_APP_FORMAT_MCUBOOT
+extern int ets_printf(const char *fmt, ...);
+extern uint32_t cache_suspend_icache(void);
+extern void cache_resume_icache(uint32_t val);
+extern void cache_invalidate_icache_all(void);
+extern int cache_dbus_mmu_set(uint32_t ext_ram, uint32_t vaddr,
+ uint32_t paddr, uint32_t psize, uint32_t num,
+ uint32_t fixed);
+extern int cache_ibus_mmu_set(uint32_t ext_ram, uint32_t vaddr,
+ uint32_t paddr, uint32_t psize, uint32_t num,
+ uint32_t fixed);
+#endif
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP32C3_APP_FORMAT_MCUBOOT
+IRAM_ATTR noreturn_function void __start(void);
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP32C3_APP_FORMAT_MCUBOOT
+HDR_ATTR static void (*_entry_point)(void) = &__start;
+#endif
+
/****************************************************************************
* Public Data
****************************************************************************/
@@ -57,6 +123,101 @@ uint8_t g_idlestack[CONFIG_IDLETHREAD_STACKSIZE]
uint32_t g_idle_topstack = ESP32C3_IDLESTACK_TOP;
/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: calc_mmu_pages
+ *
+ * Description:
+ * Calculate the number of cache pages to map.
+ *
+ * Input Parameters:
+ * size - Size of data to map
+ * vaddr - Virtual address where data will be mapped
+ *
+ * Returned Value:
+ * Number of cache MMU pages required to do the mapping.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP32C3_APP_FORMAT_MCUBOOT
+static inline uint32_t calc_mmu_pages(uint32_t size, uint32_t vaddr)
+{
+ return (size + (vaddr - (vaddr & MMU_FLASH_MASK)) + MMU_BLOCK_SIZE - 1) /
+ MMU_BLOCK_SIZE;
+}
+#endif
+
+/****************************************************************************
+ * Name: map_rom_segments
+ *
+ * Description:
+ * Configure the MMU and Cache peripherals for accessing ROM code and data.
+ *
+ * Input Parameters:
+ * None.
+ *
+ * Returned Value:
+ * None.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP32C3_APP_FORMAT_MCUBOOT
+static int map_rom_segments(void)
+{
+ uint32_t rc = 0;
+ uint32_t regval;
+ uint32_t drom_lma_aligned;
+ uint32_t drom_vma_aligned;
+ uint32_t drom_page_count;
+ uint32_t irom_lma_aligned;
+ uint32_t irom_vma_aligned;
+ uint32_t irom_page_count;
+
+ size_t partition_offset = PRIMARY_SLOT_OFFSET;
+ uint32_t app_irom_lma = partition_offset + (uint32_t)&_image_irom_lma;
+ uint32_t app_irom_size = (uint32_t)&_image_irom_size;
+ uint32_t app_irom_vma = (uint32_t)&_image_irom_vma;
+ uint32_t app_drom_lma = partition_offset + (uint32_t)&_image_drom_lma;
+ uint32_t app_drom_size = (uint32_t)&_image_drom_size;
+ uint32_t app_drom_vma = (uint32_t)&_image_drom_vma;
+
+ uint32_t autoload = cache_suspend_icache();
+ cache_invalidate_icache_all();
+
+ /* Clear the MMU entries that are already set up, so the new app only has
+ * the mappings it creates.
+ */
+
+ for (size_t i = 0; i < FLASH_MMU_TABLE_SIZE; i++)
+ {
+ FLASH_MMU_TABLE[i] = MMU_TABLE_INVALID_VAL;
+ }
+
+ drom_lma_aligned = app_drom_lma & MMU_FLASH_MASK;
+ drom_vma_aligned = app_drom_vma & MMU_FLASH_MASK;
+ drom_page_count = calc_mmu_pages(app_drom_size, app_drom_vma);
+ rc = cache_dbus_mmu_set(MMU_ACCESS_FLASH, drom_vma_aligned,
+ drom_lma_aligned, 64, (int)drom_page_count, 0);
+
+ irom_lma_aligned = app_irom_lma & MMU_FLASH_MASK;
+ irom_vma_aligned = app_irom_vma & MMU_FLASH_MASK;
+ irom_page_count = calc_mmu_pages(app_irom_size, app_irom_vma);
+ rc |= cache_ibus_mmu_set(MMU_ACCESS_FLASH, irom_vma_aligned,
+ irom_lma_aligned, 64, (int)irom_page_count, 0);
+
+ regval = getreg32(EXTMEM_ICACHE_CTRL1_REG);
+ regval &= ~(EXTMEM_ICACHE_SHUT_IBUS_M | EXTMEM_ICACHE_SHUT_DBUS_M);
+ putreg32(regval, EXTMEM_ICACHE_CTRL1_REG);
+
+ cache_resume_icache(autoload);
+
+ return (int)rc;
+}
+#endif
+
+/****************************************************************************
* Public Functions
****************************************************************************/
@@ -66,7 +227,14 @@ uint32_t g_idle_topstack = ESP32C3_IDLESTACK_TOP;
void __esp32c3_start(void)
{
- uint32_t *dest;
+#ifdef CONFIG_ESP32C3_APP_FORMAT_MCUBOOT
+ if (map_rom_segments() != 0)
+ {
+ ets_printf("Failed to setup XIP, aborting\n");
+ while (true);
+ }
+
+#endif
/* Set CPU frequency */
@@ -88,7 +256,7 @@ void __esp32c3_start(void)
* certain that there are no issues with the state of global variables.
*/
- for (dest = &_sbss; dest < &_ebss; dest++)
+ for (uint32_t *dest = &_sbss; dest < &_ebss; dest++)
{
*dest = 0;
}
diff --git a/arch/risc-v/src/esp32c3/hardware/esp32c3_cache_memory.h b/arch/risc-v/src/esp32c3/hardware/esp32c3_cache_memory.h
new file mode 100644
index 0000000..cf3e0aa
--- /dev/null
+++ b/arch/risc-v/src/esp32c3/hardware/esp32c3_cache_memory.h
@@ -0,0 +1,110 @@
+/****************************************************************************
+ * arch/risc-v/src/esp32c3/hardware/esp32c3_cache_memory.h
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_RISCV_SRC_ESP32C3_HARDWARE_ESP32C3_CACHE_MEMORY_H_
+#define __ARCH_RISCV_SRC_ESP32C3_HARDWARE_ESP32C3_CACHE_MEMORY_H_
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* IRAM0 is connected with Cache IBUS0 */
+
+#define IRAM0_ADDRESS_LOW 0x40000000
+#define IRAM0_ADDRESS_HIGH 0x44000000
+#define IRAM0_CACHE_ADDRESS_LOW 0x42000000
+#define IRAM0_CACHE_ADDRESS_HIGH 0x42800000
+
+/* DRAM0 is connected with Cache DBUS0 */
+
+#define DRAM0_ADDRESS_LOW 0x3c000000
+#define DRAM0_ADDRESS_HIGH 0x40000000
+#define DRAM0_CACHE_ADDRESS_LOW 0x3c000000
+#define DRAM0_CACHE_ADDRESS_HIGH 0x3c800000
+#define DRAM0_CACHE_OPERATION_HIGH DRAM0_CACHE_ADDRESS_HIGH
+#define ESP_CACHE_TEMP_ADDR 0x3c000000
+
+#define BUS_SIZE(bus_name) (bus_name##_ADDRESS_HIGH - \
+ bus_name##_ADDRESS_LOW)
+#define ADDRESS_IN_BUS(bus_name, vaddr) ((vaddr) >= bus_name##_ADDRESS_LOW \
+ && (vaddr) < \
+ bus_name##_ADDRESS_HIGH)
+
+#define ADDRESS_IN_IRAM0(vaddr) ADDRESS_IN_BUS(IRAM0, vaddr)
+#define ADDRESS_IN_IRAM0_CACHE(vaddr) ADDRESS_IN_BUS(IRAM0_CACHE, vaddr)
+#define ADDRESS_IN_DRAM0(vaddr) ADDRESS_IN_BUS(DRAM0, vaddr)
+#define ADDRESS_IN_DRAM0_CACHE(vaddr) ADDRESS_IN_BUS(DRAM0_CACHE, vaddr)
+
+#define BUS_IRAM0_CACHE_SIZE BUS_SIZE(IRAM0_CACHE)
+#define BUS_DRAM0_CACHE_SIZE BUS_SIZE(DRAM0_CACHE)
+
+#define CACHE_IBUS 0
+#define CACHE_IBUS_MMU_START 0
+#define CACHE_IBUS_MMU_END 0x200
+
+#define CACHE_DBUS 1
+#define CACHE_DBUS_MMU_START 0
+#define CACHE_DBUS_MMU_END 0x200
+
+#define CACHE_IROM_MMU_START 0
+#define CACHE_IROM_MMU_END Cache_Get_IROM_MMU_End()
+#define CACHE_IROM_MMU_SIZE (CACHE_IROM_MMU_END - CACHE_IROM_MMU_START)
+
+#define CACHE_DROM_MMU_START CACHE_IROM_MMU_END
+#define CACHE_DROM_MMU_END Cache_Get_DROM_MMU_End()
+#define CACHE_DROM_MMU_SIZE (CACHE_DROM_MMU_END - CACHE_DROM_MMU_START)
+
+#define CACHE_DROM_MMU_MAX_END 0x200
+
+#define ICACHE_MMU_SIZE 0x200
+#define DCACHE_MMU_SIZE 0x200
+
+#define MMU_BUS_START(i) 0
+#define MMU_BUS_SIZE(i) 0x200
+
+#define MMU_INVALID BIT(8)
+#define MMU_TYPE 0
+#define MMU_ACCESS_FLASH 0
+
+#define CACHE_MAX_SYNC_NUM 0x400000
+#define CACHE_MAX_LOCK_NUM 0x8000
+
+#define FLASH_MMU_TABLE ((volatile uint32_t*) DR_REG_MMU_TABLE)
+#define FLASH_MMU_TABLE_SIZE (ICACHE_MMU_SIZE/sizeof(uint32_t))
+
+#define MMU_TABLE_INVALID_VAL 0x100
+#define MMU_ADDRESS_MASK 0xff
+#define MMU_PAGE_SIZE 0x10000
+#define INVALID_PHY_PAGE 0xffff
+
+#define BUS_ADDR_SIZE 0x800000
+#define BUS_ADDR_MASK (BUS_ADDR_SIZE - 1)
+
+#define CACHE_ICACHE_LOW_SHIFT 0
+#define CACHE_ICACHE_HIGH_SHIFT 2
+#define CACHE_DCACHE_LOW_SHIFT 4
+#define CACHE_DCACHE_HIGH_SHIFT 6
+
+#define CACHE_MEMORY_IBANK0_ADDR 0x4037c000
+
+#endif /* __ARCH_RISCV_SRC_ESP32C3_HARDWARE_ESP32C3_CACHE_MEMORY_H_ */
diff --git a/arch/risc-v/src/esp32c3/hardware/extmem_reg.h b/arch/risc-v/src/esp32c3/hardware/extmem_reg.h
index 88ce7f7..d44cdcb 100644
--- a/arch/risc-v/src/esp32c3/hardware/extmem_reg.h
+++ b/arch/risc-v/src/esp32c3/hardware/extmem_reg.h
@@ -31,8 +31,29 @@
* Pre-processor Definitions
****************************************************************************/
-#define EXTMEM_CACHE_MMU_POWER_CTRL_REG (DR_REG_EXTMEM_BASE + 0x0AC)
+#define EXTMEM_ICACHE_CTRL1_REG (DR_REG_EXTMEM_BASE + 0x004)
#define EXTMEM_ICACHE_TAG_POWER_CTRL_REG (DR_REG_EXTMEM_BASE + 0x008)
+#define EXTMEM_CACHE_MMU_POWER_CTRL_REG (DR_REG_EXTMEM_BASE + 0x0ac)
+
+/* EXTMEM_ICACHE_SHUT_DBUS : R/W ;bitpos:[1] ;default: 1'b1 ;
+ * description: The bit is used to disable core1 ibus
+ * 0: enable 1: disable
+ */
+
+#define EXTMEM_ICACHE_SHUT_DBUS (BIT(1))
+#define EXTMEM_ICACHE_SHUT_DBUS_M (BIT(1))
+#define EXTMEM_ICACHE_SHUT_DBUS_V 0x1
+#define EXTMEM_ICACHE_SHUT_DBUS_S 1
+
+/* EXTMEM_ICACHE_SHUT_IBUS : R/W ;bitpos:[0] ;default: 1'b1 ;
+ * description: The bit is used to disable core0 ibus
+ * 0: enable 1: disable
+ */
+
+#define EXTMEM_ICACHE_SHUT_IBUS (BIT(0))
+#define EXTMEM_ICACHE_SHUT_IBUS_M (BIT(0))
+#define EXTMEM_ICACHE_SHUT_IBUS_V 0x1
+#define EXTMEM_ICACHE_SHUT_IBUS_S 0
/* EXTMEM_CACHE_MMU_MEM_FORCE_ON : R/W ;bitpos:[0] ;default: 1'b1.
* The bit is used to enable clock gating to save
diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/scripts/Make.defs b/boards/risc-v/esp32c3/esp32c3-devkit/scripts/Make.defs
index 4449874..257b015 100644
--- a/boards/risc-v/esp32c3/esp32c3-devkit/scripts/Make.defs
+++ b/boards/risc-v/esp32c3/esp32c3-devkit/scripts/Make.defs
@@ -24,7 +24,11 @@ include $(TOPDIR)/tools/esp32c3/Config.mk
include $(TOPDIR)/arch/risc-v/src/rv32im/Toolchain.defs
LDSCRIPT1 = $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32c3_out.ld
-LDSCRIPT2 = $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32c3.ld
+ifeq ($(CONFIG_ESP32C3_APP_FORMAT_MCUBOOT),y)
+ LDSCRIPT2 = $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32c3_mcuboot.ld
+else
+ LDSCRIPT2 = $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32c3.ld
+endif
LDSCRIPT3 = $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32c3_rom.ld
ifeq ($(CONFIG_CYGWIN_WINTOOL),y)
diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/scripts/esp32c3.template.ld b/boards/risc-v/esp32c3/esp32c3-devkit/scripts/esp32c3.template.ld
index 5923840..82a3398 100644
--- a/boards/risc-v/esp32c3/esp32c3-devkit/scripts/esp32c3.template.ld
+++ b/boards/risc-v/esp32c3/esp32c3-devkit/scripts/esp32c3.template.ld
@@ -47,26 +47,55 @@
#define I_D_SRAM_SIZE SRAM_DRAM_END - SRAM_DRAM_ORG
+#ifdef CONFIG_ESP32C3_FLASH_2M
+# define FLASH_SIZE 0x200000
+#elif defined (CONFIG_ESP32C3_FLASH_4M)
+# define FLASH_SIZE 0x400000
+#elif defined (CONFIG_ESP32C3_FLASH_8M)
+# define FLASH_SIZE 0x800000
+#elif defined (CONFIG_ESP32C3_FLASH_16M)
+# define FLASH_SIZE 0x1000000
+#endif
+
MEMORY
{
- /* All these values assume the flash cache is on, and have the blocks it
+#ifdef CONFIG_ESP32C3_APP_FORMAT_MCUBOOT
+ /* The origin values for "metadata" and "ROM" memory regions are the actual
+ * load addresses.
+ *
+ * NOTE: The memory region starting from 0x0 with length represented by
+ * CONFIG_ESP32C3_APP_MCUBOOT_HEADER_SIZE is reserved for the MCUboot header,
+ * which will be prepended to the binary file by the "imgtool" during the
+ * signing of firmware image.
+ */
+
+ metadata (RX) : org = CONFIG_ESP32C3_APP_MCUBOOT_HEADER_SIZE, len = 0x20
+ ROM (RX) : org = CONFIG_ESP32C3_APP_MCUBOOT_HEADER_SIZE + 0x20,
+ len = FLASH_SIZE - (CONFIG_ESP32C3_APP_MCUBOOT_HEADER_SIZE + 0x20)
+#endif
+
+ /* Below values assume the flash cache is on, and have the blocks this
* uses subtracted from the length of the various regions. The 'data access
- * port' dram/drom regions map to the same iram/irom regions but are
- * connected to the data port of the CPU and eg allow byte-wise access.
+ * port' dram/drom regions map to the same iram/irom regions but are
+ * connected to the data port of the CPU and e.g. allow bytewise access.
*/
iram0_0_seg (RX) : org = SRAM_IRAM_ORG, len = I_D_SRAM_SIZE
- /* Flash mapped instruction data.
- *
- * The 0x20 offset is a convenience for the app binary image generation.
+ /* Flash mapped instruction data. */
+
+#ifdef CONFIG_ESP32C3_APP_FORMAT_MCUBOOT
+ irom0_0_seg (RX) : org = 0x42000000, len = FLASH_SIZE
+#else
+ /* The 0x20 offset is a convenience for the app binary image generation.
* Flash cache has 64KB pages. The .bin file which is flashed to the chip
* has a 0x18 byte file header, and each segment has a 0x08 byte segment
* header. Setting this offset makes it simple to meet the flash cache MMU's
* constraint that (paddr % 64KB == vaddr % 64KB).
*/
- irom0_0_seg (RX) : org = 0x42000020, len = 0x8000000 - 0x20
+ irom0_0_seg (RX) : org = 0x42000020, len = FLASH_SIZE - 0x20
+#endif
/* Shared data RAM, excluding memory reserved for ROM bss/data/stack. */
@@ -74,7 +103,32 @@ MEMORY
/* Flash mapped constant data */
- drom0_0_seg (R) : org = 0x3c000020, len = 0x8000000 - 0x20
+#ifdef CONFIG_ESP32C3_APP_FORMAT_MCUBOOT
+ /* The DROM segment origin is offset by 0x40 for mirroring the actual ROM
+ * image layout:
+ * 0x0 - 0x1F : MCUboot header
+ * 0x20 - 0x3F : Application image metadata section
+ * 0x40 onwards: ROM code and data
+ * This is required to meet the following constraint from the external
+ * flash MMU:
+ * VMA % 64KB == LMA % 64KB
+ * i.e. the lower 16 bits of both the virtual address (address seen by the
+ * CPU) and the load address (physical address of the external flash) must
+ * be equal.
+ */
+
+ drom0_0_seg (R) : org = 0x3c000000 + (CONFIG_ESP32C3_APP_MCUBOOT_HEADER_SIZE + 0x20),
+ len = FLASH_SIZE - (CONFIG_ESP32C3_APP_MCUBOOT_HEADER_SIZE + 0x20)
+#else
+ /* The 0x20 offset is a convenience for the app binary image generation.
+ * Flash cache has 64KB pages. The .bin file which is flashed to the chip
+ * has a 0x18 byte file header, and each segment has a 0x08 byte segment
+ * header. Setting this offset makes it simple to meet the flash cache MMU's
+ * constraint that (paddr % 64KB == vaddr % 64KB).
+ */
+
+ drom0_0_seg (R) : org = 0x3c000020, len = FLASH_SIZE - 0x20
+#endif
/* RTC fast memory. Persists over deep sleep. */
diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/scripts/esp32c3_mcuboot.ld b/boards/risc-v/esp32c3/esp32c3-devkit/scripts/esp32c3_mcuboot.ld
new file mode 100644
index 0000000..94077d6
--- /dev/null
+++ b/boards/risc-v/esp32c3/esp32c3-devkit/scripts/esp32c3_mcuboot.ld
@@ -0,0 +1,308 @@
+/****************************************************************************
+ * boards/risc-v/esp32c3/esp32c3-devkit/scripts/esp32c3_mcuboot.ld
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/* Default entry point: */
+
+ENTRY(__start);
+
+SECTIONS
+{
+ .metadata :
+ {
+ /* Magic for load header */
+
+ LONG(0xace637d3)
+
+ /* Application entry point address */
+
+ KEEP(*(.entry_addr))
+
+ /* IRAM metadata:
+ * - Destination address (VMA) for IRAM region
+ * - Flash offset (LMA) for start of IRAM region
+ * - Size of IRAM region
+ */
+
+ LONG(ADDR(.iram0.text))
+ LONG(LOADADDR(.iram0.text))
+ LONG(SIZEOF(.iram0.text))
+
+ /* DRAM metadata:
+ * - Destination address (VMA) for DRAM region
+ * - Flash offset (LMA) for start of DRAM region
+ * - Size of DRAM region
+ */
+
+ LONG(ADDR(.dram0.data))
+ LONG(LOADADDR(.dram0.data))
+ LONG(SIZEOF(.dram0.data))
+ } >metadata
+
+ _image_drom_vma = ADDR(.flash.rodata);
+ _image_drom_lma = LOADADDR(.flash.rodata);
+ _image_drom_size = LOADADDR(.flash.rodata) + SIZEOF(.flash.rodata) - _image_drom_lma;
+
+ .flash.rodata :
+ {
+ _srodata = ABSOLUTE(.);
+ *(EXCLUDE_FILE (*libarch.a:esp32c3_spiflash.* esp32c3_head.* esp32c3_start.*) .rodata)
+ *(EXCLUDE_FILE (*libarch.a:esp32c3_spiflash.* esp32c3_head.* esp32c3_start.*) .rodata.*)
+
+ *(.srodata.*)
+
+ *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
+ *(.gnu.linkonce.r.*)
+ *(.rodata1)
+ __XT_EXCEPTION_TABLE_ = ABSOLUTE(.);
+ *(.xt_except_table)
+ *(.gcc_except_table .gcc_except_table.*)
+ *(.gnu.linkonce.e.*)
+ *(.gnu.version_r)
+ . = (. + 3) & ~ 3;
+ __eh_frame = ABSOLUTE(.);
+ KEEP(*(.eh_frame))
+ . = (. + 7) & ~ 3;
+
+ /* C++ constructor and destructor tables, properly ordered: */
+
+ _sinit = ABSOLUTE(.);
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ _einit = ABSOLUTE(.);
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+
+ /* C++ exception handlers table: */
+
+ __XT_EXCEPTION_DESCS_ = ABSOLUTE(.);
+ *(.xt_except_desc)
+ *(.gnu.linkonce.h.*)
+ __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
+ *(.xt_except_desc_end)
+ *(.dynamic)
+ *(.gnu.version_d)
+ . = ALIGN(4); /* This table MUST be 4-byte aligned */
+ _erodata = ABSOLUTE(.);
+
+ /* Literals are also RO data. */
+
+ _lit4_start = ABSOLUTE(.);
+ *(*.lit4)
+ *(.lit4.*)
+ *(.gnu.linkonce.lit4.*)
+ _lit4_end = ABSOLUTE(.);
+ . = ALIGN(4);
+ } >drom0_0_seg AT>ROM
+
+ .iram0.text :
+ {
+ _iram_start = ABSOLUTE(.);
+
+ /* Vectors go to start of IRAM */
+
+ KEEP(*(.exception_vectors.text));
+ . = ALIGN(4);
+
+ *(.iram1)
+ *(.iram1.*)
+ *libarch.a:esp32c3_spiflash.*(.literal .text .literal.* .text.*)
+ esp32c3_head.*(.literal .text .literal.* .text.*)
+ esp32c3_start.*(.literal .text .literal.* .text.*)
+ *(.wifi0iram .wifi0iram.*)
+ *(.wifirxiram .wifirxiram.*)
+ *(.wifislpiram .wifislpiram.*)
+ *(.wifislprxiram .wifislprxiram.*)
+ } >iram0_0_seg AT>ROM
+
+ .dram0.dummy (NOLOAD):
+ {
+ /* This section is required to skip .iram0.text area because iram0_0_seg
+ * and dram0_0_seg reflect the same address space on different buses.
+ */
+
+ . = ORIGIN(dram0_0_seg) + _iram_end - _iram_start;
+ } >dram0_0_seg
+
+ /* Shared RAM */
+
+ .dram0.bss (NOLOAD) :
+ {
+ /* .bss initialized on power-up */
+
+ . = ALIGN (8);
+ _sbss = ABSOLUTE(.);
+ *(.dynsbss)
+ *(.sbss)
+ *(.sbss.*)
+ *(.gnu.linkonce.sb.*)
+ *(.scommon)
+ *(.sbss2)
+ *(.sbss2.*)
+ *(.gnu.linkonce.sb2.*)
+ *(.dynbss)
+ KEEP (*(.bss))
+ *(.bss.*)
+ *(.share.mem)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(8);
+ _ebss = ABSOLUTE(.);
+ } >dram0_0_seg
+
+ .noinit (NOLOAD):
+ {
+ /* This section contains data that is not initialized during load,
+ * or during the application's initialization sequence.
+ */
+
+ . = ALIGN(8);
+ *(.noinit)
+ *(.noinit.*)
+ . = ALIGN(8);
+ } >dram0_0_seg
+
+ .dram0.data :
+ {
+ /* .data initialized on power-up in ROMed configurations. */
+
+ _sdata = ABSOLUTE(.);
+ KEEP (*(.data))
+ KEEP (*(.data.*))
+ KEEP (*(.gnu.linkonce.d.*))
+ KEEP (*(.data1))
+ __global_pointer$ = . + 0x800;
+ KEEP (*(.sdata))
+ KEEP (*(.sdata.*))
+ KEEP (*(.gnu.linkonce.s.*))
+ KEEP (*(.sdata2))
+ KEEP (*(.sdata2.*))
+ KEEP (*(.gnu.linkonce.s2.*))
+ KEEP (*(.jcr))
+ *(.dram1 .dram1.*)
+ *libarch.a:esp32c3_spiflash.*(.rodata .rodata.*)
+ esp32c3_head.*(.rodata .rodata.*)
+ esp32c3_start.*(.rodata .rodata.*)
+ _edata = ABSOLUTE(.);
+ . = ALIGN(4);
+
+ /* Heap starts at the end of .data */
+
+ _sheap = ABSOLUTE(.);
+ } >dram0_0_seg AT>ROM
+
+ /* Marks the end of IRAM code segment */
+
+ .iram0.text_end (NOLOAD) :
+ {
+ . = ALIGN (16);
+ } >iram0_0_seg
+
+ .iram0.data :
+ {
+ . = ALIGN(16);
+ *(.iram.data)
+ *(.iram.data*)
+ } >iram0_0_seg AT>ROM
+
+ .iram0.bss (NOLOAD) :
+ {
+ . = ALIGN(16);
+ *(.iram.bss)
+ *(.iram.bss*)
+
+ . = ALIGN(16);
+ _iram_end = ABSOLUTE(.);
+ } >iram0_0_seg
+
+ _image_irom_vma = ADDR(.flash.text);
+ _image_irom_lma = LOADADDR(.flash.text);
+ _image_irom_size = LOADADDR(.flash.text) + SIZEOF(.flash.text) - _image_irom_lma;
+
+ /* The alignment of the ".flash.text" output section is forced to
+ * 0x0000FFFF (64KB) to ensure that it will be allocated at the beginning
+ * of the next available Flash block.
+ * This is required to meet the following constraint from the external
+ * flash MMU:
+ * VMA % 64KB == LMA % 64KB
+ * i.e. the lower 16 bits of both the virtual address (address seen by the
+ * CPU) and the load address (physical address of the external flash) must
+ * be equal.
+ */
+
+ .flash_text_dummy (NOLOAD) : ALIGN(0x0000FFFF)
+ {
+ /* This section is required to skip .flash.rodata area because irom0_0_seg
+ * and drom0_0_seg reflect the same address space on different buses.
+ */
+
+ . = SIZEOF(.flash.rodata);
+ } >irom0_0_seg
+
+ .flash.text : ALIGN(0x0000FFFF)
+ {
+ _stext = .;
+
+ *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
+ *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */
+ *(.fini.literal)
+ *(.fini)
+ *(.gnu.version)
+ . = ALIGN(4);
+
+ _etext = .;
+ } >irom0_0_seg AT>ROM
+
+ .rtc.text :
+ {
+ . = ALIGN(4);
+ *(.rtc.literal .rtc.text)
+ } >rtc_seg AT>ROM
+
+ .rtc.dummy (NOLOAD) :
+ {
+ /* This section is required to skip .rtc.text area because the text and
+ * data segments reflect the same address space on different buses.
+ */
+
+ . = SIZEOF(.rtc.text);
+ } >rtc_seg
+
+ /* RTC BSS section. */
+
+ .rtc.bss (NOLOAD) :
+ {
+ *(.rtc.bss)
+ } >rtc_seg
+
+ .rtc.data :
+ {
+ *(.rtc.data)
+ *(.rtc.rodata)
+
+ /* Whatever is left from the RTC memory is used as a special heap. */
+
+ . = ALIGN (4);
+ _srtcheap = ABSOLUTE(.);
+ } >rtc_seg AT>ROM
+}
diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/scripts/esp32c3_rom.ld b/boards/risc-v/esp32c3/esp32c3-devkit/scripts/esp32c3_rom.ld
index f282eef..d251f5e 100644
--- a/boards/risc-v/esp32c3/esp32c3-devkit/scripts/esp32c3_rom.ld
+++ b/boards/risc-v/esp32c3/esp32c3-devkit/scripts/esp32c3_rom.ld
@@ -297,7 +297,7 @@ PROVIDE( ROM_Boot_Cache_Init = 0x400004c8 );
PROVIDE( Cache_Invalidate_ICache_Items = 0x400004cc );
PROVIDE( Cache_Op_Addr = 0x400004d0 );
PROVIDE( cache_invalidate_addr = 0x400004d4 );
-PROVIDE( Cache_Invalidate_ICache_All = 0x400004d8 );
+PROVIDE( cache_invalidate_icache_all = 0x400004d8 );
PROVIDE( Cache_Mask_All = 0x400004dc );
PROVIDE( Cache_UnMask_Dram0 = 0x400004e0 );
PROVIDE( Cache_Suspend_ICache_Autoload = 0x400004e4 );
@@ -331,8 +331,8 @@ PROVIDE( Cache_Get_DROM_MMU_End = 0x40000550 );
PROVIDE( Cache_Owner_Init = 0x40000554 );
PROVIDE( Cache_Occupy_ICache_MEMORY = 0x40000558 );
PROVIDE( Cache_MMU_Init = 0x4000055c );
-PROVIDE( Cache_Ibus_MMU_Set = 0x40000560 );
-PROVIDE( Cache_Dbus_MMU_Set = 0x40000564 );
+PROVIDE( cache_ibus_mmu_set = 0x40000560 );
+PROVIDE( cache_dbus_mmu_set = 0x40000564 );
PROVIDE( Cache_Count_Flash_Pages = 0x40000568 );
PROVIDE( Cache_Travel_Tag_Memory = 0x4000056c );
PROVIDE( Cache_Get_Virtual_Addr = 0x40000570 );
diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_spiflash.c b/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_spiflash.c
index 15678c4..cef2237 100644
--- a/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_spiflash.c
+++ b/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_spiflash.c
@@ -38,6 +38,9 @@
#include <nuttx/spi/spi.h>
#include <nuttx/mtd/mtd.h>
#include <nuttx/fs/nxffs.h>
+#ifdef CONFIG_BCH
+#include <nuttx/drivers/drivers.h>
+#endif
#include "esp32c3_spiflash.h"
#include "esp32c3-devkit.h"
@@ -46,11 +49,112 @@
* Pre-processor Definitions
****************************************************************************/
+#define ARRAYSIZE(x) (sizeof((x)) / sizeof((x)[0]))
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP32C3_HAVE_OTA_PARTITION
+
+struct ota_partition_s
+{
+ uint32_t offset; /* Partition offset from the beginning of MTD */
+ uint32_t size; /* Partition size in bytes */
+ const char *devpath; /* Partition device path */
+};
+
+#endif
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP32C3_HAVE_OTA_PARTITION
+static int init_ota_partitions(void);
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP32C3_HAVE_OTA_PARTITION
+static const struct ota_partition_s g_ota_partition_table[] =
+{
+ {
+ .offset = CONFIG_ESP32C3_OTA_PRIMARY_SLOT_OFFSET,
+ .size = CONFIG_ESP32C3_OTA_SLOT_SIZE,
+ .devpath = CONFIG_ESP32C3_OTA_PRIMARY_SLOT_DEVPATH
+ },
+ {
+ .offset = CONFIG_ESP32C3_OTA_SECONDARY_SLOT_OFFSET,
+ .size = CONFIG_ESP32C3_OTA_SLOT_SIZE,
+ .devpath = CONFIG_ESP32C3_OTA_SECONDARY_SLOT_DEVPATH
+ },
+ {
+ .offset = CONFIG_ESP32C3_OTA_SCRATCH_OFFSET,
+ .size = CONFIG_ESP32C3_OTA_SCRATCH_SIZE,
+ .devpath = CONFIG_ESP32C3_OTA_SCRATCH_DEVPATH
+ }
+};
+#endif
+
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
+ * Name: init_ota_partitions
+ *
+ * Description:
+ * Initialize partitions that are dedicated to firmware OTA update.
+ *
+ * Input Parameters:
+ * None.
+ *
+ * Returned Value:
+ * Zero on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP32C3_HAVE_OTA_PARTITION
+static int init_ota_partitions(void)
+{
+ FAR struct mtd_dev_s *mtd;
+#ifdef CONFIG_BCH
+ char blockdev[18];
+#endif
+ int ret = OK;
+
+ for (int i = 0; i < ARRAYSIZE(g_ota_partition_table); ++i)
+ {
+ const struct ota_partition_s *part = &g_ota_partition_table[i];
+ mtd = esp32c3_spiflash_alloc_mtdpart(part->offset, part->size);
+
+ ret = ftl_initialize(i, mtd);
+ if (ret < 0)
+ {
+ ferr("ERROR: Failed to initialize the FTL layer: %d\n", ret);
+ return ret;
+ }
+
+#ifdef CONFIG_BCH
+ snprintf(blockdev, 18, "/dev/mtdblock%d", i);
+
+ ret = bchdev_register(blockdev, part->devpath, false);
+ if (ret < 0)
+ {
+ ferr("ERROR: bchdev_register %s failed: %d\n", part->devpath, ret);
+ return ret;
+ }
+#endif
+ }
+
+ return ret;
+}
+#endif
+
+/****************************************************************************
* Name: setup_smartfs
*
* Description:
@@ -403,6 +507,14 @@ int esp32c3_spiflash_init(void)
{
int ret = OK;
+#ifdef CONFIG_ESP32C3_HAVE_OTA_PARTITION
+ ret = init_ota_partitions();
+ if (ret < 0)
+ {
+ return ret;
+ }
+#endif
+
#ifdef CONFIG_ESP32C3_WIFI_SAVE_PARAM
ret = init_wifi_partition();
if (ret < 0)
diff --git a/tools/esp32c3/Config.mk b/tools/esp32c3/Config.mk
index 440becb..4550c6f 100644
--- a/tools/esp32c3/Config.mk
+++ b/tools/esp32c3/Config.mk
@@ -60,36 +60,43 @@ endif
ESPTOOL_FLASH_OPTS := -fs $(FLASH_SIZE) -fm $(FLASH_MODE) -ff $(FLASH_FREQ)
+# Configure the variables according to build environment
+
ifdef ESPTOOL_BINDIR
- BL_OFFSET := 0x0
- PT_OFFSET := 0x8000
- BOOTLOADER := $(ESPTOOL_BINDIR)/bootloader-esp32c3.bin
- PARTITION_TABLE := $(ESPTOOL_BINDIR)/partition-table-esp32c3.bin
- FLASH_BL := $(BL_OFFSET) $(BOOTLOADER)
- FLASH_PT := $(PT_OFFSET) $(PARTITION_TABLE)
- ESPTOOL_BINS := $(FLASH_BL) $(FLASH_PT)
+ ifeq ($(CONFIG_ESP32C3_APP_FORMAT_LEGACY),y)
+ BL_OFFSET := 0x0
+ PT_OFFSET := 0x8000
+ BOOTLOADER := $(ESPTOOL_BINDIR)/bootloader-esp32c3.bin
+ PARTITION_TABLE := $(ESPTOOL_BINDIR)/partition-table-esp32c3.bin
+ FLASH_BL := $(BL_OFFSET) $(BOOTLOADER)
+ FLASH_PT := $(PT_OFFSET) $(PARTITION_TABLE)
+ ESPTOOL_BINS := $(FLASH_BL) $(FLASH_PT)
+ else ifeq ($(CONFIG_ESP32C3_APP_FORMAT_MCUBOOT),y)
+ BL_OFFSET := 0x0
+ BOOTLOADER := $(ESPTOOL_BINDIR)/mcuboot-esp32c3.bin
+ FLASH_BL := $(BL_OFFSET) $(BOOTLOADER)
+ ESPTOOL_BINS := $(FLASH_BL)
+ endif
endif
-ESPTOOL_BINS += 0x10000 nuttx.bin
+ifeq ($(CONFIG_ESP32C3_APP_FORMAT_LEGACY),y)
+ APP_OFFSET := 0x10000
+ APP_IMAGE := nuttx.bin
+ FLASH_APP := $(APP_OFFSET) $(APP_IMAGE)
+else ifeq ($(CONFIG_ESP32C3_APP_FORMAT_MCUBOOT),y)
+ ifeq ($(CONFIG_ESP32C3_ESPTOOL_TARGET_PRIMARY),y)
+ VERIFIED := --confirm
+ APP_OFFSET := $(CONFIG_ESP32C3_OTA_PRIMARY_SLOT_OFFSET)
+ else ifeq ($(CONFIG_ESP32C3_ESPTOOL_TARGET_SECONDARY),y)
+ VERIFIED :=
+ APP_OFFSET := $(CONFIG_ESP32C3_OTA_SECONDARY_SLOT_OFFSET)
+ endif
+
+ APP_IMAGE := nuttx.signed.bin
+ FLASH_APP := $(APP_OFFSET) $(APP_IMAGE)
+endif
-# ELF2IMAGE -- Convert an ELF file into a binary file in Espressif application image format
-
-define ELF2IMAGE
- $(Q) echo "MKIMAGE: ESP32-C3 binary"
- $(Q) if ! esptool.py version 1>/dev/null 2>&1; then \
- echo ""; \
- echo "esptool.py not found. Please run: \"pip install esptool\""; \
- echo ""; \
- echo "Run make again to create the nuttx.bin image."; \
- exit 1; \
- fi
- $(Q) if [ -z $(FLASH_SIZE) ]; then \
- echo "Missing Flash memory size configuration for the ESP32-C3 chip."; \
- exit 1; \
- fi
- esptool.py -c esp32c3 elf2image $(ESPTOOL_FLASH_OPTS) -o nuttx.bin nuttx
- $(Q) echo "Generated: nuttx.bin (ESP32-C3 compatible)"
-endef
+ESPTOOL_BINS += $(FLASH_APP)
# MERGEBIN -- Merge raw binary files into a single file
@@ -114,12 +121,61 @@ define MERGEBIN
endef
endif
+# SIGNBIN -- Sign the binary image file
+
+ifeq ($(CONFIG_ESP32C3_APP_FORMAT_MCUBOOT),y)
+define SIGNBIN
+ $(Q) echo "MKIMAGE: ESP32-C3 binary"
+ $(Q) if ! imgtool version 1>/dev/null 2>&1; then \
+ echo ""; \
+ echo "imgtool not found. Please run: \"pip install imgtool\""; \
+ echo ""; \
+ echo "Run make again to create the nuttx.signed.bin image."; \
+ exit 1; \
+ fi
+ imgtool sign --pad --pad-sig $(VERIFIED) --align 4 -v 0 \
+ -H $(CONFIG_ESP32C3_APP_MCUBOOT_HEADER_SIZE) --pad-header \
+ -S $(CONFIG_ESP32C3_OTA_SLOT_SIZE) \
+ nuttx.bin nuttx.signed.bin
+ $(Q) echo nuttx.signed.bin >> nuttx.manifest
+ $(Q) echo "Generated: nuttx.signed.bin (MCUboot compatible)"
+endef
+endif
+
+# ELF2IMAGE -- Convert an ELF file into a binary file in Espressif application image format
+
+ifeq ($(CONFIG_ESP32C3_APP_FORMAT_LEGACY),y)
+define ELF2IMAGE
+ $(Q) echo "MKIMAGE: ESP32-C3 binary"
+ $(Q) if ! esptool.py version 1>/dev/null 2>&1; then \
+ echo ""; \
+ echo "esptool.py not found. Please run: \"pip install esptool\""; \
+ echo ""; \
+ echo "Run make again to create the nuttx.bin image."; \
+ exit 1; \
+ fi
+ $(Q) if [ -z $(FLASH_SIZE) ]; then \
+ echo "Missing Flash memory size configuration for the ESP32-C3 chip."; \
+ exit 1; \
+ fi
+ esptool.py -c esp32c3 elf2image $(ESPTOOL_FLASH_OPTS) -o nuttx.bin nuttx
+ $(Q) echo "Generated: nuttx.bin (ESP32-C3 compatible)"
+endef
+endif
+
# POSTBUILD -- Perform post build operations
+ifeq ($(CONFIG_ESP32C3_APP_FORMAT_MCUBOOT),y)
+define POSTBUILD
+ $(call SIGNBIN)
+ $(call MERGEBIN)
+endef
+else ifeq ($(CONFIG_ESP32C3_APP_FORMAT_LEGACY),y)
define POSTBUILD
$(call ELF2IMAGE)
$(call MERGEBIN)
endef
+endif
# ESPTOOL_BAUD -- Serial port baud rate used when flashing/reading via esptool.py