mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Add JTAG related example tests
This commit is contained in:
parent
d73470a8a6
commit
79e58eff8f
7
.gitignore
vendored
7
.gitignore
vendored
@ -45,6 +45,11 @@ tools/unit-test-app/test_configs
|
|||||||
# Unit Test CMake compile log folder
|
# Unit Test CMake compile log folder
|
||||||
log_ut_cmake
|
log_ut_cmake
|
||||||
|
|
||||||
|
# test application build files
|
||||||
|
tools/test_apps/**/build
|
||||||
|
tools/test_apps/**/sdkconfig
|
||||||
|
tools/test_apps/**/sdkconfig.old
|
||||||
|
|
||||||
# IDF monitor test
|
# IDF monitor test
|
||||||
tools/test_idf_monitor/outputs
|
tools/test_idf_monitor/outputs
|
||||||
|
|
||||||
@ -77,4 +82,4 @@ flake8_output.txt
|
|||||||
build
|
build
|
||||||
|
|
||||||
# lock files for examples and components
|
# lock files for examples and components
|
||||||
dependencies.lock
|
dependencies.lock
|
||||||
|
50
examples/system/app_trace_to_host/example_test.py
Normal file
50
examples/system/app_trace_to_host/example_test.py
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import ttfw_idf
|
||||||
|
|
||||||
|
|
||||||
|
@ttfw_idf.idf_example_test(env_tag="test_jtag_arm")
|
||||||
|
def test_examples_app_trace_to_host(env, extra_data):
|
||||||
|
|
||||||
|
rel_project_path = os.path.join('examples', 'system', 'app_trace_to_host')
|
||||||
|
dut = env.get_dut('app_trace_to_host', rel_project_path)
|
||||||
|
idf_path = dut.app.get_sdk_path()
|
||||||
|
proj_path = os.path.join(idf_path, rel_project_path)
|
||||||
|
|
||||||
|
with ttfw_idf.OCDProcess(os.path.join(proj_path, 'openocd.log')):
|
||||||
|
with ttfw_idf.TelnetProcess(os.path.join(proj_path, 'telnet.log')) as telnet_p:
|
||||||
|
dut.start_app()
|
||||||
|
dut.expect_all('example: Enabling ADC1 on channel 6 / GPIO34.',
|
||||||
|
'example: Enabling CW generator on DAC channel 1',
|
||||||
|
'example: Custom divider of RTC 8 MHz clock has been set.',
|
||||||
|
'example: Sampling ADC and sending data to the host...',
|
||||||
|
re.compile(r'example: Collected \d+ samples in 20 ms.'),
|
||||||
|
'example: Sampling ADC and sending data to the UART...',
|
||||||
|
re.compile(r'example: Sample:\d, Value:\d+'),
|
||||||
|
re.compile(r'example: Collected \d+ samples in 20 ms.'),
|
||||||
|
timeout=20)
|
||||||
|
|
||||||
|
telnet_p.pexpect_proc.sendline('esp apptrace start file://adc.log 0 9000 5 0 0')
|
||||||
|
telnet_p.pexpect_proc.expect_exact('App trace params: from 2 cores, size 9000 bytes, '
|
||||||
|
'stop_tmo 5 s, poll period 0 ms, wait_rst 0, skip 0 bytes')
|
||||||
|
telnet_p.pexpect_proc.expect_exact('Targets connected.')
|
||||||
|
telnet_p.pexpect_proc.expect_exact('Targets disconnected.')
|
||||||
|
telnet_p.pexpect_proc.expect_exact('Tracing is STOPPED. Size is 9000 of 9000 @')
|
||||||
|
telnet_p.pexpect_proc.expect_exact('Data: blocks incomplete 0, lost bytes: 0')
|
||||||
|
|
||||||
|
with ttfw_idf.CustomProcess(' '.join([os.path.join(idf_path, 'tools/esp_app_trace/logtrace_proc.py'),
|
||||||
|
'adc.log',
|
||||||
|
os.path.join(dut.app.get_binary_path(rel_project_path),
|
||||||
|
'app_trace_to_host.elf')]),
|
||||||
|
logfile='logtrace_proc.log') as logtrace:
|
||||||
|
logtrace.pexpect_proc.expect_exact('Parse trace file')
|
||||||
|
logtrace.pexpect_proc.expect_exact('Parsing completed.')
|
||||||
|
logtrace.pexpect_proc.expect_exact('====================================================================')
|
||||||
|
logtrace.pexpect_proc.expect(re.compile(r'example: Sample:\d+, Value:\d+'))
|
||||||
|
logtrace.pexpect_proc.expect_exact('====================================================================')
|
||||||
|
logtrace.pexpect_proc.expect(re.compile(r'Log records count: \d+'))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
test_examples_app_trace_to_host()
|
1
examples/system/app_trace_to_host/sdkconfig.ci
Normal file
1
examples/system/app_trace_to_host/sdkconfig.ci
Normal file
@ -0,0 +1 @@
|
|||||||
|
CONFIG_CUSTOM_RTC_CLK_8M_DIV=y
|
@ -102,41 +102,20 @@ some_dummy_func: Counter = 20
|
|||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
### Generating Lcov Report
|
### Generating Gcovr Report
|
||||||
|
|
||||||
After dumping one or more times, a coverage report can be generated by calling `cmake --build build/ --target lcov-report`. This should result in an HTML code coverage report being generated in the build directory.
|
After dumping one or more times, a coverage report can be generated by calling `cmake --build build/ --target gcovr-report`. This should result in an HTML code coverage report being generated in the build directory.
|
||||||
|
|
||||||
To clean Gcov and report related data from the build directory, call `cmake --build build/ --target cov-data-clean`
|
To clean Gcov and report related data from the build directory, call `cmake --build build/ --target cov-data-clean`
|
||||||
|
|
||||||
**Note:** Currently, the CMake build system on Windows does not support Lcov. However, Lcov is available in MINGW (installed through package manager). Therefore, if the project is built using the legacy GNU Make build system, call `make lcov-report` or `make cov-data-clean` instead.
|
|
||||||
|
|
||||||
The following log should be output when generating the coverage report:
|
The following log should be output when generating the coverage report:
|
||||||
|
|
||||||
```
|
```
|
||||||
[1/1] Generating coverage report in: /home/user/projects/esp/tmp_idf/esp-idf/examples/system/gcov/build/coverage_report
|
[1/2] Generating coverage report in: /home/user/esp/esp-idf/examples/system/gcov/build/coverage_report
|
||||||
Using gcov: xtensa-esp32-elf-gcov
|
Using gcov: xtensa-esp32-elf-gcov
|
||||||
Capturing coverage data from /home/user/projects/esp/tmp_idf/esp-idf/examples/system/gcov/build
|
[2/2] cd /home/user/esp/esp-idf/examples/system/gcov/build && gcovr -r /home/user/esp/esp-idf/examples/system/gcov...a-esp32-elf-gcov -s --html-details /home/user/esp/esp-idf/examples/system/gcov/build/coverage_report/html/index.htm
|
||||||
Found gcov version: 8.2.0
|
lines: 100.0% (27 out of 27)
|
||||||
Using intermediate gcov format
|
branches: 100.0% (2 out of 2)
|
||||||
Scanning /home/user/projects/esp/tmp_idf/esp-idf/examples/system/gcov/build for .gcda files ...
|
|
||||||
Found 3 data files in /home/user/projects/esp/tmp_idf/esp-idf/examples/system/gcov/build
|
|
||||||
Processing sample/CMakeFiles/__idf_sample.dir/some_funcs.c.gcda
|
|
||||||
Processing main/CMakeFiles/__idf_main.dir/gcov_example_func.c.gcda
|
|
||||||
Processing main/CMakeFiles/__idf_main.dir/gcov_example_main.c.gcda
|
|
||||||
Finished .info-file creation
|
|
||||||
Reading data file /home/user/projects/esp/tmp_idf/esp-idf/examples/system/gcov/build/coverage_report/gcov_example.info
|
|
||||||
Found 4 entries.
|
|
||||||
Found common filename prefix "/home/user/projects/esp/tmp_idf/esp-idf/examples/system/gcov"
|
|
||||||
Writing .css and .png files.
|
|
||||||
Generating output.
|
|
||||||
Processing file /home/user/projects/esp/tmp_idf/esp-idf/components/freertos/include/freertos/task.h
|
|
||||||
Processing file components/sample/some_funcs.c
|
|
||||||
Processing file main/gcov_example_main.c
|
|
||||||
Processing file main/gcov_example_func.c
|
|
||||||
Writing directory view page.
|
|
||||||
Overall coverage rate:
|
|
||||||
lines......: 100.0% (28 of 28 lines)
|
|
||||||
functions..: 100.0% (4 of 4 functions)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
@ -162,6 +141,10 @@ This issue can be resolved in the following ways:
|
|||||||
* Reset the board by issuing the `reset` command via telnet
|
* Reset the board by issuing the `reset` command via telnet
|
||||||
* Restart OpenOCD
|
* Restart OpenOCD
|
||||||
|
|
||||||
### Outdated Lcov
|
### gcovr not found
|
||||||
|
|
||||||
Due to `lcov` not being part of the GCC bundle, it is possible that the format of the GCOV binary data can change resulting in `lcov` failing to understand it. Therefore, it is always better to use the latest `lcov` version from the [Lcov repo](https://github.com/linux-test-project/lcov).
|
gcovr can be installed from the package database of your operating system or directly as a Python package, e.g:
|
||||||
|
|
||||||
|
```
|
||||||
|
python -m pip install gcovr
|
||||||
|
```
|
||||||
|
53
examples/system/gcov/example_test.py
Normal file
53
examples/system/gcov/example_test.py
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
from pexpect import TIMEOUT
|
||||||
|
from ttfw_idf import Utility
|
||||||
|
import os
|
||||||
|
import ttfw_idf
|
||||||
|
|
||||||
|
|
||||||
|
@ttfw_idf.idf_example_test(env_tag="test_jtag_arm")
|
||||||
|
def test_examples_gcov(env, extra_data):
|
||||||
|
|
||||||
|
rel_project_path = os.path.join('examples', 'system', 'gcov')
|
||||||
|
dut = env.get_dut('gcov', rel_project_path)
|
||||||
|
idf_path = dut.app.get_sdk_path()
|
||||||
|
proj_path = os.path.join(idf_path, rel_project_path)
|
||||||
|
|
||||||
|
with ttfw_idf.OCDProcess(os.path.join(proj_path, 'openocd.log')):
|
||||||
|
with ttfw_idf.TelnetProcess(os.path.join(proj_path, 'telnet.log')) as telnet_p:
|
||||||
|
dut.start_app()
|
||||||
|
|
||||||
|
def expect_counter_output(loop, timeout=10):
|
||||||
|
dut.expect_all('blink_dummy_func: Counter = {}'.format(loop),
|
||||||
|
'some_dummy_func: Counter = {}'.format(loop * 2),
|
||||||
|
timeout=timeout)
|
||||||
|
|
||||||
|
expect_counter_output(0, timeout=20)
|
||||||
|
dut.expect('Ready to dump GCOV data...', timeout=5)
|
||||||
|
|
||||||
|
def dump_coverage():
|
||||||
|
try:
|
||||||
|
telnet_p.pexpect_proc.sendline('esp gcov dump')
|
||||||
|
telnet_p.pexpect_proc.expect_exact('Targets connected.')
|
||||||
|
telnet_p.pexpect_proc.expect_exact('gcov_example_main.c.gcda')
|
||||||
|
telnet_p.pexpect_proc.expect_exact('gcov_example_func.c.gcda')
|
||||||
|
telnet_p.pexpect_proc.expect_exact('some_funcs.c.gcda')
|
||||||
|
telnet_p.pexpect_proc.expect_exact('Targets disconnected.')
|
||||||
|
except TIMEOUT:
|
||||||
|
# Print what is happening with DUT. Limit the size if it is in loop and generating output.
|
||||||
|
Utility.console_log(dut.read(size=1000))
|
||||||
|
raise
|
||||||
|
|
||||||
|
dump_coverage()
|
||||||
|
dut.expect('GCOV data have been dumped.', timeout=5)
|
||||||
|
expect_counter_output(1)
|
||||||
|
dut.expect('Ready to dump GCOV data...', timeout=5)
|
||||||
|
dump_coverage()
|
||||||
|
dut.expect('GCOV data have been dumped.', timeout=5)
|
||||||
|
|
||||||
|
for i in range(2, 6):
|
||||||
|
expect_counter_output(i)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
test_examples_gcov()
|
1
examples/system/gcov/sdkconfig.ci
Normal file
1
examples/system/gcov/sdkconfig.ci
Normal file
@ -0,0 +1 @@
|
|||||||
|
CONFIG_FREERTOS_UNICORE=y
|
@ -65,7 +65,7 @@ static void example_task(void *p)
|
|||||||
|
|
||||||
Potential problem can arise in such program because task and timer has no any mechanism to acknowledge the events transfer. Task needs some time to process an event before waiting for the next one. In this case call to `ESP_LOGI` will be the most time consuming part of event processing. Therefore when timer's ISR is called at some rate it can happen that `xTaskNotifyFromISR` gets called several times before task calls `xTaskNotifyWait`. In these conditions some events will be lost. Possible solution for this is to increase timer's tick period or to use some events acknowledgement mechanism.
|
Potential problem can arise in such program because task and timer has no any mechanism to acknowledge the events transfer. Task needs some time to process an event before waiting for the next one. In this case call to `ESP_LOGI` will be the most time consuming part of event processing. Therefore when timer's ISR is called at some rate it can happen that `xTaskNotifyFromISR` gets called several times before task calls `xTaskNotifyWait`. In these conditions some events will be lost. Possible solution for this is to increase timer's tick period or to use some events acknowledgement mechanism.
|
||||||
|
|
||||||
Check the full example code [sysview_tracing](main/sysview_tracing.c) that when compiled in dual core mode reproduces the described problem on both cores. Below is the output of example compiled in signle core mode. It shows that task misses several events:
|
Check the full example code [sysview_tracing](main/sysview_tracing.c) that when compiled in dual core mode reproduces the described problem on both cores. Below is the output of example compiled in single core mode. It shows that task misses several events:
|
||||||
|
|
||||||
```
|
```
|
||||||
I (295) example: 0x3ffb6c10: run task
|
I (295) example: 0x3ffb6c10: run task
|
||||||
|
60
examples/system/sysview_tracing/example_test.py
Normal file
60
examples/system/sysview_tracing/example_test.py
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
from io import open
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import tempfile
|
||||||
|
import ttfw_idf
|
||||||
|
|
||||||
|
|
||||||
|
@ttfw_idf.idf_example_test(env_tag="test_jtag_arm")
|
||||||
|
def test_examples_sysview_tracing(env, extra_data):
|
||||||
|
|
||||||
|
rel_project_path = os.path.join('examples', 'system', 'sysview_tracing')
|
||||||
|
dut = env.get_dut('sysview_tracing', rel_project_path)
|
||||||
|
idf_path = dut.app.get_sdk_path()
|
||||||
|
proj_path = os.path.join(idf_path, rel_project_path)
|
||||||
|
elf_path = os.path.join(dut.app.get_binary_path(rel_project_path), 'sysview_tracing.elf')
|
||||||
|
|
||||||
|
def get_temp_file():
|
||||||
|
with tempfile.NamedTemporaryFile(delete=False) as f:
|
||||||
|
return f.name
|
||||||
|
|
||||||
|
try:
|
||||||
|
tempfiles = [get_temp_file(), get_temp_file()]
|
||||||
|
|
||||||
|
with open(os.path.join(proj_path, 'gdbinit')) as f_in, open(tempfiles[0], 'w') as f_out:
|
||||||
|
new_content = f_in.read()
|
||||||
|
# localhost connection issue occurs in docker unless:
|
||||||
|
new_content = new_content.replace(':3333', '127.0.0.1:3333', 1)
|
||||||
|
new_content = new_content.replace('file:///tmp/sysview_example.svdat', 'file://{}'.format(tempfiles[1]), 1)
|
||||||
|
f_out.write(new_content)
|
||||||
|
|
||||||
|
with ttfw_idf.OCDProcess(os.path.join(proj_path, 'openocd.log')):
|
||||||
|
dut.start_app()
|
||||||
|
|
||||||
|
def dut_expect_task_event():
|
||||||
|
dut.expect(re.compile(r'example: Task\[0x3[0-9A-Fa-f]+\]: received event \d+'), timeout=30)
|
||||||
|
|
||||||
|
dut_expect_task_event()
|
||||||
|
|
||||||
|
gdb_args = '-x {} --directory={}'.format(tempfiles[0], os.path.join(proj_path, 'main'))
|
||||||
|
with ttfw_idf.GDBProcess(os.path.join(proj_path, 'gdb.log'), elf_path, dut.app.target, gdb_args) as gdb:
|
||||||
|
gdb.pexpect_proc.expect_exact('Thread 1 hit Breakpoint 1, app_main ()')
|
||||||
|
gdb.pexpect_proc.expect_exact('Targets connected.')
|
||||||
|
gdb.pexpect_proc.expect(re.compile(r'\d+'))
|
||||||
|
|
||||||
|
dut.expect('example: Created task') # dut has been restarted by gdb since the last dut.expect()
|
||||||
|
dut_expect_task_event()
|
||||||
|
|
||||||
|
gdb.pexpect_proc.sendcontrol('c')
|
||||||
|
gdb.pexpect_proc.expect_exact('(gdb)')
|
||||||
|
finally:
|
||||||
|
for x in tempfiles:
|
||||||
|
try:
|
||||||
|
os.unlink(x)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
test_examples_sysview_tracing()
|
@ -1,3 +1,4 @@
|
|||||||
|
set pagination off
|
||||||
target remote :3333
|
target remote :3333
|
||||||
|
|
||||||
mon reset halt
|
mon reset halt
|
||||||
|
59
examples/system/sysview_tracing_heap_log/example_test.py
Normal file
59
examples/system/sysview_tracing_heap_log/example_test.py
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
from io import open
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import tempfile
|
||||||
|
import ttfw_idf
|
||||||
|
|
||||||
|
|
||||||
|
@ttfw_idf.idf_example_test(env_tag="test_jtag_arm")
|
||||||
|
def test_examples_sysview_tracing_heap_log(env, extra_data):
|
||||||
|
|
||||||
|
rel_project_path = os.path.join('examples', 'system', 'sysview_tracing_heap_log')
|
||||||
|
dut = env.get_dut('sysview_tracing_heap_log', rel_project_path)
|
||||||
|
idf_path = dut.app.get_sdk_path()
|
||||||
|
proj_path = os.path.join(idf_path, rel_project_path)
|
||||||
|
elf_path = os.path.join(dut.app.get_binary_path(rel_project_path), 'sysview_tracing_heap_log.elf')
|
||||||
|
|
||||||
|
def get_temp_file():
|
||||||
|
with tempfile.NamedTemporaryFile(delete=False) as f:
|
||||||
|
return f.name
|
||||||
|
|
||||||
|
try:
|
||||||
|
tempfiles = [get_temp_file(), get_temp_file()]
|
||||||
|
|
||||||
|
with open(os.path.join(proj_path, 'gdbinit')) as f_in, open(tempfiles[0], 'w') as f_out:
|
||||||
|
new_content = f_in.read()
|
||||||
|
# localhost connection issue occurs in docker unless:
|
||||||
|
new_content = new_content.replace(':3333', '127.0.0.1:3333', 1)
|
||||||
|
new_content = new_content.replace('file:///tmp/heap_log.svdat', 'file://{}'.format(tempfiles[1]), 1)
|
||||||
|
f_out.write(new_content)
|
||||||
|
|
||||||
|
with ttfw_idf.OCDProcess(os.path.join(proj_path, 'openocd.log')):
|
||||||
|
dut.start_app()
|
||||||
|
dut.expect('esp_apptrace: Initialized TRAX on CPU0')
|
||||||
|
|
||||||
|
gdb_args = '-x {} --directory={}'.format(tempfiles[0], os.path.join(proj_path, 'main'))
|
||||||
|
with ttfw_idf.GDBProcess(os.path.join(proj_path, 'gdb.log'), elf_path, dut.app.target, gdb_args) as gdb:
|
||||||
|
gdb.pexpect_proc.expect_exact('Thread 1 hit Temporary breakpoint 2, heap_trace_stop ()')
|
||||||
|
gdb.pexpect_proc.expect_exact('(gdb)')
|
||||||
|
|
||||||
|
# dut has been restarted by gdb since the last dut.expect()
|
||||||
|
dut.expect('esp_apptrace: Initialized TRAX on CPU0')
|
||||||
|
|
||||||
|
with ttfw_idf.CustomProcess(' '.join([os.path.join(idf_path, 'tools/esp_app_trace/sysviewtrace_proc.py'),
|
||||||
|
'-p',
|
||||||
|
'-b', elf_path,
|
||||||
|
tempfiles[1]]),
|
||||||
|
logfile='sysviewtrace_proc.log') as sysviewtrace:
|
||||||
|
sysviewtrace.pexpect_proc.expect(re.compile(r'Found \d+ leaked bytes in \d+ blocks.'), timeout=120)
|
||||||
|
finally:
|
||||||
|
for x in tempfiles:
|
||||||
|
try:
|
||||||
|
os.unlink(x)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
test_examples_sysview_tracing_heap_log()
|
@ -1,3 +1,4 @@
|
|||||||
|
set pagination off
|
||||||
target remote :3333
|
target remote :3333
|
||||||
|
|
||||||
mon reset halt
|
mon reset halt
|
||||||
|
@ -26,4 +26,4 @@ CONFIG_SYSVIEW_EVT_TIMER_EXIT_ENABLE=y
|
|||||||
CONFIG_LOG_COLORS=n
|
CONFIG_LOG_COLORS=n
|
||||||
# Enable heap tracing to host
|
# Enable heap tracing to host
|
||||||
CONFIG_HEAP_TRACING_TOHOST=y
|
CONFIG_HEAP_TRACING_TOHOST=y
|
||||||
CONFIG_HEAP_TRACING_STACK_DEPTH=10
|
CONFIG_HEAP_TRACING_STACK_DEPTH=10
|
||||||
|
@ -289,7 +289,7 @@ example_test_009:
|
|||||||
artifacts:
|
artifacts:
|
||||||
when: always
|
when: always
|
||||||
paths:
|
paths:
|
||||||
- $CI_PROJECT_DIR/examples/storage/semihost_vfs/*.log
|
- $CI_PROJECT_DIR/examples/*/*/*.log
|
||||||
expire_in: 1 week
|
expire_in: 1 week
|
||||||
variables:
|
variables:
|
||||||
SETUP_TOOLS: "1"
|
SETUP_TOOLS: "1"
|
||||||
|
@ -19,7 +19,7 @@ import pexpect
|
|||||||
|
|
||||||
|
|
||||||
class CustomProcess(object):
|
class CustomProcess(object):
|
||||||
def __init__(self, cmd, logfile, verbose):
|
def __init__(self, cmd, logfile, verbose=True):
|
||||||
self.verbose = verbose
|
self.verbose = verbose
|
||||||
self.f = open(logfile, 'w')
|
self.f = open(logfile, 'w')
|
||||||
if self.verbose:
|
if self.verbose:
|
||||||
@ -68,8 +68,8 @@ class OCDProcess(CustomProcess):
|
|||||||
|
|
||||||
|
|
||||||
class GDBProcess(CustomProcess):
|
class GDBProcess(CustomProcess):
|
||||||
def __init__(self, logfile_path, elffile_path, extra_args='', verbose=True):
|
def __init__(self, logfile_path, elffile_path, target, extra_args='', verbose=True):
|
||||||
cmd = 'xtensa-esp32-elf-gdb {} {}'.format(extra_args, elffile_path)
|
cmd = 'xtensa-{}-elf-gdb {} {}'.format(target, extra_args, elffile_path)
|
||||||
super(GDBProcess, self).__init__(cmd, logfile_path, verbose)
|
super(GDBProcess, self).__init__(cmd, logfile_path, verbose)
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
@ -82,3 +82,18 @@ class GDBProcess(CustomProcess):
|
|||||||
if self.verbose:
|
if self.verbose:
|
||||||
Utility.console_log('gdb needs to be killed', 'O')
|
Utility.console_log('gdb needs to be killed', 'O')
|
||||||
super(GDBProcess, self).close()
|
super(GDBProcess, self).close()
|
||||||
|
|
||||||
|
|
||||||
|
class TelnetProcess(CustomProcess):
|
||||||
|
def __init__(self, logfile_path, host='localhost', port=4444, verbose=True):
|
||||||
|
cmd = 'telnet {} {}'.format(host, port)
|
||||||
|
super(TelnetProcess, self).__init__(cmd, logfile_path, verbose)
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
try:
|
||||||
|
self.pexpect_proc.sendline('exit')
|
||||||
|
self.pexpect_proc.expect_exact('Connection closed by foreign host.')
|
||||||
|
except Exception:
|
||||||
|
if self.verbose:
|
||||||
|
Utility.console_log('telnet needs to be killed', 'O')
|
||||||
|
super(TelnetProcess, self).close()
|
||||||
|
@ -17,7 +17,7 @@ import re
|
|||||||
from tiny_test_fw import TinyFW, Utility
|
from tiny_test_fw import TinyFW, Utility
|
||||||
from .IDFApp import IDFApp, Example, LoadableElfTestApp, UT, TestApp # noqa: export all Apps for users
|
from .IDFApp import IDFApp, Example, LoadableElfTestApp, UT, TestApp # noqa: export all Apps for users
|
||||||
from .IDFDUT import IDFDUT, ESP32DUT, ESP32S2DUT, ESP8266DUT, ESP32QEMUDUT # noqa: export DUTs for users
|
from .IDFDUT import IDFDUT, ESP32DUT, ESP32S2DUT, ESP8266DUT, ESP32QEMUDUT # noqa: export DUTs for users
|
||||||
from .DebugUtils import OCDProcess, GDBProcess # noqa: export DebugUtils for users
|
from .DebugUtils import OCDProcess, GDBProcess, TelnetProcess, CustomProcess # noqa: export DebugUtils for users
|
||||||
|
|
||||||
|
|
||||||
def format_case_id(chip, case_name):
|
def format_case_id(chip, case_name):
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
set pagination off
|
||||||
# Connect to a running instance of OpenOCD
|
# Connect to a running instance of OpenOCD
|
||||||
target remote 127.0.0.1:3333
|
target remote 127.0.0.1:3333
|
||||||
# Reset and halt the target
|
# Reset and halt the target
|
||||||
|
@ -39,10 +39,10 @@ def test_app_loadable_elf(env, extra_data):
|
|||||||
|
|
||||||
rel_project_path = os.path.join('tools', 'test_apps', 'system', 'gdb_loadable_elf')
|
rel_project_path = os.path.join('tools', 'test_apps', 'system', 'gdb_loadable_elf')
|
||||||
app_files = ['gdb_loadable_elf.elf']
|
app_files = ['gdb_loadable_elf.elf']
|
||||||
example = ttfw_idf.LoadableElfTestApp(rel_project_path, app_files, target="esp32")
|
app = ttfw_idf.LoadableElfTestApp(rel_project_path, app_files, target="esp32")
|
||||||
idf_path = example.get_sdk_path()
|
idf_path = app.get_sdk_path()
|
||||||
proj_path = os.path.join(idf_path, rel_project_path)
|
proj_path = os.path.join(idf_path, rel_project_path)
|
||||||
elf_path = os.path.join(example.binary_path, 'gdb_loadable_elf.elf')
|
elf_path = os.path.join(app.binary_path, 'gdb_loadable_elf.elf')
|
||||||
esp_log_path = os.path.join(proj_path, 'esp.log')
|
esp_log_path = os.path.join(proj_path, 'esp.log')
|
||||||
|
|
||||||
with SerialThread(esp_log_path):
|
with SerialThread(esp_log_path):
|
||||||
@ -51,8 +51,7 @@ def test_app_loadable_elf(env, extra_data):
|
|||||||
gdb_args = '-x {} --directory={}'.format(os.path.join(proj_path, '.gdbinit.ci'),
|
gdb_args = '-x {} --directory={}'.format(os.path.join(proj_path, '.gdbinit.ci'),
|
||||||
os.path.join(proj_path, 'main'))
|
os.path.join(proj_path, 'main'))
|
||||||
|
|
||||||
with ttfw_idf.OCDProcess(openocd_log), ttfw_idf.GDBProcess(gdb_log, elf_path, gdb_args) as gdb:
|
with ttfw_idf.OCDProcess(openocd_log), ttfw_idf.GDBProcess(gdb_log, elf_path, app.target, gdb_args) as gdb:
|
||||||
gdb.pexpect_proc.sendline('') # it is for "---Type <return> to continue, or q <return> to quit---"
|
|
||||||
i = gdb.pexpect_proc.expect_exact(['Thread 1 hit Temporary breakpoint 2, app_main ()',
|
i = gdb.pexpect_proc.expect_exact(['Thread 1 hit Temporary breakpoint 2, app_main ()',
|
||||||
'Load failed'])
|
'Load failed'])
|
||||||
if i == 0:
|
if i == 0:
|
||||||
|
Loading…
Reference in New Issue
Block a user