Skip to content

Commit 53781ed

Browse files
committed
Add TraceX support
1 parent fb88f2b commit 53781ed

4 files changed

Lines changed: 192 additions & 0 deletions

File tree

threadX/traceX/inc/traceout.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/**
2+
* @file traceout.h
3+
* @brief TraceX data output interface.
4+
*/
5+
6+
#ifndef TRACEOUT_H
7+
#define TRACEOUT_H
8+
9+
#include <stdint.h>
10+
11+
/* Size of each transmitted chunk */
12+
#define TRACEOUT_CHUNK_BYTES (1024U)
13+
14+
/**
15+
* @brief Platform transmit callback.
16+
*
17+
* Must initiate a non-blocking transmit (DMA / IT).
18+
*
19+
* @param data Pointer to data buffer.
20+
* @param len Number of bytes to transmit.
21+
*/
22+
typedef void (*traceout_tx_fn_t)(const uint8_t *data, uint16_t len);
23+
24+
/**
25+
* @brief Initialize trace output streaming.
26+
*
27+
* @param tx_fn Platform transmit callback.
28+
*/
29+
void traceout_init(traceout_tx_fn_t tx_fn);
30+
31+
/**
32+
* @brief Start trace output from ISR context.
33+
*/
34+
void traceout_start_from_isr(void);
35+
36+
/**
37+
* @brief Notify trace output that transmit completed (ISR context).
38+
*/
39+
void traceout_on_tx_complete_from_isr(void);
40+
41+
#endif /* TRACEOUT_H */

threadX/traceX/inc/tracex.h

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/**
2+
* @file tracex.h
3+
* @brief TraceX control interface.
4+
*
5+
*/
6+
7+
#ifndef TRACEX_H
8+
#define TRACEX_H
9+
10+
#include "tx_api.h"
11+
#include <stdint.h>
12+
13+
/**
14+
* @brief Initialize TraceX with a user-provided buffer.
15+
*
16+
* This must be called once before starting TraceX.
17+
*
18+
* @param buffer Pointer to trace buffer.
19+
* @param size Size of trace buffer in bytes.
20+
*/
21+
void tracex_init(UCHAR *buffer, uint32_t size);
22+
23+
/**
24+
* @brief Start TraceX recording.
25+
*
26+
* Safe to call multiple times.
27+
*/
28+
void tracex_start(void);
29+
30+
/**
31+
* @brief Stop TraceX recording.
32+
*
33+
* Safe to call multiple times.
34+
*/
35+
void tracex_stop(void);
36+
37+
/**
38+
* @brief Get the TraceX buffer pointer.
39+
*
40+
* @return Pointer to trace buffer.
41+
*/
42+
UCHAR *tracex_get_buffer(void);
43+
44+
/**
45+
* @brief Get the TraceX buffer size.
46+
*
47+
* @return Buffer size in bytes.
48+
*/
49+
uint32_t tracex_get_buffer_size(void);
50+
51+
#endif /* TRACEX_H */

threadX/traceX/src/traceout.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/**
2+
* @file traceout.c
3+
* @brief TraceX data output interface.
4+
*/
5+
6+
#include "traceout.h"
7+
#include "tracex.h"
8+
9+
static traceout_tx_fn_t s_tx_fn = NULL;
10+
static volatile uint8_t s_output_active = 0U;
11+
static const uint8_t *s_dp = NULL;
12+
static uint32_t s_remaining = 0U;
13+
14+
static void start_next_chunk(void) {
15+
if (s_remaining == 0U) {
16+
s_output_active = 0U;
17+
tracex_start();
18+
return;
19+
}
20+
21+
uint32_t n =
22+
(s_remaining > TRACEOUT_CHUNK_BYTES) ? TRACEOUT_CHUNK_BYTES : s_remaining;
23+
24+
s_tx_fn(s_dp, (uint16_t)n);
25+
s_dp += n;
26+
s_remaining -= n;
27+
}
28+
29+
void traceout_init(traceout_tx_fn_t tx_fn) { s_tx_fn = tx_fn; }
30+
31+
void traceout_start_from_isr(void) {
32+
if ((s_tx_fn == NULL) || (s_output_active != 0U)) {
33+
return;
34+
}
35+
36+
tracex_stop();
37+
38+
s_dp = tracex_get_buffer();
39+
s_remaining = tracex_get_buffer_size();
40+
s_output_active = 1U;
41+
42+
start_next_chunk();
43+
}
44+
45+
void traceout_on_tx_complete_from_isr(void) {
46+
if (s_output_active != 0U) {
47+
start_next_chunk();
48+
}
49+
}

threadX/traceX/src/tracex.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/**
2+
* @file tracex.c
3+
* @brief TraceX control interface.
4+
*
5+
*/
6+
7+
#include "tracex.h"
8+
#include <stdbool.h>
9+
10+
/**
11+
* @brief Enable the CPU cycle counter used by TraceX timestamps.
12+
*
13+
* This function is implemented by the application or platform layer.
14+
* It must enable a free-running CPU cycle counter before TraceX is started.
15+
*
16+
* It is called once from tracex_start().
17+
*/
18+
void tracex_enable_cycle_counter(void);
19+
20+
static UCHAR *s_trace_buffer = NULL;
21+
static uint32_t s_trace_size = 0U;
22+
static bool s_tracex_started = false;
23+
24+
void tracex_init(UCHAR *buffer, uint32_t size) {
25+
s_trace_buffer = buffer;
26+
s_trace_size = size;
27+
}
28+
29+
UCHAR *tracex_get_buffer(void) { return s_trace_buffer; }
30+
31+
uint32_t tracex_get_buffer_size(void) { return s_trace_size; }
32+
33+
void tracex_start(void) {
34+
if ((s_tracex_started == true) || (s_trace_buffer == NULL) ||
35+
(s_trace_size == 0U)) {
36+
return;
37+
}
38+
39+
tracex_enable_cycle_counter();
40+
tx_trace_enable(s_trace_buffer, s_trace_size, 32U);
41+
s_tracex_started = true;
42+
}
43+
44+
void tracex_stop(void) {
45+
if (s_tracex_started == false) {
46+
return;
47+
}
48+
49+
tx_trace_disable();
50+
s_tracex_started = false;
51+
}

0 commit comments

Comments
 (0)