Merge branch 'bugfix/esp32s2_ldscripts' into 'master'

esp32s2: LD script fixes/improvements and re-enable SystemView examples

Closes IDF-1357, IDF-1354, and IDF-1346

See merge request espressif/esp-idf!7431
This commit is contained in:
Ivan Grokhotkov 2020-02-05 02:09:29 +08:00
commit 50466a5e4f
12 changed files with 127 additions and 87 deletions

View file

@ -5,8 +5,8 @@
MEMORY
{
iram_loader_seg (RWX) : org = 0x40050000, len = 0x4000 /* 16KB, SRAM Block_14 */
iram_seg (RWX) : org = 0x40054000, len = 0x4000 /* 16KB, SRAM Block_15 */
iram_seg (RWX) : org = 0x40050000, len = 0x4000 /* 16KB, SRAM Block_14 */
iram_loader_seg (RWX) : org = 0x40054000, len = 0x4000 /* 16KB, SRAM Block_15 */
dram_seg (RW) : org = 0x3FFE8000, len = 0x2800 /* 10KB, Top of SRAM Block_16, and before ROM data and stack */
}

View file

@ -244,6 +244,10 @@ menu "ESP32S2-specific"
bool
default "n"
config ESP32S2_MEMMAP_TRACEMEM_TWOBANKS
bool
default "n"
config ESP32S2_TRAX
bool "Use TRAX tracing feature"
default "n"

View file

@ -26,16 +26,16 @@
#define RAM_IRAM_START 0x40020000
#define RAM_DRAM_START 0x3FFB0000
#define DATA_RAM_END 0x3FFF0000 /* start address of bootloader */
#define DATA_RAM_END 0x3FFE4000 /* 2nd stage bootloader iram_loader_seg starts at block 15 */
#define IRAM_ORG (RAM_IRAM_START + CONFIG_ESP32S2_INSTRUCTION_CACHE_SIZE \
+ CONFIG_ESP32S2_DATA_CACHE_SIZE)
#define IRAM_SIZE 0x18000
#define DRAM_ORG (RAM_DRAM_START + CONFIG_ESP32S2_INSTRUCTION_CACHE_SIZE \
+ CONFIG_ESP32S2_DATA_CACHE_SIZE \
+ IRAM_SIZE)
#define DRAM_SIZE DATA_RAM_END - DRAM_ORG
+ CONFIG_ESP32S2_DATA_CACHE_SIZE)
#define I_D_RAM_SIZE DATA_RAM_END - DRAM_ORG
MEMORY
{
@ -44,8 +44,9 @@ MEMORY
are connected to the data port of the CPU and eg allow bytewise access. */
/* IRAM for CPU.*/
iram0_0_seg (RX) : org = IRAM_ORG, len = IRAM_SIZE
iram0_0_seg (RX) : org = IRAM_ORG, len = I_D_RAM_SIZE
#ifdef CONFIG_APP_BUILD_USE_FLASH_SECTIONS
/* Even though the segment name is iram, it is actually mapped to flash
*/
iram0_2_seg (RX) : org = 0x40080020, len = 0x780000-0x20
@ -57,15 +58,18 @@ MEMORY
header. Setting this offset makes it simple to meet the flash cache MMU's
constraint that (paddr % 64KB == vaddr % 64KB).)
*/
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
/* Shared data RAM, excluding memory reserved for bootloader and ROM bss/data/stack. */
dram0_0_seg (RW) : org = DRAM_ORG, len = DRAM_SIZE
dram0_0_seg (RW) : org = DRAM_ORG, len = I_D_RAM_SIZE
#ifdef CONFIG_APP_BUILD_USE_FLASH_SECTIONS
/* Flash mapped constant data */
drom0_0_seg (R) : org = 0x3F000020, len = 0x3f0000-0x20
/* (See iram0_2_seg for meaning of 0x20 offset in the above.) */
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
/* RTC fast memory (executable). Persists over deep sleep.
*/
@ -84,11 +88,7 @@ MEMORY
_static_data_end = _bss_end;
/* Heap ends at top of dram0_0_seg
ROM data mappings start from 0x3FFFC000,
0x3FFF4000...0x3FFFC000 can be reserved for trace memory mapping
*/
_heap_end = 0x3FFFC000 - CONFIG_ESP32S2_TRACEMEM_RESERVE_DRAM;
_heap_end = 0x40000000;
_data_seg_org = ORIGIN(rtc_data_seg);
@ -101,3 +101,15 @@ REGION_ALIAS("rtc_data_location", rtc_slow_seg );
#else
REGION_ALIAS("rtc_data_location", rtc_data_seg );
#endif
#ifdef CONFIG_APP_BUILD_USE_FLASH_SECTIONS
REGION_ALIAS("default_code_seg", iram0_2_seg);
#else
REGION_ALIAS("default_code_seg", iram0_0_seg);
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
#ifdef CONFIG_APP_BUILD_USE_FLASH_SECTIONS
REGION_ALIAS("default_rodata_seg", drom0_0_seg);
#else
REGION_ALIAS("default_rodata_seg", dram0_0_seg);
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS

View file

@ -164,8 +164,10 @@ SECTIONS
_iram_end = ABSOLUTE(.);
} > iram0_0_seg
ASSERT(((_iram_text_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)),
"IRAM0 segment data does not fit.")
.dram0_reserved_for_iram (NOLOAD):
{
. = ORIGIN(dram0_0_seg) + _iram_end - _iram_start;
} > dram0_0_seg
.dram0.data :
{
@ -243,9 +245,6 @@ SECTIONS
_heap_start = ABSOLUTE(.);
} > dram0_0_seg
ASSERT(((_bss_end - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)),
"DRAM segment data does not fit.")
/* When modifying the alignment, update tls_section_alignment in pxPortInitialiseStack */
.flash.rodata : ALIGN(0x10)
{
@ -307,7 +306,7 @@ SECTIONS
*(.tbss.*)
_thread_local_end = ABSOLUTE(.);
. = ALIGN(4);
} >drom0_0_seg
} >default_rodata_seg
.flash.text :
{
@ -329,5 +328,25 @@ SECTIONS
the flash.text segment.
*/
_flash_cache_start = ABSOLUTE(0);
} >iram0_2_seg
} >default_code_seg
/* Marks the end of IRAM code segment */
.iram0.text_end (NOLOAD) :
{
. = ALIGN (4);
_iram_end = ABSOLUTE(.);
} > iram0_0_seg
/* Marks the end of data, bss and possibly rodata */
.dram0.heap_start (NOLOAD) :
{
. = ALIGN (8);
_heap_start = ABSOLUTE(.);
} > dram0_0_seg
}
ASSERT(((_iram_text_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)),
"IRAM0 segment data does not fit.")
ASSERT(((_heap_start - _data_start) <= LENGTH(dram0_0_seg)),
"DRAM segment data does not fit.")

View file

@ -177,4 +177,13 @@ SOC_RESERVE_MEMORY_REGION(0x3fffc000, 0x40000000, trace_mem); //Reserve trace me
SOC_RESERVE_MEMORY_REGION(SOC_EXTRAM_DATA_LOW, SOC_EXTRAM_DATA_LOW + RESERVE_SPIRAM_SIZE, spi_ram); //SPI RAM gets added later if needed, in spiram.c; reserve it for now
#endif
extern int _data_start, _heap_start, _iram_start, _iram_end;
// Static data region. DRAM used by data+bss and possibly rodata
SOC_RESERVE_MEMORY_REGION((intptr_t)&_data_start, (intptr_t)&_heap_start, dram_data);
// IRAM code region
// ESP32 has an IRAM-only region 0x4008_0000 - 0x4009_FFFF, reserve the used part
SOC_RESERVE_MEMORY_REGION((intptr_t)&_iram_start, (intptr_t)&_iram_end, iram_code);
#endif /* BOOTLOADER_BUILD */

View file

@ -70,36 +70,44 @@ const char * const esp_isr_names[ETS_MAX_INTR_SOURCE] = {
[52] = "I2C_EXT0",
[53] = "I2C_EXT1",
[54] = "RSA",
[55] = "SPI1_DMA",
[56] = "SPI2_DMA",
[57] = "SPI3_DMA",
[58] = "WDT",
[59] = "TIMER1",
[60] = "TIMER2",
[61] = "TG0_T0_EDGE",
[62] = "TG0_T1_EDGE",
[63] = "TG0_WDT_EDGE",
[64] = "TG0_LACT_EDGE",
[65] = "TG1_T0_EDGE",
[66] = "TG1_T1_EDGE",
[67] = "TG1_WDT_EDGE",
[68] = "TG1_LACT_EDGE",
[69] = "CACHE_IA",
[70] = "SYSTIMER_TARGET0",
[71] = "SYSTIMER_TARGET1",
[72] = "SYSTIMER_TARGET2",
[73] = "ASSIST_DEBUG",
[74] = "PMS_PRO_IRAM0_ILG",
[75] = "PMS_PRO_DRAM0_ILG",
[76] = "PMS_PRO_DPORT_ILG",
[77] = "PMS_PRO_AHB_ILG",
[78] = "PMS_PRO_CACHE_ILG",
[79] = "PMS_DMA_APB_I_ILG",
[80] = "PMS_DMA_RX_I_ILG",
[81] = "PMS_DMA_TX_I_ILG",
[82] = "SPI0_REJECT_CACHE",
[83] = "SPI1_REJECT_CPU",
[55] = "SHA",
[56] = "AES",
[57] = "SPI2_DMA",
[58] = "SPI3_DMA",
[59] = "WDT",
[60] = "TIMER1",
[61] = "TIMER2",
[62] = "TG0_T0_EDGE",
[63] = "TG0_T1_EDGE",
[64] = "TG0_WDT_EDGE",
[65] = "TG0_LACT_EDGE",
[66] = "TG1_T0_EDGE",
[67] = "TG1_T1_EDGE",
[68] = "TG1_WDT_EDGE",
[69] = "TG1_LACT_EDGE",
[70] = "CACHE_IA",
[71] = "SYSTIMER_TARGET0",
[72] = "SYSTIMER_TARGET1",
[73] = "SYSTIMER_TARGET2",
[74] = "ASSIST_DEBUG",
[75] = "PMS_PRO_IRAM0_ILG",
[76] = "PMS_PRO_DRAM0_ILG",
[77] = "PMS_PRO_DPORT_ILG",
[78] = "PMS_PRO_AHB_ILG",
[79] = "PMS_PRO_CACHE_ILG",
[80] = "PMS_DMA_APB_I_ILG",
[81] = "PMS_DMA_RX_I_ILG",
[82] = "PMS_DMA_TX_I_ILG",
[83] = "SPI0_REJECT_CACHE",
[84] = "DMA_COPY",
[85] = "SPI4_DMA",
[86] = "SPI4",
[87] = "ICACHE_PRELOAD",
[88] = "DCACHE_PRELOAD",
[89] = "APB_ADC",
[90] = "CRYPTO_DMA",
[91] = "CPU_PERI_ERR",
[92] = "APB_PERI_ERR",
[93] = "DCACHE_SYNC",
[94] = "ICACHE_SYNC",
};

View file

@ -109,6 +109,8 @@ const size_t soc_memory_region_count = sizeof(soc_memory_regions)/sizeof(soc_mem
extern int _dram0_rtos_reserved_start;
extern int _data_start, _heap_start, _iram_start, _iram_end;
/* Reserved memory regions
These are removed from the soc_memory_regions array when heaps are created.
@ -116,11 +118,21 @@ extern int _dram0_rtos_reserved_start;
//ROM data region
SOC_RESERVE_MEMORY_REGION((intptr_t)&_dram0_rtos_reserved_start, SOC_BYTE_ACCESSIBLE_HIGH, rom_data_region);
// TODO: soc_memory_layout: handle trace memory regions - IDF-750
// Static data region. DRAM used by data+bss and possibly rodata
SOC_RESERVE_MEMORY_REGION((intptr_t)&_data_start, (intptr_t)&_heap_start, dram_data);
// ESP32S2 has a big D/IRAM region, the part used by code is reserved
// The address of the D/I bus are in the same order, directly shift IRAM address to get reserved DRAM address
#define I_D_OFFSET (SOC_IRAM_LOW - SOC_DRAM_LOW)
SOC_RESERVE_MEMORY_REGION((intptr_t)&_iram_start - I_D_OFFSET, (intptr_t)&_iram_end - I_D_OFFSET, iram_code);
#ifdef CONFIG_SPIRAM
SOC_RESERVE_MEMORY_REGION( SOC_EXTRAM_DATA_LOW, SOC_EXTRAM_DATA_HIGH, extram_data_region); //SPI RAM gets added later if needed, in spiram.c; reserve it for now
#endif
// Blocks 19 and 20 may be reserved for the trace memory
#if CONFIG_ESP32S2_TRACEMEM_RESERVE_DRAM > 0
SOC_RESERVE_MEMORY_REGION(0x3fffc000 - CONFIG_ESP32S2_TRACEMEM_RESERVE_DRAM, 0x3fffc000, trace_mem);
#endif
#endif // BOOTLOADER_BUILD

View file

@ -26,20 +26,10 @@ static const char *TAG = "memory_layout";
extern soc_reserved_region_t soc_reserved_memory_region_start;
extern soc_reserved_region_t soc_reserved_memory_region_end;
/*
These variables have the start and end of the data and static IRAM
area used by the program. Defined in the linker script.
*/
extern int _data_start, _heap_start, _iram_start, _iram_end;
/* static DRAM & IRAM chunks */
static const size_t EXTRA_RESERVED_REGIONS = 2;
static size_t s_get_num_reserved_regions(void)
{
return ( ( &soc_reserved_memory_region_end
- &soc_reserved_memory_region_start ) +
EXTRA_RESERVED_REGIONS );
return ( &soc_reserved_memory_region_end
- &soc_reserved_memory_region_start );
}
size_t soc_get_available_memory_region_max_count(void)
@ -63,26 +53,7 @@ static int s_compare_reserved_regions(const void *a, const void *b)
*/
static void s_prepare_reserved_regions(soc_reserved_region_t *reserved, size_t count)
{
memcpy(reserved + EXTRA_RESERVED_REGIONS,
&soc_reserved_memory_region_start,
(count - EXTRA_RESERVED_REGIONS) * sizeof(soc_reserved_region_t));
/* Add the EXTRA_RESERVED_REGIONS at the beginning */
reserved[0].start = (intptr_t)&_data_start; /* DRAM used by data+bss and possibly rodata */
reserved[0].end = (intptr_t)&_heap_start;
#if CONFIG_IDF_TARGET_ESP32
//ESP32 has a IRAM-only region 0x4008_0000 - 0x4009_FFFF, protect the used part
reserved[1].start = (intptr_t)&_iram_start; /* IRAM used by code */
reserved[1].end = (intptr_t)&_iram_end;
#elif CONFIG_IDF_TARGET_ESP32S2
//ESP32S2 has a big D/IRAM region, the part used by code is reserved
//The address of the D/I bus are in the same order, directly shift IRAM address to get reserved DRAM address
const uint32_t i_d_offset = SOC_IRAM_LOW - SOC_DRAM_LOW;
reserved[1].start = (intptr_t)&_iram_start - i_d_offset; /* IRAM used by code */
reserved[1].end = (intptr_t)&_iram_end - i_d_offset;
#else
# error chip not implemented!
#endif
memcpy(reserved, &soc_reserved_memory_region_start, count * sizeof(soc_reserved_region_t));
/* Sort by starting address */
qsort(reserved, count, sizeof(soc_reserved_region_t), s_compare_reserved_regions);

View file

@ -2,6 +2,5 @@
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
set(SUPPORTED_TARGETS esp32)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(sysview_tracing)

View file

@ -119,11 +119,15 @@ NOTE: In order to run this example you need OpenOCD version `v0.10.0-esp32-20181
Using this file GDB will connect to the target, reset it, and start tracing when it hit breakpoint at `app_main`. Trace data will be saved to `/tmp/sysview_example.svdat`.
**Note:** if running the example on ESP32-S2, modify the command name in gdbinit file from `esp32 sysview` to `esp32_s2 sysview`.
6. Run GDB using the following command from the project root directory:
```
xtensa-esp32-elf-gdb -x gdbinit build/sysview_tracing.elf
```
```
**Note:** Replace `xtensa-esp32-elf-gdb` with `xtensa-esp32s2-elf-gdb` if running the example on ESP32-S2.
7. When program prints the last message, interrupt its execution (e.g. by pressing `CTRL+C`) and type the following command in GDB console to stop tracing:

View file

@ -2,6 +2,5 @@
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
set(SUPPORTED_TARGETS esp32)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(sysview_tracing_heap_log)

View file

@ -40,6 +40,9 @@ To run the example and collect trace data:
```
xtensa-esp32-elf-gdb -x gdbinit build/sysview_tracing_heap_log.elf
```
**Note**: if running the example on ESP32-S2, modify the command name in gdbinit file from `esp32 sysview` to `esp32_s2 sysview`, and run `xtensa-esp32s2-elf-gdb` instead of `xtensa-esp32-elf-gdb`.
2. When program stops at `heap_trace_stop` quit GDB.
3. Open trace data file in SystemView tool.