example/system: add generic apptrace example with pytest support

pull/10792/head
Erhan Kurubas 2023-02-01 13:54:02 +01:00
rodzic 113132e4f4
commit 1ee5c8d877
8 zmienionych plików z 248 dodań i 0 usunięć

Wyświetl plik

@ -106,6 +106,17 @@ example_test_pytest_esp32s2_generic:
tags: [ esp32s2, generic ]
parallel: 3
example_test_pytest_esp32s2_jtag:
extends:
- .pytest_examples_dir_template
- .rules:test:example_test-esp32s2
needs:
- build_pytest_examples_jtag
tags: [ esp32s2, jtag ]
variables:
SETUP_TOOLS: "1" # need gdb openocd
PYTEST_EXTRA_FLAGS: "--log-cli-level DEBUG"
example_test_pytest_esp32s3_generic:
extends:
- .pytest_examples_dir_template
@ -115,6 +126,17 @@ example_test_pytest_esp32s3_generic:
tags: [ esp32s3, generic ]
parallel: 3
example_test_pytest_esp32s3_usb_serial_jtag:
extends:
- .pytest_examples_dir_template
- .rules:test:example_test-esp32s3
needs:
- build_pytest_examples_jtag
tags: [ esp32s3, usb_serial_jtag ]
variables:
SETUP_TOOLS: "1" # need gdb openocd
PYTEST_EXTRA_FLAGS: "--log-cli-level DEBUG"
example_test_pytest_esp32s3_f4r8:
extends:
- .pytest_examples_dir_template
@ -132,6 +154,17 @@ example_test_pytest_esp32c2_generic:
tags: [ esp32c2, generic, xtal_40mhz ]
parallel: 3
example_test_pytest_esp32c2_jtag:
extends:
- .pytest_examples_dir_template
- .rules:test:example_test-esp32c2
needs:
- build_pytest_examples_jtag
tags: [ esp32c2, jtag ]
variables:
SETUP_TOOLS: "1" # need gdb openocd
PYTEST_EXTRA_FLAGS: "--log-cli-level DEBUG"
example_test_pytest_esp32c3_generic:
extends:
- .pytest_examples_dir_template
@ -141,6 +174,17 @@ example_test_pytest_esp32c3_generic:
tags: [ esp32c3, generic ]
parallel: 3
example_test_pytest_esp32c3_usb_serial_jtag:
extends:
- .pytest_examples_dir_template
- .rules:test:example_test-esp32c3
needs:
- build_pytest_examples_jtag
tags: [ esp32c3, usb_serial_jtag ]
variables:
SETUP_TOOLS: "1" # need gdb openocd
PYTEST_EXTRA_FLAGS: "--log-cli-level DEBUG"
example_test_pytest_esp32c3_flash_suspend:
extends:
- .pytest_examples_dir_template

Wyświetl plik

@ -114,6 +114,7 @@ ENV_MARKERS = {
'MSPI_F4R8': 'runner with Quad Flash and Octal PSRAM',
'MSPI_F4R4': 'runner with Quad Flash and Quad PSRAM',
'jtag': 'runner where the chip is accessible through JTAG as well',
'usb_serial_jtag': 'runner where the chip is accessible through builtin JTAG as well',
'adc': 'ADC related tests should run on adc runners',
'xtal32k': 'Runner with external 32k crystal connected',
'no32kXtal': 'Runner with no external 32k crystal connected',

Wyświetl plik

@ -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(app_trace_basic)

Wyświetl plik

@ -0,0 +1,73 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- |
# Application Level Tracing Example (Basic)
(See the README.md file in the upper level 'examples' directory for more information about examples.)
This example demonstrates how to use the [Application Level Tracing Library](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/app_trace.html#) (henceforth referred to as **App Trace**) to log messages to a host via JTAG instead of the normal method of logging via UART.
UART logs are time consuming and can significantly slow down the function that calls it. Therefore, it is generally a bad idea to use UART logs in time-critical functions. Logging to host via JTAG is significantly faster and can be used in time-critical functions. For more details regarding logging to host via JTAG, refer to the [Logging to Host Documentation](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/app_trace.html#app-trace-logging-to-host).
### Hardware Required
To run this example, you need a supported target dev board connected to a JTAG adapter, which can come in the following forms:
* [ESP-WROVER-KIT](https://docs.espressif.com/projects/esp-idf/en/latest/hw-reference/modules-and-boards.html#esp-wrover-kit-v4-1) which integrates an on-board JTAG adapter. Ensure that the [required jumpers to enable JTAG are connected](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/get-started-wrover-kit.html#setup-options) on the WROVER-KIT.
* ESP32, ESP32-S2 or ESP32-C2 core board (e.g. ESP32-DevKitC, [ESP32-S2-Saola-1](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-saola-1-v1.2.html)) can also work as long as you connect it to an external JTAG adapter (e.g. FT2232H, J-LINK).
This example will assume that an ESP-WROVER-KIT is used.
#### Connections:
1. Connect the JTAG interface to the target board. For details about how to set up JTAG interface, please see [JTAG Debugging](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/jtag-debugging/index.html). Power up both the JTAG debugger and target board.
2. After connecting JTAG interface, you need to [Run OpenOCD](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/jtag-debugging/index.html#run-openocd).
3. Open a separate terminal window and run telnet by entering the command below. The telnet terminal window is used to feed commands to OpenOCD:
```bash
telnet localhost 4444
```
### Configure the project
```
idf.py menuconfig
```
* To enable application tracing, select the `(X) Trace memory` option under `Component config > Application Level Tracing`. This option should have been selected by default.
### Build, Flash, and Run
Build the project and flash it to the board, then run monitor tool to view serial output:
```
idf.py -p PORT flash monitor
```
(Replace PORT with the name of the serial port to use.)
**Start App Trace:** In the telnet session window, trigger OpenOCD to start App Trace on the target by entering the command below. This command will collect 9000 bytes of JTAG log data and save them to the file `file://apptrace.log` (note `file://` depends on
where OpenOCD was started). Assuming that OpenOCD was started in this example's directory, `apptrace.log` will be saved here as well.
```bash
esp apptrace start file://apptrace.log 0 2000 3 0 0
```
**Note:** For more details on OpenOCD commands regarding App Trace, refer to the [OpenOCD Application Level Tracing Commands](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/app_trace.html#openocd-application-level-tracing-commands)
(To exit the serial monitor, type ``Ctrl-]``.)
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
## Troubleshooting
### Unable to flash when OpenOCD is connected to the target
On ESP32 boards, one likely cause would be an incorrect SPI flash voltage when starting OpenOCD. Suppose a target board/module with a 3.3 V powered SPI flash is being used, but the configuration file (ex. `board/esp32-wrover.cfg` for ESP32) is selected when starting OpenOCD which can set the SPI flash voltage to 1.8 V. In this situation, the SPI flash will not work after OpenOCD connects to the target as OpenOCD has changed the SPI flash voltage. Therefore, you might not be able to flash to the target when OpenOCD is connected.
To work around this issue, users are suggested to use `board/esp32-wrover.cfg` for ESP32 boards/modules operating with an SPI flash voltage of 1.8 V, and `board/esp-wroom-32.cfg` for 3.3 V. Refer to [ESP32 Modules and Boards](https://docs.espressif.com/projects/esp-idf/en/latest/hw-reference/modules-and-boards.html) and [Set SPI Flash Voltage](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/jtag-debugging/tips-and-quirks.html#why-to-set-spi-flash-voltage-in-openocd-configuration) for more details.
(For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you as soon as possible.)

Wyświetl plik

@ -0,0 +1,2 @@
idf_component_register(SRCS "app_trace_basic_example_main.c"
INCLUDE_DIRS ".")

Wyświetl plik

@ -0,0 +1,46 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
/* Application Trace Basic Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_app_trace.h"
#include "esp_log.h"
static const char *TAG = "example";
void app_main(void)
{
ESP_LOGI(TAG, "Waiting for OpenOCD connection");
while (!esp_apptrace_host_is_connected(ESP_APPTRACE_DEST_JTAG)) {
vTaskDelay(1);
}
ESP_LOGI(TAG, "Sending example data to the host...");
for (unsigned int cnt = 1; cnt < 51; ++cnt) {
char buf[32] = {0};
snprintf(buf, sizeof(buf), "Apptrace test data[%d]:%d\n", cnt, cnt * cnt);
esp_err_t res = esp_apptrace_write(ESP_APPTRACE_DEST_JTAG, buf, strlen(buf), ESP_APPTRACE_TMO_INFINITE);
if (res != ESP_OK) {
ESP_LOGE(TAG, "Failed to write data to host [0x%x] (%s)", res, esp_err_to_name(res));
}
esp_apptrace_flush(ESP_APPTRACE_DEST_JTAG, 1000);
vTaskDelay(50 / portTICK_PERIOD_MS);
}
ESP_LOGI(TAG, "Done!");
}

Wyświetl plik

@ -0,0 +1,73 @@
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0
import time
import pexpect
import pytest
from pytest_embedded_idf import IdfDut
from pytest_embedded_jtag import OpenOcd
def apptrace_wait_stop(openocd: OpenOcd, timeout: int = 30) -> None:
stopped = False
end_before = time.time() + timeout
while not stopped:
cmd_out = openocd.write('esp apptrace status')
for line in cmd_out.splitlines():
if line.startswith('Tracing is STOPPED.'):
stopped = True
break
if not stopped and time.time() > end_before:
raise pexpect.TIMEOUT('Failed to wait for apptrace stop!')
time.sleep(1)
@pytest.mark.parametrize(
'embedded_services, no_gdb',
[
('esp,idf,jtag', 'y'),
],
indirect=True,
)
@pytest.mark.parametrize(
'port, openocd_cli_args', [
pytest.param(None, None, marks=[pytest.mark.esp32, pytest.mark.jtag]),
pytest.param(None, '-f board/esp32s2-kaluga-1.cfg', marks=[pytest.mark.esp32s2, pytest.mark.jtag]),
pytest.param(None, '-f board/esp32c2-ftdi.cfg', marks=[pytest.mark.esp32c2, pytest.mark.jtag]),
pytest.param('/dev/ttyACM0', '-f board/esp32s3-builtin.cfg', marks=[pytest.mark.esp32s3, pytest.mark.usb_serial_jtag]),
pytest.param('/dev/ttyACM0', '-f board/esp32c3-builtin.cfg', marks=[pytest.mark.esp32c3, pytest.mark.usb_serial_jtag]),
],
indirect=True
)
def test_examples_app_trace_basic(dut: IdfDut, openocd: OpenOcd) -> None:
dut.openocd.write('reset')
dut.expect_exact('example: Waiting for OpenOCD connection', timeout=5)
assert 'Targets connected.' in dut.openocd.write('esp apptrace start file://apptrace.log 0 2000 3 0 0')
apptrace_wait_stop(dut.openocd)
with open(openocd._logfile) as oocd_log: # pylint: disable=protected-access
cores = 1 if dut.app.sdkconfig.get('FREERTOS_UNICORE') is True else 2
params_str = 'App trace params: from {} cores,'.format(cores)
found = False
for line in oocd_log:
if params_str in line:
found = True
break
if found is not True:
raise RuntimeError(
'"{}" could not be found in {}'.format(params_str, openocd._logfile) # pylint: disable=protected-access
)
with open('apptrace.log') as apptrace_log:
for sample_num in range(1, 51):
log_str = 'Apptrace test data[{}]:{}'.format(sample_num, sample_num * sample_num)
found = False
for line in apptrace_log:
if log_str in line:
found = True
break
if found is not True:
raise RuntimeError(
'"{}" could not be found in {}'.format(log_str, 'apptrace.log')
)

Wyświetl plik

@ -0,0 +1,3 @@
# Enable application tracing by default
CONFIG_APPTRACE_DEST_JTAG=y
CONFIG_APPTRACE_ENABLE=y