1790 lines
72 KiB
C
1790 lines
72 KiB
C
|
/*******************************************************************************
|
||
|
* Trace Recorder Library for Tracealyzer v4.1.5
|
||
|
* Percepio AB, www.percepio.com
|
||
|
*
|
||
|
* trcRecorder.h
|
||
|
*
|
||
|
* The public API of the trace recorder.
|
||
|
*
|
||
|
* Terms of Use
|
||
|
* This file is part of the trace recorder library (RECORDER), which is the
|
||
|
* intellectual property of Percepio AB (PERCEPIO) and provided under a
|
||
|
* license as follows.
|
||
|
* The RECORDER may be used free of charge for the purpose of recording data
|
||
|
* intended for analysis in PERCEPIO products. It may not be used or modified
|
||
|
* for other purposes without explicit permission from PERCEPIO.
|
||
|
* You may distribute the RECORDER in its original source code form, assuming
|
||
|
* this text (terms of use, disclaimer, copyright notice) is unchanged. You are
|
||
|
* allowed to distribute the RECORDER with minor modifications intended for
|
||
|
* configuration or porting of the RECORDER, e.g., to allow using it on a
|
||
|
* specific processor, processor family or with a specific communication
|
||
|
* interface. Any such modifications should be documented directly below
|
||
|
* this comment block.
|
||
|
*
|
||
|
* Disclaimer
|
||
|
* The RECORDER is being delivered to you AS IS and PERCEPIO makes no warranty
|
||
|
* as to its use or performance. PERCEPIO does not and cannot warrant the
|
||
|
* performance or results you may obtain by using the RECORDER or documentation.
|
||
|
* PERCEPIO make no warranties, express or implied, as to noninfringement of
|
||
|
* third party rights, merchantability, or fitness for any particular purpose.
|
||
|
* In no event will PERCEPIO, its technology partners, or distributors be liable
|
||
|
* to you for any consequential, incidental or special damages, including any
|
||
|
* lost profits or lost savings, even if a representative of PERCEPIO has been
|
||
|
* advised of the possibility of such damages, or for any claim by any third
|
||
|
* party. Some jurisdictions do not allow the exclusion or limitation of
|
||
|
* incidental, consequential or special damages, or the exclusion of implied
|
||
|
* warranties or limitations on how long an implied warranty may last, so the
|
||
|
* above limitations may not apply to you.
|
||
|
*
|
||
|
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
||
|
*
|
||
|
* Copyright Percepio AB, 2018.
|
||
|
* www.percepio.com
|
||
|
******************************************************************************/
|
||
|
|
||
|
#ifndef TRC_RECORDER_H
|
||
|
#define TRC_RECORDER_H
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
extern "C" {
|
||
|
#endif
|
||
|
|
||
|
#include <stdint.h>
|
||
|
#include <stddef.h>
|
||
|
|
||
|
#include "trcConfig.h"
|
||
|
#include "trcPortDefines.h"
|
||
|
|
||
|
|
||
|
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)
|
||
|
typedef uint16_t traceString;
|
||
|
typedef uint8_t traceUBChannel;
|
||
|
typedef uint8_t traceObjectClass;
|
||
|
|
||
|
#if (TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1)
|
||
|
typedef uint16_t traceHandle;
|
||
|
#else
|
||
|
typedef uint8_t traceHandle;
|
||
|
#endif
|
||
|
|
||
|
#include "trcHardwarePort.h"
|
||
|
#include "trcKernelPort.h"
|
||
|
|
||
|
// Not available in snapshot mode
|
||
|
#define vTraceConsoleChannelPrintF(fmt, ...)
|
||
|
|
||
|
#endif
|
||
|
|
||
|
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
|
||
|
|
||
|
typedef const char* traceString;
|
||
|
typedef const void* traceHandle;
|
||
|
|
||
|
#include "trcHardwarePort.h"
|
||
|
#include "trcStreamingPort.h"
|
||
|
#include "trcKernelPort.h"
|
||
|
|
||
|
#endif
|
||
|
|
||
|
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
|
||
|
|
||
|
/* The user event channel for recorder warnings, must be defined in trcKernelPort.c */
|
||
|
extern traceString trcWarningChannel;
|
||
|
|
||
|
#define TRACE_GET_LOW16(value) ((uint16_t)((value) & 0x0000FFFF))
|
||
|
#define TRACE_GET_HIGH16(value) ((uint16_t)(((value) >> 16) & 0x0000FFFF))
|
||
|
#define TRACE_SET_LOW16(current, value) (((current) & 0xFFFF0000) | (value))
|
||
|
#define TRACE_SET_HIGH16(current, value) (((current) & 0x0000FFFF) | (((uint32_t)(value)) << 16))
|
||
|
|
||
|
/******************************************************************************/
|
||
|
/*** Common API - both Snapshot and Streaming mode ****************************/
|
||
|
/******************************************************************************/
|
||
|
|
||
|
/******************************************************************************
|
||
|
* vTraceEnable(int startOption);
|
||
|
*
|
||
|
* Initializes and optionally starts the trace, depending on the start option.
|
||
|
* To use the trace recorder, the startup must call vTraceEnable before any RTOS
|
||
|
* calls are made (including "create" calls). Three start options are provided:
|
||
|
*
|
||
|
* TRC_START: Starts the tracing directly. In snapshot mode this allows for
|
||
|
* starting the trace at any point in your code, assuming vTraceEnable(TRC_INIT)
|
||
|
* has been called in the startup.
|
||
|
* Can also be used for streaming without Tracealyzer control, e.g. to a local
|
||
|
* flash file system (assuming such a "stream port", see trcStreamingPort.h).
|
||
|
*
|
||
|
* TRC_START_AWAIT_HOST: For streaming mode only. Initializes the trace recorder
|
||
|
* if necessary and waits for a Start command from Tracealyzer ("Start Recording"
|
||
|
* button). This call is intentionally blocking! By calling vTraceEnable with
|
||
|
* this option from the startup code, you start tracing at this point and capture
|
||
|
* the early events.
|
||
|
*
|
||
|
* TRC_INIT: Initializes the trace recorder, but does not start the tracing.
|
||
|
* In snapshot mode, this must be followed by a vTraceEnable(TRC_START) sometime
|
||
|
* later.
|
||
|
*
|
||
|
* Usage examples:
|
||
|
*
|
||
|
* Snapshot trace, from startup:
|
||
|
* <board init>
|
||
|
* vTraceEnable(TRC_START);
|
||
|
* <RTOS init>
|
||
|
*
|
||
|
* Snapshot trace, from a later point:
|
||
|
* <board init>
|
||
|
* vTraceEnable(TRC_INIT);
|
||
|
* <RTOS init>
|
||
|
* ...
|
||
|
* vTraceEnable(TRC_START); // e.g., in task context, at some relevant event
|
||
|
*
|
||
|
* Streaming trace, from startup:
|
||
|
* <board init>
|
||
|
* vTraceEnable(TRC_START_AWAIT_HOST); // Blocks!
|
||
|
* <RTOS init>
|
||
|
*
|
||
|
* Streaming trace, from a later point:
|
||
|
* <board startup>
|
||
|
* vTraceEnable(TRC_INIT);
|
||
|
* <RTOS startup>
|
||
|
*
|
||
|
******************************************************************************/
|
||
|
void vTraceEnable(int startOption);
|
||
|
|
||
|
/******************************************************************************
|
||
|
* vTracePrintF
|
||
|
*
|
||
|
* Generates "User Events", with formatted text and data, similar to a "printf".
|
||
|
* User Events can be used for very efficient logging from your application code.
|
||
|
* It is very fast since the actual string formatting is done on the host side,
|
||
|
* when the trace is displayed. The execution time is just some microseconds on
|
||
|
* a 32-bit MCU.
|
||
|
*
|
||
|
* User Events are shown as yellow labels in the main trace view of $PNAME.
|
||
|
*
|
||
|
* An advantage of User Events is that data can be plotted in the "User Event
|
||
|
* Signal Plot" view, visualizing any data you log as User Events, discrete
|
||
|
* states or control system signals (e.g. system inputs or outputs).
|
||
|
*
|
||
|
* You may group User Events into User Event Channels. The yellow User Event
|
||
|
* labels show the logged string, preceded by the channel name within brackets.
|
||
|
*
|
||
|
* Example:
|
||
|
*
|
||
|
* "[MyChannel] Hello World!"
|
||
|
*
|
||
|
* The User Event Channels are shown in the View Filter, which makes it easy to
|
||
|
* select what User Events you wish to display. User Event Channels are created
|
||
|
* using xTraceRegisterString().
|
||
|
*
|
||
|
* Example:
|
||
|
*
|
||
|
* traceString adc_uechannel = xTraceRegisterString("ADC User Events");
|
||
|
* ...
|
||
|
* vTracePrintF(adc_uechannel,
|
||
|
* "ADC channel %d: %d volts",
|
||
|
* ch, adc_reading);
|
||
|
*
|
||
|
* The following format specifiers are supported in both modes:
|
||
|
* %d - signed integer.
|
||
|
* %u - unsigned integer.
|
||
|
* %X - hexadecimal, uppercase.
|
||
|
* %x - hexadecimal, lowercase.
|
||
|
* %s - string (see comment below)
|
||
|
*
|
||
|
* For integer formats (%d, %u, %x, %X) you may also use width and padding.
|
||
|
* If using -42 as data argument, two examples are:
|
||
|
* "%05d" -> "-0042"
|
||
|
* "%5d" -> " -42".
|
||
|
*
|
||
|
* String arguments are supported in both snapshot and streaming, but in streaming
|
||
|
* mode you need to use xTraceRegisterString and use the returned traceString as
|
||
|
* the argument. In snapshot you simply provide a char* as argument.
|
||
|
*
|
||
|
* Snapshot: vTracePrintF(myChn, "my string: %s", str);
|
||
|
* Streaming: vTracePrintF(myChn, "my string: %s", xTraceRegisterString(str));
|
||
|
*
|
||
|
* In snapshot mode you can specify 8-bit or 16-bit arguments to reduce RAM usage:
|
||
|
* %hd -> 16 bit (h) signed integer (d).
|
||
|
* %bu -> 8 bit (b) unsigned integer (u).
|
||
|
*
|
||
|
* However, in streaming mode all data arguments are assumed to be 32 bit wide.
|
||
|
* Width specifiers (e.g. %hd) are accepted but ignored (%hd treated like %d).
|
||
|
*
|
||
|
* The maximum event size also differs between the modes. In streaming this is
|
||
|
* limited by a maximum payload size of 52 bytes, including format string and
|
||
|
* data arguments. So if using one data argument, the format string is limited
|
||
|
* to 48 byte, etc. If this is exceeded, the format string is truncated and you
|
||
|
* get a warning in Tracealyzer.
|
||
|
*
|
||
|
* In snapshot mode you are limited to maximum 15 arguments, that must not exceed
|
||
|
* 32 bytes in total (not counting the format string). If exceeded, the recorder
|
||
|
* logs an internal error (displayed when opening the trace) and stops recording.
|
||
|
******************************************************************************/
|
||
|
#if (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)
|
||
|
void vTracePrintF(traceString chn, const char* fmt, ...);
|
||
|
#else
|
||
|
#define vTracePrintF(chn, ...) (void)chn
|
||
|
#endif
|
||
|
|
||
|
/******************************************************************************
|
||
|
* vTracePrint
|
||
|
*
|
||
|
* A faster version of vTracePrintF, that only allows for logging a string.
|
||
|
*
|
||
|
* Example:
|
||
|
*
|
||
|
* traceString chn = xTraceRegisterString("MyChannel");
|
||
|
* ...
|
||
|
* vTracePrint(chn, "Hello World!");
|
||
|
******************************************************************************/
|
||
|
#if (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)
|
||
|
void vTracePrint(traceString chn, const char* str);
|
||
|
#else
|
||
|
#define vTracePrint(chn, ...) (void)chn
|
||
|
#endif
|
||
|
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* vTraceConsoleChannelPrintF
|
||
|
*
|
||
|
* Wrapper for vTracePrint, using the default channel. Can be used as a drop-in
|
||
|
* replacement for printf and similar functions, e.g. in a debug logging macro.
|
||
|
*
|
||
|
* Example:
|
||
|
*
|
||
|
* // Old: #define LogString debug_console_printf
|
||
|
*
|
||
|
* // New, log to Tracealyzer instead:
|
||
|
* #define LogString vTraceConsoleChannelPrintF
|
||
|
* ...
|
||
|
* LogString("My value is: %d", myValue);
|
||
|
******************************************************************************/
|
||
|
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
|
||
|
void vTraceConsoleChannelPrintF(const char* fmt, ...);
|
||
|
#endif
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* xTraceRegisterString
|
||
|
*
|
||
|
* Register strings in the recorder, e.g. for names of user event channels.
|
||
|
*
|
||
|
* Example:
|
||
|
* myEventHandle = xTraceRegisterString("MyUserEvent");
|
||
|
* ...
|
||
|
* vTracePrintF(myEventHandle, "My value is: %d", myValue);
|
||
|
******************************************************************************/
|
||
|
#if (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)
|
||
|
traceString xTraceRegisterString(const char* name);
|
||
|
#else
|
||
|
#define xTraceRegisterString(x) (x)
|
||
|
#endif
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* vTraceSet...Name(void* object, const char* name)
|
||
|
*
|
||
|
* Parameter object: pointer to the kernel object that shall be named
|
||
|
* Parameter name: the name to set
|
||
|
*
|
||
|
* Kernel-specific functions for setting names of kernel objects, for display in
|
||
|
* Tracealyzer.
|
||
|
******************************************************************************/
|
||
|
/* See trcKernelPort.h for details (kernel-specific) */
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* xTraceSetISRProperties
|
||
|
*
|
||
|
* Stores a name and priority level for an Interrupt Service Routine, to allow
|
||
|
* for better visualization. Returns a traceHandle used by vTraceStoreISRBegin.
|
||
|
*
|
||
|
* Example:
|
||
|
* #define PRIO_ISR_TIMER1 3 // the hardware priority of the interrupt
|
||
|
* ...
|
||
|
* traceHandle Timer1Handle = xTraceSetISRProperties("ISRTimer1", PRIO_ISR_TIMER1);
|
||
|
* ...
|
||
|
* void ISR_handler()
|
||
|
* {
|
||
|
* vTraceStoreISRBegin(Timer1Handle);
|
||
|
* ...
|
||
|
* vTraceStoreISREnd(0);
|
||
|
* }
|
||
|
******************************************************************************/
|
||
|
traceHandle xTraceSetISRProperties(const char* name, uint8_t priority);
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* vTraceStoreISRBegin
|
||
|
*
|
||
|
* Registers the beginning of an Interrupt Service Routine, using a traceHandle
|
||
|
* provided by xTraceSetISRProperties.
|
||
|
*
|
||
|
* Example:
|
||
|
* #define PRIO_ISR_TIMER1 3 // the hardware priority of the interrupt
|
||
|
* ...
|
||
|
* traceHandle Timer1Handle = xTraceSetISRProperties("ISRTimer1", PRIO_ISR_TIMER1);
|
||
|
* ...
|
||
|
* void ISR_handler()
|
||
|
* {
|
||
|
* vTraceStoreISRBegin(Timer1Handle);
|
||
|
* ...
|
||
|
* vTraceStoreISREnd(0);
|
||
|
* }
|
||
|
******************************************************************************/
|
||
|
void vTraceStoreISRBegin(traceHandle handle);
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* vTraceStoreISREnd
|
||
|
*
|
||
|
* Registers the end of an Interrupt Service Routine.
|
||
|
*
|
||
|
* The parameter pendingISR indicates if the interrupt has requested a
|
||
|
* task-switch (= 1), e.g., by signaling a semaphore. Otherwise (= 0) the
|
||
|
* interrupt is assumed to return to the previous context.
|
||
|
*
|
||
|
* Example:
|
||
|
* #define PRIO_OF_ISR_TIMER1 3 // the hardware priority of the interrupt
|
||
|
* traceHandle traceHandleIsrTimer1 = 0; // The ID set by the recorder
|
||
|
* ...
|
||
|
* traceHandleIsrTimer1 = xTraceSetISRProperties("ISRTimer1", PRIO_OF_ISR_TIMER1);
|
||
|
* ...
|
||
|
* void ISR_handler()
|
||
|
* {
|
||
|
* vTraceStoreISRBegin(traceHandleIsrTimer1);
|
||
|
* ...
|
||
|
* vTraceStoreISREnd(0);
|
||
|
* }
|
||
|
******************************************************************************/
|
||
|
void vTraceStoreISREnd(int isTaskSwitchRequired);
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* vTraceInstanceFinishNow
|
||
|
*
|
||
|
* Creates an event that ends the current task instance at this very instant.
|
||
|
* This makes the viewer to splits the current fragment at this point and begin
|
||
|
* a new actor instance, even if no task-switch has occurred.
|
||
|
*****************************************************************************/
|
||
|
void vTraceInstanceFinishedNow(void);
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* vTraceInstanceFinishedNext
|
||
|
*
|
||
|
* Marks the current "task instance" as finished on the next kernel call.
|
||
|
*
|
||
|
* If that kernel call is blocking, the instance ends after the blocking event
|
||
|
* and the corresponding return event is then the start of the next instance.
|
||
|
* If the kernel call is not blocking, the viewer instead splits the current
|
||
|
* fragment right before the kernel call, which makes this call the first event
|
||
|
* of the next instance.
|
||
|
*****************************************************************************/
|
||
|
void vTraceInstanceFinishedNext(void);
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* xTraceGetLastError
|
||
|
*
|
||
|
* Returns the last error or warning as a string, or NULL if none.
|
||
|
*****************************************************************************/
|
||
|
const char* xTraceGetLastError(void);
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* vTraceClearError
|
||
|
*
|
||
|
* Clears any errors.
|
||
|
*****************************************************************************/
|
||
|
void vTraceClearError(void);
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* vTraceStop
|
||
|
*
|
||
|
* Stops the recording. Intended for snapshot mode or if streaming without
|
||
|
* Tracealyzer control (e.g., to a device file system).
|
||
|
******************************************************************************/
|
||
|
void vTraceStop(void);
|
||
|
|
||
|
/******************************************************************************
|
||
|
* vTraceSetFrequency
|
||
|
*
|
||
|
* Registers the clock rate of the time source for the event timestamping.
|
||
|
* This is normally not required, but if the default value (TRC_HWTC_FREQ_HZ)
|
||
|
* should be incorrect for your setup, you can override it using this function.
|
||
|
*
|
||
|
* Must be called prior to vTraceEnable, and the time source is assumed to
|
||
|
* have a fixed clock frequency after the startup.
|
||
|
*
|
||
|
* Note that, in snapshot mode, the value is divided by the TRC_HWTC_DIVISOR.
|
||
|
* This is a software "prescaler" that is also applied on the timestamps.
|
||
|
*****************************************************************************/
|
||
|
void vTraceSetFrequency(uint32_t frequency);
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* vTraceSetRecorderDataBuffer
|
||
|
*
|
||
|
* The trcConfig.h setting TRC_CFG_RECORDER_BUFFER_ALLOCATION allows for selecting
|
||
|
* custom allocation (TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM), which allows you to
|
||
|
* control where the recorder trace buffer is allocated.
|
||
|
*
|
||
|
* When custom allocation is selected, use TRC_ALLOC_CUSTOM_BUFFER to make the
|
||
|
* allocation (in global context) and then call vTraceSetRecorderDataBuffer to
|
||
|
* register the allocated buffer. This supports both snapshot and streaming,
|
||
|
* and has no effect if using other allocation modes than CUSTOM.
|
||
|
*
|
||
|
* NOTE: vTraceSetRecorderDataBuffer must be called before vTraceEnable.
|
||
|
******************************************************************************/
|
||
|
#if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM)
|
||
|
void vTraceSetRecorderDataBuffer(void* pRecorderData);
|
||
|
#else
|
||
|
#define vTraceSetRecorderDataBuffer(pRecorderData)
|
||
|
#endif
|
||
|
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* TRC_ALLOC_CUSTOM_BUFFER
|
||
|
*
|
||
|
* If using custom allocation of the trace buffer (i.e., your trcConfig.h has the
|
||
|
* setting TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM), this macro allows you to declare
|
||
|
* the trace buffer in a portable way that works both in snapshot and streaming.
|
||
|
*
|
||
|
* This macro has no effect if using another allocation mode, so you can easily
|
||
|
* switch between different recording modes and configurations, using the same
|
||
|
* initialization code.
|
||
|
*
|
||
|
* This translates to a single static allocation, on which you can apply linker
|
||
|
* directives to place it in a particular memory region.
|
||
|
*
|
||
|
* - Snapshot mode: "RecorderDataType <name>"
|
||
|
*
|
||
|
* - Streaming mode: "char <name> [<size>]",
|
||
|
* where <size> is defined in trcStreamingConfig.h.
|
||
|
*
|
||
|
* Example:
|
||
|
*
|
||
|
* // GCC example: place myTraceBuffer in section .tz, defined in the .ld file.
|
||
|
* TRC_ALLOC_CUSTOM_BUFFER(myTraceBuffer) __attribute__((section(".tz")));
|
||
|
*
|
||
|
* int main(void)
|
||
|
* {
|
||
|
* ...
|
||
|
* vTraceSetRecorderDataBuffer(&myTraceBuffer); // Note the "&"
|
||
|
* ...
|
||
|
* vTraceEnable(TRC_INIT); // Initialize the data structure
|
||
|
******************************************************************************/
|
||
|
#if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM)
|
||
|
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)
|
||
|
#define TRC_ALLOC_CUSTOM_BUFFER(bufname) RecorderDataType bufname;
|
||
|
#elif (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
|
||
|
#ifdef TRC_CFG_RTT_BUFFER_SIZE_UP /* J-Link RTT */
|
||
|
#define TRC_ALLOC_CUSTOM_BUFFER(bufname) char bufname [TRC_CFG_RTT_BUFFER_SIZE_UP]; /* Not static in this case, since declared in user code */
|
||
|
#else
|
||
|
#define TRC_ALLOC_CUSTOM_BUFFER(bufname) char bufname [(TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT) * (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE)];
|
||
|
#endif
|
||
|
#endif
|
||
|
#else
|
||
|
#define TRC_ALLOC_CUSTOM_BUFFER(bufname)
|
||
|
#endif
|
||
|
|
||
|
/******************************************************************************
|
||
|
* xTraceIsRecordingEnabled
|
||
|
*
|
||
|
* Returns true (1) if the recorder is enabled (i.e. is recording), otherwise 0.
|
||
|
******************************************************************************/
|
||
|
int xTraceIsRecordingEnabled(void);
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* vTraceSetFilterGroup
|
||
|
*
|
||
|
* Sets the "filter group" to assign when creating RTOS objects, such as tasks,
|
||
|
* queues, semaphores and mutexes. This together with vTraceSetFilterMask
|
||
|
* allows you to control what events that are recorded, based on the
|
||
|
* objects they refer to.
|
||
|
*
|
||
|
* There are 16 filter groups named FilterGroup0 .. FilterGroup15.
|
||
|
*
|
||
|
* Note: We don't recommend filtering out the Idle task, so make sure to call
|
||
|
* vTraceSetFilterGroup just before initializing the RTOS, in order to assign
|
||
|
* such "default" objects to the right Filter Group (typically group 0).
|
||
|
*
|
||
|
* Example:
|
||
|
*
|
||
|
* // Assign tasks T1 to FilterGroup0 (default)
|
||
|
* <Create Task T1>
|
||
|
*
|
||
|
* // Assign Q1 and Q2 to FilterGroup1
|
||
|
* vTraceSetFilterGroup(FilterGroup1);
|
||
|
* <Create Queue Q1>
|
||
|
* <Create Queue Q2>
|
||
|
*
|
||
|
* // Assigns Q3 to FilterGroup2
|
||
|
* vTraceSetFilterGroup(FilterGroup2);
|
||
|
* <Create Queue Q3>
|
||
|
*
|
||
|
* // Only include FilterGroup0 and FilterGroup2, exclude FilterGroup1 (Q1 and Q2) from the trace
|
||
|
* vTraceSetFilterMask( FilterGroup0 | FilterGroup2 );
|
||
|
*
|
||
|
* // Assign the default RTOS objects (e.g. Idle task) to FilterGroup0
|
||
|
* vTraceSetFilterGroup(FilterGroup0);
|
||
|
* <Start the RTOS scheduler>
|
||
|
*
|
||
|
* Note that you may define your own names for the filter groups using
|
||
|
* preprocessor definitions, to make the code easier to understand.
|
||
|
*
|
||
|
* Example:
|
||
|
*
|
||
|
* #define BASE FilterGroup0
|
||
|
* #define USB_EVENTS FilterGroup1
|
||
|
* #define CAN_EVENTS FilterGroup2
|
||
|
*
|
||
|
* Note that filtering per event type (regardless of object) is also available
|
||
|
* in trcConfig.h.
|
||
|
******************************************************************************/
|
||
|
void vTraceSetFilterGroup(uint16_t filterGroup);
|
||
|
|
||
|
/******************************************************************************
|
||
|
* vTraceSetFilterMask
|
||
|
*
|
||
|
* Sets the "filter mask" that is used to filter the events by object. This can
|
||
|
* be used to reduce the trace data rate, i.e., if your streaming interface is
|
||
|
* a bottleneck or if you want longer snapshot traces without increasing the
|
||
|
* buffer size.
|
||
|
*
|
||
|
* Note: There are two kinds of filters in the recorder. The other filter type
|
||
|
* excludes all events of certain kinds (e.g., OS ticks). See trcConfig.h.
|
||
|
*
|
||
|
* The filtering is based on bitwise AND with the Filter Group ID, assigned
|
||
|
* to RTOS objects such as tasks, queues, semaphores and mutexes.
|
||
|
* This together with vTraceSetFilterGroup allows you to control what
|
||
|
* events that are recorded, based on the objects they refer to.
|
||
|
*
|
||
|
* See example for vTraceSetFilterGroup.
|
||
|
******************************************************************************/
|
||
|
void vTraceSetFilterMask(uint16_t filterMask);
|
||
|
|
||
|
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)
|
||
|
|
||
|
/******************************************************************************/
|
||
|
/*** Extended API for Snapshot mode *******************************************/
|
||
|
/******************************************************************************/
|
||
|
|
||
|
/******************************************************************************
|
||
|
* TRACE_STOP_HOOK - Hook Pointer Data Type
|
||
|
*
|
||
|
* Declares a data type for a call back function that will be invoked whenever
|
||
|
* the recorder is stopped.
|
||
|
*
|
||
|
* Snapshot mode only!
|
||
|
******************************************************************************/
|
||
|
typedef void(*TRACE_STOP_HOOK)(void);
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* vTraceStopHookPtr
|
||
|
*
|
||
|
* Points to a call back function that is called from vTraceStop().
|
||
|
*
|
||
|
* Snapshot mode only!
|
||
|
******************************************************************************/
|
||
|
extern TRACE_STOP_HOOK vTraceStopHookPtr;
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* vTraceSetStopHook
|
||
|
*
|
||
|
* Sets a function to be called when the recorder is stopped.
|
||
|
*
|
||
|
* Snapshot mode only!
|
||
|
******************************************************************************/
|
||
|
void vTraceSetStopHook(TRACE_STOP_HOOK stopHookFunction);
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* uiTraceStart
|
||
|
*
|
||
|
* [DEPRECATED] Use vTraceEnable instead.
|
||
|
*
|
||
|
* Starts the recorder. The recorder will not be started if an error has been
|
||
|
* indicated using prvTraceError, e.g. if any of the Nx constants in
|
||
|
* trcSnapshotConfig.h has a too small value (TRC_CFG_NTASK, TRC_CFG_NQUEUE, etc).
|
||
|
*
|
||
|
* Returns 1 if the recorder was started successfully.
|
||
|
* Returns 0 if the recorder start was prevented due to a previous internal
|
||
|
* error. In that case, check xTraceGetLastError to get the error message.
|
||
|
* Any error message is also presented when opening a trace file.
|
||
|
*
|
||
|
* Snapshot mode only!
|
||
|
******************************************************************************/
|
||
|
uint32_t uiTraceStart(void);
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* vTraceStart
|
||
|
*
|
||
|
* [DEPRECATED] Use vTraceEnable instead.
|
||
|
*
|
||
|
* Starts the recorder. The recorder will not be started if an error has been
|
||
|
* indicated using prvTraceError, e.g. if any of the Nx constants in
|
||
|
* trcSnapshotConfig.h has a too small value (TRC_CFG_NTASK, TRC_CFG_NQUEUE, etc).
|
||
|
*
|
||
|
* Snapshot mode only!
|
||
|
******************************************************************************/
|
||
|
void vTraceStart(void);
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* vTraceClear
|
||
|
*
|
||
|
* Resets the recorder. Only necessary if a restart is desired - this is not
|
||
|
* needed in the startup initialization.
|
||
|
*
|
||
|
* Snapshot mode only!
|
||
|
******************************************************************************/
|
||
|
void vTraceClear(void);
|
||
|
|
||
|
|
||
|
/*****************************************************************************/
|
||
|
/*** INTERNAL SNAPSHOT FUNCTIONS *********************************************/
|
||
|
/*****************************************************************************/
|
||
|
|
||
|
#define TRC_UNUSED
|
||
|
|
||
|
#ifndef TRC_CFG_INCLUDE_OBJECT_DELETE
|
||
|
#define TRC_CFG_INCLUDE_OBJECT_DELETE 0
|
||
|
#endif
|
||
|
|
||
|
#ifndef TRC_CFG_INCLUDE_READY_EVENTS
|
||
|
#define TRC_CFG_INCLUDE_READY_EVENTS 1
|
||
|
#endif
|
||
|
|
||
|
#ifndef TRC_CFG_INCLUDE_OSTICK_EVENTS
|
||
|
#define TRC_CFG_INCLUDE_OSTICK_EVENTS 0
|
||
|
#endif
|
||
|
|
||
|
/* This macro will create a task in the object table */
|
||
|
#undef trcKERNEL_HOOKS_TASK_CREATE
|
||
|
#define trcKERNEL_HOOKS_TASK_CREATE(SERVICE, CLASS, pxTCB) \
|
||
|
TRACE_SET_OBJECT_NUMBER(TASK, pxTCB); \
|
||
|
TRACE_SET_OBJECT_FILTER(TASK, pxTCB, CurrentFilterGroup); \
|
||
|
prvTraceSetObjectName(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), TRACE_GET_TASK_NAME(pxTCB)); \
|
||
|
prvTraceSetPriorityProperty(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), TRACE_GET_TASK_PRIORITY(pxTCB)); \
|
||
|
if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
|
||
|
if (TRACE_GET_OBJECT_FILTER(TASK, pxTCB) & CurrentFilterMask) \
|
||
|
prvTraceStoreKernelCall(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB));
|
||
|
|
||
|
/* This macro will remove the task and store it in the event buffer */
|
||
|
#undef trcKERNEL_HOOKS_TASK_DELETE
|
||
|
#define trcKERNEL_HOOKS_TASK_DELETE(SERVICE, SERVICE_NAME, SERVICE_PROP, pxTCB) \
|
||
|
if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
|
||
|
if (TRACE_GET_OBJECT_FILTER(TASK, pxTCB) & CurrentFilterMask) \
|
||
|
prvTraceStoreKernelCall(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB)); \
|
||
|
prvTraceStoreObjectNameOnCloseEvent(SERVICE_NAME, TRACE_GET_TASK_NUMBER(pxTCB), TRACE_CLASS_TASK); \
|
||
|
prvTraceStoreObjectPropertiesOnCloseEvent(SERVICE_PROP, TRACE_GET_TASK_NUMBER(pxTCB), TRACE_CLASS_TASK); \
|
||
|
prvTraceSetPriorityProperty(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), TRACE_GET_TASK_PRIORITY(pxTCB)); \
|
||
|
prvTraceSetObjectState(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), TASK_STATE_INSTANCE_NOT_ACTIVE); \
|
||
|
prvTraceFreeObjectHandle(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB));
|
||
|
|
||
|
|
||
|
/* This macro will setup a task in the object table */
|
||
|
#undef trcKERNEL_HOOKS_OBJECT_CREATE
|
||
|
#define trcKERNEL_HOOKS_OBJECT_CREATE(SERVICE, CLASS, pxObject)\
|
||
|
TRACE_SET_OBJECT_NUMBER(CLASS, pxObject);\
|
||
|
TRACE_SET_OBJECT_FILTER(CLASS, pxObject, CurrentFilterGroup); \
|
||
|
prvMarkObjectAsUsed(TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject));\
|
||
|
if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
|
||
|
if (TRACE_GET_OBJECT_FILTER(CLASS, pxObject) & CurrentFilterMask) \
|
||
|
prvTraceStoreKernelCall(SERVICE, TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject)); \
|
||
|
prvTraceSetObjectState(TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject), 0);
|
||
|
|
||
|
/* This macro will remove the object and store it in the event buffer */
|
||
|
#undef trcKERNEL_HOOKS_OBJECT_DELETE
|
||
|
#define trcKERNEL_HOOKS_OBJECT_DELETE(SERVICE, SERVICE_NAME, SERVICE_PROP, CLASS, pxObject) \
|
||
|
if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
|
||
|
if (TRACE_GET_OBJECT_FILTER(CLASS, pxObject) & CurrentFilterMask) \
|
||
|
prvTraceStoreKernelCall(SERVICE, TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject)); \
|
||
|
prvTraceStoreObjectNameOnCloseEvent(SERVICE_NAME, TRACE_GET_OBJECT_NUMBER(CLASS, pxObject), TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject)); \
|
||
|
prvTraceStoreObjectPropertiesOnCloseEvent(SERVICE_PROP, TRACE_GET_OBJECT_NUMBER(CLASS, pxObject), TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject)); \
|
||
|
prvTraceFreeObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject));
|
||
|
|
||
|
/* This macro will create a call to a kernel service with a certain result, with an object as parameter */
|
||
|
#undef trcKERNEL_HOOKS_KERNEL_SERVICE
|
||
|
#define trcKERNEL_HOOKS_KERNEL_SERVICE(SERVICE, CLASS, pxObject) \
|
||
|
if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
|
||
|
if (TRACE_GET_OBJECT_FILTER(CLASS, pxObject) & CurrentFilterMask) \
|
||
|
prvTraceStoreKernelCall(SERVICE, TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject));
|
||
|
|
||
|
/* This macro will create a call to a kernel service with a certain result, with a null object as parameter */
|
||
|
#undef trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT
|
||
|
#define trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT(SERVICE, TRACECLASS) \
|
||
|
if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
|
||
|
prvTraceStoreKernelCall(SERVICE, TRACECLASS, 0);
|
||
|
|
||
|
/* This macro will create a call to a kernel service with a certain result, with an object as parameter */
|
||
|
#undef trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM
|
||
|
#define trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(SERVICE, CLASS, pxObject, param) \
|
||
|
if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
|
||
|
if (TRACE_GET_OBJECT_FILTER(CLASS, pxObject) & CurrentFilterMask) \
|
||
|
prvTraceStoreKernelCallWithParam(SERVICE, TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject), (uint32_t)param);
|
||
|
|
||
|
/* This macro will create a call to a kernel service with a certain result, with a null object and other value as parameter */
|
||
|
#undef trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT_WITH_PARAM
|
||
|
#define trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT_WITH_PARAM(SERVICE, TRACECLASS, param) \
|
||
|
if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
|
||
|
prvTraceStoreKernelCallWithParam(SERVICE, TRACECLASS, 0, param);
|
||
|
|
||
|
/* This macro will create a call to a kernel service with a certain result, with an object as parameter */
|
||
|
#undef trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY
|
||
|
#define trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY(SERVICE, param) \
|
||
|
if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
|
||
|
prvTraceStoreKernelCallWithNumericParamOnly(SERVICE, (uint32_t)param);
|
||
|
|
||
|
/* This macro will create a call to a kernel service with a certain result, with an object as parameter */
|
||
|
#undef trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR
|
||
|
#define trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(SERVICE, CLASS, pxObject) \
|
||
|
if (TRACE_GET_OBJECT_FILTER(CLASS, pxObject) & CurrentFilterMask) \
|
||
|
prvTraceStoreKernelCall(SERVICE, TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject));
|
||
|
|
||
|
/* This macro will create a call to a kernel service with a certain result, with an object as parameter */
|
||
|
#undef trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM_FROM_ISR
|
||
|
#define trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM_FROM_ISR(SERVICE, CLASS, pxObject, param) \
|
||
|
if (TRACE_GET_OBJECT_FILTER(CLASS, pxObject) & CurrentFilterMask) \
|
||
|
prvTraceStoreKernelCallWithParam(SERVICE, TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject), (uint32_t)param);
|
||
|
|
||
|
/* This macro will create a call to a kernel service with a certain result, with an object as parameter */
|
||
|
#undef trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY_FROM_ISR
|
||
|
#define trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY_FROM_ISR(SERVICE, param) \
|
||
|
prvTraceStoreKernelCallWithNumericParamOnly(SERVICE, (uint32_t)param);
|
||
|
|
||
|
/* This macro will set the state for an object */
|
||
|
#undef trcKERNEL_HOOKS_SET_OBJECT_STATE
|
||
|
#define trcKERNEL_HOOKS_SET_OBJECT_STATE(CLASS, pxObject, STATE) \
|
||
|
prvTraceSetObjectState(TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject), (uint8_t)STATE);
|
||
|
|
||
|
/* This macro will flag a certain task as a finished instance */
|
||
|
#undef trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED
|
||
|
#define trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED() \
|
||
|
if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
|
||
|
prvTraceSetTaskInstanceFinished(TRACE_GET_TASK_NUMBER(TRACE_GET_CURRENT_TASK()));
|
||
|
|
||
|
#if (TRC_CFG_INCLUDE_READY_EVENTS == 1)
|
||
|
/* This macro will create an event to indicate that a task became Ready */
|
||
|
#undef trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE
|
||
|
#define trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE(pxTCB) \
|
||
|
if (TRACE_GET_OBJECT_FILTER(TASK, pxTCB) & CurrentFilterMask) \
|
||
|
prvTraceStoreTaskReady(TRACE_GET_TASK_NUMBER(pxTCB));
|
||
|
#else /*(TRC_CFG_INCLUDE_READY_EVENTS == 1)*/
|
||
|
#undef trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE
|
||
|
#define trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE(pxTCB)
|
||
|
#endif /*(TRC_CFG_INCLUDE_READY_EVENTS == 1)*/
|
||
|
|
||
|
/* This macro will update the internal tick counter and call prvTracePortGetTimeStamp(0) to update the internal counters */
|
||
|
#undef trcKERNEL_HOOKS_INCREMENT_TICK
|
||
|
#define trcKERNEL_HOOKS_INCREMENT_TICK() \
|
||
|
{ \
|
||
|
extern uint32_t uiTraceTickCount; \
|
||
|
uiTraceTickCount++; \
|
||
|
prvTracePortGetTimeStamp(0); \
|
||
|
}
|
||
|
|
||
|
#if (TRC_CFG_INCLUDE_OSTICK_EVENTS == 1)
|
||
|
/* This macro will create an event indicating that the OS tick count has increased */
|
||
|
#undef trcKERNEL_HOOKS_NEW_TIME
|
||
|
#define trcKERNEL_HOOKS_NEW_TIME(SERVICE, xValue) \
|
||
|
prvTraceStoreKernelCallWithNumericParamOnly(SERVICE, xValue);
|
||
|
#else /*(TRC_CFG_INCLUDE_OSTICK_EVENTS == 1)*/
|
||
|
#undef trcKERNEL_HOOKS_NEW_TIME
|
||
|
#define trcKERNEL_HOOKS_NEW_TIME(SERVICE, xValue)
|
||
|
#endif /*(TRC_CFG_INCLUDE_OSTICK_EVENTS == 1)*/
|
||
|
|
||
|
/* This macro will create a task switch event to the currently executing task */
|
||
|
#undef trcKERNEL_HOOKS_TASK_SWITCH
|
||
|
#define trcKERNEL_HOOKS_TASK_SWITCH( pxTCB ) \
|
||
|
if (TRACE_GET_OBJECT_FILTER(TASK, pxTCB) & CurrentFilterMask) \
|
||
|
prvTraceStoreTaskswitch(TRACE_GET_TASK_NUMBER(pxTCB));
|
||
|
|
||
|
/* This macro will create an event to indicate that the task has been suspended */
|
||
|
#undef trcKERNEL_HOOKS_TASK_SUSPEND
|
||
|
#define trcKERNEL_HOOKS_TASK_SUSPEND(SERVICE, pxTCB) \
|
||
|
if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
|
||
|
if (TRACE_GET_OBJECT_FILTER(TASK, pxTCB) & CurrentFilterMask) \
|
||
|
prvTraceStoreKernelCall(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB)); \
|
||
|
prvTraceSetTaskInstanceFinished((uint8_t)TRACE_GET_TASK_NUMBER(pxTCB));
|
||
|
|
||
|
/* This macro will create an event to indicate that a task has called a wait/delay function */
|
||
|
#undef trcKERNEL_HOOKS_TASK_DELAY
|
||
|
#define trcKERNEL_HOOKS_TASK_DELAY(SERVICE, pxTCB, xValue) \
|
||
|
if (TRACE_GET_OBJECT_FILTER(TASK, pxTCB) & CurrentFilterMask) \
|
||
|
{ \
|
||
|
prvTraceStoreKernelCallWithNumericParamOnly(SERVICE, xValue); \
|
||
|
prvTraceSetTaskInstanceFinished((uint8_t)TRACE_GET_TASK_NUMBER(pxTCB)); \
|
||
|
}
|
||
|
|
||
|
/* This macro will create an event to indicate that a task has gotten its priority changed */
|
||
|
#undef trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE
|
||
|
#define trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE(SERVICE, pxTCB, uxNewPriority) \
|
||
|
if (TRACE_GET_OBJECT_FILTER(TASK, pxTCB) & CurrentFilterMask) \
|
||
|
{ \
|
||
|
prvTraceStoreKernelCallWithParam(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), prvTraceGetPriorityProperty(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB)));\
|
||
|
prvTraceSetPriorityProperty(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), (uint8_t)uxNewPriority); \
|
||
|
}
|
||
|
|
||
|
/* This macro will create an event to indicate that the task has been resumed */
|
||
|
#undef trcKERNEL_HOOKS_TASK_RESUME
|
||
|
#define trcKERNEL_HOOKS_TASK_RESUME(SERVICE, pxTCB) \
|
||
|
if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
|
||
|
if (TRACE_GET_OBJECT_FILTER(TASK, pxTCB) & CurrentFilterMask) \
|
||
|
prvTraceStoreKernelCall(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB));
|
||
|
|
||
|
#undef trcKERNEL_HOOKS_TASK_RESUME_FROM_ISR
|
||
|
#define trcKERNEL_HOOKS_TASK_RESUME_FROM_ISR(SERVICE, pxTCB) \
|
||
|
if (TRACE_GET_OBJECT_FILTER(TASK, pxTCB) & CurrentFilterMask) \
|
||
|
prvTraceStoreKernelCall(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB));
|
||
|
|
||
|
#if !defined TRC_CFG_INCLUDE_READY_EVENTS || TRC_CFG_INCLUDE_READY_EVENTS == 1
|
||
|
void prvTraceSetReadyEventsEnabled(int status);
|
||
|
void prvTraceStoreTaskReady(traceHandle handle);
|
||
|
#else
|
||
|
#define prvTraceSetReadyEventsEnabled(status)
|
||
|
#endif
|
||
|
|
||
|
void prvTraceStoreLowPower(uint32_t flag);
|
||
|
|
||
|
void prvTraceStoreTaskswitch(traceHandle task_handle);
|
||
|
|
||
|
|
||
|
#if (TRC_CFG_SCHEDULING_ONLY == 0)
|
||
|
|
||
|
void prvTraceStoreKernelCall(uint32_t eventcode, traceObjectClass objectClass, uint32_t byteParam);
|
||
|
|
||
|
void prvTraceStoreKernelCallWithNumericParamOnly(uint32_t evtcode, uint32_t param);
|
||
|
|
||
|
void prvTraceStoreKernelCallWithParam(uint32_t evtcode, traceObjectClass objectClass,
|
||
|
uint32_t objectNumber, uint32_t param);
|
||
|
#else
|
||
|
|
||
|
#define prvTraceStoreKernelCall(eventcode, objectClass, byteParam) {}
|
||
|
#define prvTraceStoreKernelCallWithNumericParamOnly(evtcode, param) {}
|
||
|
#define prvTraceStoreKernelCallWithParam(evtcode, objectClass, objectNumber, param) {}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
void prvTraceSetTaskInstanceFinished(traceHandle handle);
|
||
|
|
||
|
void prvTraceSetPriorityProperty(uint8_t objectclass, traceHandle id, uint8_t value);
|
||
|
|
||
|
uint8_t prvTraceGetPriorityProperty(uint8_t objectclass, traceHandle id);
|
||
|
|
||
|
void prvTraceSetObjectState(uint8_t objectclass, traceHandle id, uint8_t value);
|
||
|
|
||
|
void prvMarkObjectAsUsed(traceObjectClass objectclass, traceHandle handle);
|
||
|
|
||
|
void prvTraceStoreObjectNameOnCloseEvent(uint8_t evtcode, traceHandle handle,
|
||
|
traceObjectClass objectclass);
|
||
|
|
||
|
void prvTraceStoreObjectPropertiesOnCloseEvent(uint8_t evtcode, traceHandle handle,
|
||
|
traceObjectClass objectclass);
|
||
|
|
||
|
/* Internal constants for task state */
|
||
|
#define TASK_STATE_INSTANCE_NOT_ACTIVE 0
|
||
|
#define TASK_STATE_INSTANCE_ACTIVE 1
|
||
|
|
||
|
|
||
|
#if (TRC_CFG_INCLUDE_ISR_TRACING == 0)
|
||
|
|
||
|
#undef vTraceSetISRProperties
|
||
|
#define vTraceSetISRProperties(handle, name, priority)
|
||
|
|
||
|
#undef vTraceStoreISRBegin
|
||
|
#define vTraceStoreISRBegin(x) (void)x
|
||
|
|
||
|
#undef vTraceStoreISREnd
|
||
|
#define vTraceStoreISREnd(x) (void)x
|
||
|
|
||
|
#undef xTraceSetISRProperties
|
||
|
#define xTraceSetISRProperties(name, priority) 0
|
||
|
|
||
|
#endif /*(TRC_CFG_INCLUDE_ISR_TRACING == 0)*/
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* xTraceGetTraceBuffer
|
||
|
*
|
||
|
* Returns a pointer to the recorder data structure. Use this together with
|
||
|
* uiTraceGetTraceBufferSize if you wish to implement an own store/upload
|
||
|
* solution, e.g., in case a debugger connection is not available for uploading
|
||
|
* the data.
|
||
|
******************************************************************************/
|
||
|
void* xTraceGetTraceBuffer(void);
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* uiTraceGetTraceBufferSize
|
||
|
*
|
||
|
* Gets the size of the recorder data structure. For use together with
|
||
|
* vTraceGetTraceBuffer if you wish to implement an own store/upload solution,
|
||
|
* e.g., in case a debugger connection is not available for uploading the data.
|
||
|
******************************************************************************/
|
||
|
uint32_t uiTraceGetTraceBufferSize(void);
|
||
|
|
||
|
#if (TRC_CFG_SCHEDULING_ONLY == 1)
|
||
|
#undef TRC_CFG_INCLUDE_USER_EVENTS
|
||
|
#define TRC_CFG_INCLUDE_USER_EVENTS 0
|
||
|
#endif /*(TRC_CFG_SCHEDULING_ONLY == 1)*/
|
||
|
|
||
|
#if ((TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_SCHEDULING_ONLY == 0))
|
||
|
|
||
|
#if (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)
|
||
|
traceUBChannel xTraceRegisterUBChannel(traceString channel, traceString formatStr);
|
||
|
void vTraceUBData(traceUBChannel channel, ...);
|
||
|
void vTraceUBEvent(traceUBChannel channel);
|
||
|
#endif /*(TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)*/
|
||
|
|
||
|
#else /*((TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_SCHEDULING_ONLY == 0))*/
|
||
|
|
||
|
#undef vTracePrint
|
||
|
#define vTracePrint(chn, ...) (void)chn
|
||
|
#undef vTracePrintF
|
||
|
#define vTracePrintF(chn, ...) (void)chn
|
||
|
#undef xTraceRegisterString
|
||
|
#define xTraceRegisterString(x) 0; (void)x;
|
||
|
#undef xTraceRegisterChannelFormat
|
||
|
#define xTraceRegisterChannelFormat(eventLabel, formatStr) 0
|
||
|
#undef vTraceUBData
|
||
|
#define vTraceUBData(label, ...) {}
|
||
|
#undef vTraceChannelPrint
|
||
|
#define vTraceChannelPrint(label) {}
|
||
|
|
||
|
#endif /*(TRC_CFG_INCLUDE_USER_EVENTS == 1)*/
|
||
|
|
||
|
#define NEventCodes 0x100
|
||
|
|
||
|
/* Our local critical sections for the recorder */
|
||
|
#define trcCRITICAL_SECTION_BEGIN() {TRACE_ENTER_CRITICAL_SECTION(); recorder_busy++;}
|
||
|
#define trcCRITICAL_SECTION_END() {recorder_busy--; TRACE_EXIT_CRITICAL_SECTION();}
|
||
|
|
||
|
#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_Cortex_M)
|
||
|
#define trcSR_ALLOC_CRITICAL_SECTION_ON_CORTEX_M_ONLY TRACE_ALLOC_CRITICAL_SECTION
|
||
|
#define trcCRITICAL_SECTION_BEGIN_ON_CORTEX_M_ONLY trcCRITICAL_SECTION_BEGIN
|
||
|
#define trcCRITICAL_SECTION_END_ON_CORTEX_M_ONLY trcCRITICAL_SECTION_END
|
||
|
#else
|
||
|
#define trcSR_ALLOC_CRITICAL_SECTION_ON_CORTEX_M_ONLY() {}
|
||
|
#define trcCRITICAL_SECTION_BEGIN_ON_CORTEX_M_ONLY() recorder_busy++;
|
||
|
#define trcCRITICAL_SECTION_END_ON_CORTEX_M_ONLY() recorder_busy--;
|
||
|
#endif
|
||
|
|
||
|
/******************************************************************************
|
||
|
* ObjectHandleStack
|
||
|
* This data-structure is used to provide a mechanism for 1-byte trace object
|
||
|
* handles. This way, only 1 byte is necessary instead of 4 bytes (a pointer)
|
||
|
* when storing a reference to an object. This allows for up to 255 objects of
|
||
|
* each object class active at any given moment. There can be more "historic"
|
||
|
* objects, that have been deleted - that number is only limited by the size of
|
||
|
* the symbol table.
|
||
|
*
|
||
|
* Note that handle zero (0) is not used, it is a code for an invalid handle.
|
||
|
*
|
||
|
* This data structure keeps track of the FREE handles, not the handles in use.
|
||
|
* This data structure contains one stack per object class. When a handle is
|
||
|
* allocated to an object, the next free handle is popped from the stack. When
|
||
|
* a handle is released (on object delete), it is pushed back on the stack.
|
||
|
* Note that there is no initialization code that pushed the free handles
|
||
|
* initially, that is not necessary due to the following optimization:
|
||
|
*
|
||
|
* The stack of handles (objectHandles) is initially all zeros. Since zero
|
||
|
* is not a valid handle, that is a signal of additional handles needed.
|
||
|
* If a zero is received when popping a new handle, it is replaced by the
|
||
|
* index of the popped handle instead.
|
||
|
*****************************************************************************/
|
||
|
typedef struct
|
||
|
{
|
||
|
/* For each object class, the index of the next handle to allocate */
|
||
|
uint16_t indexOfNextAvailableHandle[ TRACE_NCLASSES ];
|
||
|
|
||
|
/* The lowest index of this class (constant) */
|
||
|
uint16_t lowestIndexOfClass[ TRACE_NCLASSES ];
|
||
|
|
||
|
/* The highest index of this class (constant) */
|
||
|
uint16_t highestIndexOfClass[ TRACE_NCLASSES ];
|
||
|
|
||
|
/* The highest use count for this class (for statistics) */
|
||
|
uint16_t handleCountWaterMarksOfClass[ TRACE_NCLASSES ];
|
||
|
|
||
|
/* The free object handles - a set of stacks within this array */
|
||
|
traceHandle objectHandles[ TRACE_KERNEL_OBJECT_COUNT ];
|
||
|
|
||
|
} objectHandleStackType;
|
||
|
|
||
|
extern objectHandleStackType objectHandleStacks;
|
||
|
|
||
|
/******************************************************************************
|
||
|
* Object Property Table
|
||
|
* The Object Table contains name and other properties of the objects (tasks,
|
||
|
* queues, mutexes, etc). The below data structures defines the properties of
|
||
|
* each object class and are used to cast the byte buffer into a cleaner format.
|
||
|
*
|
||
|
* The values in the object table are continuously overwritten and always
|
||
|
* represent the current state. If a property is changed during runtime, the OLD
|
||
|
* value should be stored in the trace buffer, not the new value (since the new
|
||
|
* value is found in the Object Property Table).
|
||
|
*
|
||
|
* For close events this mechanism is the old names are stored in the symbol
|
||
|
* table), for "priority set" (the old priority is stored in the event data)
|
||
|
* and for "isActive", where the value decides if the task switch event type
|
||
|
* should be "new" or "resume".
|
||
|
******************************************************************************/
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
/* = NCLASSES */
|
||
|
uint32_t NumberOfObjectClasses;
|
||
|
|
||
|
uint32_t ObjectPropertyTableSizeInBytes;
|
||
|
|
||
|
/* This is used to calculate the index in the dynamic object table
|
||
|
(handle - 1 - nofStaticObjects = index)*/
|
||
|
#if (TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1)
|
||
|
traceHandle NumberOfObjectsPerClass[2*((TRACE_NCLASSES+1)/2)];
|
||
|
#else
|
||
|
traceHandle NumberOfObjectsPerClass[4*((TRACE_NCLASSES+3)/4)];
|
||
|
#endif
|
||
|
|
||
|
/* Allocation size rounded up to the closest multiple of 4 */
|
||
|
uint8_t NameLengthPerClass[ 4*((TRACE_NCLASSES+3)/4) ];
|
||
|
|
||
|
uint8_t TotalPropertyBytesPerClass[ 4*((TRACE_NCLASSES+3)/4) ];
|
||
|
|
||
|
/* Allocation size rounded up to the closest multiple of 2 */
|
||
|
uint16_t StartIndexOfClass[ 2*((TRACE_NCLASSES+1)/2) ];
|
||
|
|
||
|
/* The actual handles issued, should be Initiated to all zeros */
|
||
|
uint8_t objbytes[ 4*((TRACE_OBJECT_TABLE_SIZE+3)/4) ];
|
||
|
} ObjectPropertyTableType;
|
||
|
|
||
|
/* Symbol table data structure */
|
||
|
typedef struct
|
||
|
{
|
||
|
/* = SYMBOL_HISTORY_TABLE_SIZE_IN_BYTES */
|
||
|
uint32_t symTableSize;
|
||
|
|
||
|
/* Entry 0 is reserved. Any reference to entry 0 implies NULL*/
|
||
|
uint32_t nextFreeSymbolIndex;
|
||
|
|
||
|
/* Size rounded up to closest multiple of 4, to avoid alignment issues*/
|
||
|
uint8_t symbytes[4*(((TRC_CFG_SYMBOL_TABLE_SIZE)+3)/4)];
|
||
|
|
||
|
/* Used for lookups - Up to 64 linked lists within the symbol table
|
||
|
connecting all entries with the same 6 bit checksum.
|
||
|
This field holds the current list heads. Should be initiated to zeros */
|
||
|
uint16_t latestEntryOfChecksum[64];
|
||
|
} symbolTableType;
|
||
|
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* The data structures of the different events, all 4 bytes long
|
||
|
******************************************************************************/
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
uint8_t type;
|
||
|
uint8_t objHandle;
|
||
|
uint16_t dts; /* differential timestamp - time since last event */
|
||
|
} TSEvent, TREvent;
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
uint8_t type;
|
||
|
uint8_t dummy;
|
||
|
uint16_t dts; /* differential timestamp - time since last event */
|
||
|
} LPEvent;
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
uint8_t type;
|
||
|
uint8_t objHandle;
|
||
|
uint16_t dts; /* differential timestamp - time since last event */
|
||
|
} KernelCall;
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
uint8_t type;
|
||
|
uint8_t objHandle;
|
||
|
uint8_t param;
|
||
|
uint8_t dts; /* differential timestamp - time since last event */
|
||
|
} KernelCallWithParamAndHandle;
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
uint8_t type;
|
||
|
uint8_t dts; /* differential timestamp - time since last event */
|
||
|
uint16_t param;
|
||
|
} KernelCallWithParam16;
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
uint8_t type;
|
||
|
uint8_t objHandle; /* the handle of the closed object */
|
||
|
uint16_t symbolIndex; /* the name of the closed object */
|
||
|
} ObjCloseNameEvent;
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
uint8_t type;
|
||
|
uint8_t arg1;
|
||
|
uint8_t arg2;
|
||
|
uint8_t arg3;
|
||
|
} ObjClosePropEvent;
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
uint8_t type;
|
||
|
uint8_t unused1;
|
||
|
uint8_t unused2;
|
||
|
uint8_t dts;
|
||
|
} TaskInstanceStatusEvent;
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
uint8_t type;
|
||
|
uint8_t dts;
|
||
|
uint16_t payload; /* the name of the user event */
|
||
|
} UserEvent;
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
uint8_t type;
|
||
|
|
||
|
/* 8 bits extra for storing DTS, if it does not fit in ordinary event
|
||
|
(this one is always MSB if used) */
|
||
|
uint8_t xts_8;
|
||
|
|
||
|
/* 16 bits extra for storing DTS, if it does not fit in ordinary event. */
|
||
|
uint16_t xts_16;
|
||
|
} XTSEvent;
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
uint8_t type;
|
||
|
|
||
|
uint8_t xps_8;
|
||
|
uint16_t xps_16;
|
||
|
} XPSEvent;
|
||
|
|
||
|
typedef struct{
|
||
|
uint8_t type;
|
||
|
uint8_t dts;
|
||
|
uint16_t size;
|
||
|
} MemEventSize;
|
||
|
|
||
|
typedef struct{
|
||
|
uint8_t type;
|
||
|
uint8_t addr_high;
|
||
|
uint16_t addr_low;
|
||
|
} MemEventAddr;
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* The separate user event buffer structure. Can be enabled in trcConfig.h.
|
||
|
******************************************************************************/
|
||
|
|
||
|
#if (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)
|
||
|
typedef struct
|
||
|
{
|
||
|
traceString name;
|
||
|
traceString defaultFormat;
|
||
|
} ChannelFormatPair;
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
uint16_t bufferID;
|
||
|
uint16_t version;
|
||
|
uint32_t wraparoundCounter;
|
||
|
uint32_t numberOfSlots;
|
||
|
uint32_t nextSlotToWrite;
|
||
|
uint8_t numberOfChannels;
|
||
|
uint8_t padding1;
|
||
|
uint8_t padding2;
|
||
|
uint8_t padding3;
|
||
|
ChannelFormatPair channels[(TRC_CFG_UB_CHANNELS)+1];
|
||
|
uint8_t channelBuffer[((TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE) + 3) & 0xFFFFFFFC]; /* 1 byte per slot, with padding for 4 byte alignment */
|
||
|
uint8_t dataBuffer[(TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE) * 4]; /* 4 bytes per slot */
|
||
|
|
||
|
} UserEventBuffer;
|
||
|
#endif
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* The main data structure, read by Tracealyzer from the RAM dump
|
||
|
******************************************************************************/
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
volatile uint8_t startmarker0; /* Volatile is important, see init code. */
|
||
|
volatile uint8_t startmarker1;
|
||
|
volatile uint8_t startmarker2;
|
||
|
volatile uint8_t startmarker3;
|
||
|
volatile uint8_t startmarker4;
|
||
|
volatile uint8_t startmarker5;
|
||
|
volatile uint8_t startmarker6;
|
||
|
volatile uint8_t startmarker7;
|
||
|
volatile uint8_t startmarker8;
|
||
|
volatile uint8_t startmarker9;
|
||
|
volatile uint8_t startmarker10;
|
||
|
volatile uint8_t startmarker11;
|
||
|
|
||
|
/* Used to determine Kernel and Endianess */
|
||
|
uint16_t version;
|
||
|
|
||
|
/* Currently 5 */
|
||
|
uint8_t minor_version;
|
||
|
|
||
|
/* This should be 0 if lower IRQ priority values implies higher priority
|
||
|
levels, such as on ARM Cortex M. If the opposite scheme is used, i.e.,
|
||
|
if higher IRQ priority values means higher priority, this should be 1. */
|
||
|
uint8_t irq_priority_order;
|
||
|
|
||
|
/* sizeof(RecorderDataType) - just for control */
|
||
|
uint32_t filesize;
|
||
|
|
||
|
/* Current number of events recorded */
|
||
|
uint32_t numEvents;
|
||
|
|
||
|
/* The buffer size, in number of event records */
|
||
|
uint32_t maxEvents;
|
||
|
|
||
|
/* The event buffer index, where to write the next event */
|
||
|
uint32_t nextFreeIndex;
|
||
|
|
||
|
/* 1 if the buffer is full, 0 otherwise */
|
||
|
uint32_t bufferIsFull;
|
||
|
|
||
|
/* The frequency of the clock/timer/counter used as time base */
|
||
|
uint32_t frequency;
|
||
|
|
||
|
/* The absolute timestamp of the last stored event, in the native
|
||
|
timebase, modulo frequency! */
|
||
|
uint32_t absTimeLastEvent;
|
||
|
|
||
|
/* The number of seconds in total - lasts for 136 years */
|
||
|
uint32_t absTimeLastEventSecond;
|
||
|
|
||
|
/* 1 if the recorder has been started, 0 if not yet started or stopped.
|
||
|
This is a 32 bit variable due to alignment issues. */
|
||
|
uint32_t recorderActive;
|
||
|
|
||
|
/* If > 0, tells the maximum time between two traced ISRs that execute
|
||
|
back-to-back. If the time between vTraceStoreISREnd and a directly
|
||
|
following vTraceISRBegin is above isrTailchainingThreshold, we assume a
|
||
|
return to the previous context in between the ISRs, otherwise we assume
|
||
|
the have executed back-to-back and don't show any fragment of the previous
|
||
|
context in between. */
|
||
|
uint32_t isrTailchainingThreshold;
|
||
|
|
||
|
/* Not used, remains for compatibility and future use */
|
||
|
uint8_t notused[24];
|
||
|
|
||
|
/* The amount of heap memory remaining at the last malloc or free event */
|
||
|
uint32_t heapMemUsage;
|
||
|
|
||
|
/* 0xF0F0F0F0 - for control only */
|
||
|
int32_t debugMarker0;
|
||
|
|
||
|
/* Set to value of TRC_CFG_USE_16BIT_OBJECT_HANDLES */
|
||
|
uint32_t isUsing16bitHandles;
|
||
|
|
||
|
/* The Object Property Table holds information about currently active
|
||
|
tasks, queues, and other recorded objects. This is updated on each
|
||
|
create call and includes object name and other properties. */
|
||
|
ObjectPropertyTableType ObjectPropertyTable;
|
||
|
|
||
|
/* 0xF1F1F1F1 - for control only */
|
||
|
int32_t debugMarker1;
|
||
|
|
||
|
/* The Symbol Table stores strings for User Events and is also used to
|
||
|
store names of deleted objects, which still may be in the trace but no
|
||
|
longer are available. */
|
||
|
symbolTableType SymbolTable;
|
||
|
|
||
|
/* For inclusion of float support, and for endian detection of floats.
|
||
|
The value should be (float)1 or (uint32_t)0 */
|
||
|
#if (TRC_CFG_INCLUDE_FLOAT_SUPPORT == 1)
|
||
|
float exampleFloatEncoding;
|
||
|
#else
|
||
|
uint32_t exampleFloatEncoding;
|
||
|
#endif
|
||
|
/* This is non-zero if an internal error occurred in the recorder, e.g., if
|
||
|
one of the Nxxx constants was too small. The systemInfo string will then
|
||
|
contain an error message that is displayed when attempting to view the
|
||
|
trace file. */
|
||
|
uint32_t internalErrorOccured;
|
||
|
|
||
|
/* 0xF2F2F2F2 - for control only */
|
||
|
int32_t debugMarker2;
|
||
|
|
||
|
/* Error messages from the recorder. */
|
||
|
char systemInfo[80];
|
||
|
|
||
|
/* 0xF3F3F3F3 - for control only */
|
||
|
int32_t debugMarker3;
|
||
|
|
||
|
/* The event data, in 4-byte records */
|
||
|
uint8_t eventData[ (TRC_CFG_EVENT_BUFFER_SIZE) * 4 ];
|
||
|
|
||
|
#if (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)
|
||
|
UserEventBuffer userEventBuffer;
|
||
|
#endif
|
||
|
|
||
|
/* This should always be 0 */
|
||
|
uint32_t endOfSecondaryBlocks;
|
||
|
|
||
|
uint8_t endmarker0;
|
||
|
uint8_t endmarker1;
|
||
|
uint8_t endmarker2;
|
||
|
uint8_t endmarker3;
|
||
|
uint8_t endmarker4;
|
||
|
uint8_t endmarker5;
|
||
|
uint8_t endmarker6;
|
||
|
uint8_t endmarker7;
|
||
|
uint8_t endmarker8;
|
||
|
uint8_t endmarker9;
|
||
|
uint8_t endmarker10;
|
||
|
uint8_t endmarker11;
|
||
|
} RecorderDataType;
|
||
|
|
||
|
extern RecorderDataType* RecorderDataPtr;
|
||
|
|
||
|
/* Internal functions */
|
||
|
|
||
|
/* Signal an error. */
|
||
|
void prvTraceError(const char* msg);
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* prvTracePortGetTimeStamp
|
||
|
*
|
||
|
* Returns the current time based on the HWTC macros which provide a hardware
|
||
|
* isolation layer towards the hardware timer/counter.
|
||
|
*
|
||
|
* The HWTC macros and prvTracePortGetTimeStamp is the main porting issue
|
||
|
* or the trace recorder library. Typically you should not need to change
|
||
|
* the code of prvTracePortGetTimeStamp if using the HWTC macros.
|
||
|
*
|
||
|
******************************************************************************/
|
||
|
void prvTracePortGetTimeStamp(uint32_t *puiTimestamp);
|
||
|
|
||
|
traceHandle prvTraceGetObjectHandle(traceObjectClass objectclass);
|
||
|
|
||
|
void prvTraceFreeObjectHandle(traceObjectClass objectclass,
|
||
|
traceHandle handle);
|
||
|
|
||
|
/* Private function. Use the public functions in trcKernelPort.h */
|
||
|
void prvTraceSetObjectName(traceObjectClass objectclass,
|
||
|
traceHandle handle,
|
||
|
const char* name);
|
||
|
|
||
|
/* Internal macros */
|
||
|
|
||
|
#define TRACE_PROPERTY_NAME_GET(objectclass, objecthandle) \
|
||
|
(const char*)(& RecorderDataPtr->ObjectPropertyTable.objbytes \
|
||
|
[uiIndexOfObject(objecthandle, objectclass)])
|
||
|
|
||
|
#define TRACE_PROPERTY_OBJECT_STATE(objectclass, handle) \
|
||
|
RecorderDataPtr->ObjectPropertyTable.objbytes[uiIndexOfObject(handle, objectclass) \
|
||
|
+ RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[objectclass]]
|
||
|
|
||
|
#define TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, handle) \
|
||
|
RecorderDataPtr->ObjectPropertyTable.objbytes[uiIndexOfObject(handle, objectclass) \
|
||
|
+ RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[objectclass] + 1]
|
||
|
|
||
|
/* DEBUG ASSERTS */
|
||
|
#if defined TRC_CFG_USE_TRACE_ASSERT && TRC_CFG_USE_TRACE_ASSERT != 0
|
||
|
#define TRACE_ASSERT(eval, msg, defRetVal) \
|
||
|
if (!(eval)) \
|
||
|
{ \
|
||
|
prvTraceError("TRACE_ASSERT: " msg); \
|
||
|
return defRetVal; \
|
||
|
}
|
||
|
#else
|
||
|
#define TRACE_ASSERT(eval, msg, defRetVal)
|
||
|
#endif
|
||
|
|
||
|
#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)*/
|
||
|
|
||
|
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
|
||
|
|
||
|
/******************************************************************************
|
||
|
* Default values for STREAM PORT macros
|
||
|
*
|
||
|
* As a normal user, this is nothing you don't need to bother about. This is
|
||
|
* only important if you want to define your own custom streaming interface.
|
||
|
*
|
||
|
* You may override these in your own trcStreamingPort.h to create a custom
|
||
|
* stream port, and thereby stream the trace on any host-target interface.
|
||
|
* These default values are suitable for most cases, except the J-Link port.
|
||
|
******************************************************************************/
|
||
|
|
||
|
/******************************************************************************
|
||
|
* TRC_STREAM_PORT_USE_INTERNAL_BUFFER
|
||
|
*
|
||
|
* There are two kinds of stream ports, those that store the event to the
|
||
|
* internal buffer (with periodic flushing by the TzCtrl task) and those that
|
||
|
* write directly to the streaming interface. Most stream ports use the
|
||
|
* recorder's internal buffer, except for the SEGGER J-Link port (also uses a
|
||
|
* RAM buffer, but one defined in the SEGGER code).
|
||
|
*
|
||
|
* If the stream port (trcStreamingPort.h) defines this as zero (0), it is
|
||
|
* expected to transmit the data directly using TRC_STREAM_PORT_COMMIT_EVENT.
|
||
|
* Otherwise it is expected that the trace data is stored in the internal buffer
|
||
|
* and the TzCtrl task will then send the buffer pages when they become full.
|
||
|
******************************************************************************/
|
||
|
#ifndef TRC_STREAM_PORT_USE_INTERNAL_BUFFER
|
||
|
#define TRC_STREAM_PORT_USE_INTERNAL_BUFFER 1
|
||
|
#endif
|
||
|
|
||
|
/******************************************************************************
|
||
|
* TRC_STREAM_PORT_ON_TRACE_BEGIN
|
||
|
*
|
||
|
* Defining any actions needed in the stream port when the recording is activated.
|
||
|
*******************************************************************************/
|
||
|
#ifndef TRC_STREAM_PORT_ON_TRACE_BEGIN
|
||
|
#define TRC_STREAM_PORT_ON_TRACE_BEGIN() /* Do nothing */
|
||
|
#endif
|
||
|
|
||
|
/******************************************************************************
|
||
|
* TRC_STREAM_PORT_ON_TRACE_BEGIN
|
||
|
*
|
||
|
* Defining any actions needed in the stream port when the tracing stops.
|
||
|
* Empty by default.
|
||
|
*******************************************************************************/
|
||
|
#ifndef TRC_STREAM_PORT_ON_TRACE_END
|
||
|
#define TRC_STREAM_PORT_ON_TRACE_END() /* Do nothing */
|
||
|
#endif
|
||
|
|
||
|
/******************************************************************************
|
||
|
* TRC_STREAM_PORT_ALLOCATE_EVENT
|
||
|
*
|
||
|
* This macro is used to allocate memory for each event record, just before
|
||
|
* assigning the record fields.
|
||
|
* Depending on "TRC_STREAM_PORT_USE_INTERNAL_BUFFER", this either allocates
|
||
|
* space in the paged event buffer, or on the local stack. In the latter case,
|
||
|
* the COMMIT event is used to write the data to the streaming interface.
|
||
|
******************************************************************************/
|
||
|
#ifndef TRC_STREAM_PORT_ALLOCATE_EVENT
|
||
|
#if (TRC_STREAM_PORT_USE_INTERNAL_BUFFER == 1)
|
||
|
#define TRC_STREAM_PORT_ALLOCATE_EVENT(_type, _ptrData, _size) _type* _ptrData; _ptrData = (_type*)prvPagedEventBufferGetWritePointer(_size);
|
||
|
#else
|
||
|
#define TRC_STREAM_PORT_ALLOCATE_EVENT(_type, _ptrData, _size) _type _tmpArray[_size / sizeof(_type)]; _type* _ptrData = _tmpArray;
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
/******************************************************************************
|
||
|
* TRC_STREAM_PORT_ALLOCATE_DYNAMIC_EVENT
|
||
|
*
|
||
|
* This macro is used to allocate memory for each event record, just before
|
||
|
* assigning the record fields.
|
||
|
* This has the same purpose as TRC_STREAM_PORT_ALLOCATE_EVENT and by default
|
||
|
* it has the same definition as TRC_STREAM_PORT_ALLOCATE_EVENT. This is used
|
||
|
* for events carrying variable-sized payload, such as strings.
|
||
|
* In the SEGGER RTT port, we need this in order to make a worst-case
|
||
|
* allocation on the stack.
|
||
|
******************************************************************************/
|
||
|
#ifndef TRC_STREAM_PORT_ALLOCATE_DYNAMIC_EVENT
|
||
|
#if (TRC_STREAM_PORT_USE_INTERNAL_BUFFER == 1)
|
||
|
#define TRC_STREAM_PORT_ALLOCATE_DYNAMIC_EVENT(_type, _ptrData, _size) TRC_STREAM_PORT_ALLOCATE_EVENT(_type, _ptrData, _size) /* We do the same thing as for non-dynamic event sizes */
|
||
|
#else
|
||
|
#define TRC_STREAM_PORT_ALLOCATE_DYNAMIC_EVENT(_type, _ptrData, _size) _type _tmpArray[sizeof(largestEventType) / sizeof(_type)]; _type* _ptrData = _tmpArray;
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
/******************************************************************************
|
||
|
* TRC_STREAM_PORT_COMMIT_EVENT
|
||
|
*
|
||
|
* The COMMIT macro is used to write a single event record directly to the
|
||
|
* streaming inteface, without first storing the event in the internal buffer.
|
||
|
* This is currently only used in the SEGGER J-Link RTT port.
|
||
|
*
|
||
|
* This relies on the TRC_STREAM_PORT_WRITE_DATA macro, defined in by the
|
||
|
* stream port in trcStreamingPort.h. The COMMIT macro calls
|
||
|
* prvTraceWarning(TRC_STREAM_PORT_WRITE_DATA) if a non-zero value is returned
|
||
|
* from TRC_STREAM_PORT_WRITE_DATA. If zero (0) is returned, it is assumed
|
||
|
* that all data was successfully written.
|
||
|
*
|
||
|
* In ports using the internal buffer, this macro has no purpose as the events
|
||
|
* are written to the internal buffer instead. They are then flushed to the
|
||
|
* streaming interface in the TzCtrl task using TRC_STREAM_PORT_WRITE_DATA.
|
||
|
******************************************************************************/
|
||
|
#ifndef TRC_STREAM_PORT_COMMIT_EVENT
|
||
|
#if (TRC_STREAM_PORT_USE_INTERNAL_BUFFER == 1)
|
||
|
#define TRC_STREAM_PORT_COMMIT_EVENT(_ptrData, _size) /* Not used */
|
||
|
#else
|
||
|
#define TRC_STREAM_PORT_COMMIT_EVENT(_ptrData, _size) \
|
||
|
{ \
|
||
|
if (TRC_STREAM_PORT_WRITE_DATA(_ptrData, _size, 0) != 0)\
|
||
|
prvTraceWarning(PSF_WARNING_STREAM_PORT_WRITE); \
|
||
|
}
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
/******************************************************************************
|
||
|
* TRC_STREAM_PORT_READ_DATA (defined in trcStreamingPort.h)
|
||
|
*
|
||
|
* Defining how to read data from host (commands from Tracealyzer).
|
||
|
*
|
||
|
* If there is no direct interface to host (e.g., if streaming to a file
|
||
|
* system) this should be defined as 0. Instead use vTraceEnable(TRC_START) and
|
||
|
* vTraceStop() to control the recording from target.
|
||
|
*
|
||
|
* Parameters:
|
||
|
*
|
||
|
* - _ptrData: a pointer to a data buffer, where the received data shall be
|
||
|
* stored (TracealyzerCommandType*).
|
||
|
*
|
||
|
* - _size: the number of bytes to read (int).
|
||
|
*
|
||
|
* - _ptrBytesRead: a pointer to an integer (int), that should be assigned
|
||
|
* with the number of bytes that was received.
|
||
|
*
|
||
|
* Example:
|
||
|
*
|
||
|
* int32_t myRead(void* ptrData, uint32_t size, int32_t* ptrBytesRead);
|
||
|
*
|
||
|
* #define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) \
|
||
|
* myRead(_ptrData, _size, _ptrBytesRead)
|
||
|
*
|
||
|
* Your "myRead" function should return 0 if successful, i.e. if at least some
|
||
|
* bytes were received. A non-zero value should be returned if the streaming
|
||
|
* interface returned an error (e.g. a closed socket), which results in the
|
||
|
* recorder calling prvTraceWarning with the error code
|
||
|
* PSF_WARNING_STREAM_PORT_WRITE.
|
||
|
*
|
||
|
* If developing your own custom stream port and using the default internal
|
||
|
* buffer, it is important that the _ptrBytesRead parameter is assigned
|
||
|
* correctly by "myRead", i.e. with the number of bytes actually written.
|
||
|
* Otherwise the data stream may get out of sync in case the streaming interface
|
||
|
* can't swallow all data at once.
|
||
|
******************************************************************************/
|
||
|
#ifndef TRC_STREAM_PORT_READ_DATA
|
||
|
#error "No definition for TRC_STREAM_PORT_READ_DATA (should be in trcStreamingPort.h)"
|
||
|
#endif
|
||
|
|
||
|
/******************************************************************************
|
||
|
* TRC_STREAM_PORT_WRITE_DATA (defined in trcStreamingPort.h)
|
||
|
*
|
||
|
* Defining how to write trace data to the streaming interface.
|
||
|
*
|
||
|
* Parameters:
|
||
|
*
|
||
|
* - _ptrData: a pointer (void*) to the data to write.
|
||
|
*
|
||
|
* - _size: the number of bytes to write (uint32_t).
|
||
|
*
|
||
|
* - _ptrBytesWritten: a pointer to an integer (int32_t), that should be
|
||
|
* assigned with the number of bytes actually written.
|
||
|
*
|
||
|
* Example:
|
||
|
*
|
||
|
* int32_t myWrite(void* ptrData, uint32_t size, int32_t* ptrBytesWritten);
|
||
|
*
|
||
|
* #define TRC_STREAM_PORT_WRITE_DATA(_ptrData, _size, _ptrBytesWritten) \
|
||
|
* myWrite(_ptrData, _size, _ptrBytesWritten)
|
||
|
*
|
||
|
* Your "myWrite" function should return 0 if successful, i.e. if at least some
|
||
|
* bytes were sent. A non-zero value should be returned if the streaming interface
|
||
|
* returned an error (e.g. a closed socket), which results in the recorder calling
|
||
|
* prvTraceWarning with the error code PSF_WARNING_STREAM_PORT_WRITE.
|
||
|
*
|
||
|
* If developing your own custom stream port and using the default internal
|
||
|
* buffer, it is important that the _ptrBytesWritten parameter is assigned
|
||
|
* correctly by "myWrite", i.e. with the number of bytes actually written.
|
||
|
* Otherwise the data stream may get out of sync in case the streaming interface
|
||
|
* can't swallow all data at once.
|
||
|
*
|
||
|
* Assuming TRC_STREAM_PORT_USE_INTERNAL_BUFFER is 1 (default), the TzCtrl task
|
||
|
* will use this macro to send one buffer page at a time. In case all data can't
|
||
|
* be written at once (if _ptrBytesWritten is less than _size), the TzCtrl task
|
||
|
* is smart enough to make repeated calls (with updated parameters) in order to
|
||
|
* send the remaining data.
|
||
|
*
|
||
|
* However, if TRC_STREAM_PORT_USE_INTERNAL_BUFFER is 0, this is used from the
|
||
|
* COMMIT macro, directly in the "event functions". In that case, the
|
||
|
* _ptrBytesWritten parameter will be NULL and should be ignored by the write
|
||
|
* function. In this case, it is assumed that all data can be sent in a single
|
||
|
* call, otherwise the write function should return a non-zero error code.
|
||
|
******************************************************************************/
|
||
|
#ifndef TRC_STREAM_PORT_WRITE_DATA
|
||
|
#error "No definition for TRC_STREAM_PORT_WRITE_DATA (should be in trcStreamingPort.h)"
|
||
|
#endif
|
||
|
|
||
|
/******************************************************************************
|
||
|
* Data structure declaration, depending on TRC_CFG_RECORDER_BUFFER_ALLOCATION
|
||
|
*******************************************************************************/
|
||
|
#if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_STATIC)
|
||
|
|
||
|
/* Static allocation. */
|
||
|
|
||
|
/* If not defined in trcStreamingPort.h */
|
||
|
#ifndef TRC_STREAM_PORT_ALLOCATE_FIELDS
|
||
|
#define TRC_STREAM_PORT_ALLOCATE_FIELDS() \
|
||
|
char _TzTraceData[(TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT) * (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE)];
|
||
|
extern char _TzTraceData[(TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT) * (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE)];
|
||
|
#endif
|
||
|
|
||
|
/* If not defined in trcStreamingPort.h */
|
||
|
#ifndef TRC_STREAM_PORT_MALLOC
|
||
|
#define TRC_STREAM_PORT_MALLOC() /* Static allocation. Not used. */
|
||
|
#endif
|
||
|
#else
|
||
|
/* For Dynamic or Custom Allocation mode */
|
||
|
|
||
|
/* If not defined in trcStreamingPort.h */
|
||
|
#ifndef TRC_STREAM_PORT_ALLOCATE_FIELDS
|
||
|
#define TRC_STREAM_PORT_ALLOCATE_FIELDS() char* _TzTraceData = NULL;
|
||
|
extern char* _TzTraceData;
|
||
|
#endif
|
||
|
|
||
|
/* If not defined in trcStreamingPort.h */
|
||
|
#ifndef TRC_STREAM_PORT_MALLOC
|
||
|
#if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC)
|
||
|
#define TRC_STREAM_PORT_MALLOC() \
|
||
|
_TzTraceData = TRC_PORT_MALLOC((TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT) * (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE));
|
||
|
extern char* _TzTraceData;
|
||
|
#else
|
||
|
#define TRC_STREAM_PORT_MALLOC() /* Custom allocation. Not used. */
|
||
|
#endif
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
#ifndef TRC_STREAM_PORT_INIT
|
||
|
#define TRC_STREAM_PORT_INIT() \
|
||
|
TRC_STREAM_PORT_MALLOC(); /* Empty if static allocation mode */ \
|
||
|
prvPagedEventBufferInit(_TzTraceData);
|
||
|
#endif
|
||
|
|
||
|
|
||
|
/* Signal an error. */
|
||
|
void prvTraceError(int errCode);
|
||
|
|
||
|
/* Signal an warning (does not stop the recorder). */
|
||
|
void prvTraceWarning(int errCode);
|
||
|
|
||
|
/******************************************************************************/
|
||
|
/*** ERROR AND WARNING CODES (check using xTraceGetLastError) *****************/
|
||
|
/******************************************************************************/
|
||
|
|
||
|
#define PSF_ERROR_NONE 0
|
||
|
#define PSF_ERROR_EVENT_CODE_TOO_LARGE 1
|
||
|
#define PSF_ERROR_ISR_NESTING_OVERFLOW 2
|
||
|
#define PSF_ERROR_DWT_NOT_SUPPORTED 3
|
||
|
#define PSF_ERROR_DWT_CYCCNT_NOT_SUPPORTED 4
|
||
|
#define PSF_ERROR_TZCTRLTASK_NOT_CREATED 5
|
||
|
|
||
|
#define PSF_WARNING_SYMBOL_TABLE_SLOTS 101
|
||
|
#define PSF_WARNING_SYMBOL_MAX_LENGTH 102
|
||
|
#define PSF_WARNING_OBJECT_DATA_SLOTS 103
|
||
|
#define PSF_WARNING_STRING_TOO_LONG 104
|
||
|
#define PSF_WARNING_STREAM_PORT_READ 105
|
||
|
#define PSF_WARNING_STREAM_PORT_WRITE 106
|
||
|
|
||
|
/******************************************************************************/
|
||
|
/*** INTERNAL STREAMING FUNCTIONS *********************************************/
|
||
|
/******************************************************************************/
|
||
|
|
||
|
/* Saves a symbol name (task name etc.) in symbol table */
|
||
|
void prvTraceSaveSymbol(const void *address, const char *name);
|
||
|
|
||
|
/* Deletes a symbol name (task name etc.) from symbol table */
|
||
|
void prvTraceDeleteSymbol(void *address);
|
||
|
|
||
|
/* Saves an object data entry (task base priority) in object data table */
|
||
|
void prvTraceSaveObjectData(const void *address, uint32_t data);
|
||
|
|
||
|
/* Removes an object data entry (task base priority) from object data table */
|
||
|
void prvTraceDeleteObjectData(void *address);
|
||
|
|
||
|
/* Store an event with zero parameters (event ID only) */
|
||
|
void prvTraceStoreEvent0(uint16_t eventID);
|
||
|
|
||
|
/* Store an event with one 32-bit parameter (pointer address or an int) */
|
||
|
void prvTraceStoreEvent1(uint16_t eventID,
|
||
|
uint32_t param1);
|
||
|
|
||
|
/* Store an event with two 32-bit parameters */
|
||
|
void prvTraceStoreEvent2(uint16_t eventID,
|
||
|
uint32_t param1,
|
||
|
uint32_t param2);
|
||
|
|
||
|
/* Store an event with three 32-bit parameters */
|
||
|
void prvTraceStoreEvent3(uint16_t eventID,
|
||
|
uint32_t param1,
|
||
|
uint32_t param2,
|
||
|
uint32_t param3);
|
||
|
|
||
|
/* Stores an event with <nParam> 32-bit integer parameters */
|
||
|
void prvTraceStoreEvent(int nParam, uint16_t EventID, ...);
|
||
|
|
||
|
/* Stories an event with a string and <nParam> 32-bit integer parameters */
|
||
|
void prvTraceStoreStringEvent(int nArgs, uint16_t eventID, const char* str, ...);
|
||
|
|
||
|
/* Initializes the paged event buffer used by certain stream ports */
|
||
|
void prvPagedEventBufferInit(char* buffer);
|
||
|
|
||
|
/* Retrieve a pointer to the paged event buffer */
|
||
|
void* prvPagedEventBufferGetWritePointer(int sizeOfEvent);
|
||
|
|
||
|
/* Transfer a full buffer page */
|
||
|
uint32_t prvPagedEventBufferTransfer(void);
|
||
|
|
||
|
/* The data structure for commands (a bit overkill) */
|
||
|
typedef struct
|
||
|
{
|
||
|
unsigned char cmdCode;
|
||
|
unsigned char param1;
|
||
|
unsigned char param2;
|
||
|
unsigned char param3;
|
||
|
unsigned char param4;
|
||
|
unsigned char param5;
|
||
|
unsigned char checksumLSB;
|
||
|
unsigned char checksumMSB;
|
||
|
} TracealyzerCommandType;
|
||
|
|
||
|
/* Checks if the provided command is a valid command */
|
||
|
int prvIsValidCommand(TracealyzerCommandType* cmd);
|
||
|
|
||
|
/* Executed the received command (Start or Stop) */
|
||
|
void prvProcessCommand(TracealyzerCommandType* cmd);
|
||
|
|
||
|
#define vTraceSetStopHook(x)
|
||
|
|
||
|
#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/
|
||
|
|
||
|
#else /* when TRC_USE_TRACEALYZER_RECORDER == 0 */
|
||
|
|
||
|
#define vTraceEnable(x)
|
||
|
#define xTraceRegisterString(x) 0; (void)x;
|
||
|
#define vTracePrint(chn, ...) (void)chn
|
||
|
#define vTracePrintF(chn, ...) (void)chn
|
||
|
#define vTraceInstanceFinishedNow()
|
||
|
#define vTraceInstanceFinishedNext()
|
||
|
#define vTraceStoreISRBegin(x) (void)x
|
||
|
#define vTraceStoreISREnd(x) (void)x
|
||
|
#define xTraceSetISRProperties(a, b) 0
|
||
|
#define vTraceStoreKernelObjectName(a, b)
|
||
|
#define xTraceRegisterChannelFormat(eventLabel, formatStr) 0
|
||
|
#define vTraceChannelPrint(label)
|
||
|
#define vTraceUBData(label, ...)
|
||
|
|
||
|
#define vTraceSetFilterGroup(x)
|
||
|
#define vTraceSetFilterMask(x)
|
||
|
|
||
|
#define prvTraceSetReadyEventsEnabled(status)
|
||
|
|
||
|
#define vTraceExcludeTask(handle)
|
||
|
|
||
|
#define uiTraceStart() (1)
|
||
|
#define vTraceStart()
|
||
|
#define vTraceStop()
|
||
|
|
||
|
#ifndef vTraceSetRecorderDataBuffer
|
||
|
#define vTraceSetRecorderDataBuffer(pRecorderData)
|
||
|
#endif
|
||
|
|
||
|
#define vTraceConsoleChannelPrintF(fmt, ...)
|
||
|
|
||
|
#ifndef TRC_ALLOC_CUSTOM_BUFFER
|
||
|
#define TRC_ALLOC_CUSTOM_BUFFER(bufname)
|
||
|
#endif
|
||
|
|
||
|
#define xTraceIsRecordingEnabled() (0)
|
||
|
|
||
|
#define vTraceSetStopHook(x)
|
||
|
|
||
|
#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#endif /* TRC_RECORDER_H */
|