mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
cleanup app_trace_to_host example
1. Cleanup the README of app_trace_to_host example based on the template. 2. Remove unused header files in the example. 3. Fix typos in public header file.
This commit is contained in:
parent
2790d4a049
commit
ed84bcee7b
@ -38,7 +38,7 @@
|
||||
// |<------------------------------------------->|TRAX_CTRL_REGS|<---->|
|
||||
// ----------------
|
||||
|
||||
// In general tracing goes in the following way. User aplication requests tracing module to send some data by calling esp_apptrace_buffer_get(),
|
||||
// In general tracing goes in the following way. User application requests tracing module to send some data by calling esp_apptrace_buffer_get(),
|
||||
// module allocates necessary buffer in current input trace block. Then user fills received buffer with data and calls esp_apptrace_buffer_put().
|
||||
// When current input trace block is filled with app data it is exposed to host and the second block becomes input one and buffer filling restarts.
|
||||
// While target application fills one TRAX block host reads another one via JTAG.
|
||||
@ -62,7 +62,7 @@
|
||||
// 21..15 bits - trace memory block transfer ID. Block counter. It can overflow. Updated by target, host should not modify it. Actually can be 2 bits;
|
||||
// 22 bit - 'host data present' flag. If set to one there is data from host, otherwise - no host data;
|
||||
// 23 bit - 'host connected' flag. If zero then host is not connected and tracing module works in post-mortem mode, otherwise in streaming mode;
|
||||
// - Status register uses TRAX_TRIGGERPC as storage. If this register is not zero then currentlly CPU is changing TRAX registers and
|
||||
// - Status register uses TRAX_TRIGGERPC as storage. If this register is not zero then current CPU is changing TRAX registers and
|
||||
// this register holds address of the instruction which application will execute when it finishes with those registers modifications.
|
||||
// See 'Targets Connection' setion for details.
|
||||
|
||||
@ -87,7 +87,7 @@
|
||||
// 4.1 Trace Memory Blocks
|
||||
// -----------------------
|
||||
|
||||
// Communication is controlled via special register. Host periodically polls control register on each core to find out if there are any data avalable.
|
||||
// Communication is controlled via special register. Host periodically polls control register on each core to find out if there are any data available.
|
||||
// When current input memory block is filled it is exposed to host and 'block_len' and 'block_id' fields are updated in the control register.
|
||||
// Host reads new register value and according to it's value starts reading data from exposed block. Meanwhile target starts filling another trace block.
|
||||
// When host finishes reading the block it clears 'block_len' field in control register indicating to the target that it is ready to accept the next one.
|
||||
@ -102,9 +102,9 @@
|
||||
// multithreading environment it can happen that task/ISR which copies data is preempted by another high prio task/ISR. So it is possible situation
|
||||
// that task/ISR will fail to complete filling its data chunk before the whole trace block is exposed to the host. To handle such conditions tracing
|
||||
// module prepends all user data chunks with header which contains allocated buffer size and actual data length within it. OpenOCD command
|
||||
// which reads application traces reports error when it reads incompleted user data block.
|
||||
// Data which are transfered from host to target are also prepended with a header. Down channel data header is simple and consists of one two bytes field
|
||||
// containing length of host data following the heder.
|
||||
// which reads application traces reports error when it reads incomplete user data block.
|
||||
// Data which are transffered from host to target are also prepended with a header. Down channel data header is simple and consists of one two bytes field
|
||||
// containing length of host data following the header.
|
||||
|
||||
// 4.3 Data Buffering
|
||||
// ------------------
|
||||
@ -141,20 +141,18 @@
|
||||
// So no local task switch occurs when mutex is locked. But this does not apply to tasks on another CPU.
|
||||
// WARNING: Priority inversion can happen when low prio task works on one CPU and medium and high prio tasks work on another.
|
||||
// WARNING: Care must be taken when selecting timeout values for trace calls from ISRs. Tracing module does not care about watchdogs when waiting
|
||||
// on internal locks and for host to complete previous block reading, so if timeout value exceedes watchdog's one it can lead to the system reboot.
|
||||
// on internal locks and for host to complete previous block reading, so if timeout value exceeds watchdog's one it can lead to the system reboot.
|
||||
|
||||
// 6. Timeouts
|
||||
// ===========
|
||||
|
||||
// Timeout mechanism is based on xthal_get_ccount() routine and supports timeout values in micorseconds.
|
||||
// Timeout mechanism is based on xthal_get_ccount() routine and supports timeout values in microseconds.
|
||||
// There are two situations when task/ISR can be delayed by tracing API call. Timeout mechanism takes into account both conditions:
|
||||
// - Trace data are locked by another task/ISR. When wating on trace data lock.
|
||||
// - Current TRAX memory input block is full when working in streaming mode (host is connected). When waiting for host to complete previous block reading.
|
||||
// When wating for any of above conditions xthal_get_ccount() is called periodically to calculate time elapsed from trace API routine entry. When elapsed
|
||||
// time exceeds specified timeout value operation is canceled and ESP_ERR_TIMEOUT code is returned.
|
||||
|
||||
// ALSO SEE example usage of application tracing module in 'components/app_trace/README.rst'
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
#include "soc/soc.h"
|
||||
|
@ -51,7 +51,7 @@ void esp_apptrace_down_buffer_config(uint8_t *buf, uint32_t size);
|
||||
*
|
||||
* @param dest Indicates HW interface to send data.
|
||||
* @param size Size of data to write to trace buffer.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
*
|
||||
* @return non-NULL on success, otherwise NULL.
|
||||
*/
|
||||
@ -63,7 +63,7 @@ uint8_t *esp_apptrace_buffer_get(esp_apptrace_dest_t dest, uint32_t size, uint32
|
||||
*
|
||||
* @param dest Indicates HW interface to send data. Should be identical to the same parameter in call to esp_apptrace_buffer_get.
|
||||
* @param ptr Address of trace buffer to release. Should be the value returned by call to esp_apptrace_buffer_get.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
@ -75,7 +75,7 @@ esp_err_t esp_apptrace_buffer_put(esp_apptrace_dest_t dest, uint8_t *ptr, uint32
|
||||
* @param dest Indicates HW interface to send data.
|
||||
* @param data Address of data to write to trace buffer.
|
||||
* @param size Size of data to write to trace buffer.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
@ -85,7 +85,7 @@ esp_err_t esp_apptrace_write(esp_apptrace_dest_t dest, const void *data, uint32_
|
||||
* @brief vprintf-like function to sent log messages to host via specified HW interface.
|
||||
*
|
||||
* @param dest Indicates HW interface to send data.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
* @param fmt Address of format string.
|
||||
* @param ap List of arguments.
|
||||
*
|
||||
@ -107,7 +107,7 @@ int esp_apptrace_vprintf(const char *fmt, va_list ap);
|
||||
* @brief Flushes remaining data in trace buffer to host.
|
||||
*
|
||||
* @param dest Indicates HW interface to flush data on.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
@ -119,7 +119,7 @@ esp_err_t esp_apptrace_flush(esp_apptrace_dest_t dest, uint32_t tmo);
|
||||
*
|
||||
* @param dest Indicates HW interface to flush data on.
|
||||
* @param min_sz Threshold for flushing data. If current filling level is above this value, data will be flushed. TRAX destinations only.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
@ -131,31 +131,31 @@ esp_err_t esp_apptrace_flush_nolock(esp_apptrace_dest_t dest, uint32_t min_sz, u
|
||||
* @param dest Indicates HW interface to read the data on.
|
||||
* @param data Address of buffer to put data from trace buffer.
|
||||
* @param size Pointer to store size of read data. Before call to this function pointed memory must hold requested size of data
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
esp_err_t esp_apptrace_read(esp_apptrace_dest_t dest, void *data, uint32_t *size, uint32_t tmo);
|
||||
|
||||
/**
|
||||
* @brief Rertrieves incoming data buffer if any.
|
||||
* @brief Retrieves incoming data buffer if any.
|
||||
* After data in buffer are processed esp_apptrace_down_buffer_put must be called to indicate it.
|
||||
*
|
||||
* @param dest Indicates HW interface to receive data.
|
||||
* @param size Address to store size of available data in down buffer. Must be initializaed with requested value.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
|
||||
* @param size Address to store size of available data in down buffer. Must be initialized with requested value.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
*
|
||||
* @return non-NULL on success, otherwise NULL.
|
||||
*/
|
||||
uint8_t *esp_apptrace_down_buffer_get(esp_apptrace_dest_t dest, uint32_t *size, uint32_t tmo);
|
||||
|
||||
/**
|
||||
* @brief Indicates that the data in down buffer are processesd.
|
||||
* @brief Indicates that the data in down buffer are processed.
|
||||
* This function is a counterpart of and must be preceeded by esp_apptrace_down_buffer_get.
|
||||
*
|
||||
* @param dest Indicates HW interface to receive data. Should be identical to the same parameter in call to esp_apptrace_down_buffer_get.
|
||||
* @param ptr Address of trace buffer to release. Should be the value returned by call to esp_apptrace_down_buffer_get.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
@ -247,7 +247,7 @@ int esp_apptrace_ftell(esp_apptrace_dest_t dest, void *stream);
|
||||
|
||||
/**
|
||||
* @brief Indicates to the host that all file operations are completed.
|
||||
* This function should be called after all file operations are finished and
|
||||
* This function should be called after all file operations are finished and
|
||||
* indicate to the host that it can perform cleanup operations (close open files etc.).
|
||||
*
|
||||
* @param dest Indicates HW interface to use.
|
||||
|
@ -3,4 +3,4 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(app_trace_to_host_test)
|
||||
project(app_trace_to_host)
|
||||
|
@ -3,7 +3,7 @@
|
||||
# project subdirectory.
|
||||
#
|
||||
|
||||
PROJECT_NAME := app_trace_to_host_test
|
||||
PROJECT_NAME := app_trace_to_host
|
||||
|
||||
include $(IDF_PATH)/make/project.mk
|
||||
|
||||
|
@ -1,19 +1,23 @@
|
||||
# Example: Application Level Tracing - Logging to Host (app_trace_to_host)
|
||||
|
||||
This test code shows how to perform high speed logging by redirecting the log messages to a host instead of UART.
|
||||
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
||||
|
||||
For description of [logging to a host](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/app_trace.html#logging-to-host) please refer to **ESP32 Programming Guide**, section **Application Level Tracing library**. The following example provides practical implementation of this functionality.
|
||||
## Overview
|
||||
|
||||
This example will show how to perform high speed logging by redirecting the log messages to a host instead of UART.
|
||||
|
||||
For more description of [logging to host](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/app_trace.html#logging-to-host) please refer to **ESP-IDF Programming Guide**, section **Application Level Tracing library**. The following example provides practical implementation of this functionality.
|
||||
|
||||
|
||||
## Use Case
|
||||
### Use Case
|
||||
|
||||
Debugging of time critical functions may not work as desired if log messages are sent though the UART port. Printing out the logs may considerably slow down tested function to the point where it will not operate as expected.
|
||||
Debugging of time critical functions may not work as desired if log messages are sent through the UART port. Printing out the logs may considerably slow down tested function to the point where it will not operate as expected.
|
||||
|
||||
Let's consider a case we are testing implementation of [zero level crossing](https://en.wikipedia.org/wiki/Zero_crossing) detection for a 50 Hz signal with ESP32's ADC.
|
||||
|
||||
We will start by checking if we can read ADC, what is the signal level and how many samples can be collected over 20 ms period by using a code snippet below:
|
||||
|
||||
```
|
||||
```c
|
||||
int sampling_period = 20;
|
||||
int i = 0;
|
||||
uint32_t sampling_start = esp_log_timestamp(); //this clock counts miliseconds
|
||||
@ -24,7 +28,7 @@ do {
|
||||
|
||||
Above code is sampling ADC in a loop continuously for 20 ms of time to collect one full period of 50 Hz signal (use 17 ms for 60 Hz signal), and printing out results. If you run this code, result will be likely as below:
|
||||
|
||||
```
|
||||
```bash
|
||||
I (4309) example: Sample:1, Value:2224
|
||||
I (4309) example: Sample:2, Value:840
|
||||
I (4309) example: Sample:3, Value:3503
|
||||
@ -36,15 +40,15 @@ As you see we were able to collect only five samples. This seems rather not adeq
|
||||
|
||||
We can remove `ESP_LOGI()` line and sample much faster, but then will not be able to see the values. To see the values we would need to save them in the memory and print out later.
|
||||
|
||||
Instead of saving samples to memory, a simple and compelling solution to this issue is sending logs to a host over a JTAG interface. This works much faster than with the UART. To do so, we need to redirect log messages to JTAG by calling the following function before `ESP_LOGx` line:
|
||||
Instead of saving samples to memory, a simple and compelling solution to this issue is sending logs to a host over a JTAG interface. This works much faster than UART. To do so, we need to redirect log messages to JTAG by calling the following function before `ESP_LOGx` line:
|
||||
|
||||
```
|
||||
```c
|
||||
esp_log_set_vprintf(esp_apptrace_vprintf);
|
||||
```
|
||||
|
||||
Once time critical messages are sent out, we can redirect `ESP_LOGx` back back to the UART by adding extra two lines of code.
|
||||
|
||||
```
|
||||
```c
|
||||
esp_log_set_vprintf(vprintf);
|
||||
esp_apptrace_flush(ESP_APPTRACE_DEST_TRAX, 100000);
|
||||
```
|
||||
@ -53,7 +57,7 @@ Note command `esp_apptrace_flush()` used to empty buffer with pending messages t
|
||||
|
||||
If checking the log received by the host, we will see over 400 samples collected!
|
||||
|
||||
```
|
||||
```bash
|
||||
...
|
||||
I (59379) example: Sample:424, Value:298
|
||||
I (59379) example: Sample:425, Value:345
|
||||
@ -62,59 +66,59 @@ I (59379) example: Sample:427, Value:432
|
||||
I (61409) example: Sample:1, Value:2653
|
||||
```
|
||||
|
||||
## How to use example
|
||||
|
||||
## Example in Action
|
||||
### Hardware Required
|
||||
|
||||
Check the full example code [app_trace_to_host](main/app_trace_to_host_test.c) that combines both tests above and runs them in a loop showing instantly the number of samples collected:
|
||||
To run this example, you need an ESP32 dev board (e.g. [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. ESP32 core board (e.g. ESP32-DevKitC) can also work as long as you connect it to an external JTAG adapter (e.g. FT2232H, J-LINK). For convenience, here we will take the [ESP-WROVER-KIT](https://docs.espressif.com/projects/esp-idf/en/latest/hw-reference/modules-and-boards.html#esp-wrover-kit-v4-1) for example.
|
||||
|
||||
```
|
||||
I (4289) example: Sampling ADC and sending data to the host...
|
||||
I (4309) example: Collected 427 samples in 20 ms.
|
||||
#### Pin Assignment:
|
||||
|
||||
I (4309) example: Sampling ADC and sending data to the UART...
|
||||
I (4309) example: Sample:1, Value:2224
|
||||
I (4309) example: Sample:2, Value:840
|
||||
I (4309) example: Sample:3, Value:3503
|
||||
I (4319) example: Sample:4, Value:27
|
||||
I (4319) example: Sample:5, Value:4095
|
||||
I (4329) example: Collected 5 samples in 20 ms.
|
||||
```
|
||||
**Note:** Connect 50 / 60 Hz sinusoidal signal to ADC1_CHANNEL_6 / GPIO34. The signal range should be from 0V to max 3.1V. Optionally you can bridge GPIO34 with DAC_CHANNEL_1 / GPIO25.
|
||||
|
||||
| DAC Output | ADC Input |
|
||||
| ----------------- | ----------------- |
|
||||
| Channel1 (GPIO25) | Channel6 (GPIO34) |
|
||||
|
||||
## Do it Yourself
|
||||
#### Extra Connections:
|
||||
|
||||
To run the example and retrieve the log from the host, do the following:
|
||||
1. Connect JTAG interface to ESP32 board, power up both JTAG and ESP32. 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).
|
||||
|
||||
1. Connect JTAG interface to ESP32 board, power up both JTAG and ESP32. For details how to setup JTAG interface see [JTAG Debugging](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/jtag-debugging/index.html).
|
||||
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). If you are using the [Binary Distribution of OpenOCD](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/jtag-debugging/index.html#jtag-debugging-setup-openocd) and one of versions of [ESP-WROVER-KIT](https://docs.espressif.com/projects/esp-idf/en/latest/hw-reference/modules-and-boards.html#esp-wrover-kit-v4-1), respective command line will look as follows:
|
||||
|
||||
2. [Run OpenOCD](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/jtag-debugging/index.html#run-openocd). If you are using the [binary distribution of OpenOCD](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/jtag-debugging/index.html#jtag-debugging-setup-openocd) and one of versions of [ESP-WROVER-KIT](https://docs.espressif.com/projects/esp-idf/en/latest/hw-reference/modules-and-boards.html#esp-wrover-kit-v3), respective command line will look as follows:
|
||||
|
||||
```
|
||||
```bash
|
||||
cd ~/esp/openocd-esp32
|
||||
bin/openocd -s share/openocd/scripts -f interface/ftdi/esp32_devkitj_v1.cfg -f board/esp-wroom-32.cfg
|
||||
```
|
||||
|
||||
3. Compile and load the example. Note to enable application tracing in menuconfig by going to `Component config > Application Level Tracing` and selecting `(X) Trace memory`
|
||||
3. Open a separate terminal window and run telnet by entering:
|
||||
|
||||
4. Connect 50 Hz sinusoidal signal to ADC1_CHANNEL_6 / GPIO34. The signal range should be from 0V to max 3.1V. Optionally bridge GPIO34 with DAC_CHANNEL_1 / GPIO25, that generates 130 Hz signal within 0V..3.1V. To get 50 Hz, you need to set non standard divider of RTC 8 MHz clock to lower the minimum CW (Cosine Waveform) generator's frequency. You can do it in menuconfig by going to `Component config > Example configuration > Set custom RTC 8 MHz clock divider to lower CW frequency`.
|
||||
|
||||
5. Open a separate terminal window and run telnet by entering:
|
||||
|
||||
```
|
||||
```bash
|
||||
telnet localhost 4444
|
||||
```
|
||||
|
||||
6. In telnet execute the following command:
|
||||
|
||||
```
|
||||
|
||||
### Configure the project
|
||||
|
||||
Enter `make menuconfig` if you are using GNU Make based build system or enter `idf.py menuconfig` if you are using CMake based build system. Then go into `Example Configuration` menu.
|
||||
|
||||
- By default, the DAC will generate 130 Hz signal within 0V..3.1V. To get 50Hz, you need to set non-standard driver of RTC 8MHz clock to lower minimum CW (Cosine Waveform) generator's frequency in `Set custom RTC 8 MHz clock divider to lower CW frequency`.
|
||||
|
||||
**Note** To enable application tracing, go to `Component config > Application Level Tracing` and select `(X) Trace memory`. (By default, this option has been switched on in the sdkconfig.defaults).
|
||||
|
||||
### Build, Flash and Run
|
||||
|
||||
1. Enter `make -j4 flash monitor` if you are using GNU Make based build system or enter `idf.py build flash monitor` if you are using CMake based build system. (To exit the serial monitor, type ``Ctrl-]``.)
|
||||
See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects.
|
||||
|
||||
2. In the telnet session window, run the following command. This command will collect 9000 bytes of log data and save them to `adc.log` file in `~/esp/openocd-esp32` folder.
|
||||
|
||||
```bash
|
||||
esp32 apptrace start file://adc.log 0 9000 5 0 0
|
||||
```
|
||||
|
||||
This command should collect 9000 bytes of log data and save them to `adc.log` file in `~/esp/openocd-esp32` folder.
|
||||
3. Decode and print out retrieved log file by executing:
|
||||
|
||||
7. Decode and print out retrieved log file by executing:
|
||||
|
||||
```
|
||||
```bash
|
||||
$IDF_PATH/tools/esp_app_trace/logtrace_proc.py ~/esp/openocd-esp32/adc.log ~/esp/app_trace_to_host/build/app_trace_to_host_test.elf
|
||||
```
|
||||
|
||||
@ -170,8 +174,32 @@ To run the example and retrieve the log from the host, do the following:
|
||||
|
||||
This is the log we have been looking for, complete with timestamps as if printed to UART, but almost two orders of magnitude faster.
|
||||
|
||||
## Example Output
|
||||
|
||||
Check the full example code [app_trace_to_host](main/app_trace_to_host_test.c) that combines both tests above and runs them in a loop showing instantly the number of samples collected:
|
||||
|
||||
```
|
||||
I (4289) example: Sampling ADC and sending data to the host...
|
||||
I (4309) example: Collected 427 samples in 20 ms.
|
||||
|
||||
I (4309) example: Sampling ADC and sending data to the UART...
|
||||
I (4309) example: Sample:1, Value:2224
|
||||
I (4309) example: Sample:2, Value:840
|
||||
I (4309) example: Sample:3, Value:3503
|
||||
I (4319) example: Sample:4, Value:27
|
||||
I (4319) example: Sample:5, Value:4095
|
||||
I (4329) example: Collected 5 samples in 20 ms.
|
||||
```
|
||||
|
||||
**note** Above result is generated under CPU running at 240 MHz.
|
||||
|
||||
## Conclusion
|
||||
|
||||
With this example code we have demonstrated powerful functionality of logging to host with JTAG interface. With standard UART communication speed setting of 115200 BPS, printing out a single line of a log message takes about 4 ms. This is also the maximum period we can sequentially execute other tasks in between. By providing the same logging over JTAG, we were able improve performance of this process over 80 times.
|
||||
With this example code we have demonstrated powerful functionality of logging to host with JTAG interface. With standard UART communication baud rate setting of 115200, printing out a single line of a log message takes about 4 ms. This is also the maximum period we can sequentially execute other tasks in between. By providing the same logging over JTAG, we will be able to improve performance of this process over 80 times.
|
||||
|
||||
## Troubleshooting
|
||||
1. I can not flash new firmware when OpenOCD is connected to ESP32.
|
||||
* One likely cause would be that you set wrong SPI flash voltage when you start OpenOCD. Suppose you're working with an ESP32 board / module which has a 3.3V powered SPI flash, but you select
|
||||
`board/esp32-wrover.cfg` configuration file when start OpenOCD. In this situation, you might not be able to flash ESP32 when OpenOCD is connected. So make sure what the working voltage of the SPI flash is. Currently, for 1.8V flash, we'd like to suggest using `board/esp32-wrover.cfg` and for 3.3V flash, using `board/esp-wroom-32.cfg`. For more information about it, please 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 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.)
|
||||
|
@ -1,4 +1,4 @@
|
||||
set(COMPONENT_SRCS "app_trace_to_host_test.c")
|
||||
set(COMPONENT_SRCS "app_trace_to_host_example_main.c")
|
||||
set(COMPONENT_ADD_INCLUDEDIRS ".")
|
||||
|
||||
register_component()
|
||||
|
@ -8,25 +8,15 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/adc.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_app_trace.h"
|
||||
|
||||
#include "soc/rtc_io_reg.h"
|
||||
#include "esp_log.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/sens_reg.h"
|
||||
#include "soc/rtc.h"
|
||||
|
||||
#include "driver/adc.h"
|
||||
#include "driver/dac.h"
|
||||
|
||||
|
||||
#define ADC1_TEST_CHANNEL (ADC1_CHANNEL_6)
|
||||
#define TEST_SAMPLING_PERIOD 20
|
||||
|
||||
@ -49,7 +39,6 @@
|
||||
|
||||
static const char *TAG = "example";
|
||||
|
||||
|
||||
/*
|
||||
* Enable cosine waveform generator (CW)
|
||||
* on channel 1 / GPIO25 to provide sinusoidal signal
|
||||
@ -57,7 +46,7 @@ static const char *TAG = "example";
|
||||
* of speed of logging to the host
|
||||
* sequentially with data retrieval from ADC
|
||||
*/
|
||||
void enable_cosine_generator(void)
|
||||
static void enable_cosine_generator(void)
|
||||
{
|
||||
// Enable tone generator common to both DAC channels 1 and 2
|
||||
SET_PERI_REG_MASK(SENS_SAR_DAC_CTRL1_REG, SENS_SW_TONE_EN);
|
||||
@ -75,30 +64,28 @@ void enable_cosine_generator(void)
|
||||
dac_output_enable(DAC_CHANNEL_1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Sample data an ADC1 channel 6 / GPIO34
|
||||
* over specific 'sampling_period' in milliseconds.
|
||||
* Print out sampling result using standard ESP_LOGI() function.
|
||||
* Return the number of samples collected.
|
||||
*/
|
||||
int adc1_sample_and_show(int sampling_period)
|
||||
static int adc1_sample_and_show(int sampling_period)
|
||||
{
|
||||
int i = 0;
|
||||
uint32_t sampling_start = esp_log_timestamp();
|
||||
uint32_t sampling_start = esp_log_timestamp();
|
||||
do {
|
||||
ESP_LOGI(TAG, "Sample:%d, Value:%d", ++i, adc1_get_raw(ADC1_TEST_CHANNEL));
|
||||
} while (esp_log_timestamp() - sampling_start < sampling_period);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Main program loop that is sampling data on ADC
|
||||
* and logging results with application tracing to the host
|
||||
* as well as for comparison printing out sampling result to UART
|
||||
*/
|
||||
void test_task(void *arg)
|
||||
void app_main()
|
||||
{
|
||||
ESP_LOGI(TAG, "Enabling ADC1 on channel 6 / GPIO34.");
|
||||
adc1_config_width(ADC_WIDTH_BIT_12);
|
||||
@ -108,9 +95,8 @@ void test_task(void *arg)
|
||||
enable_cosine_generator();
|
||||
|
||||
while (1) {
|
||||
|
||||
/*
|
||||
* Test of Logging with the Application Trace
|
||||
* Logging with the Application Trace
|
||||
*/
|
||||
ESP_LOGI(TAG, "Sampling ADC and sending data to the host...");
|
||||
// Route LOGx() to the host
|
||||
@ -123,7 +109,7 @@ void test_task(void *arg)
|
||||
ESP_LOGI(TAG, "Collected %d samples in %d ms.\n", samples_collected, TEST_SAMPLING_PERIOD);
|
||||
|
||||
/*
|
||||
* Test of Logging to UART
|
||||
* Logging to UART
|
||||
*/
|
||||
ESP_LOGI(TAG, "Sampling ADC and sending data to the UART...");
|
||||
samples_collected = adc1_sample_and_show(TEST_SAMPLING_PERIOD);
|
||||
@ -133,8 +119,3 @@ void test_task(void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void app_main()
|
||||
{
|
||||
xTaskCreate(test_task, "test_task", 1024 * 3, NULL, 10, NULL);
|
||||
}
|
Loading…
Reference in New Issue
Block a user