risc-v/esp32c3: Enable booting from MCUboot bootloader

Signed-off-by: Gustavo Henrique Nihei <gustavo.nihei@espressif.com>
This commit is contained in:
Gustavo Henrique Nihei
2021-09-10 13:29:22 -03:00
committed by Xiang Xiao
parent 17ec1d04c0
commit 3c63cb522c
10 changed files with 1009 additions and 64 deletions

View File

@@ -516,13 +516,6 @@ config ESP32C3_UART1_CTSPIN
endif # ESP32C3_UART1 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 endmenu
menu "Real-Time Timer" menu "Real-Time Timer"
@@ -760,7 +753,8 @@ config ESP32C3_WIFI_FS_MOUNTPT
config ESP32C3_WIFI_MTD_OFFSET config ESP32C3_WIFI_MTD_OFFSET
hex "Wi-Fi MTD partition 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 depends on ESP32C3_WIFI_SAVE_PARAM
---help--- ---help---
This is the base address of the Wi-Fi MTD partition. This is the base address of the Wi-Fi MTD partition.
@@ -840,9 +834,50 @@ endmenu # BLE Configuration
menu "SPI Flash configuration" menu "SPI Flash configuration"
depends on ESP32C3_SPIFLASH 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 config ESP32C3_MTD_OFFSET
hex "MTD base address in SPI Flash" hex "MTD base address in SPI Flash"
default 0x180000 default 0x180000 if !ESP32C3_HAVE_OTA_PARTITION
default 0x250000 if ESP32C3_HAVE_OTA_PARTITION
---help--- ---help---
MTD base address in SPI Flash. 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 If this option is enabled, SPI Flash driver read and write functions
will output input parameters and return values (if applicable). will output input parameters and return values (if applicable).
endmenu # ESP32C3_SPIFLASH endmenu # SPI Flash configuration
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
menu "GDMA Configuration" menu "GDMA Configuration"
depends on ESP32C3_DMA depends on ESP32C3_DMA
@@ -909,6 +931,96 @@ config ESP32C3_TICKLESS
select ARCH_HAVE_TICKLESS select ARCH_HAVE_TICKLESS
select SCHED_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" menu "AES accelerator"
depends on ESP32C3_AES_ACCELERATOR depends on ESP32C3_AES_ACCELERATOR

View File

@@ -35,17 +35,83 @@
#include "esp32c3_lowputc.h" #include "esp32c3_lowputc.h"
#include "esp32c3_start.h" #include "esp32c3_start.h"
#include "esp32c3_wdt.h" #include "esp32c3_wdt.h"
#include "hardware/esp32c3_cache_memory.h"
#include "hardware/extmem_reg.h"
/**************************************************************************** /****************************************************************************
* Pre-processor Definitions * Pre-processor Definitions
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_DEBUG_FEATURES #ifdef CONFIG_DEBUG_FEATURES
# define showprogress(c) riscv_lowputc(c) # define showprogress(c) riscv_lowputc(c)
#else #else
# define showprogress(c) # define showprogress(c)
#endif #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 * Public Data
****************************************************************************/ ****************************************************************************/
@@ -56,6 +122,101 @@ uint8_t g_idlestack[CONFIG_IDLETHREAD_STACKSIZE]
aligned_data(16) locate_data(".noinit"); aligned_data(16) locate_data(".noinit");
uint32_t g_idle_topstack = ESP32C3_IDLESTACK_TOP; 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 * Public Functions
****************************************************************************/ ****************************************************************************/
@@ -66,7 +227,14 @@ uint32_t g_idle_topstack = ESP32C3_IDLESTACK_TOP;
void __esp32c3_start(void) 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 */ /* Set CPU frequency */
@@ -88,7 +256,7 @@ void __esp32c3_start(void)
* certain that there are no issues with the state of global variables. * 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; *dest = 0;
} }

View File

@@ -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_ */

View File

@@ -31,8 +31,29 @@
* Pre-processor Definitions * 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_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. /* EXTMEM_CACHE_MMU_MEM_FORCE_ON : R/W ;bitpos:[0] ;default: 1'b1.
* The bit is used to enable clock gating to save * The bit is used to enable clock gating to save

View File

@@ -24,7 +24,11 @@ include $(TOPDIR)/tools/esp32c3/Config.mk
include $(TOPDIR)/arch/risc-v/src/rv32im/Toolchain.defs include $(TOPDIR)/arch/risc-v/src/rv32im/Toolchain.defs
LDSCRIPT1 = $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32c3_out.ld 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 LDSCRIPT3 = $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32c3_rom.ld
ifeq ($(CONFIG_CYGWIN_WINTOOL),y) ifeq ($(CONFIG_CYGWIN_WINTOOL),y)

View File

@@ -47,26 +47,55 @@
#define I_D_SRAM_SIZE SRAM_DRAM_END - SRAM_DRAM_ORG #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 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 * 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 * 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. * 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 iram0_0_seg (RX) : org = SRAM_IRAM_ORG, len = I_D_SRAM_SIZE
/* Flash mapped instruction data. /* Flash mapped instruction data. */
*
* The 0x20 offset is a convenience for the app binary image generation. #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 * 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 * 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 * header. Setting this offset makes it simple to meet the flash cache MMU's
* constraint that (paddr % 64KB == vaddr % 64KB). * 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. */ /* Shared data RAM, excluding memory reserved for ROM bss/data/stack. */
@@ -74,7 +103,32 @@ MEMORY
/* Flash mapped constant data */ /* 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. */ /* RTC fast memory. Persists over deep sleep. */

View File

@@ -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
}

View File

@@ -297,7 +297,7 @@ PROVIDE( ROM_Boot_Cache_Init = 0x400004c8 );
PROVIDE( Cache_Invalidate_ICache_Items = 0x400004cc ); PROVIDE( Cache_Invalidate_ICache_Items = 0x400004cc );
PROVIDE( Cache_Op_Addr = 0x400004d0 ); PROVIDE( Cache_Op_Addr = 0x400004d0 );
PROVIDE( cache_invalidate_addr = 0x400004d4 ); PROVIDE( cache_invalidate_addr = 0x400004d4 );
PROVIDE( Cache_Invalidate_ICache_All = 0x400004d8 ); PROVIDE( cache_invalidate_icache_all = 0x400004d8 );
PROVIDE( Cache_Mask_All = 0x400004dc ); PROVIDE( Cache_Mask_All = 0x400004dc );
PROVIDE( Cache_UnMask_Dram0 = 0x400004e0 ); PROVIDE( Cache_UnMask_Dram0 = 0x400004e0 );
PROVIDE( Cache_Suspend_ICache_Autoload = 0x400004e4 ); PROVIDE( Cache_Suspend_ICache_Autoload = 0x400004e4 );
@@ -331,8 +331,8 @@ PROVIDE( Cache_Get_DROM_MMU_End = 0x40000550 );
PROVIDE( Cache_Owner_Init = 0x40000554 ); PROVIDE( Cache_Owner_Init = 0x40000554 );
PROVIDE( Cache_Occupy_ICache_MEMORY = 0x40000558 ); PROVIDE( Cache_Occupy_ICache_MEMORY = 0x40000558 );
PROVIDE( Cache_MMU_Init = 0x4000055c ); PROVIDE( Cache_MMU_Init = 0x4000055c );
PROVIDE( Cache_Ibus_MMU_Set = 0x40000560 ); PROVIDE( cache_ibus_mmu_set = 0x40000560 );
PROVIDE( Cache_Dbus_MMU_Set = 0x40000564 ); PROVIDE( cache_dbus_mmu_set = 0x40000564 );
PROVIDE( Cache_Count_Flash_Pages = 0x40000568 ); PROVIDE( Cache_Count_Flash_Pages = 0x40000568 );
PROVIDE( Cache_Travel_Tag_Memory = 0x4000056c ); PROVIDE( Cache_Travel_Tag_Memory = 0x4000056c );
PROVIDE( Cache_Get_Virtual_Addr = 0x40000570 ); PROVIDE( Cache_Get_Virtual_Addr = 0x40000570 );

View File

@@ -38,6 +38,9 @@
#include <nuttx/spi/spi.h> #include <nuttx/spi/spi.h>
#include <nuttx/mtd/mtd.h> #include <nuttx/mtd/mtd.h>
#include <nuttx/fs/nxffs.h> #include <nuttx/fs/nxffs.h>
#ifdef CONFIG_BCH
#include <nuttx/drivers/drivers.h>
#endif
#include "esp32c3_spiflash.h" #include "esp32c3_spiflash.h"
#include "esp32c3-devkit.h" #include "esp32c3-devkit.h"
@@ -46,10 +49,111 @@
* Pre-processor Definitions * 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 * 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 * Name: setup_smartfs
* *
@@ -403,6 +507,14 @@ int esp32c3_spiflash_init(void)
{ {
int ret = OK; 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 #ifdef CONFIG_ESP32C3_WIFI_SAVE_PARAM
ret = init_wifi_partition(); ret = init_wifi_partition();
if (ret < 0) if (ret < 0)

View File

@@ -60,36 +60,43 @@ endif
ESPTOOL_FLASH_OPTS := -fs $(FLASH_SIZE) -fm $(FLASH_MODE) -ff $(FLASH_FREQ) ESPTOOL_FLASH_OPTS := -fs $(FLASH_SIZE) -fm $(FLASH_MODE) -ff $(FLASH_FREQ)
# Configure the variables according to build environment
ifdef ESPTOOL_BINDIR ifdef ESPTOOL_BINDIR
BL_OFFSET := 0x0 ifeq ($(CONFIG_ESP32C3_APP_FORMAT_LEGACY),y)
PT_OFFSET := 0x8000 BL_OFFSET := 0x0
BOOTLOADER := $(ESPTOOL_BINDIR)/bootloader-esp32c3.bin PT_OFFSET := 0x8000
PARTITION_TABLE := $(ESPTOOL_BINDIR)/partition-table-esp32c3.bin BOOTLOADER := $(ESPTOOL_BINDIR)/bootloader-esp32c3.bin
FLASH_BL := $(BL_OFFSET) $(BOOTLOADER) PARTITION_TABLE := $(ESPTOOL_BINDIR)/partition-table-esp32c3.bin
FLASH_PT := $(PT_OFFSET) $(PARTITION_TABLE) FLASH_BL := $(BL_OFFSET) $(BOOTLOADER)
ESPTOOL_BINS := $(FLASH_BL) $(FLASH_PT) 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 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
# ELF2IMAGE -- Convert an ELF file into a binary file in Espressif application image format APP_IMAGE := nuttx.signed.bin
FLASH_APP := $(APP_OFFSET) $(APP_IMAGE)
endif
define ELF2IMAGE ESPTOOL_BINS += $(FLASH_APP)
$(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
# MERGEBIN -- Merge raw binary files into a single file # MERGEBIN -- Merge raw binary files into a single file
@@ -114,12 +121,61 @@ define MERGEBIN
endef endef
endif 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 # 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 define POSTBUILD
$(call ELF2IMAGE) $(call ELF2IMAGE)
$(call MERGEBIN) $(call MERGEBIN)
endef endef
endif
# ESPTOOL_BAUD -- Serial port baud rate used when flashing/reading via esptool.py # ESPTOOL_BAUD -- Serial port baud rate used when flashing/reading via esptool.py