mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
tools: add test for ROM symbols in GDB
This commit is contained in:
parent
2e9f175ae5
commit
7561367808
@ -31,6 +31,7 @@
|
||||
- "**/build*/flash_project_args"
|
||||
- "**/build*/config/sdkconfig.json"
|
||||
- "**/build*/bootloader/*.bin"
|
||||
- "**/build*/bootloader/*.elf"
|
||||
- "**/build*/partition_table/*.bin"
|
||||
- $SIZE_INFO_LOCATION
|
||||
when: always
|
||||
|
@ -34,3 +34,11 @@ URL_TO_DOC = 'https://docs.espressif.com/projects/esp-idf'
|
||||
|
||||
SUPPORTED_TARGETS = ['esp32', 'esp32s2', 'esp32c3', 'esp32s3', 'esp32c2']
|
||||
PREVIEW_TARGETS = ['linux', 'esp32h2']
|
||||
|
||||
OPENOCD_TAGET_CONFIG_DEFAULT = '-f interface/ftdi/esp32_devkitj_v1.cfg -f target/{target}.cfg'
|
||||
OPENOCD_TAGET_CONFIG: Dict[str, str] = {
|
||||
'esp32': '-f board/esp32-wrover-kit-3.3v.cfg',
|
||||
'esp32s2': '-f board/esp32s2-kaluga-1.cfg',
|
||||
'esp32c3': '-f board/esp32c3-builtin.cfg',
|
||||
'esp32s3': '-f board/esp32s3-builtin.cfg',
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ from threading import Thread
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from click.core import Context
|
||||
from idf_py_actions.constants import OPENOCD_TAGET_CONFIG, OPENOCD_TAGET_CONFIG_DEFAULT
|
||||
from idf_py_actions.errors import FatalError
|
||||
from idf_py_actions.tools import PropertyDict, ensure_build_directory
|
||||
|
||||
@ -59,6 +60,11 @@ source {connect}
|
||||
'''
|
||||
|
||||
|
||||
def get_openocd_arguments(target: str) -> str:
|
||||
default_args = OPENOCD_TAGET_CONFIG_DEFAULT.format(target=target)
|
||||
return str(OPENOCD_TAGET_CONFIG.get(target, default_args))
|
||||
|
||||
|
||||
def action_extensions(base_actions: Dict, project_path: str) -> Dict:
|
||||
OPENOCD_OUT_FILE = 'openocd_out.txt'
|
||||
GDBGUI_OUT_FILE = 'gdbgui_out.txt'
|
||||
@ -286,12 +292,6 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict:
|
||||
"""
|
||||
Execute openocd as external tool
|
||||
"""
|
||||
OPENOCD_TAGET_CONFIG = {
|
||||
'esp32': '-f board/esp32-wrover-kit-3.3v.cfg',
|
||||
'esp32s2': '-f board/esp32s2-kaluga-1.cfg',
|
||||
'esp32c3': '-f board/esp32c3-builtin.cfg',
|
||||
'esp32s3': '-f board/esp32s3-builtin.cfg',
|
||||
}
|
||||
if os.getenv('OPENOCD_SCRIPTS') is None:
|
||||
raise FatalError('OPENOCD_SCRIPTS not found in the environment: Please run export.sh/export.bat', ctx)
|
||||
openocd_arguments = os.getenv('OPENOCD_COMMANDS') if openocd_commands is None else openocd_commands
|
||||
@ -299,8 +299,7 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict:
|
||||
if openocd_arguments is None:
|
||||
# use default value if commands not defined in the environment nor command line
|
||||
target = project_desc['target']
|
||||
default_args = '-f interface/ftdi/esp32_devkitj_v1.cfg -f target/{}.cfg'.format(target)
|
||||
openocd_arguments = OPENOCD_TAGET_CONFIG.get(target, default_args)
|
||||
openocd_arguments = get_openocd_arguments(target)
|
||||
print('Note: OpenOCD cfg not found (via env variable OPENOCD_COMMANDS nor as a --openocd-commands argument)\n'
|
||||
'OpenOCD arguments default to: "{}"'.format(openocd_arguments))
|
||||
# script directory is taken from the environment by OpenOCD, update only if command line arguments to override
|
||||
@ -405,9 +404,9 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict:
|
||||
"""
|
||||
Synchronous GDB target with text ui mode
|
||||
"""
|
||||
gdb(action, ctx, args, 1, gdbinit, require_openocd)
|
||||
gdb(action, ctx, args, False, 1, gdbinit, require_openocd)
|
||||
|
||||
def gdb(action: str, ctx: Context, args: PropertyDict, gdb_tui: Optional[int], gdbinit: Optional[str], require_openocd: bool) -> None:
|
||||
def gdb(action: str, ctx: Context, args: PropertyDict, batch: bool, gdb_tui: Optional[int], gdbinit: Optional[str], require_openocd: bool) -> None:
|
||||
"""
|
||||
Synchronous GDB target
|
||||
"""
|
||||
@ -420,6 +419,8 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict:
|
||||
args = [gdb, *get_gdb_args(project_desc)]
|
||||
if gdb_tui is not None:
|
||||
args += ['-tui']
|
||||
if batch:
|
||||
args += ['--batch']
|
||||
t = Thread(target=run_gdb, args=(args,))
|
||||
t.start()
|
||||
while True:
|
||||
@ -476,12 +477,17 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict:
|
||||
'callback': gdb,
|
||||
'help': 'Run the GDB.',
|
||||
'options': [
|
||||
{
|
||||
'names': ['--batch'],
|
||||
'help': ('exit after processing gdbinit.\n'),
|
||||
'hidden': True,
|
||||
'is_flag': True,
|
||||
'default': False,
|
||||
},
|
||||
{
|
||||
'names': ['--gdb-tui', '--gdb_tui'],
|
||||
'help':
|
||||
('run gdb in TUI mode\n'),
|
||||
'default':
|
||||
None,
|
||||
'help': ('run gdb in TUI mode\n'),
|
||||
'default': None,
|
||||
}, gdbinit, fail_if_openocd_failed
|
||||
],
|
||||
'order_dependencies': ['all', 'flash'],
|
||||
|
6
tools/test_apps/system/gdb/CMakeLists.txt
Normal file
6
tools/test_apps/system/gdb/CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
||||
# The following lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(gdb)
|
6
tools/test_apps/system/gdb/README.md
Normal file
6
tools/test_apps/system/gdb/README.md
Normal file
@ -0,0 +1,6 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- |
|
||||
|
||||
# IDF GDB test application
|
||||
|
||||
This project tests if `idf.py gdb` works correct
|
3
tools/test_apps/system/gdb/main/CMakeLists.txt
Normal file
3
tools/test_apps/system/gdb/main/CMakeLists.txt
Normal file
@ -0,0 +1,3 @@
|
||||
idf_component_register(SRCS "hello_world_main.c"
|
||||
INCLUDE_DIRS "")
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")
|
46
tools/test_apps/system/gdb/main/hello_world_main.c
Normal file
46
tools/test_apps/system/gdb/main/hello_world_main.c
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_chip_info.h"
|
||||
#include "esp_flash.h"
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
printf("Hello world!\n");
|
||||
|
||||
/* Print chip information */
|
||||
esp_chip_info_t chip_info;
|
||||
uint32_t flash_size;
|
||||
esp_chip_info(&chip_info);
|
||||
printf("This is %s chip with %d CPU core(s), WiFi%s%s, ",
|
||||
CONFIG_IDF_TARGET,
|
||||
chip_info.cores,
|
||||
(chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "",
|
||||
(chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : "");
|
||||
|
||||
printf("silicon revision %d, ", chip_info.revision);
|
||||
if(esp_flash_get_size(NULL, &flash_size) != ESP_OK) {
|
||||
printf("Get flash size failed");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("%uMB %s flash\n", flash_size / (1024 * 1024),
|
||||
(chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external");
|
||||
|
||||
printf("Minimum free heap size: %d bytes\n", esp_get_minimum_free_heap_size());
|
||||
|
||||
for (int i = 10; i >= 0; i--) {
|
||||
printf("Restarting in %d seconds...\n", i);
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
printf("Restarting now.\n");
|
||||
fflush(stdout);
|
||||
esp_restart();
|
||||
}
|
53
tools/test_apps/system/gdb/pytest_gdb.py
Normal file
53
tools/test_apps/system/gdb/pytest_gdb.py
Normal file
@ -0,0 +1,53 @@
|
||||
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
import os
|
||||
import re
|
||||
import signal
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
import pexpect
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
|
||||
try:
|
||||
from idf_py_actions.debug_ext import get_openocd_arguments
|
||||
except ModuleNotFoundError:
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', '..'))
|
||||
from idf_py_actions.debug_ext import get_openocd_arguments
|
||||
|
||||
|
||||
@pytest.mark.supported_targets
|
||||
@pytest.mark.test_jtag_arm
|
||||
def test_idf_gdb(dut: Dut) -> None:
|
||||
# Need to wait a moment to connect via OpenOCD after the hard reset happened.
|
||||
# Along with this check that app runs ok
|
||||
dut.expect('Hello world!')
|
||||
|
||||
# Don't need to have output from UART any more
|
||||
dut.serial.stop_redirect_thread()
|
||||
|
||||
with open(os.path.join(dut.logdir, 'ocd.log'), 'w') as ocd_log:
|
||||
ocd = subprocess.Popen(f'openocd {get_openocd_arguments(dut.target)}', stdout=ocd_log, stderr=ocd_log, shell=True)
|
||||
|
||||
try:
|
||||
gdb_env = os.environ.copy()
|
||||
gdb_env['ESP_IDF_GDB_TESTING'] = '1'
|
||||
|
||||
with open(os.path.join(dut.logdir, 'gdb.log'), 'w') as gdb_log, \
|
||||
pexpect.spawn(f'idf.py -B {dut.app.binary_path} gdb --batch',
|
||||
env=gdb_env,
|
||||
timeout=60,
|
||||
logfile=gdb_log,
|
||||
encoding='utf-8',
|
||||
codec_errors='ignore') as p:
|
||||
p.expect(re.compile(r'add symbol table from file.*bootloader.elf'))
|
||||
p.expect(re.compile(r'add symbol table from file.*rom.elf'))
|
||||
p.expect_exact('hit Temporary breakpoint 1, app_main ()')
|
||||
finally:
|
||||
try:
|
||||
ocd.send_signal(signal.SIGINT)
|
||||
ocd.communicate(timeout=15)
|
||||
except subprocess.TimeoutExpired:
|
||||
ocd.kill()
|
||||
ocd.communicate()
|
Loading…
Reference in New Issue
Block a user