ThreadX provides built-in event trace support for all ThreadX services, thread state changes, and user-defined events. To use event trace, simply build the ThreadX, NetX Duo, and FileX libraries with TX_ENABLE_EVENT_TRACE defined and enable tracing by calling the tx_trace_enable function. This chapter describes that process.
Event Trace Format
The format of the ThreadX event trace buffer is divided into three sections, namely the control header, object registry, and the trace entries. The following describes the general layout of the ThreadX event trace buffer:
Control Header
Object Registry Entry 0
…
Object Register Entry "n"
Event Trace Entry 0
…
Event Trace Entry "n"
Event Trace Control Header
The control header defines the exact layout of the event trace buffer. This includes how many ThreadX objects can be registered as well as how many events can be recorded. In addition, the control header defines where each of the elements of the trace buffer resides. The following data structure defines the control header:
typedef struct TX_TRACE_CONTROL_HEADER_STRUCT
{
ULONG tx_trace_control_header_id;
ULONG tx_trace_control_header_timer_valid_mask;
ULONG tx_trace_control_header_trace_base_address;
ULONG tx_trace_control_header_object_registry_start_pointer;
USHORT tx_trace_control_header_reserved1;
USHORT tx_trace_control_header_object_registry_name_size;
ULONG tx_trace_control_header_object_registry_end_pointer;
ULONG tx_trace_control_header_buffer_start_pointer;
ULONG tx_trace_control_header_buffer_end_pointer;
ULONG tx_trace_control_header_buffer_current_pointer;
ULONG tx_trace_control_header_reserved2;
ULONG tx_trace_control_header_reserved3;
ULONG tx_trace_control_header_reserved4;
} TX_TRACE_CONTROL_HEADER;
Control Header ID
The control header ID consists of the 32-bit HEX value of 0x54585442, which corresponds to the ASCII characters TXTB. Since this value is written as a 32-bit unsigned variable, it can also be used to detect the endianness of the event trace buffer. For example, if the value in the first four byes of memory is 0x54, 0x58, 0x54, 0x42, the event trace buffer was written in big endian format. Otherwise, the event trace buffer was written in little endian format.
Timer Valid Mask
The timer valid mask defines how many bits of the timestamp in the actual event trace entries are valid. For example, if the time-stamp source has 16-bits, the value in this field should be 0xFFFF. A 32-bit time-stamp source would have a value of 0xFFFFFFFF. This value is defined by the TX_TRACE_TIME_MASK constant in tx_port.h.
Trace Base Address
The trace buffer base address is the address the application specified as the start of the trace buffer in the tx_trace_enable call. This address is maintained for the sole use of the analysis tool to derive bufferrelative offsets for the various elements in the buffer. For example, the buffer relative offset of the current event in the trace buffer is calculated by simple subtraction of the base address from the current event address.
Registry Start and End Pointers
The registry start pointer points to the address of the first object registry entry, while the registry end pointer points to the address im../mediately following the last register entry. These values are setup during the tx_trace_enable processing and are not changed throughout the duration of tracing.
Registry Name Size
The registry name size defines maximum size in bytes for each object name in the registry entry and is defined by the symbol TX_TRACE_OBJECT_REGISTRY_NAME. The default value is 32 and is defined in tx_trace.h. The object name corresponds to the name given by the application when the object was created. For example, the object registry name for a thread is the name supplied by the application to the tx_thread_createcall.
Buffer Start and End Pointers
The event trace buffer start pointer points to the address of the first trace entry, while the registry end pointer points to the address im../mediately following the last trace entry. These values are setup during the tx_trace_enable</ processing and are not changed throughout the duration of tracing.
Current Buffer Pointer
The event trace buffer current pointer points to the address of the oldest trace entry. Since the trace entries are maintained in a circular list, the current buffer pointer is also represents the next trace entry to be written. |
Event Trace Object Registry
The event trace object registry contains n object registry entries that correspond to the objects created by the application. The main purpose of the object registry is for external analysis tools to correlate actual object names with the object addresses of the trace buffer entries. The number of registry entries is specified by the application in the tx_trace_enable call.
Each object register entry contains information about a specific ThreadX object previously created by the application. The following data structure defines each object registry entry:
typedef struct TX_TRACE_OBJECT_REGISTRY_ENTRY_STRUCT
{
UCHAR tx_trace_object_registry_entry_object_available**;
UCHAR tx_trace_object_registry_entry_object_type**;
UCHAR tx_trace_object_registry_entry_object_reserved1;
UCHAR tx_trace_object_registry_entry_object_reserved2;
ULONG tx_trace_thread_registry_entry_object_pointer;
ULONG tx_trace_object_registry_entry_object_parameter_1;
ULONG tx_trace_object_registry_entry_object_parameter_2;
UCHAR tx_trace_thread_registry_entry_object_name[TX_TRACE_OBJECT_REGISTRY_NAME];
} TX_TRACE_OBJECT_REGISTRY_ENTRY;
Object Available Flag
The object available flag is set to 1 if the object registry entry is available. Otherwise, if the value is not 1, the object registry entry is not available. Note that the entry could still contain valid information even though it is available.
Object Entry Type
The object entry type identifies the type of object in this entry. The following is a list of the valid object types:
| Value | Object Type |
|---|---|
0 |
Not Valid |
1 |
Thread |
2 |
Timer |
3 |
Queue |
4 |
Semaphore |
5 |
Mutex |
6 |
Event Flags Group |
7 |
Block Pool |
8 |
Byte Pool |
9 |
../media |
10 |
File |
11 |
IP |
12 |
Packet Pool |
13 |
TCP Socket |
14 |
UDP Socket |
15-20 |
Reserved |
21 |
USB Host Stack Device |
22 |
USB Host Stack Interface |
23 |
USB Host Endpoint |
24 |
USB Host Class |
25 |
USB Device |
26 |
USB Device Interface |
27 |
USB Device Endpoint |
28 |
USB Device Class |
Object Pointer
The object pointer specifies the object address that is used for accessing the object using the ThreadX API.
Object Reserved Fields
For all objects other than threads, these reserved fields should be 0. For threads, the priority of the thread at the time it is entered into the registry is placed in these two reserved fields.
Object Parameters
The object parameters contain supplemental information about the object. The following describes the supplemental information for each ThreadX object:
| Object Type | Parameter 1 | Parameter 2 |
|---|---|---|
Thread |
Stack Start |
Stack Size |
Timer |
Initial Ticks |
Reschedule Ticks |
Queue |
Queue Size |
Message Size |
Semaphore |
Initial Instances |
- |
Mutex |
Inheritance Flag |
- |
Event Flags Group |
- |
- |
Block Pool |
Total Blocks |
Block Size |
Byte Pool |
Total Bytes |
- |
../media |
Fat Cache Size |
Sector Cache Size |
File |
- |
- |
IP |
Stack Start |
Stack Size |
Packet Pool |
Packet Size |
Number of Packets |
TCP Socket |
IP address |
Window Size |
UDP Socket |
IP address |
RX Queue Max |
Object Name
The object name contains the name of the ThreadX object. The name is the name provided to ThreadX at the time the object was created. By default, the object name has a maximum of 32 characters. Actual names greater than 32 characters are truncated.
Event Trace Entries
The event trace entries are found in the bottom portion of the event trace buffer. The entries are maintained in a circular list, with the current entry pointer pointing to the oldest entry. The number of entries in the list is calculated by the tx_trace_enable call.
Each object register entry contains information about a specific ThreadX trace event. The following data structure defines each trace event entry:
typedef struct TX_TRACE_BUFFER_ENTRY_STRUCT
{
ULONG tx_trace_buffer_entry_thread_pointer;
ULONG tx_trace_buffer_entry_thread_priority;
ULONG tx_trace_buffer_entry_event_id;
ULONG tx_trace_buffer_entry_time_stamp;
ULONG tx_trace_buffer_entry_information_field_1;
ULONG tx_trace_buffer_entry_information_field_2;
ULONG tx_trace_buffer_entry_information_field_3;
ULONG tx_trace_buffer_entry_information_field_4;
} TX_TRACE_BUFFER_ENTRY;
Thread Pointer
The thread pointer contains the address of the thread running at the time of this event. If the event occurred during initialization (no thread running), the value of this pointer is 0xF0F0F0F0. If the event occurred during an Interrupt Service Routine (ISR), the value of this pointer is 0xFFFFFFFF. If the entry has not yet been used, the value of this pointer is 0.
Thread Priority
The thread priority field contains the thread priority and preemption-threshold of the thread that was running at the time of this event. If an interrupt context is present (thread pointer is 0xFFFFFFFF), the value of this field is not the priority but instead the value of _tx_thread_current_ptr at the time of the event. Otherwise, the value of this field is 0.
Event ID
The event ID specifies the event that took place. Valid ThreadX trace event IDs range from 1 through 1024. Values starting at 1025 and above are reserved for user-specific events. Please refer to the tx_trace.h file for the complete definition of ThreadX event IDs.</td>
Information Fields (1-4)
The information fields contain additional information about the specific event. Please refer to the tx_trace.h file for the complete description of the information fields for each of the defined ThreadX event IDs.