summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMing Yue <mingyue86010@gmail.com>2020-08-13 14:29:33 -0700
committerGitHub <noreply@github.com>2020-08-13 14:29:33 -0700
commitd248555de5ec05260201e48a06f8252852c5fb18 (patch)
tree371807ff06428845017c19a42692118d62c71125
parent70dcbe4527a45ab4fea6d58c016e7d3032f31e8c (diff)
downloadfreertos-git-d248555de5ec05260201e48a06f8252852c5fb18.tar.gz
Update #169 -- Percepio Tracealyzer Recorder v4.3.11 (#201)
* * Pull Request for Percepio Tracealyzer Recorder v4.3.11 * Update Tracealyzer demo config file. Co-authored-by: Erik Tamlin <erik.tamlin@percepio.com>
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/Trace_Recorder_Configuration/trcConfig.h141
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/aws_secure_sockets.tzext.h170
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/aws_wifi.tzext.h169
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcExtensions.h422
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcHardwarePort.h1036
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcKernelPort.h5356
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcPortDefines.h275
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcRecorder.h3694
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcConfig.h712
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcSnapshotConfig.h754
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcStreamingConfig.h314
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/readme.txt152
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/AFR_WIFI_LOCAL/Readme-Streamport.txt22
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/AFR_WIFI_LOCAL/include/trcStreamingPort.h161
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/AFR_WIFI_LOCAL/trcStreamingPort.c191
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/Readme-ARM_ITM.txt58
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/include/trcStreamingPort.h228
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/trcStreamingPort.c240
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/Readme-Streamport.txt36
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/include/trcStreamingPort.h174
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/trcStreamingPort.c206
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/Readme-Streamport.txt42
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/include/SEGGER_RTT_Conf.h4
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/include/trcStreamingPort.h392
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/trcStreamingPort.c127
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/Readme-Streamport.txt70
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/include/trcStreamingPort.h134
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/trcStreamingPort.c366
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP_Win32/Readme-Streamport.txt38
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP_Win32/include/trcStreamingPort.h75
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP_Win32/trcStreamingPort.c210
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/USB_CDC/Readme-Streamport.txt52
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/USB_CDC/include/trcStreamingPort.h166
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/USB_CDC/trcStreamingPort.c537
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/tracealyzer_readme.txt748
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcKernelPort.c1916
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcSnapshotRecorder.c6179
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcStreamingRecorder.c3931
38 files changed, 16058 insertions, 13440 deletions
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/Trace_Recorder_Configuration/trcConfig.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/Trace_Recorder_Configuration/trcConfig.h
index 3a6fab81b..0989814e6 100644
--- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/Trace_Recorder_Configuration/trcConfig.h
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/Trace_Recorder_Configuration/trcConfig.h
@@ -98,22 +98,32 @@ extern "C" {
* TRC_RECORDER_MODE_STREAMING
******************************************************************************/
#define TRC_CFG_RECORDER_MODE TRC_RECORDER_MODE_SNAPSHOT
+
/******************************************************************************
* TRC_CFG_FREERTOS_VERSION
*
* Specify what version of FreeRTOS that is used (don't change unless using the
* trace recorder library with an older version of FreeRTOS).
*
- * TRC_FREERTOS_VERSION_7_3 If using FreeRTOS v7.3.x
- * TRC_FREERTOS_VERSION_7_4 If using FreeRTOS v7.4.x
- * TRC_FREERTOS_VERSION_7_5_OR_7_6 If using FreeRTOS v7.5.0 - v7.6.0
- * TRC_FREERTOS_VERSION_8_X If using FreeRTOS v8.X.X
- * TRC_FREERTOS_VERSION_9_0_0 If using FreeRTOS v9.0.0
- * TRC_FREERTOS_VERSION_9_0_1 If using FreeRTOS v9.0.1
- * TRC_FREERTOS_VERSION_9_0_2 If using FreeRTOS v9.0.2
- * TRC_FREERTOS_VERSION_10_0_0 If using FreeRTOS v10.0.0 or later
+ * TRC_FREERTOS_VERSION_7_3_X If using FreeRTOS v7.3.X
+ * TRC_FREERTOS_VERSION_7_4_X If using FreeRTOS v7.4.X
+ * TRC_FREERTOS_VERSION_7_5_X If using FreeRTOS v7.5.X
+ * TRC_FREERTOS_VERSION_7_6_X If using FreeRTOS v7.6.X
+ * TRC_FREERTOS_VERSION_8_X_X If using FreeRTOS v8.X.X
+ * TRC_FREERTOS_VERSION_9_0_0 If using FreeRTOS v9.0.0
+ * TRC_FREERTOS_VERSION_9_0_1 If using FreeRTOS v9.0.1
+ * TRC_FREERTOS_VERSION_9_0_2 If using FreeRTOS v9.0.2
+ * TRC_FREERTOS_VERSION_10_0_0 If using FreeRTOS v10.0.0
+ * TRC_FREERTOS_VERSION_10_0_1 If using FreeRTOS v10.0.1
+ * TRC_FREERTOS_VERSION_10_1_0 If using FreeRTOS v10.1.0
+ * TRC_FREERTOS_VERSION_10_1_1 If using FreeRTOS v10.1.1
+ * TRC_FREERTOS_VERSION_10_2_0 If using FreeRTOS v10.2.0
+ * TRC_FREERTOS_VERSION_10_2_1 If using FreeRTOS v10.2.1
+ * TRC_FREERTOS_VERSION_10_3_0 If using FreeRTOS v10.3.0
+ * TRC_FREERTOS_VERSION_10_3_1 If using FreeRTOS v10.3.1
+ * TRC_FREERTOS_VERSION_10_4_0 If using FreeRTOS v10.4.0 or later
*****************************************************************************/
-#define TRC_CFG_FREERTOS_VERSION TRC_FREERTOS_VERSION_10_0_0
+#define TRC_CFG_FREERTOS_VERSION TRC_FREERTOS_VERSION_10_3_1
/*******************************************************************************
* TRC_CFG_SCHEDULING_ONLY
@@ -144,13 +154,13 @@ extern "C" {
*
* Macro which should be defined as either zero (0) or one (1).
*
- * If this is zero (0), all code related to User Events is excluded in order
+ * If this is zero (0), all code related to User Events is excluded in order
* to reduce code size. Any attempts of storing User Events are then silently
* ignored.
*
- * User Events are application-generated events, like "printf" but for the
- * trace log, generated using vTracePrint and vTracePrintF.
- * The formatting is done on host-side, by Tracealyzer. User Events are
+ * User Events are application-generated events, like "printf" but for the
+ * trace log, generated using vTracePrint and vTracePrintF.
+ * The formatting is done on host-side, by Tracealyzer. User Events are
* therefore much faster than a console printf and can often be used
* in timing critical code without problems.
*
@@ -170,7 +180,14 @@ extern "C" {
* Macro which should be defined as either zero (0) or one (1).
*
* If this is zero (0), the code for recording Interrupt Service Routines is
- * excluded, in order to reduce code size.
+ * excluded, in order to reduce code size. This means that any calls to
+ * vTraceStoreISRBegin/vTraceStoreISREnd will be ignored.
+ * This does not completely disable ISR tracing, in cases where an ISR is
+ * calling a traced kernel service. These events will still be recorded and
+ * show up in anonymous ISR instances in Tracealyzer, with names such as
+ * "ISR sending to <queue name>".
+ * To disable such tracing, please refer to vTraceSetFilterGroup and
+ * vTraceSetFilterMask.
*
* Default value is 1.
*
@@ -234,7 +251,7 @@ extern "C" {
*
* Macro which should be defined as either zero (0) or one (1).
*
- * If this is zero (0), the trace will exclude any "pending function call"
+ * If this is zero (0), the trace will exclude any "pending function call"
* events, such as xTimerPendFunctionCall().
*
* Default value is 0 since dependent on timers.c
@@ -253,6 +270,90 @@ extern "C" {
******************************************************************************/
#define TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS 0
+ /******************************************************************************
+ * TRC_CFG_ENABLE_STACK_MONITOR
+ *
+ * If enabled (1), the recorder periodically reports the unused stack space of
+ * all active tasks.
+ * The stack monitoring runs in the Tracealyzer Control task, TzCtrl. This task
+ * is always created by the recorder when in streaming mode.
+ * In snapshot mode, the TzCtrl task is only used for stack monitoring and is
+ * not created unless this is enabled.
+ *****************************************************************************/
+#define TRC_CFG_ENABLE_STACK_MONITOR 0
+
+ /******************************************************************************
+ * TRC_CFG_STACK_MONITOR_MAX_TASKS
+ *
+ * Macro which should be defined as a non-zero integer value.
+ *
+ * This controls how many tasks that can be monitored by the stack monitor.
+ * If this is too small, some tasks will be excluded and a warning is shown.
+ *
+ * Default value is 10.
+ *****************************************************************************/
+#define TRC_CFG_STACK_MONITOR_MAX_TASKS 10
+
+ /******************************************************************************
+ * TRC_CFG_STACK_MONITOR_MAX_REPORTS
+ *
+ * Macro which should be defined as a non-zero integer value.
+ *
+ * This defines how many tasks that will be subject to stack usage analysis for
+ * each execution of the Tracealyzer Control task (TzCtrl). Note that the stack
+ * monitoring cycles between the tasks, so this does not affect WHICH tasks that
+ * are monitored, but HOW OFTEN each task stack is analyzed.
+ *
+ * This setting can be combined with TRC_CFG_CTRL_TASK_DELAY to tune the
+ * frequency of the stack monitoring. This is motivated since the stack analysis
+ * can take some time to execute.
+ * However, note that the stack analysis runs in a separate task (TzCtrl) that
+ * can be executed on low priority. This way, you can avoid that the stack
+ * analysis disturbs any time-sensitive tasks.
+ *
+ * Default value is 1.
+ *****************************************************************************/
+#define TRC_CFG_STACK_MONITOR_MAX_REPORTS 1
+
+ /*******************************************************************************
+ * Configuration Macro: TRC_CFG_CTRL_TASK_PRIORITY
+ *
+ * The scheduling priority of the Tracealyzer Control (TzCtrl) task.
+ *
+ * In streaming mode, TzCtrl is used to receive start/stop commands from
+ * Tracealyzer and in some cases also to transmit the trace data (for stream
+ * ports that uses the internal buffer, like TCP/IP). For such stream ports,
+ * make sure the TzCtrl priority is high enough to ensure reliable periodic
+ * execution and transfer of the data, but low enough to avoid disturbing any
+ * time-sensitive functions.
+ *
+ * In Snapshot mode, TzCtrl is only used for the stack usage monitoring and is
+ * not created if stack monitoring is disabled. TRC_CFG_CTRL_TASK_PRIORITY should
+ * be low, to avoid disturbing any time-sensitive tasks.
+ ******************************************************************************/
+#define TRC_CFG_CTRL_TASK_PRIORITY 1
+
+ /*******************************************************************************
+ * Configuration Macro: TRC_CFG_CTRL_TASK_DELAY
+ *
+ * The delay between loops of the TzCtrl task (see TRC_CFG_CTRL_TASK_PRIORITY),
+ * which affects the frequency of the stack monitoring.
+ *
+ * In streaming mode, this also affects the trace data transfer if you are using
+ * a stream port leveraging the internal buffer (like TCP/IP). A shorter delay
+ * increases the CPU load of TzCtrl somewhat, but may improve the performance of
+ * of the trace streaming, especially if the trace buffer is small.
+ ******************************************************************************/
+#define TRC_CFG_CTRL_TASK_DELAY 10
+
+ /*******************************************************************************
+ * Configuration Macro: TRC_CFG_CTRL_TASK_STACK_SIZE
+ *
+ * The stack size of the Tracealyzer Control (TzCtrl) task.
+ * See TRC_CFG_CTRL_TASK_PRIORITY for further information about TzCtrl.
+ ******************************************************************************/
+#define TRC_CFG_CTRL_TASK_STACK_SIZE (configMINIMAL_STACK_SIZE * 2)
+
/*******************************************************************************
* Configuration Macro: TRC_CFG_RECORDER_BUFFER_ALLOCATION
*
@@ -286,6 +387,16 @@ extern "C" {
*****************************************************************************/
#define TRC_CFG_MAX_ISR_NESTING 8
+/******************************************************************************
+ * TRC_CFG_ACKNOWLEDGE_QUEUE_SET_SEND
+ *
+ * When using FreeRTOS v10.3.0 or v10.3.1, please make sure that the trace
+ * point in prvNotifyQueueSetContainer() in queue.c is renamed from
+ * traceQUEUE_SEND to traceQUEUE_SET_SEND in order to tell them apart from
+ * other traceQUEUE_SEND trace points. Then set this to TRC_ACKNOWLEDGED.
+ *****************************************************************************/
+#define TRC_CFG_ACKNOWLEDGE_QUEUE_SET_SEND TRC_ACKNOWLEDGED /* 0 or TRC_ACKNOWLEDGED */
+
/* Specific configuration, depending on Streaming/Snapshot mode */
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)
#include "trcSnapshotConfig.h"
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/aws_secure_sockets.tzext.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/aws_secure_sockets.tzext.h
new file mode 100644
index 000000000..f2ebf74c0
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/aws_secure_sockets.tzext.h
@@ -0,0 +1,170 @@
+/*******************************************************************************
+ * Trace Recorder Library for Tracealyzer v4.2.0
+ * Percepio AB, www.percepio.com
+ *
+ * aws_secure_socket.tzext.h
+ *
+ * An example of a Tracealyzer extension for tracing API calls, in this case
+ * for tracing selected functions in Amazon FreeRTOS/aws_secure_sockets.
+ * See trcExtensions.h for information on how to use this.
+ *
+ * To create your own extension, first make sure to read the documentation
+ * in trcExtensions.h. Then, to create an extension header file like this
+ * one, you need to provide:
+ *
+ * - Extension Definitions - name and event codes of the extensions.
+ *
+ * - Trace Wrappers - calls the original function and traces the event.
+ *
+ * - Function Redefinitions - changes the function calls to the trace wrappers.
+ *
+ * See the below comments for details about these definitions. Note that you
+ * also need a matching .xml file for Tracealyzer to understand the data.
+ * See trcExtensions.h for further information.
+ *
+ * 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 _AWS_SECURE_SOCKETS_TZEXT_H
+#define _AWS_SECURE_SOCKETS_TZEXT_H
+
+/***** Extension Definitions *****/
+
+/******************************************************************************
+ * <EXTENSIONPREFIX>_NAME
+ * The name of the extension as a string constant. This name is used by the
+ * Tracealyzer host application to find the right XML file for interpreting
+ * the events. Assuming the extension name is "aws_secure_sockets", Tracealyzer
+ * will look for an XML file named "aws_secure_sockets-<VERSION>.xml", first in
+ * the folder of the current trace file, next in the Tracealyzer 4/cfg folder.
+ * For the VERSION part, see the TRC_EXT_<ExtName>_VERSION macros below.
+ *
+ * Note: The extension name displayed in Tracealyzer is defined in the XML file
+ * in the EventGroup element (e.g. <EventGroup name="SOCKETS">)
+ *
+ *****************************************************************************/
+#define TRC_EXT_SOCKETS_NAME "aws_secure_sockets"
+
+/******************************************************************************
+ * <EXTENSIONPREFIX>_VERSION_MAJOR
+ * <EXTENSIONPREFIX>_VERSION_MINOR
+ * <EXTENSIONPREFIX>_VERSION_PATCH
+ *
+ * The version code of the extension (MAJOR.MINOR.PATCH)
+ *
+ * If you increment the version code when modifying an extension, you can still
+ * show old traces recorded using an earlier version of the extension.
+ *
+ * Assuming the extension name is "aws_secure_sockets", and the below version
+ * codes are 1 (MAJOR), 2 (MINOR), 3 (PATCH), Tracealyzer will assume the
+ * corresponding XML file is named "aws_secure_sockets-v1.2.3.xml". So if then
+ * view a trace recorded with extension version 1.2.2, those traces will look
+ * for "aws_secure_sockets-v1.2.2.xml" instead.
+ *
+ * Note that major and minor are stored as 8 bit values, while patch is stored
+ * using 16 bits. They are treated as unsigned integers, so the maximum values
+ * are 256, 256 and 65535.
+ *****************************************************************************/
+#define TRC_EXT_SOCKETS_VERSION_MAJOR 1
+
+#define TRC_EXT_SOCKETS_VERSION_MINOR 0
+
+#define TRC_EXT_SOCKETS_VERSION_PATCH 0
+
+
+/******************************************************************************
+ * <EXTENSIONPREFIX>_<EVENTCODE>
+ * The event codes used in the trace wrapper functions. Important that these
+ * are relative to <PREFIX>_FIRST.
+ *****************************************************************************/
+#define EVENTCODE_SOCKETS_Connect (TRC_EXT_BASECODE + 0)
+
+#define EVENTCODE_SOCKETS_Send (TRC_EXT_BASECODE + 1)
+
+#define EVENTCODE_SOCKETS_Recv (TRC_EXT_BASECODE + 2)
+
+/******************************************************************************
+ * <EXTENSIONPREFIX>_COUNT
+ * The number of event codes used by this extension. Should be at least 1.
+ * Tracealyzer allows for events codes up to 4095.
+ *****************************************************************************/
+#define TRC_EXT_SOCKETS_COUNT 2
+
+
+/***** Trace Wrappers *****/
+
+#include "aws_secure_sockets.h" /* Including the original header file, so that custom data types are understood. */
+
+static inline int32_t SOCKETS_Connect__trace( Socket_t xSocket, SocketsSockaddr_t * pxAddress, Socklen_t xAddressLength )
+{
+ int32_t ret = SOCKETS_Connect(xSocket, pxAddress, xAddressLength);
+
+ // Note: The host-side xml file assumes that ret == 0 means OK, otherwise timeout/error.
+ prvTraceStoreEvent3(EVENTCODE_SOCKETS_Connect, (uint32_t)xSocket, (uint32_t)pxAddress->ulAddress, (uint32_t)ret);
+
+ return ret;
+}
+
+static inline int32_t SOCKETS_Send__trace( Socket_t xSocket, const void * pvBuffer, size_t xDataLength, uint32_t ulFlags )
+{
+ int32_t ret = SOCKETS_Send(xSocket, pvBuffer, xDataLength, ulFlags);
+
+ // Note: The host-side xml file assumes that ret == 0 means OK, otherwise timeout/error.
+ prvTraceStoreEvent2(EVENTCODE_SOCKETS_Send, (uint32_t)xSocket, (uint32_t)ret);
+
+ return ret;
+}
+
+
+static inline int32_t SOCKETS_Recv__trace( Socket_t xSocket, void * pvBuffer, size_t xBufferLength, uint32_t ulFlags )
+{
+ int32_t ret = SOCKETS_Recv(xSocket, pvBuffer, xBufferLength, ulFlags);
+
+ // Note: The host-side xml file assumes that ret == 0 means OK, otherwise timeout/error.
+ prvTraceStoreEvent2(EVENTCODE_SOCKETS_Recv, (uint32_t)xSocket, (uint32_t)ret);
+
+ return ret;
+}
+
+/***** Function Redefinitions *****/
+
+#define SOCKETS_Connect SOCKETS_Connect__trace
+
+#define SOCKETS_Send SOCKETS_Send__trace
+
+#define SOCKETS_Recv SOCKETS_Recv__trace
+
+#endif /* _AWS_SECURE_SOCKETS_TZEXT_H */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/aws_wifi.tzext.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/aws_wifi.tzext.h
new file mode 100644
index 000000000..238eacaff
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/aws_wifi.tzext.h
@@ -0,0 +1,169 @@
+/*******************************************************************************
+ * Trace Recorder Library for Tracealyzer v4.2.0
+ * Percepio AB, www.percepio.com
+ *
+ * aws_secure_socket.tzext.h
+ *
+ * An example of a Tracealyzer extension for tracing API calls, in this case
+ * for tracing selected functions in Amazon FreeRTOS/aws_wifi.
+ * See trcExtensions.h for information on how to use this.
+ *
+ * To create your own extension, first make sure to read the documentation
+ * in trcExtensions.h. Then, to create an extension header file like this
+ * one, you need to provide:
+ *
+ * - Extension Definitions - name and event codes of the extensions.
+ *
+ * - Trace Wrappers - calls the original function and traces the event.
+ *
+ * - Function Redefinitions - changes the function calls to the trace wrappers.
+ *
+ * See the below comments for details about these definitions. Note that you
+ * also need a matching .xml file for Tracealyzer to understand the data.
+ * See trcExtensions.h for further information.
+ *
+ * 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 _AWS_WIFI_TZEXT_H
+#define _AWS_WIFI_TZEXT_H
+
+/***** Extension Definitions (must use the same prefix!) *****/
+
+/******************************************************************************
+ * <EXTENSIONPREFIX>_NAME
+ * The name of the extension as a string constant. This name is used by the
+ * Tracealyzer host application to find the right XML file for interpreting
+ * the events. Assuming the extension name is "aws_secure_sockets", Tracealyzer
+ * will look for an XML file named "aws_secure_sockets-<VERSION>.xml", first in
+ * the folder of the current trace file, next in the Tracealyzer 4/cfg folder.
+ * For the VERSION part, see the TRC_EXT_<ExtName>_VERSION macros below.
+ *
+ * Note: The extension name displayed in Tracealyzer is defined in the XML file
+ * in the EventGroup element (e.g. <EventGroup name="SOCKETS">)
+ *
+ *****************************************************************************/
+#define TRC_EXT_WIFI_NAME "aws_wifi"
+
+/******************************************************************************
+ * <EXTENSIONPREFIX>_VERSION_MAJOR
+ * <EXTENSIONPREFIX>_VERSION_MINOR
+ * <EXTENSIONPREFIX>_VERSION_PATCH
+ *
+ * The version code of the extension (MAJOR.MINOR.PATCH)
+ *
+ * If you increment the version code when modifying an extension, you can still
+ * show old traces recorded using an earlier version of the extension.
+ *
+ * Assuming the extension name is "aws_secure_sockets", and the below version
+ * codes are 1 (MAJOR), 2 (MINOR), 3 (PATCH), Tracealyzer will assume the
+ * corresponding XML file is named "aws_secure_sockets-v1.2.3.xml". So if then
+ * view a trace recorded with extension version 1.2.2, those traces will look
+ * for "aws_secure_sockets-v1.2.2.xml" instead.
+ *
+ * Note that major and minor are stored as 8 bit values, while patch is stored
+ * using 16 bits. They are treated as unsigned integers, so the maximum values
+ * are 256, 256 and 65535.
+ *****************************************************************************/
+#define TRC_EXT_WIFI_VERSION_MAJOR 1
+
+#define TRC_EXT_WIFI_VERSION_MINOR 0
+
+#define TRC_EXT_WIFI_VERSION_PATCH 0
+
+/******************************************************************************
+ * <EXTENSIONPREFIX>_<EVENTCODE>
+ * The event codes used in the trace wrapper functions. Important that these
+ * are relative to <PREFIX>_FIRST.
+ *****************************************************************************/
+#define EVENTCODE_WIFI_On (TRC_EXT_BASECODE + 0)
+
+#define EVENTCODE_WIFI_Off (TRC_EXT_BASECODE + 1)
+
+#define EVENTCODE_WIFI_ConnectAP (TRC_EXT_BASECODE + 2)
+
+/******************************************************************************
+ * <EXTENSIONPREFIX>_COUNT
+ * The number of event codes used by this extension. Should be at least 1.
+ * Tracealyzer allows for events codes up to 4095.
+ *****************************************************************************/
+#define TRC_EXT_WIFI_COUNT 3
+
+
+/***** Trace Wrappers *****/
+
+#include "aws_wifi.h" /* Including the original header file, so that custom data types are understood. */
+
+static inline WIFIReturnCode_t WIFI_On__trace( void )
+{
+ WIFIReturnCode_t ret = WIFI_On();
+
+ // Note: The host-side xml file assumes that ret == 0 means OK, otherwise timeout/error.
+ prvTraceStoreEvent1(EVENTCODE_WIFI_On, (uint32_t)ret);
+
+ return ret;
+}
+
+ static inline WIFIReturnCode_t WIFI_Off__trace( void )
+ {
+ WIFIReturnCode_t ret = WIFI_Off();
+
+ // Note: The host-side xml file assumes that ret == 0 means OK, otherwise timeout/error.
+ prvTraceStoreEvent1(EVENTCODE_WIFI_Off, (uint32_t)ret);
+
+ return ret;
+ }
+
+ static inline WIFIReturnCode_t WIFI_ConnectAP__trace( const WIFINetworkParams_t * const pxNetworkParams )
+ {
+ WIFIReturnCode_t ret = WIFI_ConnectAP(pxNetworkParams);
+
+ // Note: The host-side xml file assumes that ret == 0 means OK, otherwise timeout/error.
+
+ prvTraceStoreStringEvent(2, EVENTCODE_WIFI_ConnectAP, pxNetworkParams->pcSSID, pxNetworkParams->xSecurity, ret);
+
+ return ret;
+ }
+
+/***** Function Redefinitions *****/
+
+#define WIFI_On WIFI_On__trace
+
+#define WIFI_Off WIFI_Off__trace
+
+#define WIFI_ConnectAP WIFI_ConnectAP__trace
+
+#endif /* _AWS_SECURE_SOCKETS2_TZEXT_H */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcExtensions.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcExtensions.h
new file mode 100644
index 000000000..dfcdfcea7
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcExtensions.h
@@ -0,0 +1,422 @@
+/*******************************************************************************
+ * Trace Recorder Library for Tracealyzer v4.3.11
+ * Percepio AB, www.percepio.com
+ *
+ * trcExtensions.h
+ *
+ * The extension interface of the recorder library, allowing for tracing
+ * function calls to any API without modifications. All that is needed is a
+ * single #include line in the .c files calling the API.
+ *
+ * This can be used to provide more detailed traces, including calls to e.g.
+ * middleware, drivers or important APIs in your application code. This can be
+ * applied selectively to specified functions and may include selected
+ * parameters as well as the return value.
+ *
+ * Unlike the "User Event" concept, an extension is intended for systematic use
+ * and can benefit from all powerful features in Tracealyzer via host-side XML
+ * files that configure how Tracealyzer should interpret each event.
+ *
+ * Extensions are self-contained and easy to integrate, which makes them
+ * convenient for distribution. Software vendors can thus develop such
+ * extensions and provide trace support for their users.
+ *
+ * An extension consists of two files:
+ *
+ * - An extension header file (e.g. "api.tzext.h") - this defines how to
+ * trace the API function calls.
+ *
+ * - An XML file for the Tracealyzer application (e.g. "api-v1.0.0.xml").
+ * This needs to match the tracing setup in your extension header file.
+ *
+ *
+ * USAGE
+ *
+ * This description assumes you already have the extension files for the APIs you
+ * like to trace. To include them, follow these steps:
+ *
+ * 1. Update trcExtensions.h with respect to:
+ *
+ * 1.1. TRC_CFG_EXTENSION_COUNT: The number of extensions to enable (max 4).
+ *
+ * 1.2. The name(s) of the extension header file(s) to include.
+ *
+ * 1.3. The Extension Prefix, i.e., the first part of the definition names
+ * used in each header file.
+ *
+ * 2. Add #include "trcExtensions.h" in all .c files calling the API:
+ *
+ * #include ...
+ * #include "api.h" // The API you like to trace
+ * #include ...
+ * #include "trcExtensions.h"
+ *
+ * We recommend to put this as the LAST #include statement.
+ *
+ * HOWEVER, don't include "trcExtensions.h" in the .c files containing the
+ * functions you intend to trace. The compiler will then complain about
+ * multiple definitions of the trace wrapper function.
+ *
+ * 3. Copy the extension XML file to the "Tracealyzer 4/cfg" folder.
+ * On Windows this is typically
+ *
+ * C:\Program Files\Percepio\Tracealyzer 4\cfg
+ *
+ *
+ * HOW IT WORKS
+ *
+ * By including "trcExtensions.h" in your .c files, the preprocessor will
+ * redefine all calls of the functions specified in the extension header file.
+ * Calls to those functions will now instead call the "trace wrapper functions"
+ * defined in the extension header. The trace wrapper functions then call the
+ * original function as well as the trace recorder library.
+ *
+ * call foo(a) ----> foo__trace(a) -----> foo(a)
+ * -----> trace recorder library
+ *
+ * Note that the trace wrapper function should have the same declaration as the
+ * original function (apart from the name) and also returns any return value
+ * back to the original caller. So functionally this is completely transparent.
+ *
+ * This works also for calls via function pointers, as the assignments of the
+ * function pointers will be affected, so the function pointers will point to
+ * the trace wrapper function.
+ *
+ * It even works when calling binary libraries, since only the calling code
+ * is modified, not the API itself.
+ *
+ * Extensions include a version code (Major.Minor.Patch), which is registered
+ * in the trace and also part of the XML file name. This way, Tracealyzer
+ * automatically finds the matching XML file, even if you open a old trace
+ * recorded using a earlier version of the extension (e.g. if the API has
+ * changed).
+ *
+ * LIMITATIONS
+ *
+ * The main limitation of this automatic approach is that it only allows for
+ * tracing call between different .c files. Moreover, you can't trace multiple
+ * APIs with calls between them. This since the calling file must include
+ * trcExtensions.h, while the called file must NOT include this.
+ *
+ * It is however possible to get around this limitation. You need to add
+ * #undef lines for each affected function to locally disable the redefinition,
+ * and modify each function call to instead call the trace wrapper function.
+ *
+ * #include "trcExtensions.h"
+ * #undef foo
+ * ...
+ * void foo(int a)
+ * {
+ * ...
+ * }
+ * ...
+ * foo__trace(a); // in another function - call foo and trace it
+ *
+ * These changes can remain in your code if you like, as the trace wrappers
+ * works even if the recorder is disabled.
+ *
+ * MAKING YOUR OWN EXTENSIONS
+ *
+ * Examples are found in the extensions directory. We recommend that you start
+ * by looking at aws_secure_sockets files (.h and .xml) that provides a basic
+ * example. The aws_wifi files provides a more advanced example.
+ * The header files include detailed documentation about how to design them,
+ *
+ * The XML files should have the same name as specified in the NAME property
+ * in the header file, followed by the version, i.e.
+ *
+ * <NAME>-v<VERSION_MAJOR>.<<VERSION_MINOR>.<VERSION_PATCH>.xml
+ *
+ * Documentation for the XML file format is not yet available, but is under
+ * development.
+ *
+ *
+ * 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 TRCEXTENSIONS_H_
+#define TRCEXTENSIONS_H_
+
+#include "trcRecorder.h"
+
+/******************************************************************************
+ * TRC_CFG_EXTENSION_COUNT
+ *
+ * Defines the number of extensions included in the trace. Maximum 4 extensions
+ * can be included.
+ *
+ * Default value is 0 (extension support disabled).
+ *
+ *****************************************************************************/
+#define TRC_CFG_EXTENSION_COUNT 0
+
+/******************************************************************************
+ * TRC_CFG_EXT_MAX_NAME_LEN
+ *
+ * Defines the maximum length of extension name(s), i.e. the <EXTENSION>_NAME
+ * macro(s) in trcExtensions.h.
+ *
+ * This value should will by rounded up to the nearest multiple of 4, and must
+ * not be zero. To disable extension support, see TRC_CFG_EXTENSION_COUNT.
+ *
+ * It is important that this setting is large enough so extension names are
+ * not truncated, otherwise the host-side Tracealyzer application won't be able
+ * to find the corresponding XML file.
+ *
+ * You may adjust this to reduce memory usage, or increase it to allow for
+ * longer extension names.
+ *
+ * Default value is 20.
+ *****************************************************************************/
+#define TRC_CFG_EXT_MAX_NAME_LEN 20
+
+/******************************************************************************
+ * TRC_EXTENSION_EVENTCODE_BASE
+ *
+ * The first event code used for the Extension system. This will be the first
+ * event code of the first extension, and other event codes are relative to
+ * this. This can be modified but this is normally not required.
+ *****************************************************************************/
+#define TRC_EXTENSION_EVENTCODE_BASE 256
+
+/*** Included Extensions ******************************************************
+ *
+ * Below you specify what extensions to include. For each
+ * extension you must define:
+ *
+ * - HEADER: The header file that defines the trace extension.
+ *
+ * - EXTENSION_PREFIX: The first part of the HEADER definition names.
+ *
+ *****************************************************************************/
+#define TRC_EXT1_HEADER "aws_secure_sockets.tzext.h"
+#define TRC_EXT1_PREFIX TRC_EXT_SOCKETS
+
+#define TRC_EXT2_HEADER "aws_wifi.tzext.h"
+#define TRC_EXT2_PREFIX TRC_EXT_WIFI
+
+#define TRC_EXT3_HEADER "Here you specify the header file for Extensions 3."
+#define TRC_EXT3_PREFIX NOT_DEFINED
+
+#define TRC_EXT4_HEADER "Here you specify the header file for Extensions 4."
+#define TRC_EXT4_PREFIX NOT_DEFINED
+
+/*** Don't modify below ******************************************************/
+
+#define ROUNDUP4(n) (4*((n+3)/4))
+
+typedef struct{
+ uint16_t firstEventCode;
+ uint16_t lastEventCode;
+ uint16_t patchVersion;
+ uint8_t minorVersion;
+ uint8_t majorVersion;
+ char name[ROUNDUP4(TRC_CFG_EXT_MAX_NAME_LEN)];
+} PSFExtensionEntryType;
+
+typedef struct{
+ uint16_t extensionEntryCount;
+ uint16_t baseEventCode;
+#if (TRC_CFG_EXTENSION_COUNT > 0)
+ uint8_t extensionEntryNameMaxLength;
+ uint8_t extensionEntrySize;
+ PSFExtensionEntryType extension[TRC_CFG_EXTENSION_COUNT];
+#endif
+} PSFExtensionInfoType;
+
+
+extern PSFExtensionInfoType PSFExtensionInfo;
+
+#define CAT(a, ...) PRIMITIVE_CAT(a, __VA_ARGS__)
+#define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__
+
+#define TRC_EXT_BASECODE (PSFExtensionInfo.extension[TRC_EXT_NUMBER-1].firstEventCode)
+
+#if (TRC_CFG_EXTENSION_COUNT >= 1)
+ #ifdef TRC_EXT1_HEADER
+ #define TRC_EXT_NUMBER 1
+ #include TRC_EXT1_HEADER
+ #undef TRC_EXT_NUMBER
+ #endif
+#endif
+
+#if (TRC_CFG_EXTENSION_COUNT >= 2)
+ #ifdef TRC_EXT2_HEADER
+ #define TRC_EXT_NUMBER 2
+ #include TRC_EXT2_HEADER
+ #undef TRC_EXT_NUMBER
+ #endif
+#endif
+
+#if (TRC_CFG_EXTENSION_COUNT >= 3)
+ #ifdef TRC_EXT3_HEADER
+ #define TRC_EXT_NUMBER 3
+ #include TRC_EXT3_HEADER
+ #undef TRC_EXT_NUMBER
+ #endif
+#endif
+
+#if (TRC_CFG_EXTENSION_COUNT == 4)
+ #ifdef TRC_EXT3_HEADER
+ #define TRC_EXT_NUMBER 4
+ #include TRC_EXT4_HEADER
+ #undef TRC_EXT_NUMBER
+ #endif
+#endif
+
+#define TRC_EXT1_COUNT CAT(TRC_EXT1_PREFIX, _COUNT)
+#define TRC_EXT2_COUNT CAT(TRC_EXT2_PREFIX, _COUNT)
+#define TRC_EXT3_COUNT CAT(TRC_EXT3_PREFIX, _COUNT)
+#define TRC_EXT4_COUNT CAT(TRC_EXT4_PREFIX, _COUNT)
+
+#define TRC_EXT1_NAME CAT(TRC_EXT1_PREFIX, _NAME)
+#define TRC_EXT2_NAME CAT(TRC_EXT2_PREFIX, _NAME)
+#define TRC_EXT3_NAME CAT(TRC_EXT3_PREFIX, _NAME)
+#define TRC_EXT4_NAME CAT(TRC_EXT4_PREFIX, _NAME)
+
+#define TRC_EXT1_VERSION_MAJOR CAT(TRC_EXT1_PREFIX, _VERSION_MAJOR)
+#define TRC_EXT2_VERSION_MAJOR CAT(TRC_EXT2_PREFIX, _VERSION_MAJOR)
+#define TRC_EXT3_VERSION_MAJOR CAT(TRC_EXT3_PREFIX, _VERSION_MAJOR)
+#define TRC_EXT4_VERSION_MAJOR CAT(TRC_EXT4_PREFIX, _VERSION_MAJOR)
+
+#define TRC_EXT1_VERSION_MINOR CAT(TRC_EXT1_PREFIX, _VERSION_MINOR)
+#define TRC_EXT2_VERSION_MINOR CAT(TRC_EXT2_PREFIX, _VERSION_MINOR)
+#define TRC_EXT3_VERSION_MINOR CAT(TRC_EXT3_PREFIX, _VERSION_MINOR)
+#define TRC_EXT4_VERSION_MINOR CAT(TRC_EXT4_PREFIX, _VERSION_MINOR)
+
+#define TRC_EXT1_VERSION_PATCH CAT(TRC_EXT1_PREFIX, _VERSION_PATCH)
+#define TRC_EXT2_VERSION_PATCH CAT(TRC_EXT2_PREFIX, _VERSION_PATCH)
+#define TRC_EXT3_VERSION_PATCH CAT(TRC_EXT3_PREFIX, _VERSION_PATCH)
+#define TRC_EXT4_VERSION_PATCH CAT(TRC_EXT4_PREFIX, _VERSION_PATCH)
+
+#if ((TRC_CFG_EXTENSION_COUNT > 4) || (TRC_CFG_EXTENSION_COUNT < 0))
+ #error "TRC_CFG_EXTENSION_COUNT must be in range [0..4]"
+#endif
+
+#if (TRC_CFG_EXTENSION_COUNT == 0)
+#define TRC_EXTENSIONS_DATA
+#endif
+
+#if (TRC_CFG_EXTENSION_COUNT == 1)
+#define TRC_EXTENSIONS_DATA \
+{ \
+ { TRC_EXTENSION_EVENTCODE_BASE, \
+ TRC_EXTENSION_EVENTCODE_BASE + TRC_EXT1_COUNT-1, \
+ TRC_EXT1_VERSION_PATCH, \
+ TRC_EXT1_VERSION_MINOR, \
+ TRC_EXT1_VERSION_MAJOR, \
+ TRC_EXT1_NAME } \
+}
+#endif
+
+#if (TRC_CFG_EXTENSION_COUNT == 2)
+#define TRC_EXTENSIONS_DATA \
+{ \
+ { TRC_EXTENSION_EVENTCODE_BASE, \
+ TRC_EXTENSION_EVENTCODE_BASE + TRC_EXT1_COUNT-1, \
+ TRC_EXT1_VERSION_PATCH, \
+ TRC_EXT1_VERSION_MINOR, \
+ TRC_EXT1_VERSION_MAJOR, \
+ TRC_EXT1_NAME } \
+ ,{ TRC_EXTENSION_EVENTCODE_BASE + TRC_EXT1_COUNT, \
+ TRC_EXTENSION_EVENTCODE_BASE + TRC_EXT1_COUNT + TRC_EXT2_COUNT-1, \
+ TRC_EXT2_VERSION_PATCH, \
+ TRC_EXT2_VERSION_MINOR, \
+ TRC_EXT2_VERSION_MAJOR, \
+ TRC_EXT2_NAME } \
+}
+#endif
+
+#if (TRC_CFG_EXTENSION_COUNT == 3)
+#define TRC_EXTENSIONS_DATA \
+{ \
+ { TRC_EXTENSION_EVENTCODE_BASE, \
+ TRC_EXTENSION_EVENTCODE_BASE + TRC_EXT1_COUNT-1, \
+ TRC_EXT1_VERSION_PATCH, \
+ TRC_EXT1_VERSION_MINOR, \
+ TRC_EXT1_VERSION_MAJOR, \
+ TRC_EXT1_NAME } \
+ ,{ TRC_EXTENSION_EVENTCODE_BASE + TRC_EXT1_COUNT, \
+ TRC_EXTENSION_EVENTCODE_BASE + TRC_EXT1_COUNT + TRC_EXT2_COUNT-1, \
+ TRC_EXT2_VERSION_PATCH, \
+ TRC_EXT2_VERSION_MINOR, \
+ TRC_EXT2_VERSION_MAJOR, \
+ TRC_EXT2_NAME } \
+ ,{ TRC_EXTENSION_EVENTCODE_BASE + TRC_EXT1_COUNT + TRC_EXT2_COUNT, \
+ TRC_EXTENSION_EVENTCODE_BASE + TRC_EXT1_COUNT + TRC_EXT2_COUNT + TRC_EXT3_COUNT - 1, \
+ TRC_EXT3_VERSION_PATCH, \
+ TRC_EXT3_VERSION_MINOR, \
+ TRC_EXT3_VERSION_MAJOR, \
+ TRC_EXT3_NAME } \
+}
+#endif
+#if (TRC_CFG_EXTENSION_COUNT == 4)
+#define TRC_EXTENSIONS_DATA \
+{ \
+ { TRC_EXTENSION_EVENTCODE_BASE, \
+ TRC_EXTENSION_EVENTCODE_BASE + TRC_EXT1_COUNT-1, \
+ TRC_EXT1_VERSION_PATCH, \
+ TRC_EXT1_VERSION_MINOR, \
+ TRC_EXT1_VERSION_MAJOR, \
+ TRC_EXT1_NAME } \
+ ,{ TRC_EXTENSION_EVENTCODE_BASE + TRC_EXT1_COUNT, \
+ TRC_EXTENSION_EVENTCODE_BASE + TRC_EXT1_COUNT + TRC_EXT2_COUNT-1, \
+ TRC_EXT2_VERSION_PATCH, \
+ TRC_EXT2_VERSION_MINOR, \
+ TRC_EXT2_VERSION_MAJOR, \
+ TRC_EXT2_NAME } \
+ ,{ TRC_EXTENSION_EVENTCODE_BASE + TRC_EXT1_COUNT + TRC_EXT2_COUNT, \
+ TRC_EXTENSION_EVENTCODE_BASE + TRC_EXT1_COUNT + TRC_EXT2_COUNT + TRC_EXT3_COUNT - 1, \
+ TRC_EXT3_VERSION_PATCH, \
+ TRC_EXT3_VERSION_MINOR, \
+ TRC_EXT3_VERSION_MAJOR, \
+ TRC_EXT3_NAME } \
+ ,{ TRC_EXTENSION_EVENTCODE_BASE + TRC_EXT1_COUNT + TRC_EXT2_COUNT + TRC_EXT3_COUNT, \
+ TRC_EXTENSION_EVENTCODE_BASE + TRC_EXT1_COUNT + TRC_EXT2_COUNT + TRC_EXT3_COUNT + TRC_EXT4_COUNT- 1, \
+ TRC_EXT4_VERSION_PATCH, \
+ TRC_EXT4_VERSION_MINOR, \
+ TRC_EXT4_VERSION_MAJOR, \
+ TRC_EXT4_NAME } \
+}
+#endif
+
+#if (TRC_CFG_EXTENSION_COUNT > 0)
+#define TRC_EXTENSION_INFO {TRC_CFG_EXTENSION_COUNT, TRC_EXTENSION_EVENTCODE_BASE, ROUNDUP4(TRC_CFG_EXT_MAX_NAME_LEN), sizeof(PSFExtensionEntryType), TRC_EXTENSIONS_DATA}
+#else
+#define TRC_EXTENSION_INFO {TRC_CFG_EXTENSION_COUNT, TRC_EXTENSION_EVENTCODE_BASE}
+#endif
+
+#endif /* TRCEXTENSIONS_H_ */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcHardwarePort.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcHardwarePort.h
index 6bd981c4c..e452999ee 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcHardwarePort.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcHardwarePort.h
@@ -1,478 +1,558 @@
-/*******************************************************************************
- * Trace Recorder Library for Tracealyzer v4.1.5
- * Percepio AB, www.percepio.com
- *
- * trcHardwarePort.h
- *
- * The hardware abstraction layer for 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_HARDWARE_PORT_H
-#define TRC_HARDWARE_PORT_H
-
-#include "trcPortDefines.h"
-
-
-#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_NOT_SET)
- #error "TRC_CFG_HARDWARE_PORT not selected - see trcConfig.h"
-#endif
-
-/*******************************************************************************
- * TRC_IRQ_PRIORITY_ORDER
- *
- * Macro which should be defined as an integer of 0 or 1.
- *
- * 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.
- *
- * This setting is not critical. It is used only to sort and colorize the
- * interrupts in priority order, in case you record interrupts using
- * the vTraceStoreISRBegin and vTraceStoreISREnd routines.
- *
- ******************************************************************************
- *
- * HWTC Macros
- *
- * These macros provides a hardware isolation layer representing the
- * hardware timer/counter used for the event timestamping.
- *
- * TRC_HWTC_COUNT: How to read the current value of the timer/counter.
- *
- * TRC_HWTC_TYPE: Tells the type of timer/counter used for TRC_HWTC_COUNT:
- *
- * - TRC_FREE_RUNNING_32BIT_INCR:
- * Free-running 32-bit timer/counter, counting upwards from 0.
- *
- * - TRC_FREE_RUNNING_32BIT_DECR
- * Free-running 32-bit timer/counter, counting downwards from 0xFFFFFFFF.
- *
- * - TRC_OS_TIMER_INCR
- * Periodic timer that drives the OS tick interrupt, counting upwards
- * from 0 until (TRC_HWTC_PERIOD-1).
- *
- * - TRC_OS_TIMER_DECR
- * Periodic timer that drives the OS tick interrupt, counting downwards
- * from TRC_HWTC_PERIOD-1 until 0.
- *
- * - TRC_CUSTOM_TIMER_INCR
- * A custom timer or counter independent of the OS tick, counting
- * downwards from TRC_HWTC_PERIOD-1 until 0. (Currently only supported
- * in streaming mode).
- *
- * - TRC_CUSTOM_TIMER_DECR
- * A custom timer independent of the OS tick, counting downwards
- * from TRC_HWTC_PERIOD-1 until 0. (Currently only supported
- * in streaming mode).
- *
- * TRC_HWTC_PERIOD: The number of HWTC_COUNT ticks until the timer wraps
- * around. If using TRC_FREE_RUNNING_32BIT_INCR/DECR, this should be 0.
- *
- * TRC_HWTC_FREQ_HZ: The clock rate of the TRC_HWTC_COUNT counter in Hz. If using
- * TRC_OS_TIMER_INCR/DECR, this is should be TRC_HWTC_PERIOD * TRACE_TICK_RATE_HZ.
- * If using a free-running timer, this is often TRACE_CPU_CLOCK_HZ (if running at
- * the core clock rate). If using TRC_CUSTOM_TIMER_INCR/DECR, this should match
- * the clock rate of your custom timer (i.e., TRC_HWTC_COUNT). If the default value
- * of TRC_HWTC_FREQ_HZ is incorrect for your setup, you can override it by calling
- * vTraceSetFrequency before calling vTraceEnable.
- *
- * TRC_HWTC_DIVISOR (used in snapshot mode only):
- * In snapshot mode, the timestamp resolution is TRC_HWTC_FREQ_HZ/TRC_HWTC_DIVISOR.
- * If the timer frequency is very high (hundreds of MHz), we recommend increasing
- * the TRC_HWTC_DIVISOR prescaler, to reduce the bandwidth needed to store
- * timestamps. This since extra "XTS" events are inserted if the time since the
- * previous event exceeds a certain limit (255 or 65535 depending on event type).
- * It is advised to keep the time between most events below 65535 native ticks
- * (after division by TRC_HWTC_DIVISOR) to avoid frequent XTS events.
- ******************************************************************************/
-
-#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_NOT_SET)
- #error "TRC_CFG_HARDWARE_PORT not selected - see trcConfig.h"
-#endif
-
-#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Win32)
- /* This can be used as a template for any free-running 32-bit counter */
- #define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR
- #define TRC_HWTC_COUNT (ulGetRunTimeCounterValue())
- #define TRC_HWTC_PERIOD 0
- #define TRC_HWTC_DIVISOR 1
- #define TRC_HWTC_FREQ_HZ 100000
-
- #define TRC_IRQ_PRIORITY_ORDER 1
-
- #define TRC_PORT_SPECIFIC_INIT()
-
-#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_HWIndependent)
- /* Timestamping by OS tick only (typically 1 ms resolution) */
- #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
- #define TRC_HWTC_COUNT 0
- #define TRC_HWTC_PERIOD 1
- #define TRC_HWTC_DIVISOR 1
- #define TRC_HWTC_FREQ_HZ TRACE_TICK_RATE_HZ
-
- /* Set the meaning of IRQ priorities in ISR tracing - see above */
- #define TRC_IRQ_PRIORITY_ORDER NOT_SET
-
-#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_Cortex_M)
-
- #ifndef __CORTEX_M
- #error "Can't find the CMSIS API. Please include your processor's header file in trcConfig.h"
- #endif
-
- /**************************************************************************
- * For Cortex-M3, M4 and M7, the DWT cycle counter is used for timestamping.
- * For Cortex-M0 and M0+, the SysTick timer is used since DWT is not
- * available. Systick timestamping can also be forced on Cortex-M3, M4 and
- * M7 by defining the preprocessor directive TRC_CFG_ARM_CM_USE_SYSTICK,
- * either directly below or in trcConfig.h.
- *
- * #define TRC_CFG_ARM_CM_USE_SYSTICK
- **************************************************************************/
-
- #if ((__CORTEX_M >= 0x03) && (! defined TRC_CFG_ARM_CM_USE_SYSTICK))
-
- void prvTraceInitCortexM(void);
-
- #define TRC_REG_DEMCR (*(volatile uint32_t*)0xE000EDFC)
- #define TRC_REG_DWT_CTRL (*(volatile uint32_t*)0xE0001000)
- #define TRC_REG_DWT_CYCCNT (*(volatile uint32_t*)0xE0001004)
- #define TRC_REG_DWT_EXCCNT (*(volatile uint32_t*)0xE000100C)
-
- #define TRC_REG_ITM_LOCKACCESS (*(volatile uint32_t*)0xE0001FB0)
- #define TRC_ITM_LOCKACCESS_UNLOCK (0xC5ACCE55)
-
- /* Bit mask for TRCENA bit in DEMCR - Global enable for DWT and ITM */
- #define TRC_DEMCR_TRCENA (1 << 24)
-
- /* Bit mask for NOPRFCNT bit in DWT_CTRL. If 1, DWT_EXCCNT is not supported */
- #define TRC_DWT_CTRL_NOPRFCNT (1 << 24)
-
- /* Bit mask for NOCYCCNT bit in DWT_CTRL. If 1, DWT_CYCCNT is not supported */
- #define TRC_DWT_CTRL_NOCYCCNT (1 << 25)
-
- /* Bit mask for EXCEVTENA_ bit in DWT_CTRL. Set to 1 to enable DWT_EXCCNT */
- #define TRC_DWT_CTRL_EXCEVTENA (1 << 18)
-
- /* Bit mask for EXCEVTENA_ bit in DWT_CTRL. Set to 1 to enable DWT_CYCCNT */
- #define TRC_DWT_CTRL_CYCCNTENA (1)
-
- #define TRC_PORT_SPECIFIC_INIT() prvTraceInitCortexM()
-
- #define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR
- #define TRC_HWTC_COUNT TRC_REG_DWT_CYCCNT
- #define TRC_HWTC_PERIOD 0
- #define TRC_HWTC_DIVISOR 4
- #define TRC_HWTC_FREQ_HZ TRACE_CPU_CLOCK_HZ
- #define TRC_IRQ_PRIORITY_ORDER 0
-
- #else
-
- #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR
- #define TRC_HWTC_COUNT (*((volatile uint32_t*)0xE000E018))
- #define TRC_HWTC_PERIOD ((*((volatile uint32_t*)0xE000E014)) + 1)
- #define TRC_HWTC_DIVISOR 4
- #define TRC_HWTC_FREQ_HZ TRACE_CPU_CLOCK_HZ
- #define TRC_IRQ_PRIORITY_ORDER 0
-
- #endif
-
-#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Renesas_RX600)
-
- #include "iodefine.h"
-
- #if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
-
- #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
- #define TRC_HWTC_COUNT (CMT0.CMCNT)
-
- #elif (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)
-
- /* Decreasing counters better for Tickless Idle? */
- #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR
- #define TRC_HWTC_COUNT (CMT0.CMCOR - CMT0.CMCNT)
-
- #endif
-
- #define TRC_HWTC_PERIOD (CMT0.CMCOR + 1)
- #define TRC_HWTC_DIVISOR 1
- #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD)
- #define TRC_IRQ_PRIORITY_ORDER 1
-
-#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_MICROCHIP_PIC24_PIC32)
-
- #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
- #define TRC_HWTC_COUNT (TMR1)
- #define TRC_HWTC_PERIOD (PR1 + 1)
- #define TRC_HWTC_DIVISOR 1
- #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD)
- #define TRC_IRQ_PRIORITY_ORDER 0
-
-#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_TEXAS_INSTRUMENTS_TMS570_RM48)
-
- #define TRC_RTIFRC0 *((uint32_t *)0xFFFFFC10)
- #define TRC_RTICOMP0 *((uint32_t *)0xFFFFFC50)
- #define TRC_RTIUDCP0 *((uint32_t *)0xFFFFFC54)
-
- #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
- #define TRC_HWTC_COUNT (TRC_RTIFRC0 - (TRC_RTICOMP0 - TRC_RTIUDCP0))
- #define TRC_HWTC_PERIOD (TRC_RTIUDCP0)
- #define TRC_HWTC_DIVISOR 1
- #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD)
- #define TRC_IRQ_PRIORITY_ORDER 0
-
-#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Atmel_AT91SAM7)
-
- /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
-
- #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
- #define TRC_HWTC_COUNT ((uint32_t)(AT91C_BASE_PITC->PITC_PIIR & 0xFFFFF))
- #define TRC_HWTC_PERIOD ((uint32_t)(AT91C_BASE_PITC->PITC_PIMR + 1))
- #define TRC_HWTC_DIVISOR 1
- #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD)
- #define TRC_IRQ_PRIORITY_ORDER 1
-
-#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Atmel_UC3A0)
-
- /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO*/
-
- /* For Atmel AVR32 (AT32UC3A) */
-
- #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
- #define TRC_HWTC_COUNT ((uint32_t)sysreg_read(AVR32_COUNT))
- #define TRC_HWTC_PERIOD ((uint32_t)(sysreg_read(AVR32_COMPARE) + 1))
- #define TRC_HWTC_DIVISOR 1
- #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD)
- #define TRC_IRQ_PRIORITY_ORDER 1
-
-#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_NXP_LPC210X)
-
- /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
-
- /* Tested with LPC2106, but should work with most LPC21XX chips. */
-
- #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
- #define TRC_HWTC_COUNT *((uint32_t *)0xE0004008 )
- #define TRC_HWTC_PERIOD *((uint32_t *)0xE0004018 )
- #define TRC_HWTC_DIVISOR 1
- #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD)
- #define TRC_IRQ_PRIORITY_ORDER 0
-
-#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_TEXAS_INSTRUMENTS_MSP430)
-
- /* UNOFFICIAL PORT - NOT YET VERIFIED */
-
- #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
- #define TRC_HWTC_COUNT (TA0R)
- #define TRC_HWTC_PERIOD (((uint16_t)TACCR0)+1)
- #define TRC_HWTC_DIVISOR 1
- #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD)
- #define TRC_IRQ_PRIORITY_ORDER 1
-
-#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XILINX_PPC405)
-
- /* UNOFFICIAL PORT - NOT YET VERIFIED */
-
- #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR
- #define TRC_HWTC_COUNT mfspr(0x3db)
- #define TRC_HWTC_PERIOD (TRACE_CPU_CLOCK_HZ / TRACE_TICK_RATE_HZ)
- #define TRC_HWTC_DIVISOR 1
- #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD)
- #define TRC_IRQ_PRIORITY_ORDER 0
-
-#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XILINX_PPC440)
-
- /* UNOFFICIAL PORT */
-
- /* This should work with most PowerPC chips */
-
- #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR
- #define TRC_HWTC_COUNT mfspr(0x016)
- #define TRC_HWTC_PERIOD (TRACE_CPU_CLOCK_HZ / TRACE_TICK_RATE_HZ)
- #define TRC_HWTC_DIVISOR 1
- #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD)
- #define TRC_IRQ_PRIORITY_ORDER 0
-
-#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XILINX_MICROBLAZE)
-
- /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
-
- /* This should work with most Microblaze configurations.
- * It uses the AXI Timer 0 - the tick interrupt source.
- * If an AXI Timer 0 peripheral is available on your hardware platform, no modifications are required.
- */
- #include "xtmrctr_l.h"
-
- #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR
- #define TRC_HWTC_COUNT XTmrCtr_GetTimerCounterReg( XPAR_TMRCTR_0_BASEADDR, 0 )
- #define TRC_HWTC_PERIOD (XTmrCtr_mGetLoadReg( XPAR_TMRCTR_0_BASEADDR, 0) + 1)
- #define TRC_HWTC_DIVISOR 16
- #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD)
- #define TRC_IRQ_PRIORITY_ORDER 0
-
-#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Altera_NiosII)
-
- /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
-
- #include "system.h"
- #include "sys/alt_timestamp.h"
-
- #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
- #define TRC_HWTC_COUNT (uint32_t)alt_timestamp()
- #define TRC_HWTC_PERIOD 0xFFFFFFFF
- #define TRC_HWTC_FREQ_HZ TIMESTAMP_TIMER_FREQ
- #define TRC_HWTC_DIVISOR 1
- #define TRC_IRQ_PRIORITY_ORDER 0
-
-#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_CORTEX_A9)
-
- /* INPUT YOUR PERIPHERAL BASE ADDRESS HERE */
- #define TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS 0xSOMETHING
-
- #define TRC_CA9_MPCORE_PRIVATE_MEMORY_OFFSET 0x0600
- #define TRC_CA9_MPCORE_PRIVCTR_PERIOD_REG (*(volatile uint32_t*)(TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS + TRC_CA9_MPCORE_PRIVATE_MEMORY_OFFSET + 0x00))
- #define TRC_CA9_MPCORE_PRIVCTR_COUNTER_REG (*(volatile uint32_t*)(TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS + TRC_CA9_MPCORE_PRIVATE_MEMORY_OFFSET + 0x04))
- #define TRC_CA9_MPCORE_PRIVCTR_CONTROL_REG (*(volatile uint32_t*)(TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS + TRC_CA9_MPCORE_PRIVATE_MEMORY_OFFSET + 0x08))
-
- #define TRC_CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_MASK 0x0000FF00
- #define TRC_CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_SHIFT 8
- #define TRC_CA9_MPCORE_PRIVCTR_PRESCALER (((TRC_CA9_MPCORE_PRIVCTR_CONTROL_REG & TRC_CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_MASK) >> TRC_CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_SHIFT) + 1)
-
- #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR
- #define TRC_HWTC_COUNT TRC_CA9_MPCORE_PRIVCTR_COUNTER_REG
- #define TRC_HWTC_PERIOD (TRC_CA9_MPCORE_PRIVCTR_PERIOD_REG + 1)
-
- /****************************************************************************************
- NOTE: The private timer ticks with a very high frequency (half the core-clock usually),
- depending on the prescaler used. If a low prescaler is used, the number of HW ticks between
- the trace events gets large, and thereby inefficient to store (sometimes extra events are
- needed). To improve efficiency, you may use the TRC_HWTC_DIVISOR as an additional prescaler.
- *****************************************************************************************/
- #define TRC_HWTC_DIVISOR 1
-
- #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD)
- #define TRC_IRQ_PRIORITY_ORDER 0
-
-#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_POWERPC_Z4)
-
- /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
-
- #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR
- //#define HWTC_COUNT_DIRECTION DIRECTION_DECREMENTING
- #define TRC_HWTC_COUNT PIT.TIMER[configTICK_PIT_CHANNEL].CVAL.R // must be the PIT channel used for the systick
- #define TRC_HWTC_PERIOD ((configPIT_CLOCK_HZ / configTICK_RATE_HZ) - 1U) // TODO FIXME or maybe not -1? what's the right "period" value?
- #define TRC_HWTC_FREQ_HZ configPIT_CLOCK_HZ
- #define TRC_HWTC_DIVISOR 1
- #define TRC_IRQ_PRIORITY_ORDER 1 // higher IRQ priority values are more significant
-
-#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_APPLICATION_DEFINED)
-
- #if !( defined (TRC_HWTC_TYPE) && defined (TRC_HWTC_COUNT) && defined (TRC_HWTC_PERIOD) && defined (TRC_HWTC_FREQ_HZ) && defined (TRC_IRQ_PRIORITY_ORDER) )
- #error "The hardware port is not completely defined!"
- #endif
-
-#elif (TRC_CFG_HARDWARE_PORT != TRC_HARDWARE_PORT_NOT_SET)
-
- #error "TRC_CFG_HARDWARE_PORT had unsupported value!"
- #define TRC_CFG_HARDWARE_PORT TRC_HARDWARE_PORT_NOT_SET
-
-#endif
-
-#ifndef TRC_HWTC_DIVISOR
- #define TRC_HWTC_DIVISOR 1
-#endif
-
-#ifndef TRC_PORT_SPECIFIC_INIT
- #define TRC_PORT_SPECIFIC_INIT()
-#endif
-
-/* If Win32 port */
-#ifdef WIN32
-
- #undef _WIN32_WINNT
- #define _WIN32_WINNT 0x0600
-
- /* Standard includes. */
- #include <stdio.h>
- #include <windows.h>
- #include <direct.h>
-
- /***************************************************************************
- * The Win32 port by default saves the trace to file and then kills the
- * program when the recorder is stopped, to facilitate quick, simple tests
- * of the recorder.
- ***************************************************************************/
- #define WIN32_PORT_SAVE_WHEN_STOPPED 1
- #define WIN32_PORT_EXIT_WHEN_STOPPED 1
-
-#endif
-
-#if (TRC_CFG_HARDWARE_PORT != TRC_HARDWARE_PORT_NOT_SET)
-
- #ifndef TRC_HWTC_TYPE
- #error "TRC_HWTC_TYPE is not set!"
- #endif
-
- #ifndef TRC_HWTC_COUNT
- #error "TRC_HWTC_COUNT is not set!"
- #endif
-
- #ifndef TRC_HWTC_PERIOD
- #error "TRC_HWTC_PERIOD is not set!"
- #endif
-
- #ifndef TRC_HWTC_DIVISOR
- #error "TRC_HWTC_DIVISOR is not set!"
- #endif
-
- #ifndef TRC_IRQ_PRIORITY_ORDER
- #error "TRC_IRQ_PRIORITY_ORDER is not set!"
- #elif (TRC_IRQ_PRIORITY_ORDER != 0) && (TRC_IRQ_PRIORITY_ORDER != 1)
- #error "TRC_IRQ_PRIORITY_ORDER has bad value!"
- #endif
-
- #if (TRC_HWTC_DIVISOR < 1)
- #error "TRC_HWTC_DIVISOR must be a non-zero positive value!"
- #endif
-
- #ifndef TRC_HWTC_FREQ_HZ
- #error "TRC_HWTC_FREQ_HZ not defined!"
- #endif
-
-#endif
-
-#endif /*TRC_SNAPSHOT_HARDWARE_PORT_H*/
+/*******************************************************************************
+ * Trace Recorder Library for Tracealyzer v4.3.11
+ * Percepio AB, www.percepio.com
+ *
+ * trcHardwarePort.h
+ *
+ * The hardware abstraction layer for 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_HARDWARE_PORT_H
+#define TRC_HARDWARE_PORT_H
+
+#include "trcPortDefines.h"
+
+
+#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_NOT_SET)
+ #error "TRC_CFG_HARDWARE_PORT not selected - see trcConfig.h"
+#endif
+
+/*******************************************************************************
+ * TRC_IRQ_PRIORITY_ORDER
+ *
+ * Macro which should be defined as an integer of 0 or 1.
+ *
+ * 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.
+ *
+ * This setting is not critical. It is used only to sort and colorize the
+ * interrupts in priority order, in case you record interrupts using
+ * the vTraceStoreISRBegin and vTraceStoreISREnd routines.
+ *
+ ******************************************************************************
+ *
+ * HWTC Macros
+ *
+ * These macros provides a hardware isolation layer representing the
+ * hardware timer/counter used for the event timestamping.
+ *
+ * TRC_HWTC_COUNT: How to read the current value of the timer/counter.
+ *
+ * TRC_HWTC_TYPE: Tells the type of timer/counter used for TRC_HWTC_COUNT:
+ *
+ * - TRC_FREE_RUNNING_32BIT_INCR:
+ * Free-running 32-bit timer/counter, counting upwards from 0.
+ *
+ * - TRC_FREE_RUNNING_32BIT_DECR
+ * Free-running 32-bit timer/counter, counting downwards from 0xFFFFFFFF.
+ *
+ * - TRC_OS_TIMER_INCR
+ * Periodic timer that drives the OS tick interrupt, counting upwards
+ * from 0 until (TRC_HWTC_PERIOD-1).
+ *
+ * - TRC_OS_TIMER_DECR
+ * Periodic timer that drives the OS tick interrupt, counting downwards
+ * from TRC_HWTC_PERIOD-1 until 0.
+ *
+ * - TRC_CUSTOM_TIMER_INCR
+ * A custom timer or counter independent of the OS tick, counting
+ * downwards from TRC_HWTC_PERIOD-1 until 0. (Currently only supported
+ * in streaming mode).
+ *
+ * - TRC_CUSTOM_TIMER_DECR
+ * A custom timer independent of the OS tick, counting downwards
+ * from TRC_HWTC_PERIOD-1 until 0. (Currently only supported
+ * in streaming mode).
+ *
+ * TRC_HWTC_PERIOD: The number of HWTC_COUNT ticks until the timer wraps
+ * around. If using TRC_FREE_RUNNING_32BIT_INCR/DECR, this should be 0.
+ *
+ * TRC_HWTC_FREQ_HZ: The clock rate of the TRC_HWTC_COUNT counter in Hz. If using
+ * TRC_OS_TIMER_INCR/DECR, this is should be TRC_HWTC_PERIOD * TRACE_TICK_RATE_HZ.
+ * If using a free-running timer, this is often TRACE_CPU_CLOCK_HZ (if running at
+ * the core clock rate). If using TRC_CUSTOM_TIMER_INCR/DECR, this should match
+ * the clock rate of your custom timer (i.e., TRC_HWTC_COUNT). If the default value
+ * of TRC_HWTC_FREQ_HZ is incorrect for your setup, you can override it by calling
+ * vTraceSetFrequency before calling vTraceEnable.
+ *
+ * TRC_HWTC_DIVISOR (used in snapshot mode only):
+ * In snapshot mode, the timestamp resolution is TRC_HWTC_FREQ_HZ/TRC_HWTC_DIVISOR.
+ * If the timer frequency is very high (hundreds of MHz), we recommend increasing
+ * the TRC_HWTC_DIVISOR prescaler, to reduce the bandwidth needed to store
+ * timestamps. This since extra "XTS" events are inserted if the time since the
+ * previous event exceeds a certain limit (255 or 65535 depending on event type).
+ * It is advised to keep the time between most events below 65535 native ticks
+ * (after division by TRC_HWTC_DIVISOR) to avoid frequent XTS events.
+ ******************************************************************************/
+
+#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_NOT_SET)
+ #error "TRC_CFG_HARDWARE_PORT not selected - see trcConfig.h"
+#endif
+
+#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Win32)
+ /* This can be used as a template for any free-running 32-bit counter */
+ #define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR
+ #define TRC_HWTC_COUNT (ulGetRunTimeCounterValue())
+ #define TRC_HWTC_PERIOD 0
+ #define TRC_HWTC_DIVISOR 1
+ #define TRC_HWTC_FREQ_HZ 100000
+
+ #define TRC_IRQ_PRIORITY_ORDER 1
+
+ #define TRC_PORT_SPECIFIC_INIT()
+
+#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_HWIndependent)
+ /* Timestamping by OS tick only (typically 1 ms resolution) */
+ #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
+ #define TRC_HWTC_COUNT 0
+ #define TRC_HWTC_PERIOD 1
+ #define TRC_HWTC_DIVISOR 1
+ #define TRC_HWTC_FREQ_HZ TRACE_TICK_RATE_HZ
+
+ /* Set the meaning of IRQ priorities in ISR tracing - see above */
+ #define TRC_IRQ_PRIORITY_ORDER NOT_SET
+
+#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_Cortex_M)
+
+ #ifndef __CORTEX_M
+ #error "Can't find the CMSIS API. Please include your processor's header file in trcConfig.h"
+ #endif
+
+ /**************************************************************************
+ * For Cortex-M3, M4 and M7, the DWT cycle counter is used for timestamping.
+ * For Cortex-M0 and M0+, the SysTick timer is used since DWT is not
+ * available. Systick timestamping can also be forced on Cortex-M3, M4 and
+ * M7 by defining the preprocessor directive TRC_CFG_ARM_CM_USE_SYSTICK,
+ * either directly below or in trcConfig.h.
+ *
+ * #define TRC_CFG_ARM_CM_USE_SYSTICK
+ **************************************************************************/
+
+ #if ((__CORTEX_M >= 0x03) && (! defined TRC_CFG_ARM_CM_USE_SYSTICK))
+
+ void prvTraceInitCortexM(void);
+
+ #define TRC_REG_DEMCR (*(volatile uint32_t*)0xE000EDFC)
+ #define TRC_REG_DWT_CTRL (*(volatile uint32_t*)0xE0001000)
+ #define TRC_REG_DWT_CYCCNT (*(volatile uint32_t*)0xE0001004)
+ #define TRC_REG_DWT_EXCCNT (*(volatile uint32_t*)0xE000100C)
+
+ #define TRC_REG_ITM_LOCKACCESS (*(volatile uint32_t*)0xE0001FB0)
+ #define TRC_ITM_LOCKACCESS_UNLOCK (0xC5ACCE55)
+
+ /* Bit mask for TRCENA bit in DEMCR - Global enable for DWT and ITM */
+ #define TRC_DEMCR_TRCENA (1 << 24)
+
+ /* Bit mask for NOPRFCNT bit in DWT_CTRL. If 1, DWT_EXCCNT is not supported */
+ #define TRC_DWT_CTRL_NOPRFCNT (1 << 24)
+
+ /* Bit mask for NOCYCCNT bit in DWT_CTRL. If 1, DWT_CYCCNT is not supported */
+ #define TRC_DWT_CTRL_NOCYCCNT (1 << 25)
+
+ /* Bit mask for EXCEVTENA_ bit in DWT_CTRL. Set to 1 to enable DWT_EXCCNT */
+ #define TRC_DWT_CTRL_EXCEVTENA (1 << 18)
+
+ /* Bit mask for EXCEVTENA_ bit in DWT_CTRL. Set to 1 to enable DWT_CYCCNT */
+ #define TRC_DWT_CTRL_CYCCNTENA (1)
+
+ #define TRC_PORT_SPECIFIC_INIT() prvTraceInitCortexM()
+
+ #define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR
+ #define TRC_HWTC_COUNT TRC_REG_DWT_CYCCNT
+ #define TRC_HWTC_PERIOD 0
+ #define TRC_HWTC_DIVISOR 4
+ #define TRC_HWTC_FREQ_HZ TRACE_CPU_CLOCK_HZ
+ #define TRC_IRQ_PRIORITY_ORDER 0
+
+ #else
+
+ #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR
+ #define TRC_HWTC_COUNT (*((volatile uint32_t*)0xE000E018))
+ #define TRC_HWTC_PERIOD ((*((volatile uint32_t*)0xE000E014)) + 1)
+ #define TRC_HWTC_DIVISOR 4
+ #define TRC_HWTC_FREQ_HZ TRACE_CPU_CLOCK_HZ
+ #define TRC_IRQ_PRIORITY_ORDER 0
+
+ #endif
+
+#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Renesas_RX600)
+
+ #include "iodefine.h"
+
+ #if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
+
+ #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
+ #define TRC_HWTC_COUNT (CMT0.CMCNT)
+
+ #elif (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)
+
+ /* Decreasing counters better for Tickless Idle? */
+ #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR
+ #define TRC_HWTC_COUNT (CMT0.CMCOR - CMT0.CMCNT)
+
+ #endif
+
+ #define TRC_HWTC_PERIOD (CMT0.CMCOR + 1)
+ #define TRC_HWTC_DIVISOR 1
+ #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD)
+ #define TRC_IRQ_PRIORITY_ORDER 1
+
+#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_MICROCHIP_PIC24_PIC32)
+
+ #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
+ #define TRC_HWTC_COUNT (TMR1)
+ #define TRC_HWTC_PERIOD (PR1 + 1)
+ #define TRC_HWTC_DIVISOR 1
+ #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD)
+ #define TRC_IRQ_PRIORITY_ORDER 1
+
+#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_TEXAS_INSTRUMENTS_TMS570_RM48)
+
+ #define TRC_RTIFRC0 *((uint32_t *)0xFFFFFC10)
+ #define TRC_RTICOMP0 *((uint32_t *)0xFFFFFC50)
+ #define TRC_RTIUDCP0 *((uint32_t *)0xFFFFFC54)
+
+ #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
+ #define TRC_HWTC_COUNT (TRC_RTIFRC0 - (TRC_RTICOMP0 - TRC_RTIUDCP0))
+ #define TRC_HWTC_PERIOD (TRC_RTIUDCP0)
+ #define TRC_HWTC_DIVISOR 1
+ #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD)
+ #define TRC_IRQ_PRIORITY_ORDER 0
+
+#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Atmel_AT91SAM7)
+
+ /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
+
+ #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
+ #define TRC_HWTC_COUNT ((uint32_t)(AT91C_BASE_PITC->PITC_PIIR & 0xFFFFF))
+ #define TRC_HWTC_PERIOD ((uint32_t)(AT91C_BASE_PITC->PITC_PIMR + 1))
+ #define TRC_HWTC_DIVISOR 1
+ #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD)
+ #define TRC_IRQ_PRIORITY_ORDER 1
+
+#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Atmel_UC3A0)
+
+ /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO*/
+
+ /* For Atmel AVR32 (AT32UC3A) */
+
+ #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
+ #define TRC_HWTC_COUNT ((uint32_t)sysreg_read(AVR32_COUNT))
+ #define TRC_HWTC_PERIOD ((uint32_t)(sysreg_read(AVR32_COMPARE) + 1))
+ #define TRC_HWTC_DIVISOR 1
+ #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD)
+ #define TRC_IRQ_PRIORITY_ORDER 1
+
+#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_NXP_LPC210X)
+
+ /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
+
+ /* Tested with LPC2106, but should work with most LPC21XX chips. */
+
+ #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
+ #define TRC_HWTC_COUNT *((uint32_t *)0xE0004008 )
+ #define TRC_HWTC_PERIOD *((uint32_t *)0xE0004018 )
+ #define TRC_HWTC_DIVISOR 1
+ #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD)
+ #define TRC_IRQ_PRIORITY_ORDER 0
+
+#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_TEXAS_INSTRUMENTS_MSP430)
+
+ /* UNOFFICIAL PORT - NOT YET VERIFIED */
+
+ #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
+ #define TRC_HWTC_COUNT (TA0R)
+ #define TRC_HWTC_PERIOD (((uint16_t)TACCR0)+1)
+ #define TRC_HWTC_DIVISOR 1
+ #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD)
+ #define TRC_IRQ_PRIORITY_ORDER 1
+
+#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XILINX_PPC405)
+
+ /* UNOFFICIAL PORT - NOT YET VERIFIED */
+
+ #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR
+ #define TRC_HWTC_COUNT mfspr(0x3db)
+ #define TRC_HWTC_PERIOD (TRACE_CPU_CLOCK_HZ / TRACE_TICK_RATE_HZ)
+ #define TRC_HWTC_DIVISOR 1
+ #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD)
+ #define TRC_IRQ_PRIORITY_ORDER 0
+
+#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XILINX_PPC440)
+
+ /* UNOFFICIAL PORT */
+
+ /* This should work with most PowerPC chips */
+
+ #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR
+ #define TRC_HWTC_COUNT mfspr(0x016)
+ #define TRC_HWTC_PERIOD (TRACE_CPU_CLOCK_HZ / TRACE_TICK_RATE_HZ)
+ #define TRC_HWTC_DIVISOR 1
+ #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD)
+ #define TRC_IRQ_PRIORITY_ORDER 0
+
+#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XILINX_MICROBLAZE)
+
+ /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
+
+ /* This should work with most Microblaze configurations.
+ * It uses the AXI Timer 0 - the tick interrupt source.
+ * If an AXI Timer 0 peripheral is available on your hardware platform, no modifications are required.
+ */
+ #include "xtmrctr_l.h"
+
+ #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR
+ #define TRC_HWTC_COUNT XTmrCtr_GetTimerCounterReg( XPAR_TMRCTR_0_BASEADDR, 0 )
+ #define TRC_HWTC_PERIOD (XTmrCtr_mGetLoadReg( XPAR_TMRCTR_0_BASEADDR, 0) + 1)
+ #define TRC_HWTC_DIVISOR 16
+ #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD)
+ #define TRC_IRQ_PRIORITY_ORDER 0
+
+#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XILINX_ZyncUltraScaleR5)
+
+ #include "xttcps_hw.h"
+
+ #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
+ #define TRC_HWTC_COUNT (*(volatile uint32_t *)(configTIMER_BASEADDR + XTTCPS_COUNT_VALUE_OFFSET))
+ #define TRC_HWTC_PERIOD (*(volatile uint32_t *)(configTIMER_BASEADDR + XTTCPS_INTERVAL_VAL_OFFSET))
+ #define TRC_HWTC_DIVISOR 16
+ #define TRC_HWTC_FREQ_HZ (TRC_HWTC_PERIOD * TRACE_TICK_RATE_HZ)
+ #define TRC_IRQ_PRIORITY_ORDER 0
+
+ #ifdef __GNUC__
+ /* For Arm Cortex-A and Cortex-R in general. */
+ static inline uint32_t prvGetCPSR(void)
+ {
+ unsigned long ret;
+ /* GCC-style assembly for getting the CPSR/APSR register, where the system execution mode is found. */
+ asm volatile (" mrs %0, cpsr" : "=r" (ret) : /* no inputs */ );
+ return ret;
+ }
+ #else
+ #error "Only GCC Supported!"
+ #endif
+
+#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Altera_NiosII)
+
+ /* OFFICIAL PORT */
+
+ #include <system.h>
+ #include <altera_avalon_timer_regs.h>
+
+ #define NOT_SET 1
+
+ /* The base address for the sustem timer set.
+ * The name user for the system timer can be found in the BSP editor.
+ * If the name of the timer is sys_tmr SYSTEM_TIMER_BASE should be set to SYS_TMR_BASE.
+ */
+ #define SYSTEM_TIMER_BASE NOT_SET
+
+ #if (SYSTEM_TIMER == NOT_SET)
+ #error "Set SYSTEM_TIMER_BASE to the timer base used for system ticks."
+ #endif
+
+ static inline uint32_t altera_nios2_GetTimerSnapReg(void)
+ {
+ /* A processor can read the current counter value by first writing to either snapl or snaph to request a coherent snapshot of the counter,
+ * and then reading snapl and snaph for the full 32-bit value.
+ */
+ IOWR_ALTERA_AVALON_TIMER_SNAPL(SYSTEM_TIMER_BASE, 0);
+ return (IORD_ALTERA_AVALON_TIMER_SNAPH(SYSTEM_TIMER_BASE) << 16) | IORD_ALTERA_AVALON_TIMER_SNAPL(SYSTEM_TIMER_BASE);
+ }
+
+ #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR
+ #define TRC_HWTC_COUNT altera_nios2_GetTimerSnapReg()
+ #define TRC_HWTC_PERIOD (configCPU_CLOCK_HZ / configTICK_RATE_HZ )
+ #define TRC_HWTC_DIVISOR 16
+ #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD)
+ #define TRC_IRQ_PRIORITY_ORDER 0
+
+#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_CORTEX_A9)
+
+ /**************************************************************************
+ * This hardware port only supports FreeRTOS and the GCC compiler at the
+ * moment, due to the implementation of critical sections (trcKernelPort.h).
+ *
+ * Assuming FreeRTOS is used:
+ *
+ * For critical sections, this uses vTaskEnterCritical is when called from
+ * task context and ulPortSetInterruptMask when called from ISR context.
+ * Thus, it does not disable all ISRs. This means that the trace recorder
+ * can only be called from ISRs with priority less or equal to
+ * configMAX_API_CALL_INTERRUPT_PRIORITY (like FreeRTOS fromISR functions).
+ *
+ * This hardware port has been tested on it a Xilinx Zync 7000 (Cortex-A9),
+ * but should work with all Cortex-A and R processors assuming that
+ * TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS is set accordingly.
+ **************************************************************************/
+
+ /* INPUT YOUR PERIPHERAL BASE ADDRESS HERE (0xF8F00000 for Xilinx Zynq 7000)*/
+ #define TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS 0
+
+ #if (TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS == 0)
+ #error "Please specify TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS."
+ #endif
+
+ #define TRC_CA9_MPCORE_PRIVATE_MEMORY_OFFSET 0x0600
+ #define TRC_CA9_MPCORE_PRIVCTR_PERIOD_REG (*(volatile uint32_t*)(TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS + TRC_CA9_MPCORE_PRIVATE_MEMORY_OFFSET + 0x00))
+ #define TRC_CA9_MPCORE_PRIVCTR_COUNTER_REG (*(volatile uint32_t*)(TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS + TRC_CA9_MPCORE_PRIVATE_MEMORY_OFFSET + 0x04))
+ #define TRC_CA9_MPCORE_PRIVCTR_CONTROL_REG (*(volatile uint32_t*)(TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS + TRC_CA9_MPCORE_PRIVATE_MEMORY_OFFSET + 0x08))
+
+ #define TRC_CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_MASK 0x0000FF00
+ #define TRC_CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_SHIFT 8
+ #define TRC_CA9_MPCORE_PRIVCTR_PRESCALER (((TRC_CA9_MPCORE_PRIVCTR_CONTROL_REG & TRC_CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_MASK) >> TRC_CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_SHIFT) + 1)
+
+ #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR
+ #define TRC_HWTC_COUNT TRC_CA9_MPCORE_PRIVCTR_COUNTER_REG
+ #define TRC_HWTC_PERIOD (TRC_CA9_MPCORE_PRIVCTR_PERIOD_REG + 1)
+
+ /****************************************************************************************
+ NOTE: The private timer ticks with a very high frequency (half the core-clock usually),
+ depending on the prescaler used. If a low prescaler is used, the number of HW ticks between
+ the trace events gets large, and thereby inefficient to store (sometimes extra events are
+ needed). To improve efficiency, you may use the TRC_HWTC_DIVISOR as an additional prescaler.
+ *****************************************************************************************/
+ #define TRC_HWTC_DIVISOR 1
+
+ #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD)
+ #define TRC_IRQ_PRIORITY_ORDER 0
+
+ #ifdef __GNUC__
+ /* For Arm Cortex-A and Cortex-R in general. */
+ static inline uint32_t prvGetCPSR(void)
+ {
+ unsigned long ret;
+ /* GCC-style assembly for getting the CPSR/APSR register, where the system execution mode is found. */
+ asm volatile (" mrs %0, cpsr" : "=r" (ret) : /* no inputs */ );
+ return ret;
+ }
+ #else
+ #error "Only GCC Supported!"
+ #endif
+
+
+#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_POWERPC_Z4)
+
+ /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
+
+ #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR
+ //#define HWTC_COUNT_DIRECTION DIRECTION_DECREMENTING
+ #define TRC_HWTC_COUNT PIT.TIMER[configTICK_PIT_CHANNEL].CVAL.R // must be the PIT channel used for the systick
+ #define TRC_HWTC_PERIOD ((configPIT_CLOCK_HZ / configTICK_RATE_HZ) - 1U) // TODO FIXME or maybe not -1? what's the right "period" value?
+ #define TRC_HWTC_FREQ_HZ configPIT_CLOCK_HZ
+ #define TRC_HWTC_DIVISOR 1
+ #define TRC_IRQ_PRIORITY_ORDER 1 // higher IRQ priority values are more significant
+
+#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_APPLICATION_DEFINED)
+
+ #if !( defined (TRC_HWTC_TYPE) && defined (TRC_HWTC_COUNT) && defined (TRC_HWTC_PERIOD) && defined (TRC_HWTC_FREQ_HZ) && defined (TRC_IRQ_PRIORITY_ORDER) )
+ #error "The hardware port is not completely defined!"
+ #endif
+
+#elif (TRC_CFG_HARDWARE_PORT != TRC_HARDWARE_PORT_NOT_SET)
+
+ #error "TRC_CFG_HARDWARE_PORT had unsupported value!"
+ #define TRC_CFG_HARDWARE_PORT TRC_HARDWARE_PORT_NOT_SET
+
+#endif
+
+#ifndef TRC_HWTC_DIVISOR
+ #define TRC_HWTC_DIVISOR 1
+#endif
+
+#ifndef TRC_PORT_SPECIFIC_INIT
+ #define TRC_PORT_SPECIFIC_INIT()
+#endif
+
+/* If Win32 port */
+#ifdef WIN32
+
+ #undef _WIN32_WINNT
+ #define _WIN32_WINNT 0x0600
+
+ /* Standard includes. */
+ #include <stdio.h>
+ #include <windows.h>
+ #include <direct.h>
+
+ /***************************************************************************
+ * The Win32 port by default saves the trace to file and then kills the
+ * program when the recorder is stopped, to facilitate quick, simple tests
+ * of the recorder.
+ ***************************************************************************/
+ #define WIN32_PORT_SAVE_WHEN_STOPPED 1
+ #define WIN32_PORT_EXIT_WHEN_STOPPED 1
+
+#endif
+
+#if (TRC_CFG_HARDWARE_PORT != TRC_HARDWARE_PORT_NOT_SET)
+
+ #ifndef TRC_HWTC_TYPE
+ #error "TRC_HWTC_TYPE is not set!"
+ #endif
+
+ #ifndef TRC_HWTC_COUNT
+ #error "TRC_HWTC_COUNT is not set!"
+ #endif
+
+ #ifndef TRC_HWTC_PERIOD
+ #error "TRC_HWTC_PERIOD is not set!"
+ #endif
+
+ #ifndef TRC_HWTC_DIVISOR
+ #error "TRC_HWTC_DIVISOR is not set!"
+ #endif
+
+ #ifndef TRC_IRQ_PRIORITY_ORDER
+ #error "TRC_IRQ_PRIORITY_ORDER is not set!"
+ #elif (TRC_IRQ_PRIORITY_ORDER != 0) && (TRC_IRQ_PRIORITY_ORDER != 1)
+ #error "TRC_IRQ_PRIORITY_ORDER has bad value!"
+ #endif
+
+ #if (TRC_HWTC_DIVISOR < 1)
+ #error "TRC_HWTC_DIVISOR must be a non-zero positive value!"
+ #endif
+
+ #ifndef TRC_HWTC_FREQ_HZ
+ #error "TRC_HWTC_FREQ_HZ not defined!"
+ #endif
+
+#endif
+
+#endif /*TRC_SNAPSHOT_HARDWARE_PORT_H*/
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcKernelPort.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcKernelPort.h
index 965dabad9..d877e81c6 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcKernelPort.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcKernelPort.h
@@ -1,2565 +1,2791 @@
-/*******************************************************************************
- * Trace Recorder Library for Tracealyzer v4.1.5
- * Percepio AB, www.percepio.com
- *
- * 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.
- *
- * FreeRTOS-specific definitions needed by the trace recorder
- *
- * <LICENSE INFO>
- *
- * Tabs are used for indent in this file (1 tab = 4 spaces)
- *
- * Copyright Percepio AB, 2018.
- * www.percepio.com
- ******************************************************************************/
-
-#ifndef TRC_KERNEL_PORT_H
-#define TRC_KERNEL_PORT_H
-
-#include "FreeRTOS.h" /* Defines configUSE_TRACE_FACILITY */
-#include "trcPortDefines.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define TRC_USE_TRACEALYZER_RECORDER configUSE_TRACE_FACILITY
-
-/*** FreeRTOS version codes **************************************************/
-#define FREERTOS_VERSION_NOT_SET 0
-#define TRC_FREERTOS_VERSION_7_3 1 /* v7.3 is earliest supported.*/
-#define TRC_FREERTOS_VERSION_7_4 2
-#define TRC_FREERTOS_VERSION_7_5_OR_7_6 3
-#define TRC_FREERTOS_VERSION_8_X 4 /* Any v8.x.x*/
-#define TRC_FREERTOS_VERSION_9_0_0 5
-#define TRC_FREERTOS_VERSION_9_0_1 6
-#define TRC_FREERTOS_VERSION_9_0_2 7
-#define TRC_FREERTOS_VERSION_10_0_0 8 /* If using FreeRTOS v10.0.0 or later version */
-
-#define TRC_FREERTOS_VERSION_9_X 42 /* Not allowed anymore */
-
-#if (TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_X)
-/* This setting for TRC_CFG_FREERTOS_VERSION is no longer allowed as v9.0.1 needs special handling. */
-#error "Please specify your exact FreeRTOS version in trcConfig.h, from the options listed above."
-#endif
-
-#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
-#define prvGetStreamBufferType(x) ((( StreamBuffer_t * )x )->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER)
-#else
-#define prvGetStreamBufferType(x) 0
-#endif
-
-/* Added mainly for our internal testing. This makes it easier to create test applications that
- runs on multiple FreeRTOS versions. */
-#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_8_X)
- /* FreeRTOS v7.0 and later */
- #define STRING_CAST(x) ( (signed char*) x )
- #define TickType portTickType
-#else
- /* FreeRTOS v8.0 and later */
- #define STRING_CAST(x) x
- #define TickType TickType_t
-#endif
-
-#if (defined(TRC_USE_TRACEALYZER_RECORDER)) && (TRC_USE_TRACEALYZER_RECORDER == 1)
-
-/*******************************************************************************
- * INCLUDE_xTaskGetCurrentTaskHandle must be set to 1 for tracing to work properly
- ******************************************************************************/
-#undef INCLUDE_xTaskGetCurrentTaskHandle
-#define INCLUDE_xTaskGetCurrentTaskHandle 1
-
-#if (TRC_CFG_SCHEDULING_ONLY == 0)
-/*******************************************************************************
- * vTraceSetQueueName(void* object, const char* name)
- *
- * Parameter object: pointer to the Queue that shall be named
- * Parameter name: the name to set (const string literal)
- *
- * Sets a name for Queue objects for display in Tracealyzer.
- ******************************************************************************/
-void vTraceSetQueueName(void* object, const char* name);
-
-/*******************************************************************************
- * vTraceSetSemaphoreName(void* object, const char* name)
- *
- * Parameter object: pointer to the Semaphore that shall be named
- * Parameter name: the name to set (const string literal)
- *
- * Sets a name for Semaphore objects for display in Tracealyzer.
- ******************************************************************************/
-void vTraceSetSemaphoreName(void* object, const char* name);
-
-/*******************************************************************************
- * vTraceSetMutexName(void* object, const char* name)
- *
- * Parameter object: pointer to the Mutex that shall be named
- * Parameter name: the name to set (const string literal)
- *
- * Sets a name for Semaphore objects for display in Tracealyzer.
- ******************************************************************************/
-void vTraceSetMutexName(void* object, const char* name);
-
-#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1)
-/*******************************************************************************
-* vTraceSetEventGroupName(void* object, const char* name)
-*
-* Parameter object: pointer to the EventGroup that shall be named
-* Parameter name: the name to set (const string literal)
-*
-* Sets a name for EventGroup objects for display in Tracealyzer.
-******************************************************************************/
-void vTraceSetEventGroupName(void* object, const char* name);
-#else /* (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1) */
-#define vTraceSetEventGroupName(object, name) /* Do nothing */
-#endif /* (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1) */
-
-#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1)
-/*******************************************************************************
-* vTraceSetStreamBufferName(void* object, const char* name)
-*
-* Parameter object: pointer to the StreamBuffer that shall be named
-* Parameter name: the name to set (const string literal)
-*
-* Sets a name for StreamBuffer objects for display in Tracealyzer.
-******************************************************************************/
-void vTraceSetStreamBufferName(void* object, const char* name);
-#else /* (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1) */
-#define vTraceSetStreamBufferName(object, name) /* Do nothing */
-#endif /* (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1) */
-
-#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1)
-/*******************************************************************************
- * vTraceSetMessageBufferName(void* object, const char* name)
- *
- * Parameter object: pointer to the MessageBuffer that shall be named
- * Parameter name: the name to set (const string literal)
- *
- * Sets a name for MessageBuffer objects for display in Tracealyzer.
- ******************************************************************************/
-void vTraceSetMessageBufferName(void* object, const char* name);
-#else /* (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1) */
-#define vTraceSetMessageBufferName(object, name) /* Do nothing */
-#endif /* (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1) */
-
-#else /* (TRC_CFG_SCHEDULING_ONLY == 0) */
-
-#define vTraceSetQueueName(object, name) /* Do nothing */
-#define vTraceSetSemaphoreName(object, name) /* Do nothing */
-#define vTraceSetMutexName(object, name) /* Do nothing */
-#define vTraceSetEventGroupName(object, name) /* Do nothing */
-#define vTraceSetStreamBufferName(object, name) /* Do nothing */
-#define vTraceSetMessageBufferName(object, name) /* Do nothing */
-
-#endif /* (TRC_CFG_SCHEDULING_ONLY == 0) */
-
-/*******************************************************************************
- * Note: Setting names for event groups is difficult to support, this has been
- * excluded intentionally. This since we don't know if event_groups.c is
- * included in the build, so referencing it from the recorder may cause errors.
- ******************************************************************************/
-
-/* Gives the currently executing task (wrapper for RTOS-specific function) */
-void* prvTraceGetCurrentTaskHandle(void);
-
-#if (((TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT) && (TRC_CFG_INCLUDE_ISR_TRACING == 1)) || (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING))
-/* Tells if the scheduler currently is suspended (task-switches can't occur) */
-unsigned char prvTraceIsSchedulerSuspended(void);
-
-/*******************************************************************************
- * INCLUDE_xTaskGetSchedulerState must be set to 1 for tracing to work properly
- ******************************************************************************/
-#undef INCLUDE_xTaskGetSchedulerState
-#define INCLUDE_xTaskGetSchedulerState 1
-
-#endif /* (((TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT) && (TRC_CFG_INCLUDE_ISR_TRACING == 1)) || (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)) */
-
-#define TRACE_KERNEL_VERSION 0x1AA1
-#define TRACE_TICK_RATE_HZ configTICK_RATE_HZ /* Defined in "FreeRTOS.h" */
-#define TRACE_CPU_CLOCK_HZ configCPU_CLOCK_HZ /* Defined in "FreeRTOSConfig.h" */
-#define TRACE_GET_CURRENT_TASK() prvTraceGetCurrentTaskHandle()
-
-#define TRACE_GET_OS_TICKS() (uiTraceTickCount) /* Streaming only */
-
-/* If using dynamic allocation of snapshot trace buffer... */
-#define TRACE_MALLOC(size) pvPortMalloc(size)
-
-#if defined(configUSE_TIMERS)
-#if (configUSE_TIMERS == 1)
-#undef INCLUDE_xTimerGetTimerDaemonTaskHandle
-#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1
-#endif /* configUSE_TIMERS == 1*/
-#endif /* configUSE_TIMERS */
-
-/* For ARM Cortex-M devices - assumes the ARM CMSIS API is available */
-#if (defined (__CORTEX_M))
- #define TRACE_ALLOC_CRITICAL_SECTION() uint32_t __irq_status;
- #define TRACE_ENTER_CRITICAL_SECTION() {__irq_status = __get_PRIMASK(); __set_PRIMASK(1);} /* PRIMASK disables ALL interrupts - allows for tracing in any ISR */
- #define TRACE_EXIT_CRITICAL_SECTION() {__set_PRIMASK(__irq_status);}
-#endif
-
-#if ((TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_CORTEX_A9) || (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Renesas_RX600) || (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_MICROCHIP_PIC24_PIC32) || (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Altera_NiosII))
- #define TRACE_ALLOC_CRITICAL_SECTION() int __irq_status;
- #define TRACE_ENTER_CRITICAL_SECTION() {__irq_status = portSET_INTERRUPT_MASK_FROM_ISR();}
- #define TRACE_EXIT_CRITICAL_SECTION() {portCLEAR_INTERRUPT_MASK_FROM_ISR(__irq_status);}
-#endif
-
-#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Win32)
- /* In the Win32 port, there are no real interrupts, so we can use the normal critical sections */
- #define TRACE_ALLOC_CRITICAL_SECTION()
- #define TRACE_ENTER_CRITICAL_SECTION() portENTER_CRITICAL()
- #define TRACE_EXIT_CRITICAL_SECTION() portEXIT_CRITICAL()
-#endif
-
-#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_POWERPC_Z4)
-#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X)
- /* FreeRTOS v8.0 or later */
- #define TRACE_ALLOC_CRITICAL_SECTION() UBaseType_t __irq_status;
- #define TRACE_ENTER_CRITICAL_SECTION() {__irq_status = portSET_INTERRUPT_MASK_FROM_ISR();}
- #define TRACE_EXIT_CRITICAL_SECTION() {portCLEAR_INTERRUPT_MASK_FROM_ISR(__irq_status);}
-#else
- /* FreeRTOS v7.x */
- #define TRACE_ALLOC_CRITICAL_SECTION() unsigned portBASE_TYPE __irq_status;
- #define TRACE_ENTER_CRITICAL_SECTION() {__irq_status = portSET_INTERRUPT_MASK_FROM_ISR();}
- #define TRACE_EXIT_CRITICAL_SECTION() {portCLEAR_INTERRUPT_MASK_FROM_ISR(__irq_status);}
-#endif
-#endif
-
-#ifndef TRACE_ENTER_CRITICAL_SECTION
- #error "This hardware port has no definition for critical sections! See http://percepio.com/2014/10/27/how-to-define-critical-sections-for-the-recorder/"
-#endif
-
-
-#if (TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_0_1)
- /******************************************************************************
- * Fix for FreeRTOS v9.0.1 to correctly identify xQueuePeek events.
- *
- * In FreeRTOS v9.0.1, the below trace hooks are incorrectly used from three
- * different functions. This as the earlier function xQueueGenericReceive
- * has been replaced by xQueuePeek, xQueueSemaphoreTake and xQueueReceive.
- *
- * xQueueGenericReceive had a parameter "xJustPeeking", used by the trace hooks
- * to tell between xQueuePeek events and others. This is no longer present, so
- * we need another way to correctly identify peek events. Since all three
- * functions call the same trace macros, the context of these macro is unknown.
- *
- * We therefore check the __LINE__ macro inside of the trace macros. This gives
- * the line number of queue.c, where the macros are used. This can be used to
- * tell if the context is xQueuePeek or another function.
- * __LINE__ is a standard compiler feature since ancient times, so it should
- * work on all common compilers.
- *
- * This might seem as a quite brittle and unusual solution, but works in this
- * particular case and is only for FreeRTOS v9.0.1.
- * Future versions of FreeRTOS should not need this fix, as we have submitted
- * a correction of queue.c with individual trace macros for each function.
- ******************************************************************************/
-#define isQueueReceiveHookActuallyPeek (__LINE__ > 1674) /* Half way between the closes trace points */
-
-#elif (TRC_CFG_FREERTOS_VERSION <= TRC_FREERTOS_VERSION_9_0_0)
-#define isQueueReceiveHookActuallyPeek xJustPeeking
-
-#elif (TRC_CFG_FREERTOS_VERSION > TRC_FREERTOS_VERSION_9_0_1)
-#define isQueueReceiveHookActuallyPeek (__LINE__ < 0) /* instead of pdFALSE to fix a warning of "constant condition" */
-
-#endif
-
-extern uint16_t CurrentFilterMask;
-
-extern uint16_t CurrentFilterGroup;
-
-uint8_t prvTraceGetQueueType(void* handle);
-
-uint16_t prvTraceGetTaskNumberLow16(void* handle);
-uint16_t prvTraceGetTaskNumberHigh16(void* handle);
-void prvTraceSetTaskNumberLow16(void* handle, uint16_t value);
-void prvTraceSetTaskNumberHigh16(void* handle, uint16_t value);
-
-uint16_t prvTraceGetQueueNumberLow16(void* handle);
-uint16_t prvTraceGetQueueNumberHigh16(void* handle);
-void prvTraceSetQueueNumberLow16(void* handle, uint16_t value);
-void prvTraceSetQueueNumberHigh16(void* handle, uint16_t value);
-
-#if (TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
-uint16_t prvTraceGetTimerNumberLow16(void* handle);
-uint16_t prvTraceGetTimerNumberHigh16(void* handle);
-void prvTraceSetTimerNumberLow16(void* handle, uint16_t value);
-void prvTraceSetTimerNumberHigh16(void* handle, uint16_t value);
-#endif /* (TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
-
-#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
-uint16_t prvTraceGetEventGroupNumberLow16(void* handle);
-uint16_t prvTraceGetEventGroupNumberHigh16(void* handle);
-void prvTraceSetEventGroupNumberLow16(void* handle, uint16_t value);
-void prvTraceSetEventGroupNumberHigh16(void* handle, uint16_t value);
-#endif /* (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
-
-#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
-uint16_t prvTraceGetStreamBufferNumberLow16(void* handle);
-uint16_t prvTraceGetStreamBufferNumberHigh16(void* handle);
-void prvTraceSetStreamBufferNumberLow16(void* handle, uint16_t value);
-void prvTraceSetStreamBufferNumberHigh16(void* handle, uint16_t value);
-#endif /* (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
-
-#define TRACE_GET_TASK_FILTER(pxTask) prvTraceGetTaskNumberHigh16((void*)pxTask)
-#define TRACE_SET_TASK_FILTER(pxTask, group) prvTraceSetTaskNumberHigh16((void*)pxTask, group)
-
-#define TRACE_GET_QUEUE_FILTER(pxObject) prvTraceGetQueueNumberHigh16((void*)pxObject)
-#define TRACE_SET_QUEUE_FILTER(pxObject, group) prvTraceSetQueueNumberHigh16((void*)pxObject, group)
-
-#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
-#define TRACE_GET_EVENTGROUP_FILTER(pxObject) prvTraceGetEventGroupNumberHigh16((void*)pxObject)
-#define TRACE_SET_EVENTGROUP_FILTER(pxObject, group) prvTraceSetEventGroupNumberHigh16((void*)pxObject, group)
-#else /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
-/* FreeRTOS versions before v10.0 does not support filtering for event groups */
-#define TRACE_GET_EVENTGROUP_FILTER(pxObject) 1
-#define TRACE_SET_EVENTGROUP_FILTER(pxObject, group)
-#endif /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
-
-#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
-#define TRACE_GET_TIMER_FILTER(pxObject) prvTraceGetTimerNumberHigh16((void*)pxObject)
-#define TRACE_SET_TIMER_FILTER(pxObject, group) prvTraceSetTimerNumberHigh16((void*)pxObject, group)
-#else /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
-/* FreeRTOS versions before v10.0 does not support filtering for timers */
-#define TRACE_GET_TIMER_FILTER(pxObject) 1
-#define TRACE_SET_TIMER_FILTER(pxObject, group)
-#endif /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
-
-#define TRACE_GET_STREAMBUFFER_FILTER(pxObject) prvTraceGetStreamBufferNumberHigh16((void*)pxObject)
-#define TRACE_SET_STREAMBUFFER_FILTER(pxObject, group) prvTraceSetStreamBufferNumberHigh16((void*)pxObject, group)
-
-/* We can only support filtering if FreeRTOS is at least v7.4 */
-#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_7_4)
-#define TRACE_GET_OBJECT_FILTER(CLASS, pxObject) TRACE_GET_##CLASS##_FILTER(pxObject)
-#define TRACE_SET_OBJECT_FILTER(CLASS, pxObject, group) TRACE_SET_##CLASS##_FILTER(pxObject, group)
-#else /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_7_4) */
-#define TRACE_GET_OBJECT_FILTER(CLASS, pxObject) 1
-#define TRACE_SET_OBJECT_FILTER(CLASS, pxObject, group)
-#endif /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_7_4) */
-
-/******************************************************************************/
-/*** Definitions for Snapshot mode ********************************************/
-/******************************************************************************/
-#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)
-
-/*** The object classes *******************************************************/
-
-#define TRACE_NCLASSES 9
-#define TRACE_CLASS_QUEUE ((traceObjectClass)0)
-#define TRACE_CLASS_SEMAPHORE ((traceObjectClass)1)
-#define TRACE_CLASS_MUTEX ((traceObjectClass)2)
-#define TRACE_CLASS_TASK ((traceObjectClass)3)
-#define TRACE_CLASS_ISR ((traceObjectClass)4)
-#define TRACE_CLASS_TIMER ((traceObjectClass)5)
-#define TRACE_CLASS_EVENTGROUP ((traceObjectClass)6)
-#define TRACE_CLASS_STREAMBUFFER ((traceObjectClass)7)
-#define TRACE_CLASS_MESSAGEBUFFER ((traceObjectClass)8)
-
-/*** Definitions for Object Table ********************************************/
-#define TRACE_KERNEL_OBJECT_COUNT ((TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER) + (TRC_CFG_NEVENTGROUP) + (TRC_CFG_NSTREAMBUFFER) + (TRC_CFG_NMESSAGEBUFFER))
-
-/* Queue properties (except name): current number of message in queue */
-#define PropertyTableSizeQueue ((TRC_CFG_NAME_LEN_QUEUE) + 1)
-
-/* Semaphore properties (except name): state (signaled = 1, cleared = 0) */
-#define PropertyTableSizeSemaphore ((TRC_CFG_NAME_LEN_SEMAPHORE) + 1)
-
-/* Mutex properties (except name): owner (task handle, 0 = free) */
-#define PropertyTableSizeMutex ((TRC_CFG_NAME_LEN_MUTEX) + 1)
-
-/* Task properties (except name): Byte 0: Current priority
- Byte 1: state (if already active)
- Byte 2: legacy, not used
- Byte 3: legacy, not used */
-#define PropertyTableSizeTask ((TRC_CFG_NAME_LEN_TASK) + 4)
-
-/* ISR properties: Byte 0: priority
- Byte 1: state (if already active) */
-#define PropertyTableSizeISR ((TRC_CFG_NAME_LEN_ISR) + 2)
-
-/* TRC_CFG_NTIMER properties: Byte 0: state (unused for now) */
-#define PropertyTableSizeTimer ((TRC_CFG_NAME_LEN_TIMER) + 1)
-
-/* TRC_CFG_NEVENTGROUP properties: Byte 0-3: state (unused for now)*/
-#define PropertyTableSizeEventGroup ((TRC_CFG_NAME_LEN_EVENTGROUP) + 4)
-
-/* TRC_CFG_NSTREAMBUFFER properties: Byte 0-3: state (unused for now)*/
-#define PropertyTableSizeStreamBuffer ((TRC_CFG_NAME_LEN_STREAMBUFFER) + 4)
-
-/* TRC_CFG_NMESSAGEBUFFER properties: Byte 0-3: state (unused for now)*/
-#define PropertyTableSizeMessageBuffer ((TRC_CFG_NAME_LEN_MESSAGEBUFFER) + 4)
-
-
-/* The layout of the byte array representing the Object Property Table */
-#define StartIndexQueue (0)
-#define StartIndexSemaphore (StartIndexQueue + (TRC_CFG_NQUEUE) * PropertyTableSizeQueue)
-#define StartIndexMutex (StartIndexSemaphore + (TRC_CFG_NSEMAPHORE) * PropertyTableSizeSemaphore)
-#define StartIndexTask (StartIndexMutex + (TRC_CFG_NMUTEX) * PropertyTableSizeMutex)
-#define StartIndexISR (StartIndexTask + (TRC_CFG_NTASK) * PropertyTableSizeTask)
-#define StartIndexTimer (StartIndexISR + (TRC_CFG_NISR) * PropertyTableSizeISR)
-#define StartIndexEventGroup (StartIndexTimer + (TRC_CFG_NTIMER) * PropertyTableSizeTimer)
-#define StartIndexStreamBuffer (StartIndexEventGroup + (TRC_CFG_NEVENTGROUP) * PropertyTableSizeEventGroup)
-#define StartIndexMessageBuffer (StartIndexStreamBuffer + (TRC_CFG_NSTREAMBUFFER) * PropertyTableSizeStreamBuffer)
-
-/* Number of bytes used by the object table */
-#define TRACE_OBJECT_TABLE_SIZE (StartIndexMessageBuffer + (TRC_CFG_NMESSAGEBUFFER) * PropertyTableSizeMessageBuffer)
-
-/* Flag to tell the context of tracePEND_FUNC_CALL_FROM_ISR */
-extern int uiInEventGroupSetBitsFromISR;
-
-/* Initialization of the object property table */
-void vTraceInitObjectPropertyTable(void);
-
-/* Initialization of the handle mechanism, see e.g, prvTraceGetObjectHandle */
-void vTraceInitObjectHandleStack(void);
-
-/* Returns the "Not enough handles" error message for the specified object class */
-const char* pszTraceGetErrorNotEnoughHandles(traceObjectClass objectclass);
-
-void* prvTraceGetCurrentTaskHandle(void);
-
-/******************************************************************************
- * TraceQueueClassTable
- * Translates a FreeRTOS QueueType into trace objects classes (TRACE_CLASS_).
- * Has one entry for each QueueType, gives TRACE_CLASS ID.
- ******************************************************************************/
-extern traceObjectClass TraceQueueClassTable[5];
-
-
-/*** Event codes for snapshot mode - must match Tracealyzer config files ******/
-
-#define NULL_EVENT (0x00UL)
-
-/*******************************************************************************
- * EVENTGROUP_DIV
- *
- * Miscellaneous events.
- ******************************************************************************/
-#define EVENTGROUP_DIV (NULL_EVENT + 1UL) /*0x01*/
-#define DIV_XPS (EVENTGROUP_DIV + 0UL) /*0x01*/
-#define DIV_TASK_READY (EVENTGROUP_DIV + 1UL) /*0x02*/
-#define DIV_NEW_TIME (EVENTGROUP_DIV + 2UL) /*0x03*/
-
-/*******************************************************************************
- * EVENTGROUP_TS
- *
- * Events for storing task-switches and interrupts. The RESUME events are
- * generated if the task/interrupt is already marked active.
- ******************************************************************************/
-#define EVENTGROUP_TS (EVENTGROUP_DIV + 3UL) /*0x04*/
-#define TS_ISR_BEGIN (EVENTGROUP_TS + 0UL) /*0x04*/
-#define TS_ISR_RESUME (EVENTGROUP_TS + 1UL) /*0x05*/
-#define TS_TASK_BEGIN (EVENTGROUP_TS + 2UL) /*0x06*/
-#define TS_TASK_RESUME (EVENTGROUP_TS + 3UL) /*0x07*/
-
-/*******************************************************************************
- * EVENTGROUP_OBJCLOSE_NAME
- *
- * About Close Events
- * When an object is evicted from the object property table (object close), two
- * internal events are stored (EVENTGROUP_OBJCLOSE_NAME and
- * EVENTGROUP_OBJCLOSE_PROP), containing the handle-name mapping and object
- * properties valid up to this point.
- ******************************************************************************/
-#define EVENTGROUP_OBJCLOSE_NAME_TRCSUCCESS (EVENTGROUP_TS + 4UL) /*0x08*/
-
-/*******************************************************************************
- * EVENTGROUP_OBJCLOSE_PROP
- *
- * The internal event carrying properties of deleted objects
- * The handle and object class of the closed object is not stored in this event,
- * but is assumed to be the same as in the preceding CLOSE event. Thus, these
- * two events must be generated from within a critical section.
- * When queues are closed, arg1 is the "state" property (i.e., number of
- * buffered messages/signals).
- * When actors are closed, arg1 is priority, arg2 is handle of the "instance
- * finish" event, and arg3 is event code of the "instance finish" event.
- * In this case, the lower three bits is the object class of the instance finish
- * handle. The lower three bits are not used (always zero) when queues are
- * closed since the queue type is given in the previous OBJCLOSE_NAME event.
- ******************************************************************************/
-#define EVENTGROUP_OBJCLOSE_PROP_TRCSUCCESS (EVENTGROUP_OBJCLOSE_NAME_TRCSUCCESS + 8UL) /*0x10*/
-
-/*******************************************************************************
- * EVENTGROUP_CREATE
- *
- * The events in this group are used to log Kernel object creations.
- * The lower three bits in the event code gives the object class, i.e., type of
- * create operation (task, queue, semaphore, etc).
- ******************************************************************************/
-#define EVENTGROUP_CREATE_OBJ_TRCSUCCESS (EVENTGROUP_OBJCLOSE_PROP_TRCSUCCESS + 8UL) /*0x18*/
-
-/*******************************************************************************
- * EVENTGROUP_SEND
- *
- * The events in this group are used to log Send/Give events on queues,
- * semaphores and mutexes The lower three bits in the event code gives the
- * object class, i.e., what type of object that is operated on (queue, semaphore
- * or mutex).
- ******************************************************************************/
-#define EVENTGROUP_SEND_TRCSUCCESS (EVENTGROUP_CREATE_OBJ_TRCSUCCESS + 8UL) /*0x20*/
-
-/*******************************************************************************
- * EVENTGROUP_RECEIVE
- *
- * The events in this group are used to log Receive/Take events on queues,
- * semaphores and mutexes. The lower three bits in the event code gives the
- * object class, i.e., what type of object that is operated on (queue, semaphore
- * or mutex).
- ******************************************************************************/
-#define EVENTGROUP_RECEIVE_TRCSUCCESS (EVENTGROUP_SEND_TRCSUCCESS + 8UL) /*0x28*/
-
-/* Send/Give operations, from ISR */
-#define EVENTGROUP_SEND_FROM_ISR_TRCSUCCESS \
- (EVENTGROUP_RECEIVE_TRCSUCCESS + 8UL) /*0x30*/
-
-/* Receive/Take operations, from ISR */
-#define EVENTGROUP_RECEIVE_FROM_ISR_TRCSUCCESS \
- (EVENTGROUP_SEND_FROM_ISR_TRCSUCCESS + 8UL) /*0x38*/
-
-/* "Failed" event type versions of above (timeout, failed allocation, etc) */
-#define EVENTGROUP_KSE_TRCFAILED \
- (EVENTGROUP_RECEIVE_FROM_ISR_TRCSUCCESS + 8UL) /*0x40*/
-
-/* Failed create calls - memory allocation failed */
-#define EVENTGROUP_CREATE_OBJ_TRCFAILED (EVENTGROUP_KSE_TRCFAILED) /*0x40*/
-
-/* Failed send/give - timeout! */
-#define EVENTGROUP_SEND_TRCFAILED (EVENTGROUP_CREATE_OBJ_TRCFAILED + 8UL) /*0x48*/
-
-/* Failed receive/take - timeout! */
-#define EVENTGROUP_RECEIVE_TRCFAILED (EVENTGROUP_SEND_TRCFAILED + 8UL) /*0x50*/
-
-/* Failed non-blocking send/give - queue full */
-#define EVENTGROUP_SEND_FROM_ISR_TRCFAILED (EVENTGROUP_RECEIVE_TRCFAILED + 8UL) /*0x58*/
-
-/* Failed non-blocking receive/take - queue empty */
-#define EVENTGROUP_RECEIVE_FROM_ISR_TRCFAILED \
- (EVENTGROUP_SEND_FROM_ISR_TRCFAILED + 8UL) /*0x60*/
-
-/* Events when blocking on receive/take */
-#define EVENTGROUP_RECEIVE_TRCBLOCK \
- (EVENTGROUP_RECEIVE_FROM_ISR_TRCFAILED + 8UL) /*0x68*/
-
-/* Events when blocking on send/give */
-#define EVENTGROUP_SEND_TRCBLOCK (EVENTGROUP_RECEIVE_TRCBLOCK + 8UL) /*0x70*/
-
-/* Events on queue peek (receive) */
-#define EVENTGROUP_PEEK_TRCSUCCESS (EVENTGROUP_SEND_TRCBLOCK + 8UL) /*0x78*/
-
-/* Events on object delete (vTaskDelete or vQueueDelete) */
-#define EVENTGROUP_DELETE_OBJ_TRCSUCCESS (EVENTGROUP_PEEK_TRCSUCCESS + 8UL) /*0x80*/
-
-/* Other events - object class is implied: TASK */
-#define EVENTGROUP_OTHERS (EVENTGROUP_DELETE_OBJ_TRCSUCCESS + 8UL) /*0x88*/
-#define TASK_DELAY_UNTIL (EVENTGROUP_OTHERS + 0UL) /*0x88*/
-#define TASK_DELAY (EVENTGROUP_OTHERS + 1UL) /*0x89*/
-#define TASK_SUSPEND (EVENTGROUP_OTHERS + 2UL) /*0x8A*/
-#define TASK_RESUME (EVENTGROUP_OTHERS + 3UL) /*0x8B*/
-#define TASK_RESUME_FROM_ISR (EVENTGROUP_OTHERS + 4UL) /*0x8C*/
-#define TASK_PRIORITY_SET (EVENTGROUP_OTHERS + 5UL) /*0x8D*/
-#define TASK_PRIORITY_INHERIT (EVENTGROUP_OTHERS + 6UL) /*0x8E*/
-#define TASK_PRIORITY_DISINHERIT (EVENTGROUP_OTHERS + 7UL) /*0x8F*/
-
-#define EVENTGROUP_MISC_PLACEHOLDER (EVENTGROUP_OTHERS + 8UL) /*0x90*/
-#define PEND_FUNC_CALL (EVENTGROUP_MISC_PLACEHOLDER+0UL) /*0x90*/
-#define PEND_FUNC_CALL_FROM_ISR (EVENTGROUP_MISC_PLACEHOLDER+1UL) /*0x91*/
-#define PEND_FUNC_CALL_TRCFAILED (EVENTGROUP_MISC_PLACEHOLDER+2UL) /*0x92*/
-#define PEND_FUNC_CALL_FROM_ISR_TRCFAILED (EVENTGROUP_MISC_PLACEHOLDER+3UL) /*0x93*/
-#define MEM_MALLOC_SIZE (EVENTGROUP_MISC_PLACEHOLDER+4UL) /*0x94*/
-#define MEM_MALLOC_ADDR (EVENTGROUP_MISC_PLACEHOLDER+5UL) /*0x95*/
-#define MEM_FREE_SIZE (EVENTGROUP_MISC_PLACEHOLDER+6UL) /*0x96*/
-#define MEM_FREE_ADDR (EVENTGROUP_MISC_PLACEHOLDER+7UL) /*0x97*/
-
-/* User events */
-#define EVENTGROUP_USEREVENT (EVENTGROUP_MISC_PLACEHOLDER + 8UL) /*0x98*/
-#define USER_EVENT (EVENTGROUP_USEREVENT + 0UL)
-
-/* Allow for 0-15 arguments (the number of args is added to event code) */
-#define USER_EVENT_LAST (EVENTGROUP_USEREVENT + 15UL) /*0xA7*/
-
-/*******************************************************************************
- * XTS Event - eXtended TimeStamp events
- * The timestamps used in the recorder are "differential timestamps" (DTS), i.e.
- * the time since the last stored event. The DTS fields are either 1 or 2 bytes
- * in the other events, depending on the bytes available in the event struct.
- * If the time since the last event (the DTS) is larger than allowed for by
- * the DTS field of the current event, an XTS event is inserted immediately
- * before the original event. The XTS event contains up to 3 additional bytes
- * of the DTS value - the higher bytes of the true DTS value. The lower 1-2
- * bytes are stored in the normal DTS field.
- * There are two types of XTS events, XTS8 and XTS16. An XTS8 event is stored
- * when there is only room for 1 byte (8 bit) DTS data in the original event,
- * which means a limit of 0xFF (255UL). The XTS16 is used when the original event
- * has a 16 bit DTS field and thereby can handle values up to 0xFFFF (65535UL).
- *
- * Using a very high frequency time base can result in many XTS events.
- * Preferably, the time between two OS ticks should fit in 16 bits, i.e.,
- * at most 65535. If your time base has a higher frequency, you can define
- * the TRACE
- ******************************************************************************/
-
-#define EVENTGROUP_SYS (EVENTGROUP_USEREVENT + 16UL) /*0xA8*/
-#define XTS8 (EVENTGROUP_SYS + 0UL) /*0xA8*/
-#define XTS16 (EVENTGROUP_SYS + 1UL) /*0xA9*/
-#define EVENT_BEING_WRITTEN (EVENTGROUP_SYS + 2UL) /*0xAA*/
-#define RESERVED_DUMMY_CODE (EVENTGROUP_SYS + 3UL) /*0xAB*/
-#define LOW_POWER_BEGIN (EVENTGROUP_SYS + 4UL) /*0xAC*/
-#define LOW_POWER_END (EVENTGROUP_SYS + 5UL) /*0xAD*/
-#define XID (EVENTGROUP_SYS + 6UL) /*0xAE*/
-#define XTS16L (EVENTGROUP_SYS + 7UL) /*0xAF*/
-
-#define EVENTGROUP_TIMER (EVENTGROUP_SYS + 8UL) /*0xB0*/
-#define TIMER_CREATE (EVENTGROUP_TIMER + 0UL) /*0xB0*/
-#define TIMER_START (EVENTGROUP_TIMER + 1UL) /*0xB1*/
-#define TIMER_RST (EVENTGROUP_TIMER + 2UL) /*0xB2*/
-#define TIMER_STOP (EVENTGROUP_TIMER + 3UL) /*0xB3*/
-#define TIMER_CHANGE_PERIOD (EVENTGROUP_TIMER + 4UL) /*0xB4*/
-#define TIMER_DELETE_OBJ (EVENTGROUP_TIMER + 5UL) /*0xB5*/
-#define TIMER_START_FROM_ISR (EVENTGROUP_TIMER + 6UL) /*0xB6*/
-#define TIMER_RESET_FROM_ISR (EVENTGROUP_TIMER + 7UL) /*0xB7*/
-#define TIMER_STOP_FROM_ISR (EVENTGROUP_TIMER + 8UL) /*0xB8*/
-
-#define TIMER_CREATE_TRCFAILED (EVENTGROUP_TIMER + 9UL) /*0xB9*/
-#define TIMER_START_TRCFAILED (EVENTGROUP_TIMER + 10UL) /*0xBA*/
-#define TIMER_RESET_TRCFAILED (EVENTGROUP_TIMER + 11UL) /*0xBB*/
-#define TIMER_STOP_TRCFAILED (EVENTGROUP_TIMER + 12UL) /*0xBC*/
-#define TIMER_CHANGE_PERIOD_TRCFAILED (EVENTGROUP_TIMER + 13UL) /*0xBD*/
-#define TIMER_DELETE_TRCFAILED (EVENTGROUP_TIMER + 14UL) /*0xBE*/
-#define TIMER_START_FROM_ISR_TRCFAILED (EVENTGROUP_TIMER + 15UL) /*0xBF*/
-#define TIMER_RESET_FROM_ISR_TRCFAILED (EVENTGROUP_TIMER + 16UL) /*0xC0*/
-#define TIMER_STOP_FROM_ISR_TRCFAILED (EVENTGROUP_TIMER + 17UL) /*0xC1*/
-
-#define EVENTGROUP_EG (EVENTGROUP_TIMER + 18UL) /*0xC2*/
-#define EVENT_GROUP_CREATE (EVENTGROUP_EG + 0UL) /*0xC2*/
-#define EVENT_GROUP_CREATE_TRCFAILED (EVENTGROUP_EG + 1UL) /*0xC3*/
-#define EVENT_GROUP_SYNC_TRCBLOCK (EVENTGROUP_EG + 2UL) /*0xC4*/
-#define EVENT_GROUP_SYNC_END (EVENTGROUP_EG + 3UL) /*0xC5*/
-#define EVENT_GROUP_WAIT_BITS_TRCBLOCK (EVENTGROUP_EG + 4UL) /*0xC6*/
-#define EVENT_GROUP_WAIT_BITS_END (EVENTGROUP_EG + 5UL) /*0xC7*/
-#define EVENT_GROUP_CLEAR_BITS (EVENTGROUP_EG + 6UL) /*0xC8*/
-#define EVENT_GROUP_CLEAR_BITS_FROM_ISR (EVENTGROUP_EG + 7UL) /*0xC9*/
-#define EVENT_GROUP_SET_BITS (EVENTGROUP_EG + 8UL) /*0xCA*/
-#define EVENT_GROUP_DELETE_OBJ (EVENTGROUP_EG + 9UL) /*0xCB*/
-#define EVENT_GROUP_SYNC_END_TRCFAILED (EVENTGROUP_EG + 10UL) /*0xCC*/
-#define EVENT_GROUP_WAIT_BITS_END_TRCFAILED (EVENTGROUP_EG + 11UL) /*0xCD*/
-#define EVENT_GROUP_SET_BITS_FROM_ISR (EVENTGROUP_EG + 12UL) /*0xCE*/
-#define EVENT_GROUP_SET_BITS_FROM_ISR_TRCFAILED (EVENTGROUP_EG + 13UL) /*0xCF*/
-
-#define TASK_INSTANCE_FINISHED_NEXT_KSE (EVENTGROUP_EG + 14UL) /*0xD0*/
-#define TASK_INSTANCE_FINISHED_DIRECT (EVENTGROUP_EG + 15UL) /*0xD1*/
-
-#define TRACE_TASK_NOTIFY_GROUP (EVENTGROUP_EG + 16UL) /*0xD2*/
-#define TRACE_TASK_NOTIFY (TRACE_TASK_NOTIFY_GROUP + 0UL) /*0xD2*/
-#define TRACE_TASK_NOTIFY_TAKE (TRACE_TASK_NOTIFY_GROUP + 1UL) /*0xD3*/
-#define TRACE_TASK_NOTIFY_TAKE_TRCBLOCK (TRACE_TASK_NOTIFY_GROUP + 2UL) /*0xD4*/
-#define TRACE_TASK_NOTIFY_TAKE_TRCFAILED (TRACE_TASK_NOTIFY_GROUP + 3UL) /*0xD5*/
-#define TRACE_TASK_NOTIFY_WAIT (TRACE_TASK_NOTIFY_GROUP + 4UL) /*0xD6*/
-#define TRACE_TASK_NOTIFY_WAIT_TRCBLOCK (TRACE_TASK_NOTIFY_GROUP + 5UL) /*0xD7*/
-#define TRACE_TASK_NOTIFY_WAIT_TRCFAILED (TRACE_TASK_NOTIFY_GROUP + 6UL) /*0xD8*/
-#define TRACE_TASK_NOTIFY_FROM_ISR (TRACE_TASK_NOTIFY_GROUP + 7UL) /*0xD9*/
-#define TRACE_TASK_NOTIFY_GIVE_FROM_ISR (TRACE_TASK_NOTIFY_GROUP + 8UL) /*0xDA*/
-
-#define TIMER_EXPIRED (TRACE_TASK_NOTIFY_GROUP + 9UL) /* 0xDB */
-
- /* Events on queue peek (receive) */
-#define EVENTGROUP_PEEK_TRCBLOCK (TRACE_TASK_NOTIFY_GROUP + 10UL) /*0xDC*/
-/* peek block on queue: 0xDC */
-/* peek block on semaphore: 0xDD */
-/* peek block on mutex: 0xDE */
-
-/* Events on queue peek (receive) */
-#define EVENTGROUP_PEEK_TRCFAILED (EVENTGROUP_PEEK_TRCBLOCK + 3UL) /*0xDF*/
-/* peek failed on queue: 0xDF */
-/* peek failed on semaphore: 0xE0 */
-/* peek failed on mutex: 0xE1 */
-
-#define EVENTGROUP_STREAMBUFFER_DIV (EVENTGROUP_PEEK_TRCFAILED + 3UL) /*0xE2*/
-#define TRACE_STREAMBUFFER_RESET (EVENTGROUP_STREAMBUFFER_DIV + 0) /*0xE2*/
-#define TRACE_MESSAGEBUFFER_RESET (EVENTGROUP_STREAMBUFFER_DIV + 1UL) /*0xE3*/
-#define TRACE_STREAMBUFFER_OBJCLOSE_NAME_TRCSUCCESS (EVENTGROUP_STREAMBUFFER_DIV + 2UL) /*0xE4*/
-#define TRACE_MESSAGEBUFFER_OBJCLOSE_NAME_TRCSUCCESS (EVENTGROUP_STREAMBUFFER_DIV + 3UL) /*0xE5*/
-#define TRACE_STREAMBUFFER_OBJCLOSE_PROP_TRCSUCCESS (EVENTGROUP_STREAMBUFFER_DIV + 4UL) /*0xE6*/
-#define TRACE_MESSAGEBUFFER_OBJCLOSE_PROP_TRCSUCCESS (EVENTGROUP_STREAMBUFFER_DIV + 5UL) /*0xE7*/
-
-/* The following are using previously "lost" event codes */
-#define TRACE_STREAMBUFFER_CREATE_OBJ_TRCSUCCESS (EVENTGROUP_CREATE_OBJ_TRCSUCCESS + 4UL) /*0x1C*/
-#define TRACE_STREAMBUFFER_CREATE_OBJ_TRCFAILED (EVENTGROUP_CREATE_OBJ_TRCFAILED + 4UL) /*0x44*/
-#define TRACE_STREAMBUFFER_DELETE_OBJ_TRCSUCCESS (EVENTGROUP_DELETE_OBJ_TRCSUCCESS + 4UL) /*0x84*/
-#define TRACE_STREAMBUFFER_SEND_TRCSUCCESS (EVENTGROUP_SEND_TRCSUCCESS + 3UL) /*0x23*/
-#define TRACE_STREAMBUFFER_SEND_TRCBLOCK (EVENTGROUP_SEND_TRCBLOCK + 3UL) /*0x73*/
-#define TRACE_STREAMBUFFER_SEND_TRCFAILED (EVENTGROUP_SEND_TRCFAILED + 3UL) /*0x4B*/
-#define TRACE_STREAMBUFFER_RECEIVE_TRCSUCCESS (EVENTGROUP_RECEIVE_TRCSUCCESS + 3UL) /*0x2B*/
-#define TRACE_STREAMBUFFER_RECEIVE_TRCBLOCK (EVENTGROUP_RECEIVE_TRCBLOCK + 3UL) /*0x6B*/
-#define TRACE_STREAMBUFFER_RECEIVE_TRCFAILED (EVENTGROUP_RECEIVE_TRCFAILED + 3UL) /*0x53*/
-#define TRACE_STREAMBUFFER_SEND_FROM_ISR_TRCSUCCESS (EVENTGROUP_SEND_FROM_ISR_TRCSUCCESS + 3UL) /*0x33*/
-#define TRACE_STREAMBUFFER_SEND_FROM_ISR_TRCFAILED (EVENTGROUP_SEND_FROM_ISR_TRCFAILED + 3UL) /*0x5B*/
-#define TRACE_STREAMBUFFER_RECEIVE_FROM_ISR_TRCSUCCESS (EVENTGROUP_RECEIVE_FROM_ISR_TRCSUCCESS + 3UL) /*0x3B*/
-#define TRACE_STREAMBUFFER_RECEIVE_FROM_ISR_TRCFAILED (EVENTGROUP_RECEIVE_FROM_ISR_TRCFAILED + 3UL) /*0x63*/
-
-/* The following are using previously "lost" event codes. These macros aren't even directly referenced, instead we do (equivalent STREAMBUFFER code) + 1. */
-#define TRACE_MESSAGEBUFFER_CREATE_OBJ_TRCSUCCESS (EVENTGROUP_CREATE_OBJ_TRCSUCCESS + 5UL) /*0x1D*/
-#define TRACE_MESSAGEBUFFER_CREATE_OBJ_TRCFAILED (EVENTGROUP_CREATE_OBJ_TRCFAILED + 5UL) /*0x45*/
-#define TRACE_MESSAGEBUFFER_DELETE_OBJ_TRCSUCCESS (EVENTGROUP_DELETE_OBJ_TRCSUCCESS + 5UL) /*0x85*/
-#define TRACE_MESSAGEBUFFER_SEND_TRCSUCCESS (EVENTGROUP_SEND_TRCSUCCESS + 4UL) /*0x24*/
-#define TRACE_MESSAGEBUFFER_SEND_TRCBLOCK (EVENTGROUP_SEND_TRCBLOCK + 4UL) /*0x74*/
-#define TRACE_MESSAGEBUFFER_SEND_TRCFAILED (EVENTGROUP_SEND_TRCFAILED + 4UL) /*0x4C*/
-#define TRACE_MESSAGEBUFFER_RECEIVE_TRCSUCCESS (EVENTGROUP_RECEIVE_TRCSUCCESS + 4UL) /*0x2C*/
-#define TRACE_MESSAGEBUFFER_RECEIVE_TRCBLOCK (EVENTGROUP_RECEIVE_TRCBLOCK + 4UL) /*0x6C*/
-#define TRACE_MESSAGEBUFFER_RECEIVE_TRCFAILED (EVENTGROUP_RECEIVE_TRCFAILED + 4UL) /*0x54*/
-#define TRACE_MESSAGEBUFFER_SEND_FROM_ISR_TRCSUCCESS (EVENTGROUP_SEND_FROM_ISR_TRCSUCCESS + 4UL) /*0x34*/
-#define TRACE_MESSAGEBUFFER_SEND_FROM_ISR_TRCFAILED (EVENTGROUP_SEND_FROM_ISR_TRCFAILED + 4UL) /*0x5C*/
-#define TRACE_MESSAGEBUFFER_RECEIVE_FROM_ISR_TRCSUCCESS (EVENTGROUP_RECEIVE_FROM_ISR_TRCSUCCESS + 4UL) /*0x3C*/
-#define TRACE_MESSAGEBUFFER_RECEIVE_FROM_ISR_TRCFAILED (EVENTGROUP_RECEIVE_FROM_ISR_TRCFAILED + 4UL) /*0x64*/
-
-/* LAST EVENT (0xE7) */
-
-/****************************
-* MACROS TO GET TRACE CLASS *
-****************************/
-#define TRACE_GET_TRACE_CLASS_FROM_TASK_CLASS(kernelClass) (TRACE_CLASS_TASK)
-#define TRACE_GET_TRACE_CLASS_FROM_TASK_OBJECT(pxObject) (TRACE_CLASS_TASK)
-
-#define TRACE_GET_TRACE_CLASS_FROM_QUEUE_CLASS(kernelClass) TraceQueueClassTable[kernelClass]
-#define TRACE_GET_TRACE_CLASS_FROM_QUEUE_OBJECT(pxObject) TRACE_GET_TRACE_CLASS_FROM_QUEUE_CLASS(prvTraceGetQueueType(pxObject))
-
-#define TRACE_GET_TRACE_CLASS_FROM_TIMER_CLASS(kernelClass) (TRACE_CLASS_TIMER)
-#define TRACE_GET_TRACE_CLASS_FROM_TIMER_OBJECT(pxObject) (TRACE_CLASS_TIMER)
-
-#define TRACE_GET_TRACE_CLASS_FROM_EVENTGROUP_CLASS(kernelClass) (TRACE_CLASS_EVENTGROUP)
-#define TRACE_GET_TRACE_CLASS_FROM_EVENTGROUP_OBJECT(pxObject) (TRACE_CLASS_EVENTGROUP)
-
-/* TRACE_GET_TRACE_CLASS_FROM_STREAMBUFFER_CLASS can only be accessed with a parameter indicating if it is a MessageBuffer */
-#define TRACE_GET_TRACE_CLASS_FROM_STREAMBUFFER_CLASS(xIsMessageBuffer) (xIsMessageBuffer == 1 ? TRACE_CLASS_MESSAGEBUFFER : TRACE_CLASS_STREAMBUFFER)
-#define TRACE_GET_TRACE_CLASS_FROM_STREAMBUFFER_OBJECT(pxObject) (prvGetStreamBufferType(pxObject) == 1 ? TRACE_CLASS_MESSAGEBUFFER : TRACE_CLASS_STREAMBUFFER)
-
-/* Generic versions */
-#define TRACE_GET_CLASS_TRACE_CLASS(CLASS, kernelClass) TRACE_GET_TRACE_CLASS_FROM_##CLASS##_CLASS(kernelClass)
-#define TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject) TRACE_GET_TRACE_CLASS_FROM_##CLASS##_OBJECT(pxObject)
-
-/******************************
-* MACROS TO GET OBJECT NUMBER *
-******************************/
-#define TRACE_GET_TASK_NUMBER(pxTCB) (traceHandle)(prvTraceGetTaskNumberLow16(pxTCB))
-#define TRACE_SET_TASK_NUMBER(pxTCB) prvTraceSetTaskNumberLow16(pxTCB, prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(TASK, pxTCB)));
-
-#define TRACE_GET_QUEUE_NUMBER(queue) ( ( traceHandle ) prvTraceGetQueueNumberLow16(queue) )
-#define TRACE_SET_QUEUE_NUMBER(queue) prvTraceSetQueueNumberLow16(queue, (uint16_t)prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, queue)));
-
-#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
-#define TRACE_GET_TIMER_NUMBER(tmr) ( ( traceHandle ) prvTraceGetTimerNumberLow16(tmr) )
-#define TRACE_SET_TIMER_NUMBER(tmr) prvTraceSetTimerNumberLow16(tmr, (uint16_t)prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(TIMER, tmr)));
-#else /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
-#define TRACE_GET_TIMER_NUMBER(tmr) ( ( traceHandle ) ((Timer_t*)tmr)->uxTimerNumber )
-#define TRACE_SET_TIMER_NUMBER(tmr) ((Timer_t*)tmr)->uxTimerNumber = prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(TIMER, tmr));
-#endif /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
-
-#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
-#define TRACE_GET_EVENTGROUP_NUMBER(eg) ( ( traceHandle ) prvTraceGetEventGroupNumberLow16(eg) )
-#define TRACE_SET_EVENTGROUP_NUMBER(eg) prvTraceSetEventGroupNumberLow16(eg, (uint16_t)prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(EVENTGROUP, eg)));
-#else /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
-#define TRACE_GET_EVENTGROUP_NUMBER(eg) ( ( traceHandle ) uxEventGroupGetNumber(eg) )
-#define TRACE_SET_EVENTGROUP_NUMBER(eg) ((EventGroup_t*)eg)->uxEventGroupNumber = prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(EVENTGROUP, eg));
-#endif /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
-
-
-#define TRACE_GET_STREAMBUFFER_NUMBER(sb) ( ( traceHandle ) prvTraceGetStreamBufferNumberLow16(sb) )
-#define TRACE_SET_STREAMBUFFER_NUMBER(sb) prvTraceSetStreamBufferNumberLow16(sb, (uint16_t)prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(STREAMBUFFER, sb)));
-
-/* Generic versions */
-#define TRACE_GET_OBJECT_NUMBER(CLASS, pxObject) TRACE_GET_##CLASS##_NUMBER(pxObject)
-#define TRACE_SET_OBJECT_NUMBER(CLASS, pxObject) TRACE_SET_##CLASS##_NUMBER(pxObject)
-
-/******************************
-* MACROS TO GET EVENT CODES *
-******************************/
-#define TRACE_GET_TASK_CLASS_EVENT_CODE(SERVICE, RESULT, kernelClass) (uint8_t)(EVENTGROUP_##SERVICE##_##RESULT + TRACE_GET_CLASS_TRACE_CLASS(TASK, kernelClass))
-#define TRACE_GET_QUEUE_CLASS_EVENT_CODE(SERVICE, RESULT, kernelClass) (uint8_t)(EVENTGROUP_##SERVICE##_##RESULT + TRACE_GET_CLASS_TRACE_CLASS(QUEUE, kernelClass))
-#define TRACE_GET_TIMER_CLASS_EVENT_CODE(SERVICE, RESULT, kernelClass) -- THIS IS NOT USED --
-#define TRACE_GET_EVENTGROUP_CLASS_EVENT_CODE(SERVICE, RESULT, kernelClass) -- THIS IS NOT USED --
-#define TRACE_GET_STREAMBUFFER_CLASS_EVENT_CODE(SERVICE, RESULT, isMessageBuffer) (uint8_t)(TRACE_STREAMBUFFER_##SERVICE##_##RESULT + (uint8_t)isMessageBuffer)
-
-#define TRACE_GET_TASK_OBJECT_EVENT_CODE(SERVICE, RESULT, pxTCB) (uint8_t)(EVENTGROUP_##SERVICE##_##RESULT + TRACE_CLASS_TASK)
-#define TRACE_GET_QUEUE_OBJECT_EVENT_CODE(SERVICE, RESULT, pxObject) (uint8_t)(EVENTGROUP_##SERVICE##_##RESULT + TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, pxObject))
-#define TRACE_GET_TIMER_OBJECT_EVENT_CODE(SERVICE, RESULT, UNUSED) -- THIS IS NOT USED --
-#define TRACE_GET_EVENTGROUP_OBJECT_EVENT_CODE(SERVICE, RESULT, UNUSED) -- THIS IS NOT USED --
-#define TRACE_GET_STREAMBUFFER_OBJECT_EVENT_CODE(SERVICE, RESULT, pxObject) (uint8_t)(TRACE_STREAMBUFFER_##SERVICE##_##RESULT + prvGetStreamBufferType(pxObject))
-
-/* Generic versions */
-#define TRACE_GET_CLASS_EVENT_CODE(SERVICE, RESULT, CLASS, kernelClass) TRACE_GET_##CLASS##_CLASS_EVENT_CODE(SERVICE, RESULT, kernelClass)
-#define TRACE_GET_OBJECT_EVENT_CODE(SERVICE, RESULT, CLASS, pxObject) TRACE_GET_##CLASS##_OBJECT_EVENT_CODE(SERVICE, RESULT, pxObject)
-
-/******************************
-* SPECIAL MACROS FOR TASKS *
-******************************/
-#define TRACE_GET_TASK_PRIORITY(pxTCB) ((uint8_t)pxTCB->uxPriority)
-#define TRACE_GET_TASK_NAME(pxTCB) ((char*)pxTCB->pcTaskName)
-
-/*** The trace macros for snapshot mode **************************************/
-
-/* A macro that will update the tick count when returning from tickless idle */
-#undef traceINCREASE_TICK_COUNT
-#define traceINCREASE_TICK_COUNT( xCount )
-
-/* Called for each task that becomes ready */
-#undef traceMOVED_TASK_TO_READY_STATE
-#define traceMOVED_TASK_TO_READY_STATE( pxTCB ) \
- trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE(pxTCB);
-
-/* Called on each OS tick. Will call uiPortGetTimestamp to make sure it is called at least once every OS tick. */
-#undef traceTASK_INCREMENT_TICK
-
-#if (TRC_CFG_FREERTOS_VERSION <= TRC_FREERTOS_VERSION_7_4)
-
-#define traceTASK_INCREMENT_TICK( xTickCount ) \
- if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || uxMissedTicks == 0) { trcKERNEL_HOOKS_INCREMENT_TICK(); } \
- if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE) { trcKERNEL_HOOKS_NEW_TIME(DIV_NEW_TIME, xTickCount + 1); }
-
-#else
-
-#define traceTASK_INCREMENT_TICK( xTickCount ) \
- if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || xPendedTicks == 0) { trcKERNEL_HOOKS_INCREMENT_TICK(); } \
- if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE) { trcKERNEL_HOOKS_NEW_TIME(DIV_NEW_TIME, xTickCount + 1); }
-
-#endif
-
-/* Called on each task-switch */
-#undef traceTASK_SWITCHED_IN
-#define traceTASK_SWITCHED_IN() \
- trcKERNEL_HOOKS_TASK_SWITCH(TRACE_GET_CURRENT_TASK());
-
-/* Called on vTaskCreate */
-#undef traceTASK_CREATE
-#define traceTASK_CREATE(pxNewTCB) \
- if (pxNewTCB != NULL) \
- { \
- trcKERNEL_HOOKS_TASK_CREATE(TRACE_GET_OBJECT_EVENT_CODE(CREATE_OBJ, TRCSUCCESS, TASK, pxNewTCB), TASK, pxNewTCB); \
- }
-
-/* Called in vTaskCreate, if it fails (typically if the stack can not be allocated) */
-#undef traceTASK_CREATE_FAILED
-#define traceTASK_CREATE_FAILED() \
- trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY(TRACE_GET_CLASS_EVENT_CODE(CREATE_OBJ, TRCFAILED, TASK, NOT_USED), 0);
-
-/* Called on vTaskDelete */
-#undef traceTASK_DELETE
-#define traceTASK_DELETE( pxTaskToDelete ) \
- { TRACE_ALLOC_CRITICAL_SECTION(); \
- TRACE_ENTER_CRITICAL_SECTION(); \
- trcKERNEL_HOOKS_TASK_DELETE(TRACE_GET_OBJECT_EVENT_CODE(DELETE_OBJ, TRCSUCCESS, TASK, pxTaskToDelete), TRACE_GET_OBJECT_EVENT_CODE(OBJCLOSE_NAME, TRCSUCCESS, TASK, pxTaskToDelete), TRACE_GET_OBJECT_EVENT_CODE(OBJCLOSE_PROP, TRCSUCCESS, TASK, pxTaskToDelete), pxTaskToDelete); \
- TRACE_EXIT_CRITICAL_SECTION(); }
-
-#if (TRC_CFG_SCHEDULING_ONLY == 0)
-
-#if defined(configUSE_TICKLESS_IDLE)
-#if (configUSE_TICKLESS_IDLE != 0)
-
-#undef traceLOW_POWER_IDLE_BEGIN
-#define traceLOW_POWER_IDLE_BEGIN() \
- { \
- extern uint32_t trace_disable_timestamp; \
- prvTraceStoreLowPower(0); \
- trace_disable_timestamp = 1; \
- }
-
-#undef traceLOW_POWER_IDLE_END
-#define traceLOW_POWER_IDLE_END() \
- { \
- extern uint32_t trace_disable_timestamp; \
- trace_disable_timestamp = 0; \
- prvTraceStoreLowPower(1); \
- }
-
-#endif /* (configUSE_TICKLESS_IDLE != 0) */
-#endif /* defined(configUSE_TICKLESS_IDLE) */
-
-/* Called on vTaskSuspend */
-#undef traceTASK_SUSPEND
-#define traceTASK_SUSPEND( pxTaskToSuspend ) \
- trcKERNEL_HOOKS_TASK_SUSPEND(TASK_SUSPEND, pxTaskToSuspend);
-
-/* Called from special case with timer only */
-#undef traceTASK_DELAY_SUSPEND
-#define traceTASK_DELAY_SUSPEND( pxTaskToSuspend ) \
- trcKERNEL_HOOKS_TASK_SUSPEND(TASK_SUSPEND, pxTaskToSuspend); \
- trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED();
-
-/* Called on vTaskDelay - note the use of FreeRTOS variable xTicksToDelay */
-#undef traceTASK_DELAY
-#define traceTASK_DELAY() \
- trcKERNEL_HOOKS_TASK_DELAY(TASK_DELAY, pxCurrentTCB, xTicksToDelay); \
- trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED();
-
-/* Called on vTaskDelayUntil - note the use of FreeRTOS variable xTimeToWake */
-#undef traceTASK_DELAY_UNTIL
-#if TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0
-#define traceTASK_DELAY_UNTIL(xTimeToWake) \
- trcKERNEL_HOOKS_TASK_DELAY(TASK_DELAY_UNTIL, pxCurrentTCB, xTimeToWake); \
- trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED();
-#else /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */
-#define traceTASK_DELAY_UNTIL() \
- trcKERNEL_HOOKS_TASK_DELAY(TASK_DELAY_UNTIL, pxCurrentTCB, xTimeToWake); \
- trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED();
-#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */
-
-/* Called in xQueueCreate, and thereby for all other object based on queues, such as semaphores. */
-#undef traceQUEUE_CREATE
-#define traceQUEUE_CREATE( pxNewQueue ) \
- trcKERNEL_HOOKS_OBJECT_CREATE(TRACE_GET_OBJECT_EVENT_CODE(CREATE_OBJ, TRCSUCCESS, QUEUE, pxNewQueue), QUEUE, pxNewQueue);
-
-/* Called in xQueueCreate, if the queue creation fails */
-#undef traceQUEUE_CREATE_FAILED
-#define traceQUEUE_CREATE_FAILED( queueType ) \
- trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY(TRACE_GET_CLASS_EVENT_CODE(CREATE_OBJ, TRCFAILED, QUEUE, queueType), 0);
-
-/* Called on vQueueDelete */
-#undef traceQUEUE_DELETE
-#define traceQUEUE_DELETE( pxQueue ) \
- { TRACE_ALLOC_CRITICAL_SECTION(); \
- TRACE_ENTER_CRITICAL_SECTION(); \
- trcKERNEL_HOOKS_OBJECT_DELETE(TRACE_GET_OBJECT_EVENT_CODE(DELETE_OBJ, TRCSUCCESS, QUEUE, pxQueue), TRACE_GET_OBJECT_EVENT_CODE(OBJCLOSE_NAME, TRCSUCCESS, QUEUE, pxQueue), TRACE_GET_OBJECT_EVENT_CODE(OBJCLOSE_PROP, TRCSUCCESS, QUEUE, pxQueue), QUEUE, pxQueue); \
- TRACE_EXIT_CRITICAL_SECTION(); }
-
-/* This macro is not necessary as of FreeRTOS v9.0.0 */
-#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0)
-/* Called in xQueueCreateMutex, and thereby also from xSemaphoreCreateMutex and xSemaphoreCreateRecursiveMutex */
-#undef traceCREATE_MUTEX
-#define traceCREATE_MUTEX( pxNewQueue ) \
- trcKERNEL_HOOKS_OBJECT_CREATE(TRACE_GET_OBJECT_EVENT_CODE(CREATE_OBJ, TRCSUCCESS, QUEUE, pxNewQueue), QUEUE, pxNewQueue);
-
-/* Called in xQueueCreateMutex when the operation fails (when memory allocation fails) */
-#undef traceCREATE_MUTEX_FAILED
-#define traceCREATE_MUTEX_FAILED() \
- trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY(TRACE_GET_CLASS_EVENT_CODE(CREATE_OBJ, TRCFAILED, QUEUE, queueQUEUE_TYPE_MUTEX), 0);
-#endif /* (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0) */
-
-/* Called when the Mutex can not be given, since not holder */
-#undef traceGIVE_MUTEX_RECURSIVE_FAILED
-#define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ) \
- trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND, TRCFAILED, QUEUE, pxMutex), QUEUE, pxMutex);
-
-/* Called when a message is sent to a queue */ /* CS IS NEW ! */
-#undef traceQUEUE_SEND
-#define traceQUEUE_SEND( pxQueue ) \
- trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND, TRCSUCCESS, QUEUE, pxQueue), QUEUE, pxQueue); \
- trcKERNEL_HOOKS_SET_OBJECT_STATE(QUEUE, pxQueue, TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, pxQueue) == TRACE_CLASS_MUTEX ? (uint8_t)0 : (uint8_t)(pxQueue->uxMessagesWaiting + 1));
-
-/* Called when a message failed to be sent to a queue (timeout) */
-#undef traceQUEUE_SEND_FAILED
-#define traceQUEUE_SEND_FAILED( pxQueue ) \
- trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND, TRCFAILED, QUEUE, pxQueue), QUEUE, pxQueue);
-
-/* Called when the task is blocked due to a send operation on a full queue */
-#undef traceBLOCKING_ON_QUEUE_SEND
-#define traceBLOCKING_ON_QUEUE_SEND( pxQueue ) \
- trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND, TRCBLOCK, QUEUE, pxQueue), QUEUE, pxQueue);
-
-/* Called when a message is received from a queue */
-#undef traceQUEUE_RECEIVE
-#define traceQUEUE_RECEIVE( pxQueue ) \
- if (isQueueReceiveHookActuallyPeek) \
- { \
- trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(PEEK, TRCSUCCESS, QUEUE, pxQueue), QUEUE, pxQueue); \
- } \
- else \
- { \
- trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE, TRCSUCCESS, QUEUE, pxQueue), QUEUE, pxQueue); \
- } \
- trcKERNEL_HOOKS_SET_OBJECT_STATE(QUEUE, pxQueue, TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, pxQueue) == TRACE_CLASS_MUTEX ? (uint8_t)TRACE_GET_TASK_NUMBER(TRACE_GET_CURRENT_TASK()) : (uint8_t)(pxQueue->uxMessagesWaiting - 1));
-
-/* Called when a receive operation on a queue fails (timeout) */
-#undef traceQUEUE_RECEIVE_FAILED
-#define traceQUEUE_RECEIVE_FAILED( pxQueue ) \
- if (isQueueReceiveHookActuallyPeek) \
- { \
- trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(PEEK, TRCFAILED, QUEUE, pxQueue), QUEUE, pxQueue); \
- } \
- else \
- { \
- trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE, TRCFAILED, QUEUE, pxQueue), QUEUE, pxQueue); \
- }
-
-/* Called when the task is blocked due to a receive operation on an empty queue */
-#undef traceBLOCKING_ON_QUEUE_RECEIVE
-#define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ) \
- if (isQueueReceiveHookActuallyPeek) \
- { \
- trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(PEEK, TRCBLOCK, QUEUE, pxQueue), QUEUE, pxQueue); \
- } \
- else \
- { \
- trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE, TRCBLOCK, QUEUE, pxQueue), QUEUE, pxQueue); \
- } \
- if (TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, pxQueue) != TRACE_CLASS_MUTEX) \
- { \
- trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); \
- }
-
-/* Called on xQueuePeek */
-#undef traceQUEUE_PEEK
-#define traceQUEUE_PEEK( pxQueue ) \
- trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(PEEK, TRCSUCCESS, QUEUE, pxQueue), QUEUE, pxQueue);
-
-/* Called on xQueuePeek fail/timeout (added in FreeRTOS v9.0.2) */
-#undef traceQUEUE_PEEK_FAILED
-#define traceQUEUE_PEEK_FAILED( pxQueue ) \
- trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(PEEK, TRCFAILED, QUEUE, pxQueue), QUEUE, pxQueue);
-
-/* Called on xQueuePeek blocking (added in FreeRTOS v9.0.2) */
-#undef traceBLOCKING_ON_QUEUE_PEEK
-#define traceBLOCKING_ON_QUEUE_PEEK( pxQueue ) \
- trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(PEEK, TRCBLOCK, QUEUE, pxQueue), QUEUE, pxQueue); \
- if (TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, pxQueue) != TRACE_CLASS_MUTEX) \
- { \
- trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); \
- }
-
-/* Called when a message is sent from interrupt context, e.g., using xQueueSendFromISR */
-#undef traceQUEUE_SEND_FROM_ISR
-#define traceQUEUE_SEND_FROM_ISR( pxQueue ) \
- trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(TRACE_GET_OBJECT_EVENT_CODE(SEND_FROM_ISR, TRCSUCCESS, QUEUE, pxQueue), QUEUE, pxQueue); \
- trcKERNEL_HOOKS_SET_OBJECT_STATE(QUEUE, pxQueue, (uint8_t)(pxQueue->uxMessagesWaiting + 1));
-
-/* Called when a message send from interrupt context fails (since the queue was full) */
-#undef traceQUEUE_SEND_FROM_ISR_FAILED
-#define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ) \
- trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(TRACE_GET_OBJECT_EVENT_CODE(SEND_FROM_ISR, TRCFAILED, QUEUE, pxQueue), QUEUE, pxQueue);
-
-/* Called when a message is received in interrupt context, e.g., using xQueueReceiveFromISR */
-#undef traceQUEUE_RECEIVE_FROM_ISR
-#define traceQUEUE_RECEIVE_FROM_ISR( pxQueue ) \
- trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE_FROM_ISR, TRCSUCCESS, QUEUE, pxQueue), QUEUE, pxQueue); \
- trcKERNEL_HOOKS_SET_OBJECT_STATE(QUEUE, pxQueue, (uint8_t)(pxQueue->uxMessagesWaiting - 1));
-
-/* Called when a message receive from interrupt context fails (since the queue was empty) */
-#undef traceQUEUE_RECEIVE_FROM_ISR_FAILED
-#define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ) \
- trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE_FROM_ISR, TRCFAILED, QUEUE, pxQueue), QUEUE, pxQueue);
-
-#undef traceQUEUE_REGISTRY_ADD
-#define traceQUEUE_REGISTRY_ADD(object, name) prvTraceSetObjectName(TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, object), TRACE_GET_OBJECT_NUMBER(QUEUE, object), name);
-
-/* Called in vTaskPrioritySet */
-#undef traceTASK_PRIORITY_SET
-#define traceTASK_PRIORITY_SET( pxTask, uxNewPriority ) \
- trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE(TASK_PRIORITY_SET, pxTask, uxNewPriority);
-
-/* Called in vTaskPriorityInherit, which is called by Mutex operations */
-#undef traceTASK_PRIORITY_INHERIT
-#define traceTASK_PRIORITY_INHERIT( pxTask, uxNewPriority ) \
- trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE(TASK_PRIORITY_INHERIT, pxTask, uxNewPriority);
-
-/* Called in vTaskPriorityDisinherit, which is called by Mutex operations */
-#undef traceTASK_PRIORITY_DISINHERIT
-#define traceTASK_PRIORITY_DISINHERIT( pxTask, uxNewPriority ) \
- trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE(TASK_PRIORITY_DISINHERIT, pxTask, uxNewPriority);
-
-/* Called in vTaskResume */
-#undef traceTASK_RESUME
-#define traceTASK_RESUME( pxTaskToResume ) \
- trcKERNEL_HOOKS_TASK_RESUME(TASK_RESUME, pxTaskToResume);
-
-/* Called in vTaskResumeFromISR */
-#undef traceTASK_RESUME_FROM_ISR
-#define traceTASK_RESUME_FROM_ISR( pxTaskToResume ) \
- trcKERNEL_HOOKS_TASK_RESUME_FROM_ISR(TASK_RESUME_FROM_ISR, pxTaskToResume);
-
-
-#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X)
-
-#if (TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1)
-
-extern void vTraceStoreMemMangEvent(uint32_t ecode, uint32_t address, int32_t size);
-
-/* MALLOC and FREE are always stored, no matter if they happen inside filtered task */
-#undef traceMALLOC
-#define traceMALLOC( pvAddress, uiSize ) \
- if (pvAddress != 0) \
- vTraceStoreMemMangEvent(MEM_MALLOC_SIZE, ( uint32_t ) pvAddress, (int32_t)uiSize);
-
-#undef traceFREE
-#define traceFREE( pvAddress, uiSize ) \
- vTraceStoreMemMangEvent(MEM_FREE_SIZE, ( uint32_t ) pvAddress, -((int32_t)uiSize));
-
-#endif /* (TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1) */
-
-#if (TRC_CFG_INCLUDE_TIMER_EVENTS == 1)
-
-/* Called in timer.c - xTimerCreate */
-#undef traceTIMER_CREATE
-#define traceTIMER_CREATE(tmr) \
- trcKERNEL_HOOKS_OBJECT_CREATE(TIMER_CREATE, TIMER, tmr);
-
-#undef traceTIMER_CREATE_FAILED
-#define traceTIMER_CREATE_FAILED() \
- trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY(TIMER_CREATE_TRCFAILED, 0);
-
-/* Note that xCommandID can never be tmrCOMMAND_EXECUTE_CALLBACK (-1) since the trace macro is not called in that case */
-#undef traceTIMER_COMMAND_SEND
-#define traceTIMER_COMMAND_SEND(tmr, xCommandID, xOptionalValue, xReturn) \
- if (xCommandID > tmrCOMMAND_START_DONT_TRACE) \
- { \
- if (xCommandID == tmrCOMMAND_CHANGE_PERIOD) \
- { \
- if (xReturn == pdPASS) { \
- trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TIMER_CHANGE_PERIOD, TIMER, tmr, xOptionalValue); \
- } \
- else \
- { \
- trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TIMER_CHANGE_PERIOD_TRCFAILED, TIMER, tmr, xOptionalValue); \
- } \
- } \
- else if ((xCommandID == tmrCOMMAND_DELETE) && (xReturn == pdPASS)) \
- { \
- trcKERNEL_HOOKS_OBJECT_DELETE(TIMER_DELETE_OBJ, EVENTGROUP_OBJCLOSE_NAME_TRCSUCCESS + TRACE_GET_OBJECT_TRACE_CLASS(TIMER, tmr), EVENTGROUP_OBJCLOSE_PROP_TRCSUCCESS + TRACE_GET_OBJECT_TRACE_CLASS(TIMER, tmr), TIMER, tmr); \
- } \
- else \
- { \
- trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENTGROUP_TIMER + (uint32_t)xCommandID + ((xReturn == pdPASS) ? 0 : (TIMER_CREATE_TRCFAILED - TIMER_CREATE)), TIMER, tmr, xOptionalValue); \
- }\
- }
-
-#undef traceTIMER_EXPIRED
-#define traceTIMER_EXPIRED(tmr) \
- trcKERNEL_HOOKS_KERNEL_SERVICE(TIMER_EXPIRED, TIMER, tmr);
-
-#endif /* (TRC_CFG_INCLUDE_TIMER_EVENTS == 1) */
-
-#if (TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS == 1)
-
-#undef tracePEND_FUNC_CALL
-#define tracePEND_FUNC_CALL(func, arg1, arg2, ret) \
- if (ret == pdPASS){ \
- trcKERNEL_HOOKS_KERNEL_SERVICE(PEND_FUNC_CALL, TASK, xTimerGetTimerDaemonTaskHandle() ); \
- } \
- else \
- { \
- trcKERNEL_HOOKS_KERNEL_SERVICE(PEND_FUNC_CALL_TRCFAILED, TASK, xTimerGetTimerDaemonTaskHandle() ); \
- }
-
-#undef tracePEND_FUNC_CALL_FROM_ISR
-#define tracePEND_FUNC_CALL_FROM_ISR(func, arg1, arg2, ret) \
- if (! uiInEventGroupSetBitsFromISR) \
- prvTraceStoreKernelCall(PEND_FUNC_CALL_FROM_ISR, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(xTimerGetTimerDaemonTaskHandle()) ); \
- uiInEventGroupSetBitsFromISR = 0;
-
-#endif /* (TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS == 1) */
-
-#endif /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X) */
-
-#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1)
-
-#undef traceEVENT_GROUP_CREATE
-#define traceEVENT_GROUP_CREATE(eg) \
- trcKERNEL_HOOKS_OBJECT_CREATE(EVENT_GROUP_CREATE, EVENTGROUP, eg);
-
-#undef traceEVENT_GROUP_CREATE_FAILED
-#define traceEVENT_GROUP_CREATE_FAILED() \
- trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY(EVENT_GROUP_CREATE_TRCFAILED, 0);
-
-#undef traceEVENT_GROUP_DELETE
-#define traceEVENT_GROUP_DELETE(eg) \
- { TRACE_ALLOC_CRITICAL_SECTION(); \
- TRACE_ENTER_CRITICAL_SECTION(); \
- trcKERNEL_HOOKS_OBJECT_DELETE(EVENT_GROUP_DELETE_OBJ, EVENTGROUP_OBJCLOSE_NAME_TRCSUCCESS + TRACE_GET_OBJECT_TRACE_CLASS(EVENTGROUP, eg), EVENTGROUP_OBJCLOSE_NAME_TRCSUCCESS + TRACE_GET_OBJECT_TRACE_CLASS(EVENTGROUP, eg), EVENTGROUP, eg); \
- TRACE_EXIT_CRITICAL_SECTION(); }
-
-#undef traceEVENT_GROUP_SYNC_BLOCK
-#define traceEVENT_GROUP_SYNC_BLOCK(eg, bitsToSet, bitsToWaitFor) \
- trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_SYNC_TRCBLOCK, EVENTGROUP, eg, bitsToWaitFor);
-
-#undef traceEVENT_GROUP_SYNC_END
-#define traceEVENT_GROUP_SYNC_END(eg, bitsToSet, bitsToWaitFor, wasTimeout) \
- if (wasTimeout) \
- { \
- trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_SYNC_END_TRCFAILED, EVENTGROUP, eg, bitsToWaitFor); \
- } \
- else \
- { \
- trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_SYNC_END, EVENTGROUP, eg, bitsToWaitFor); \
- }
-
-#undef traceEVENT_GROUP_WAIT_BITS_BLOCK
-#define traceEVENT_GROUP_WAIT_BITS_BLOCK(eg, bitsToWaitFor) \
- trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_WAIT_BITS_TRCBLOCK, EVENTGROUP, eg, bitsToWaitFor); \
- trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED();
-
-#undef traceEVENT_GROUP_WAIT_BITS_END
-#define traceEVENT_GROUP_WAIT_BITS_END(eg, bitsToWaitFor, wasTimeout) \
- if (wasTimeout) \
- { \
- trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_WAIT_BITS_END_TRCFAILED, EVENTGROUP, eg, bitsToWaitFor); \
- } \
- else \
- { \
- trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_WAIT_BITS_END, EVENTGROUP, eg, bitsToWaitFor); \
- }
-
-#undef traceEVENT_GROUP_CLEAR_BITS
-#define traceEVENT_GROUP_CLEAR_BITS(eg, bitsToClear) \
- trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_CLEAR_BITS, EVENTGROUP, eg, bitsToClear);
-
-#undef traceEVENT_GROUP_CLEAR_BITS_FROM_ISR
-#define traceEVENT_GROUP_CLEAR_BITS_FROM_ISR(eg, bitsToClear) \
- trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM_FROM_ISR(EVENT_GROUP_CLEAR_BITS_FROM_ISR, EVENTGROUP, eg, bitsToClear);
-
-#undef traceEVENT_GROUP_SET_BITS
-#define traceEVENT_GROUP_SET_BITS(eg, bitsToSet) \
- trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_SET_BITS, EVENTGROUP, eg, bitsToSet);
-
-#undef traceEVENT_GROUP_SET_BITS_FROM_ISR
-#define traceEVENT_GROUP_SET_BITS_FROM_ISR(eg, bitsToSet) \
- trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM_FROM_ISR(EVENT_GROUP_SET_BITS_FROM_ISR, EVENTGROUP, eg, bitsToSet); \
- uiInEventGroupSetBitsFromISR = 1;
-
-#endif /* (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1) */
-
-#undef traceTASK_NOTIFY_TAKE
-#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0)
-#define traceTASK_NOTIFY_TAKE() \
- if (pxCurrentTCB->eNotifyState == eNotified){ \
- trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TRACE_TASK_NOTIFY_TAKE, TASK, pxCurrentTCB, xTicksToWait); \
- } \
- else{ \
- trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TRACE_TASK_NOTIFY_TAKE_TRCFAILED, TASK, pxCurrentTCB, xTicksToWait); \
- }
-#else /* TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0 */
-#define traceTASK_NOTIFY_TAKE( index ) \
- if (pxCurrentTCB->ucNotifyState[ ( index ) ] == taskNOTIFICATION_RECEIVED){ \
- trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TRACE_TASK_NOTIFY_TAKE, TASK, pxCurrentTCB, xTicksToWait); \
- }else{ \
- trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TRACE_TASK_NOTIFY_TAKE_TRCFAILED, TASK, pxCurrentTCB, xTicksToWait);}
-#endif /* TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0 */
-
-#undef traceTASK_NOTIFY_TAKE_BLOCK
-#define traceTASK_NOTIFY_TAKE_BLOCK() \
- trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TRACE_TASK_NOTIFY_TAKE_TRCBLOCK, TASK, pxCurrentTCB, xTicksToWait); \
- trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED();
-
-#undef traceTASK_NOTIFY_WAIT
-#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0)
-#define traceTASK_NOTIFY_WAIT() \
- if (TRACE_GET_OBJECT_FILTER(TASK, pxCurrentTCB) & CurrentFilterMask) \
- { \
- if (pxCurrentTCB->eNotifyState == eNotified) \
- prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxCurrentTCB), xTicksToWait); \
- else \
- prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT_TRCFAILED, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxCurrentTCB), xTicksToWait); \
- }
-#else /* TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0 */
-#define traceTASK_NOTIFY_WAIT( index ) \
- if (TRACE_GET_OBJECT_FILTER(TASK, pxCurrentTCB) & CurrentFilterMask) \
- { \
- if (pxCurrentTCB->ucNotifyState[ ( index ) ] == taskNOTIFICATION_RECEIVED) \
- prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxCurrentTCB), xTicksToWait); \
- else \
- prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT_TRCFAILED, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxCurrentTCB), xTicksToWait); \
- }
-#endif /* TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0 */
-
-#undef traceTASK_NOTIFY_WAIT_BLOCK
-#define traceTASK_NOTIFY_WAIT_BLOCK() \
- if (TRACE_GET_OBJECT_FILTER(TASK, pxCurrentTCB) & CurrentFilterMask) \
- prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT_TRCBLOCK, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxCurrentTCB), xTicksToWait); \
- trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED();
-
-#undef traceTASK_NOTIFY
-#define traceTASK_NOTIFY() \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(TASK, xTaskToNotify) & CurrentFilterMask) \
- prvTraceStoreKernelCall(TRACE_TASK_NOTIFY, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(xTaskToNotify));
-
-#undef traceTASK_NOTIFY_FROM_ISR
-#define traceTASK_NOTIFY_FROM_ISR() \
- if (TRACE_GET_OBJECT_FILTER(TASK, xTaskToNotify) & CurrentFilterMask) \
- prvTraceStoreKernelCall(TRACE_TASK_NOTIFY_FROM_ISR, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(xTaskToNotify));
-
-#undef traceTASK_NOTIFY_GIVE_FROM_ISR
-#define traceTASK_NOTIFY_GIVE_FROM_ISR() \
- if (TRACE_GET_OBJECT_FILTER(TASK, xTaskToNotify) & CurrentFilterMask) \
- prvTraceStoreKernelCall(TRACE_TASK_NOTIFY_GIVE_FROM_ISR, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(xTaskToNotify));
-
-#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1)
-
-#undef traceSTREAM_BUFFER_CREATE
-#define traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer ) \
- trcKERNEL_HOOKS_OBJECT_CREATE(TRACE_GET_OBJECT_EVENT_CODE(CREATE_OBJ, TRCSUCCESS, STREAMBUFFER, pxStreamBuffer), STREAMBUFFER, pxStreamBuffer);
-
-#undef traceSTREAM_BUFFER_CREATE_FAILED
-#define traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ) \
- trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY(TRACE_GET_CLASS_EVENT_CODE(CREATE_OBJ, TRCFAILED, STREAMBUFFER, xIsMessageBuffer), 0);
-
-#undef traceSTREAM_BUFFER_CREATE_STATIC_FAILED
-#define traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer ) \
- traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer )
-
-#undef traceSTREAM_BUFFER_DELETE
-#define traceSTREAM_BUFFER_DELETE( xStreamBuffer ) \
- trcKERNEL_HOOKS_OBJECT_DELETE(TRACE_GET_OBJECT_EVENT_CODE(DELETE_OBJ, TRCSUCCESS, STREAMBUFFER, xStreamBuffer), TRACE_GET_OBJECT_EVENT_CODE(OBJCLOSE_NAME, TRCSUCCESS, STREAMBUFFER, xStreamBuffer), TRACE_GET_OBJECT_EVENT_CODE(OBJCLOSE_PROP, TRCSUCCESS, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer);
-
-#undef traceSTREAM_BUFFER_RESET
-#define traceSTREAM_BUFFER_RESET( xStreamBuffer ) \
- trcKERNEL_HOOKS_KERNEL_SERVICE(prvGetStreamBufferType(xStreamBuffer) > 0 ? TRACE_MESSAGEBUFFER_RESET : TRACE_STREAMBUFFER_RESET, STREAMBUFFER, xStreamBuffer); \
- trcKERNEL_HOOKS_SET_OBJECT_STATE(STREAMBUFFER, xStreamBuffer, 0);
-
-#undef traceSTREAM_BUFFER_SEND
-#define traceSTREAM_BUFFER_SEND( xStreamBuffer, xReturn ) \
- trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND, TRCSUCCESS, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); \
- trcKERNEL_HOOKS_SET_OBJECT_STATE(STREAMBUFFER, xStreamBuffer, prvBytesInBuffer(xStreamBuffer));
-
-#undef traceBLOCKING_ON_STREAM_BUFFER_SEND
-#define traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer ) \
- trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND, TRCBLOCK, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer);
-
-#undef traceSTREAM_BUFFER_SEND_FAILED
-#define traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer ) \
- trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND, TRCFAILED, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer);
-
-#undef traceSTREAM_BUFFER_RECEIVE
-#define traceSTREAM_BUFFER_RECEIVE( xStreamBuffer, xReceivedLength ) \
- trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE, TRCSUCCESS, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); \
- trcKERNEL_HOOKS_SET_OBJECT_STATE(STREAMBUFFER, xStreamBuffer, prvBytesInBuffer(xStreamBuffer));
-
-
-#undef traceBLOCKING_ON_STREAM_BUFFER_RECEIVE
-#define traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer ) \
- trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE, TRCBLOCK, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer);
-
-#undef traceSTREAM_BUFFER_RECEIVE_FAILED
-#define traceSTREAM_BUFFER_RECEIVE_FAILED( xStreamBuffer ) \
- trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE, TRCFAILED, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer);
-
-#undef traceSTREAM_BUFFER_SEND_FROM_ISR
-#define traceSTREAM_BUFFER_SEND_FROM_ISR( xStreamBuffer, xReturn ) \
- if( xReturn > ( size_t ) 0 ) \
- { \
- trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(TRACE_GET_OBJECT_EVENT_CODE(SEND_FROM_ISR, TRCSUCCESS, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); \
- trcKERNEL_HOOKS_SET_OBJECT_STATE(STREAMBUFFER, xStreamBuffer, prvBytesInBuffer(xStreamBuffer)); \
- } \
- else \
- { \
- trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(TRACE_GET_OBJECT_EVENT_CODE(SEND_FROM_ISR, TRCFAILED, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); \
- }
-
-#undef traceSTREAM_BUFFER_RECEIVE_FROM_ISR
-#define traceSTREAM_BUFFER_RECEIVE_FROM_ISR( xStreamBuffer, xReceivedLength ) \
- if( xReceivedLength > ( size_t ) 0 ) \
- { \
- trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE_FROM_ISR, TRCSUCCESS, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); \
- trcKERNEL_HOOKS_SET_OBJECT_STATE(STREAMBUFFER, xStreamBuffer, prvBytesInBuffer(xStreamBuffer)); \
- } \
- else \
- { \
- trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE_FROM_ISR, TRCFAILED, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); \
- }
-
-#endif /* (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1) */
-
-#endif /* (TRC_CFG_SCHEDULING_ONLY == 0) */
-
-#endif /*#if TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT */
-
-/******************************************************************************/
-/*** Definitions for Streaming mode *******************************************/
-/******************************************************************************/
-#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
-
-/*******************************************************************************
-* vTraceStoreKernelObjectName
-*
-* Set the name for a kernel object (defined by its address).
-******************************************************************************/
-void vTraceStoreKernelObjectName(void* object, const char* name);
-
-/*******************************************************************************
-* prvIsNewTCB
-*
-* Tells if this task is already executing, or if there has been a task-switch.
-* Assumed to be called within a trace hook in kernel context.
-*******************************************************************************/
-uint32_t prvIsNewTCB(void* pNewTCB);
-
-#define TRACE_GET_CURRENT_TASK() prvTraceGetCurrentTaskHandle()
-
-/*************************************************************************/
-/* KERNEL SPECIFIC OBJECT CONFIGURATION */
-/*************************************************************************/
-
-/*******************************************************************************
- * The event codes - should match the offline config file.
- ******************************************************************************/
-
-/*** Event codes for streaming - should match the Tracealyzer config file *****/
-#define PSF_EVENT_NULL_EVENT 0x00
-
-#define PSF_EVENT_TRACE_START 0x01
-#define PSF_EVENT_TS_CONFIG 0x02
-#define PSF_EVENT_OBJ_NAME 0x03
-#define PSF_EVENT_TASK_PRIORITY 0x04
-#define PSF_EVENT_TASK_PRIO_INHERIT 0x05
-#define PSF_EVENT_TASK_PRIO_DISINHERIT 0x06
-#define PSF_EVENT_DEFINE_ISR 0x07
-
-#define PSF_EVENT_TASK_CREATE 0x10
-#define PSF_EVENT_QUEUE_CREATE 0x11
-#define PSF_EVENT_SEMAPHORE_BINARY_CREATE 0x12
-#define PSF_EVENT_MUTEX_CREATE 0x13
-#define PSF_EVENT_TIMER_CREATE 0x14
-#define PSF_EVENT_EVENTGROUP_CREATE 0x15
-#define PSF_EVENT_SEMAPHORE_COUNTING_CREATE 0x16
-#define PSF_EVENT_MUTEX_RECURSIVE_CREATE 0x17
-#define PSF_EVENT_STREAMBUFFER_CREATE 0x18
-#define PSF_EVENT_MESSAGEBUFFER_CREATE 0x19
-
-#define PSF_EVENT_TASK_DELETE 0x20
-#define PSF_EVENT_QUEUE_DELETE 0x21
-#define PSF_EVENT_SEMAPHORE_DELETE 0x22
-#define PSF_EVENT_MUTEX_DELETE 0x23
-#define PSF_EVENT_TIMER_DELETE 0x24
-#define PSF_EVENT_EVENTGROUP_DELETE 0x25
-#define PSF_EVENT_STREAMBUFFER_DELETE 0x28
-#define PSF_EVENT_MESSAGEBUFFER_DELETE 0x29
-
-#define PSF_EVENT_TASK_READY 0x30
-#define PSF_EVENT_NEW_TIME 0x31
-#define PSF_EVENT_NEW_TIME_SCHEDULER_SUSPENDED 0x32
-#define PSF_EVENT_ISR_BEGIN 0x33
-#define PSF_EVENT_ISR_RESUME 0x34
-#define PSF_EVENT_TS_BEGIN 0x35
-#define PSF_EVENT_TS_RESUME 0x36
-#define PSF_EVENT_TASK_ACTIVATE 0x37
-
-#define PSF_EVENT_MALLOC 0x38
-#define PSF_EVENT_FREE 0x39
-
-#define PSF_EVENT_LOWPOWER_BEGIN 0x3A
-#define PSF_EVENT_LOWPOWER_END 0x3B
-
-#define PSF_EVENT_IFE_NEXT 0x3C
-#define PSF_EVENT_IFE_DIRECT 0x3D
-
-#define PSF_EVENT_TASK_CREATE_FAILED 0x40
-#define PSF_EVENT_QUEUE_CREATE_FAILED 0x41
-#define PSF_EVENT_SEMAPHORE_BINARY_CREATE_FAILED 0x42
-#define PSF_EVENT_MUTEX_CREATE_FAILED 0x43
-#define PSF_EVENT_TIMER_CREATE_FAILED 0x44
-#define PSF_EVENT_EVENTGROUP_CREATE_FAILED 0x45
-#define PSF_EVENT_SEMAPHORE_COUNTING_CREATE_FAILED 0x46
-#define PSF_EVENT_MUTEX_RECURSIVE_CREATE_FAILED 0x47
-#define PSF_EVENT_STREAMBUFFER_CREATE_FAILED 0x49
-#define PSF_EVENT_MESSAGEBUFFER_CREATE_FAILED 0x4A
-
-#define PSF_EVENT_TIMER_DELETE_FAILED 0x48
-
-#define PSF_EVENT_QUEUE_SEND 0x50
-#define PSF_EVENT_SEMAPHORE_GIVE 0x51
-#define PSF_EVENT_MUTEX_GIVE 0x52
-
-#define PSF_EVENT_QUEUE_SEND_FAILED 0x53
-#define PSF_EVENT_SEMAPHORE_GIVE_FAILED 0x54
-#define PSF_EVENT_MUTEX_GIVE_FAILED 0x55
-
-#define PSF_EVENT_QUEUE_SEND_BLOCK 0x56
-#define PSF_EVENT_SEMAPHORE_GIVE_BLOCK 0x57
-#define PSF_EVENT_MUTEX_GIVE_BLOCK 0x58
-
-#define PSF_EVENT_QUEUE_SEND_FROMISR 0x59
-#define PSF_EVENT_SEMAPHORE_GIVE_FROMISR 0x5A
-
-#define PSF_EVENT_QUEUE_SEND_FROMISR_FAILED 0x5C
-#define PSF_EVENT_SEMAPHORE_GIVE_FROMISR_FAILED 0x5D
-
-#define PSF_EVENT_QUEUE_RECEIVE 0x60
-#define PSF_EVENT_SEMAPHORE_TAKE 0x61
-#define PSF_EVENT_MUTEX_TAKE 0x62
-
-#define PSF_EVENT_QUEUE_RECEIVE_FAILED 0x63
-#define PSF_EVENT_SEMAPHORE_TAKE_FAILED 0x64
-#define PSF_EVENT_MUTEX_TAKE_FAILED 0x65
-
-#define PSF_EVENT_QUEUE_RECEIVE_BLOCK 0x66
-#define PSF_EVENT_SEMAPHORE_TAKE_BLOCK 0x67
-#define PSF_EVENT_MUTEX_TAKE_BLOCK 0x68
-
-#define PSF_EVENT_QUEUE_RECEIVE_FROMISR 0x69
-#define PSF_EVENT_SEMAPHORE_TAKE_FROMISR 0x6A
-
-#define PSF_EVENT_QUEUE_RECEIVE_FROMISR_FAILED 0x6C
-#define PSF_EVENT_SEMAPHORE_TAKE_FROMISR_FAILED 0x6D
-
-#define PSF_EVENT_QUEUE_PEEK 0x70
-#define PSF_EVENT_SEMAPHORE_PEEK 0x71
-#define PSF_EVENT_MUTEX_PEEK 0x72
-
-#define PSF_EVENT_QUEUE_PEEK_FAILED 0x73
-#define PSF_EVENT_SEMAPHORE_PEEK_FAILED 0x74
-#define PSF_EVENT_MUTEX_PEEK_FAILED 0x75
-
-#define PSF_EVENT_QUEUE_PEEK_BLOCK 0x76
-#define PSF_EVENT_SEMAPHORE_PEEK_BLOCK 0x77
-#define PSF_EVENT_MUTEX_PEEK_BLOCK 0x78
-
-#define PSF_EVENT_TASK_DELAY_UNTIL 0x79
-#define PSF_EVENT_TASK_DELAY 0x7A
-#define PSF_EVENT_TASK_SUSPEND 0x7B
-#define PSF_EVENT_TASK_RESUME 0x7C
-#define PSF_EVENT_TASK_RESUME_FROMISR 0x7D
-
-#define PSF_EVENT_TIMER_PENDFUNCCALL 0x80
-#define PSF_EVENT_TIMER_PENDFUNCCALL_FROMISR 0x81
-#define PSF_EVENT_TIMER_PENDFUNCCALL_FAILED 0x82
-#define PSF_EVENT_TIMER_PENDFUNCCALL_FROMISR_FAILED 0x83
-
-#define PSF_EVENT_USER_EVENT 0x90
-
-#define PSF_EVENT_TIMER_START 0xA0
-#define PSF_EVENT_TIMER_RESET 0xA1
-#define PSF_EVENT_TIMER_STOP 0xA2
-#define PSF_EVENT_TIMER_CHANGEPERIOD 0xA3
-#define PSF_EVENT_TIMER_START_FROMISR 0xA4
-#define PSF_EVENT_TIMER_RESET_FROMISR 0xA5
-#define PSF_EVENT_TIMER_STOP_FROMISR 0xA6
-#define PSF_EVENT_TIMER_CHANGEPERIOD_FROMISR 0xA7
-#define PSF_EVENT_TIMER_START_FAILED 0xA8
-#define PSF_EVENT_TIMER_RESET_FAILED 0xA9
-#define PSF_EVENT_TIMER_STOP_FAILED 0xAA
-#define PSF_EVENT_TIMER_CHANGEPERIOD_FAILED 0xAB
-#define PSF_EVENT_TIMER_START_FROMISR_FAILED 0xAC
-#define PSF_EVENT_TIMER_RESET_FROMISR_FAILED 0xAD
-#define PSF_EVENT_TIMER_STOP_FROMISR_FAILED 0xAE
-#define PSF_EVENT_TIMER_CHANGEPERIOD_FROMISR_FAILED 0xAF
-
-#define PSF_EVENT_EVENTGROUP_SYNC 0xB0
-#define PSF_EVENT_EVENTGROUP_WAITBITS 0xB1
-#define PSF_EVENT_EVENTGROUP_CLEARBITS 0xB2
-#define PSF_EVENT_EVENTGROUP_CLEARBITS_FROMISR 0xB3
-#define PSF_EVENT_EVENTGROUP_SETBITS 0xB4
-#define PSF_EVENT_EVENTGROUP_SETBITS_FROMISR 0xB5
-#define PSF_EVENT_EVENTGROUP_SYNC_BLOCK 0xB6
-#define PSF_EVENT_EVENTGROUP_WAITBITS_BLOCK 0xB7
-#define PSF_EVENT_EVENTGROUP_SYNC_FAILED 0xB8
-#define PSF_EVENT_EVENTGROUP_WAITBITS_FAILED 0xB9
-
-#define PSF_EVENT_QUEUE_SEND_FRONT 0xC0
-#define PSF_EVENT_QUEUE_SEND_FRONT_FAILED 0xC1
-#define PSF_EVENT_QUEUE_SEND_FRONT_BLOCK 0xC2
-#define PSF_EVENT_QUEUE_SEND_FRONT_FROMISR 0xC3
-#define PSF_EVENT_QUEUE_SEND_FRONT_FROMISR_FAILED 0xC4
-#define PSF_EVENT_MUTEX_GIVE_RECURSIVE 0xC5
-#define PSF_EVENT_MUTEX_GIVE_RECURSIVE_FAILED 0xC6
-#define PSF_EVENT_MUTEX_TAKE_RECURSIVE 0xC7
-#define PSF_EVENT_MUTEX_TAKE_RECURSIVE_FAILED 0xC8
-
-#define PSF_EVENT_TASK_NOTIFY 0xC9
-#define PSF_EVENT_TASK_NOTIFY_TAKE 0xCA
-#define PSF_EVENT_TASK_NOTIFY_TAKE_BLOCK 0xCB
-#define PSF_EVENT_TASK_NOTIFY_TAKE_FAILED 0xCC
-#define PSF_EVENT_TASK_NOTIFY_WAIT 0xCD
-#define PSF_EVENT_TASK_NOTIFY_WAIT_BLOCK 0xCE
-#define PSF_EVENT_TASK_NOTIFY_WAIT_FAILED 0xCF
-#define PSF_EVENT_TASK_NOTIFY_FROM_ISR 0xD0
-#define PSF_EVENT_TASK_NOTIFY_GIVE_FROM_ISR 0xD1
-
-#define PSF_EVENT_TIMER_EXPIRED 0xD2
-
-#define PSF_EVENT_STREAMBUFFER_SEND 0xD3
-#define PSF_EVENT_STREAMBUFFER_SEND_BLOCK 0xD4
-#define PSF_EVENT_STREAMBUFFER_SEND_FAILED 0xD5
-#define PSF_EVENT_STREAMBUFFER_RECEIVE 0xD6
-#define PSF_EVENT_STREAMBUFFER_RECEIVE_BLOCK 0xD7
-#define PSF_EVENT_STREAMBUFFER_RECEIVE_FAILED 0xD8
-#define PSF_EVENT_STREAMBUFFER_SEND_FROM_ISR 0xD9
-#define PSF_EVENT_STREAMBUFFER_SEND_FROM_ISR_FAILED 0xDA
-#define PSF_EVENT_STREAMBUFFER_RECEIVE_FROM_ISR 0xDB
-#define PSF_EVENT_STREAMBUFFER_RECEIVE_FROM_ISR_FAILED 0xDC
-#define PSF_EVENT_STREAMBUFFER_RESET 0xDD
-
-#define PSF_EVENT_MESSAGEBUFFER_SEND 0xDE
-#define PSF_EVENT_MESSAGEBUFFER_SEND_BLOCK 0xDF
-#define PSF_EVENT_MESSAGEBUFFER_SEND_FAILED 0xE0
-#define PSF_EVENT_MESSAGEBUFFER_RECEIVE 0xE1
-#define PSF_EVENT_MESSAGEBUFFER_RECEIVE_BLOCK 0xE2
-#define PSF_EVENT_MESSAGEBUFFER_RECEIVE_FAILED 0xE3
-#define PSF_EVENT_MESSAGEBUFFER_SEND_FROM_ISR 0xE4
-#define PSF_EVENT_MESSAGEBUFFER_SEND_FROM_ISR_FAILED 0xE5
-#define PSF_EVENT_MESSAGEBUFFER_RECEIVE_FROM_ISR 0xE6
-#define PSF_EVENT_MESSAGEBUFFER_RECEIVE_FROM_ISR_FAILED 0xE7
-#define PSF_EVENT_MESSAGEBUFFER_RESET 0xE8
-
-/*** The trace macros for streaming ******************************************/
-
-/* A macro that will update the tick count when returning from tickless idle */
-#undef traceINCREASE_TICK_COUNT
-/* Note: This can handle time adjustments of max 2^32 ticks, i.e., 35 seconds at 120 MHz. Thus, tick-less idle periods longer than 2^32 ticks will appear "compressed" on the time line.*/
-#define traceINCREASE_TICK_COUNT( xCount ) { extern uint32_t uiTraceTickCount; uiTraceTickCount += xCount; }
-
-#if (TRC_CFG_INCLUDE_OSTICK_EVENTS == 1)
-#define OS_TICK_EVENT(uxSchedulerSuspended, xTickCount) if (uxSchedulerSuspended == (unsigned portBASE_TYPE) pdFALSE) { prvTraceStoreEvent1(PSF_EVENT_NEW_TIME, (uint32_t)(xTickCount + 1)); }
-#else
-#define OS_TICK_EVENT(uxSchedulerSuspended, xTickCount)
-#endif
-
-/* Called on each OS tick. Will call uiPortGetTimestamp to make sure it is called at least once every OS tick. */
-#undef traceTASK_INCREMENT_TICK
-#if TRC_CFG_FREERTOS_VERSION <= TRC_FREERTOS_VERSION_7_4
-#define traceTASK_INCREMENT_TICK( xTickCount ) \
- if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || uxMissedTicks == 0) { extern uint32_t uiTraceTickCount; uiTraceTickCount++; } \
- OS_TICK_EVENT(uxSchedulerSuspended, xTickCount)
-#else
-#define traceTASK_INCREMENT_TICK( xTickCount ) \
- if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || uxPendedTicks == 0) { extern uint32_t uiTraceTickCount; uiTraceTickCount++; } \
- OS_TICK_EVENT(uxSchedulerSuspended, xTickCount)
-#endif /* TRC_CFG_FREERTOS_VERSION <= TRC_FREERTOS_VERSION_7_4 */
-
-/* Called on each task-switch */
-#undef traceTASK_SWITCHED_IN
-#define traceTASK_SWITCHED_IN() \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- { \
- if (prvIsNewTCB(pxCurrentTCB)) \
- { \
- prvTraceStoreEvent2(PSF_EVENT_TASK_ACTIVATE, (uint32_t)pxCurrentTCB, pxCurrentTCB->uxPriority); \
- } \
- }
-
-/* Called for each task that becomes ready */
-#if (TRC_CFG_INCLUDE_READY_EVENTS == 1)
-#undef traceMOVED_TASK_TO_READY_STATE
-#define traceMOVED_TASK_TO_READY_STATE( pxTCB ) \
- if (TRACE_GET_OBJECT_FILTER(TASK, pxTCB) & CurrentFilterMask) \
- prvTraceStoreEvent1(PSF_EVENT_TASK_READY, (uint32_t)pxTCB);
-#endif
-
-#undef traceTASK_CREATE
-#if TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0
-#define traceTASK_CREATE(pxNewTCB) \
- if (pxNewTCB != NULL) \
- { \
- prvTraceSaveSymbol(pxNewTCB, pxNewTCB->pcTaskName); \
- prvTraceSaveObjectData(pxNewTCB, pxNewTCB->uxPriority); \
- prvTraceStoreStringEvent(1, PSF_EVENT_OBJ_NAME, pxNewTCB->pcTaskName, pxNewTCB); \
- TRACE_SET_OBJECT_FILTER(TASK, pxNewTCB, CurrentFilterGroup); \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(TASK, pxNewTCB) & CurrentFilterMask) \
- prvTraceStoreEvent2(PSF_EVENT_TASK_CREATE, (uint32_t)pxNewTCB, pxNewTCB->uxPriority); \
- }
-#else /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */
-#define traceTASK_CREATE(pxNewTCB) \
- if (pxNewTCB != NULL) \
- { \
- prvTraceSaveSymbol(pxNewTCB, (const char*)pcName); \
- prvTraceSaveObjectData(pxNewTCB, uxPriority); \
- prvTraceStoreStringEvent(1, PSF_EVENT_OBJ_NAME, (const char*)pcName, pxNewTCB); \
- TRACE_SET_OBJECT_FILTER(TASK, pxNewTCB, CurrentFilterGroup); \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(TASK, pxNewTCB) & CurrentFilterMask) \
- prvTraceStoreEvent2(PSF_EVENT_TASK_CREATE, (uint32_t)pxNewTCB, uxPriority); \
- }
-#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */
-
-/* Called in vTaskCreate, if it fails (typically if the stack can not be allocated) */
-#undef traceTASK_CREATE_FAILED
-#define traceTASK_CREATE_FAILED() \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- prvTraceStoreEvent0(PSF_EVENT_TASK_CREATE_FAILED);
-
-/* Called on vTaskDelete */
-#undef traceTASK_DELETE // We don't allow for filtering out "delete" events. They are important and not very frequent. Moreover, we can't exclude create events, so this should be symmetrical.
-#define traceTASK_DELETE( pxTaskToDelete ) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(TASK, pxTaskToDelete) & CurrentFilterMask) \
- prvTraceStoreEvent2(PSF_EVENT_TASK_DELETE, (uint32_t)pxTaskToDelete, (pxTaskToDelete != NULL) ? (pxTaskToDelete->uxPriority) : 0); \
- prvTraceDeleteSymbol(pxTaskToDelete); \
- prvTraceDeleteObjectData(pxTaskToDelete);
-
-#if (TRC_CFG_SCHEDULING_ONLY == 0)
-
-#if (defined(configUSE_TICKLESS_IDLE) && configUSE_TICKLESS_IDLE != 0)
-
-#undef traceLOW_POWER_IDLE_BEGIN
-#define traceLOW_POWER_IDLE_BEGIN() \
- { \
- prvTraceStoreEvent1(PSF_EVENT_LOWPOWER_BEGIN, xExpectedIdleTime); \
- }
-
-#undef traceLOW_POWER_IDLE_END
-#define traceLOW_POWER_IDLE_END() \
- { \
- prvTraceStoreEvent0(PSF_EVENT_LOWPOWER_END); \
- }
-
-#endif /* (defined(configUSE_TICKLESS_IDLE) && configUSE_TICKLESS_IDLE != 0) */
-
-/* Called on vTaskSuspend */
-#undef traceTASK_SUSPEND
-#define traceTASK_SUSPEND( pxTaskToSuspend ) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(TASK, pxTaskToSuspend) & CurrentFilterMask) \
- prvTraceStoreEvent1(PSF_EVENT_TASK_SUSPEND, (uint32_t)pxTaskToSuspend);
-
-/* Called on vTaskDelay - note the use of FreeRTOS variable xTicksToDelay */
-#undef traceTASK_DELAY
-#define traceTASK_DELAY() \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- prvTraceStoreEvent1(PSF_EVENT_TASK_DELAY, xTicksToDelay);
-
-/* Called on vTaskDelayUntil - note the use of FreeRTOS variable xTimeToWake */
-#undef traceTASK_DELAY_UNTIL
-#if TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0
-#define traceTASK_DELAY_UNTIL(xTimeToWake) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- prvTraceStoreEvent1(PSF_EVENT_TASK_DELAY_UNTIL, (uint32_t)xTimeToWake);
-#else /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */
-#define traceTASK_DELAY_UNTIL() \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- prvTraceStoreEvent1(PSF_EVENT_TASK_DELAY_UNTIL, (uint32_t)xTimeToWake);
-#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */
-
-#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0)
-#define traceQUEUE_CREATE_HELPER() \
- case queueQUEUE_TYPE_MUTEX: \
- prvTraceStoreEvent1(PSF_EVENT_MUTEX_CREATE, (uint32_t)pxNewQueue); \
- break; \
- case queueQUEUE_TYPE_RECURSIVE_MUTEX: \
- prvTraceStoreEvent1(PSF_EVENT_MUTEX_RECURSIVE_CREATE, (uint32_t)pxNewQueue); \
- break;
-#else
-#define traceQUEUE_CREATE_HELPER()
-#endif /* (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0) */
-
-/* Called in xQueueCreate, and thereby for all other object based on queues, such as semaphores. */
-#undef traceQUEUE_CREATE
-#define traceQUEUE_CREATE( pxNewQueue )\
- TRACE_SET_OBJECT_FILTER(QUEUE, pxNewQueue, CurrentFilterGroup); \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- { \
- if (TRACE_GET_OBJECT_FILTER(QUEUE, pxNewQueue) & CurrentFilterMask) \
- { \
- switch (pxNewQueue->ucQueueType) \
- { \
- case queueQUEUE_TYPE_BASE: \
- prvTraceStoreEvent2(PSF_EVENT_QUEUE_CREATE, (uint32_t)pxNewQueue, uxQueueLength); \
- break; \
- case queueQUEUE_TYPE_BINARY_SEMAPHORE: \
- prvTraceStoreEvent1(PSF_EVENT_SEMAPHORE_BINARY_CREATE, (uint32_t)pxNewQueue); \
- break; \
- traceQUEUE_CREATE_HELPER() \
- } \
- } \
- }
-
-#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0)
-#define traceQUEUE_CREATE_FAILED_HELPER() \
- case queueQUEUE_TYPE_MUTEX: \
- prvTraceStoreEvent1(PSF_EVENT_MUTEX_CREATE_FAILED, 0); \
- break; \
- case queueQUEUE_TYPE_RECURSIVE_MUTEX: \
- prvTraceStoreEvent1(PSF_EVENT_MUTEX_RECURSIVE_CREATE_FAILED, 0); \
- break;
-#else
-#define traceQUEUE_CREATE_FAILED_HELPER()
-#endif /* (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0) */
-
-/* Called in xQueueCreate, if the queue creation fails */
-#undef traceQUEUE_CREATE_FAILED
-#define traceQUEUE_CREATE_FAILED( queueType ) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- { \
- switch (queueType) \
- { \
- case queueQUEUE_TYPE_BASE: \
- prvTraceStoreEvent2(PSF_EVENT_QUEUE_CREATE_FAILED, 0, uxQueueLength); \
- break; \
- case queueQUEUE_TYPE_BINARY_SEMAPHORE: \
- prvTraceStoreEvent1(PSF_EVENT_SEMAPHORE_BINARY_CREATE_FAILED, 0); \
- break; \
- traceQUEUE_CREATE_FAILED_HELPER() \
- } \
- }
-
-#undef traceQUEUE_DELETE // We don't allow for filtering out "delete" events. They are important and not very frequent. Moreover, we can't exclude create events, so this should be symmetrical.
-#define traceQUEUE_DELETE( pxQueue ) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- { \
- if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \
- { \
- switch (pxQueue->ucQueueType) \
- { \
- case queueQUEUE_TYPE_BASE: \
- prvTraceStoreEvent2(PSF_EVENT_QUEUE_DELETE, (uint32_t)pxQueue, (pxQueue != NULL) ? (pxQueue->uxMessagesWaiting) : 0); \
- break; \
- case queueQUEUE_TYPE_MUTEX: \
- case queueQUEUE_TYPE_RECURSIVE_MUTEX: \
- prvTraceStoreEvent2(PSF_EVENT_MUTEX_DELETE, (uint32_t)pxQueue, (pxQueue != NULL) ? (pxQueue->uxMessagesWaiting) : 0); \
- break; \
- case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \
- case queueQUEUE_TYPE_BINARY_SEMAPHORE: \
- prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_DELETE, (uint32_t)pxQueue, (pxQueue != NULL) ? (pxQueue->uxMessagesWaiting) : 0); \
- break; \
- } \
- } \
- } \
- prvTraceDeleteSymbol(pxQueue);
-
-/* Called in xQueueCreateCountingSemaphore, if the queue creation fails */
-#undef traceCREATE_COUNTING_SEMAPHORE
-#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X)
-#define traceCREATE_COUNTING_SEMAPHORE() \
- TRACE_SET_OBJECT_FILTER(QUEUE, xHandle, CurrentFilterGroup); \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(QUEUE, xHandle) & CurrentFilterMask) \
- prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE, (uint32_t)xHandle, uxMaxCount)
-#elif (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_7_5_OR_7_6)
-#define traceCREATE_COUNTING_SEMAPHORE() \
- TRACE_SET_OBJECT_FILTER(QUEUE, xHandle, CurrentFilterGroup); \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(QUEUE, xHandle) & CurrentFilterMask) \
- prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE, (uint32_t)xHandle, uxInitialCount);
-#elif (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_7_4)
-#define traceCREATE_COUNTING_SEMAPHORE() \
- TRACE_SET_OBJECT_FILTER(QUEUE, xHandle, CurrentFilterGroup); \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(QUEUE, xHandle) & CurrentFilterMask) \
- prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE, (uint32_t)xHandle, uxCountValue);
-#else
-#define traceCREATE_COUNTING_SEMAPHORE() \
- TRACE_SET_OBJECT_FILTER(QUEUE, pxHandle, CurrentFilterGroup); \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(QUEUE, pxHandle) & CurrentFilterMask) \
- prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE, (uint32_t)pxHandle, uxCountValue);
-#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X */
-
-#undef traceCREATE_COUNTING_SEMAPHORE_FAILED
-#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X)
-#define traceCREATE_COUNTING_SEMAPHORE_FAILED() \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE_FAILED, 0, uxMaxCount);
-#elif (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_7_5_OR_7_6)
-#define traceCREATE_COUNTING_SEMAPHORE_FAILED() \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE_FAILED, 0, uxInitialCount);
-#elif (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_7_4)
-#define traceCREATE_COUNTING_SEMAPHORE_FAILED() \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE_FAILED, 0, uxCountValue);
-#else
-#define traceCREATE_COUNTING_SEMAPHORE_FAILED() \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE_FAILED, 0, uxCountValue);
-#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X */
-
-
-/* This macro is not necessary as of FreeRTOS v9.0.0 */
-#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0)
-/* Called in xQueueCreateMutex, and thereby also from xSemaphoreCreateMutex and xSemaphoreCreateRecursiveMutex */
-#undef traceCREATE_MUTEX
-#define traceCREATE_MUTEX( pxNewQueue ) \
- TRACE_SET_OBJECT_FILTER(QUEUE, pxNewQueue, CurrentFilterGroup); \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- { \
- if (TRACE_GET_OBJECT_FILTER(QUEUE, pxNewQueue) & CurrentFilterMask) \
- { \
- switch (pxNewQueue->ucQueueType) \
- { \
- case queueQUEUE_TYPE_MUTEX: \
- prvTraceStoreEvent1(PSF_EVENT_MUTEX_CREATE, (uint32_t)pxNewQueue); \
- break; \
- case queueQUEUE_TYPE_RECURSIVE_MUTEX: \
- prvTraceStoreEvent1(PSF_EVENT_MUTEX_RECURSIVE_CREATE, (uint32_t)pxNewQueue); \
- break; \
- } \
- }\
- }
-
-/* Called in xQueueCreateMutex when the operation fails (when memory allocation fails) */
-#undef traceCREATE_MUTEX_FAILED
-#define traceCREATE_MUTEX_FAILED() \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- prvTraceStoreEvent1(PSF_EVENT_MUTEX_CREATE_FAILED, 0);
-#endif /* (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0) */
-
-/* Called when a message is sent to a queue */ /* CS IS NEW ! */
-#undef traceQUEUE_SEND
-#define traceQUEUE_SEND( pxQueue ) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \
- switch (pxQueue->ucQueueType) \
- { \
- case queueQUEUE_TYPE_BASE: \
- prvTraceStoreEvent2(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND : PSF_EVENT_QUEUE_SEND_FRONT, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting + 1); \
- break; \
- case queueQUEUE_TYPE_BINARY_SEMAPHORE: \
- case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \
- prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_GIVE, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting + 1); \
- break; \
- case queueQUEUE_TYPE_MUTEX: \
- case queueQUEUE_TYPE_RECURSIVE_MUTEX: \
- prvTraceStoreEvent1(PSF_EVENT_MUTEX_GIVE, (uint32_t)pxQueue); \
- break; \
- }
-
-/* Called when a message failed to be sent to a queue (timeout) */
-#undef traceQUEUE_SEND_FAILED
-#define traceQUEUE_SEND_FAILED( pxQueue ) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \
- switch (pxQueue->ucQueueType) \
- { \
- case queueQUEUE_TYPE_BASE: \
- prvTraceStoreEvent2(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND_FAILED : PSF_EVENT_QUEUE_SEND_FRONT_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \
- break; \
- case queueQUEUE_TYPE_BINARY_SEMAPHORE: \
- case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \
- prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_GIVE_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \
- break; \
- case queueQUEUE_TYPE_MUTEX: \
- case queueQUEUE_TYPE_RECURSIVE_MUTEX: \
- prvTraceStoreEvent1(PSF_EVENT_MUTEX_GIVE_FAILED, (uint32_t)pxQueue); \
- break; \
- }
-
-/* Called when the task is blocked due to a send operation on a full queue */
-#undef traceBLOCKING_ON_QUEUE_SEND
-#define traceBLOCKING_ON_QUEUE_SEND( pxQueue ) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \
- switch (pxQueue->ucQueueType) \
- { \
- case queueQUEUE_TYPE_BASE: \
- prvTraceStoreEvent2(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND_BLOCK : PSF_EVENT_QUEUE_SEND_FRONT_BLOCK, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \
- break; \
- case queueQUEUE_TYPE_BINARY_SEMAPHORE: \
- case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \
- prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_GIVE_BLOCK, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \
- break; \
- case queueQUEUE_TYPE_MUTEX: \
- case queueQUEUE_TYPE_RECURSIVE_MUTEX: \
- prvTraceStoreEvent1(PSF_EVENT_MUTEX_GIVE_BLOCK, (uint32_t)pxQueue); \
- break; \
- }
-
-/**************************************************************************/
-/* Makes sure xQueueGiveFromISR also has a xCopyPosition parameter */
-/**************************************************************************/
-/* Helpers needed to correctly expand names */
-#define TZ__CAT2(a,b) a ## b
-#define TZ__CAT(a,b) TZ__CAT2(a, b)
-
-/* Expands name if this header is included... uxQueueType must be a macro that only exists in queue.c or whatever, and it must expand to nothing or to something that's valid in identifiers */
-#define xQueueGiveFromISR(a,b) TZ__CAT(xQueueGiveFromISR__, uxQueueType) (a,b)
-
-/* If in queue.c, the "uxQueueType" macro expands to "pcHead". queueSEND_TO_BACK is the value we need to send in */
-#define xQueueGiveFromISR__pcHead(__a, __b) MyWrapper(__a, __b, const BaseType_t xCopyPosition); \
-BaseType_t xQueueGiveFromISR(__a, __b) { return MyWrapper(xQueue, pxHigherPriorityTaskWoken, queueSEND_TO_BACK); } \
-BaseType_t MyWrapper(__a, __b, const BaseType_t xCopyPosition)
-
-/* If not in queue.c, "uxQueueType" isn't expanded */
-#define xQueueGiveFromISR__uxQueueType(__a, __b) xQueueGiveFromISR(__a,__b)
-
-/**************************************************************************/
-/* End of xQueueGiveFromISR fix */
-/**************************************************************************/
-
-/* Called when a message is sent from interrupt context, e.g., using xQueueSendFromISR */
-#undef traceQUEUE_SEND_FROM_ISR
-#define traceQUEUE_SEND_FROM_ISR( pxQueue ) \
- if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \
- switch (pxQueue->ucQueueType) \
- { \
- case queueQUEUE_TYPE_BASE: \
- prvTraceStoreEvent2(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND_FROMISR : PSF_EVENT_QUEUE_SEND_FRONT_FROMISR, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting + 1); \
- break; \
- case queueQUEUE_TYPE_BINARY_SEMAPHORE: \
- case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \
- prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_GIVE_FROMISR, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting + 1); \
- break; \
- }
-
-/* Called when a message send from interrupt context fails (since the queue was full) */
-#undef traceQUEUE_SEND_FROM_ISR_FAILED
-#define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ) \
- if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \
- switch (pxQueue->ucQueueType) \
- { \
- case queueQUEUE_TYPE_BASE: \
- prvTraceStoreEvent2(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND_FROMISR_FAILED : PSF_EVENT_QUEUE_SEND_FRONT_FROMISR_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \
- break; \
- case queueQUEUE_TYPE_BINARY_SEMAPHORE: \
- case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \
- prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_GIVE_FROMISR_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \
- break; \
- }
-
-/* Called when a message is received from a queue */
-#undef traceQUEUE_RECEIVE
-#define traceQUEUE_RECEIVE( pxQueue ) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \
- switch (pxQueue->ucQueueType) \
- { \
- case queueQUEUE_TYPE_BASE: \
- if (isQueueReceiveHookActuallyPeek) \
- prvTraceStoreEvent3(PSF_EVENT_QUEUE_PEEK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting - 1); \
- else\
- prvTraceStoreEvent3(PSF_EVENT_QUEUE_RECEIVE, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting - 1); \
- break; \
- case queueQUEUE_TYPE_BINARY_SEMAPHORE: \
- case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \
- if (isQueueReceiveHookActuallyPeek) \
- prvTraceStoreEvent3(PSF_EVENT_SEMAPHORE_PEEK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting - 1); \
- else \
- prvTraceStoreEvent3(PSF_EVENT_SEMAPHORE_TAKE, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting - 1); \
- break; \
- case queueQUEUE_TYPE_MUTEX: \
- case queueQUEUE_TYPE_RECURSIVE_MUTEX: \
- if (isQueueReceiveHookActuallyPeek) \
- prvTraceStoreEvent2(PSF_EVENT_MUTEX_PEEK, (uint32_t)pxQueue, xTicksToWait); \
- else \
- prvTraceStoreEvent2(PSF_EVENT_MUTEX_TAKE, (uint32_t)pxQueue, xTicksToWait); \
- break; \
- }
-
-/* Called when a receive operation on a queue fails (timeout) */
-#undef traceQUEUE_RECEIVE_FAILED
-#define traceQUEUE_RECEIVE_FAILED( pxQueue ) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \
- switch (pxQueue->ucQueueType) \
- { \
- case queueQUEUE_TYPE_BASE: \
- prvTraceStoreEvent3(isQueueReceiveHookActuallyPeek ? PSF_EVENT_QUEUE_PEEK_FAILED : PSF_EVENT_QUEUE_RECEIVE_FAILED, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \
- break; \
- case queueQUEUE_TYPE_BINARY_SEMAPHORE: \
- case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \
- prvTraceStoreEvent3(isQueueReceiveHookActuallyPeek ? PSF_EVENT_SEMAPHORE_PEEK_FAILED : PSF_EVENT_SEMAPHORE_TAKE_FAILED, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \
- break; \
- case queueQUEUE_TYPE_MUTEX: \
- case queueQUEUE_TYPE_RECURSIVE_MUTEX: \
- prvTraceStoreEvent2(isQueueReceiveHookActuallyPeek ? PSF_EVENT_MUTEX_PEEK_FAILED : PSF_EVENT_MUTEX_TAKE_FAILED, (uint32_t)pxQueue, xTicksToWait); \
- break; \
- }
-
-/* Called when the task is blocked due to a receive operation on an empty queue */
-#undef traceBLOCKING_ON_QUEUE_RECEIVE
-#define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \
- switch (pxQueue->ucQueueType) \
- { \
- case queueQUEUE_TYPE_BASE: \
- prvTraceStoreEvent3(isQueueReceiveHookActuallyPeek ? PSF_EVENT_QUEUE_PEEK_BLOCK : PSF_EVENT_QUEUE_RECEIVE_BLOCK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \
- break; \
- case queueQUEUE_TYPE_BINARY_SEMAPHORE: \
- case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \
- prvTraceStoreEvent3(isQueueReceiveHookActuallyPeek ? PSF_EVENT_SEMAPHORE_PEEK_BLOCK : PSF_EVENT_SEMAPHORE_TAKE_BLOCK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \
- break; \
- case queueQUEUE_TYPE_MUTEX: \
- case queueQUEUE_TYPE_RECURSIVE_MUTEX: \
- prvTraceStoreEvent2(isQueueReceiveHookActuallyPeek ? PSF_EVENT_MUTEX_PEEK_BLOCK : PSF_EVENT_MUTEX_TAKE_BLOCK, (uint32_t)pxQueue, xTicksToWait); \
- break; \
- }
-
-#if (TRC_CFG_FREERTOS_VERSION > TRC_FREERTOS_VERSION_9_0_1)
-/* Called when a peek operation on a queue fails (timeout) */
-#undef traceQUEUE_PEEK_FAILED
-#define traceQUEUE_PEEK_FAILED( pxQueue ) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \
- switch (pxQueue->ucQueueType) \
- { \
- case queueQUEUE_TYPE_BASE: \
- prvTraceStoreEvent3(PSF_EVENT_QUEUE_PEEK_FAILED, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \
- break; \
- case queueQUEUE_TYPE_BINARY_SEMAPHORE: \
- case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \
- prvTraceStoreEvent3(PSF_EVENT_SEMAPHORE_PEEK_FAILED, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \
- break; \
- case queueQUEUE_TYPE_MUTEX: \
- case queueQUEUE_TYPE_RECURSIVE_MUTEX: \
- prvTraceStoreEvent2(PSF_EVENT_MUTEX_PEEK_FAILED, (uint32_t)pxQueue, xTicksToWait); \
- break; \
- }
-
-/* Called when the task is blocked due to a peek operation on an empty queue */
-#undef traceBLOCKING_ON_QUEUE_PEEK
-#define traceBLOCKING_ON_QUEUE_PEEK( pxQueue ) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \
- switch (pxQueue->ucQueueType) \
- { \
- case queueQUEUE_TYPE_BASE: \
- prvTraceStoreEvent3(PSF_EVENT_QUEUE_PEEK_BLOCK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \
- break; \
- case queueQUEUE_TYPE_BINARY_SEMAPHORE: \
- case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \
- prvTraceStoreEvent3(PSF_EVENT_SEMAPHORE_PEEK_BLOCK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \
- break; \
- case queueQUEUE_TYPE_MUTEX: \
- case queueQUEUE_TYPE_RECURSIVE_MUTEX: \
- prvTraceStoreEvent2(PSF_EVENT_MUTEX_PEEK_BLOCK, (uint32_t)pxQueue, xTicksToWait); \
- break; \
- }
-
-#endif /* (TRC_CFG_FREERTOS_VERSION > TRC_FREERTOS_VERSION_9_0_1) */
-
-/* Called when a message is received in interrupt context, e.g., using xQueueReceiveFromISR */
-#undef traceQUEUE_RECEIVE_FROM_ISR
-#define traceQUEUE_RECEIVE_FROM_ISR( pxQueue ) \
- if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \
- switch (pxQueue->ucQueueType) \
- { \
- case queueQUEUE_TYPE_BASE: \
- prvTraceStoreEvent2(PSF_EVENT_QUEUE_RECEIVE_FROMISR, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting - 1); \
- break; \
- case queueQUEUE_TYPE_BINARY_SEMAPHORE: \
- case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \
- prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_TAKE_FROMISR, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting - 1); \
- break; \
- }
-
-/* Called when a message receive from interrupt context fails (since the queue was empty) */
-#undef traceQUEUE_RECEIVE_FROM_ISR_FAILED
-#define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ) \
- if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \
- switch (pxQueue->ucQueueType) \
- { \
- case queueQUEUE_TYPE_BASE: \
- prvTraceStoreEvent2(PSF_EVENT_QUEUE_RECEIVE_FROMISR_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \
- break; \
- case queueQUEUE_TYPE_BINARY_SEMAPHORE: \
- case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \
- prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_TAKE_FROMISR_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \
- break; \
- }
-
-/* Called on xQueuePeek */
-#undef traceQUEUE_PEEK
-#define traceQUEUE_PEEK( pxQueue ) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \
- switch (pxQueue->ucQueueType) \
- { \
- case queueQUEUE_TYPE_BASE: \
- prvTraceStoreEvent3(PSF_EVENT_QUEUE_PEEK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \
- break; \
- case queueQUEUE_TYPE_BINARY_SEMAPHORE: \
- case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \
- prvTraceStoreEvent3(PSF_EVENT_SEMAPHORE_PEEK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \
- break; \
- case queueQUEUE_TYPE_MUTEX: \
- case queueQUEUE_TYPE_RECURSIVE_MUTEX: \
- prvTraceStoreEvent1(PSF_EVENT_MUTEX_PEEK, (uint32_t)pxQueue); \
- break; \
- }
-
-/* Called in vTaskPrioritySet */
-#undef traceTASK_PRIORITY_SET
-#define traceTASK_PRIORITY_SET( pxTask, uxNewPriority ) \
- prvTraceSaveObjectData(pxTask, uxNewPriority); \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(TASK, pxTask) & CurrentFilterMask) \
- prvTraceStoreEvent2(PSF_EVENT_TASK_PRIORITY, (uint32_t)pxTask, uxNewPriority);
-
-/* Called in vTaskPriorityInherit, which is called by Mutex operations */
-#undef traceTASK_PRIORITY_INHERIT
-#define traceTASK_PRIORITY_INHERIT( pxTask, uxNewPriority ) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(TASK, pxTask) & CurrentFilterMask) \
- prvTraceStoreEvent2(PSF_EVENT_TASK_PRIO_INHERIT, (uint32_t)pxTask, uxNewPriority);
-
-/* Called in vTaskPriorityDisinherit, which is called by Mutex operations */
-#undef traceTASK_PRIORITY_DISINHERIT
-#define traceTASK_PRIORITY_DISINHERIT( pxTask, uxNewPriority ) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(TASK, pxTask) & CurrentFilterMask) \
- prvTraceStoreEvent2(PSF_EVENT_TASK_PRIO_DISINHERIT, (uint32_t)pxTask, uxNewPriority);
-
-/* Called in vTaskResume */
-#undef traceTASK_RESUME
-#define traceTASK_RESUME( pxTaskToResume ) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(TASK, pxTaskToResume) & CurrentFilterMask) \
- prvTraceStoreEvent1(PSF_EVENT_TASK_RESUME, (uint32_t)pxTaskToResume);
-
-/* Called in vTaskResumeFromISR */
-#undef traceTASK_RESUME_FROM_ISR
-#define traceTASK_RESUME_FROM_ISR( pxTaskToResume ) \
- if (TRACE_GET_OBJECT_FILTER(TASK, pxTaskToResume) & CurrentFilterMask) \
- prvTraceStoreEvent1(PSF_EVENT_TASK_RESUME_FROMISR, (uint32_t)pxTaskToResume);
-
-#if (TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1)
-
-#undef traceMALLOC
-#define traceMALLOC( pvAddress, uiSize ) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- prvTraceStoreEvent2(PSF_EVENT_MALLOC, (uint32_t)pvAddress, uiSize);
-
-#undef traceFREE
-#define traceFREE( pvAddress, uiSize ) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- prvTraceStoreEvent2(PSF_EVENT_FREE, (uint32_t)pvAddress, (uint32_t)(0 - uiSize)); /* "0 -" instead of just "-" to get rid of a warning... */
-
-#endif /* (TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1) */
-
-#if (TRC_CFG_INCLUDE_TIMER_EVENTS == 1)
-
-/* Called in timer.c - xTimerCreate */
-#undef traceTIMER_CREATE
-#define traceTIMER_CREATE(tmr) \
- TRACE_SET_OBJECT_FILTER(TIMER, tmr, CurrentFilterGroup); \
- prvTraceSaveSymbol(tmr, tmr->pcTimerName); \
- prvTraceStoreStringEvent(1, PSF_EVENT_OBJ_NAME, tmr->pcTimerName, tmr); \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(TIMER, tmr) & CurrentFilterMask) \
- prvTraceStoreEvent2(PSF_EVENT_TIMER_CREATE, (uint32_t)tmr, tmr->xTimerPeriodInTicks);
-
-#undef traceTIMER_CREATE_FAILED
-#define traceTIMER_CREATE_FAILED() \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- prvTraceStoreEvent0(PSF_EVENT_TIMER_CREATE_FAILED);
-
-#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X)
-#define traceTIMER_COMMAND_SEND_8_0_CASES(tmr) \
- case tmrCOMMAND_RESET: \
- prvTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_RESET : PSF_EVENT_TIMER_RESET_FAILED, (uint32_t)tmr, xOptionalValue); \
- break; \
- case tmrCOMMAND_START_FROM_ISR: \
- prvTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_START_FROMISR : PSF_EVENT_TIMER_START_FROMISR_FAILED, (uint32_t)tmr, xOptionalValue); \
- break; \
- case tmrCOMMAND_RESET_FROM_ISR: \
- prvTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_RESET_FROMISR : PSF_EVENT_TIMER_RESET_FROMISR_FAILED, (uint32_t)tmr, xOptionalValue); \
- break; \
- case tmrCOMMAND_STOP_FROM_ISR: \
- prvTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_STOP_FROMISR : PSF_EVENT_TIMER_STOP_FROMISR_FAILED, (uint32_t)tmr, xOptionalValue); \
- break; \
- case tmrCOMMAND_CHANGE_PERIOD_FROM_ISR: \
- prvTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_CHANGEPERIOD_FROMISR : PSF_EVENT_TIMER_CHANGEPERIOD_FROMISR_FAILED, (uint32_t)tmr, xOptionalValue); \
- break;
-#else /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X */
-#define traceTIMER_COMMAND_SEND_8_0_CASES(tmr)
-#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X */
-
-/* Note that xCommandID can never be tmrCOMMAND_EXECUTE_CALLBACK (-1) since the trace macro is not called in that case */
-#undef traceTIMER_COMMAND_SEND
-#define traceTIMER_COMMAND_SEND(tmr, xCommandID, xOptionalValue, xReturn) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(TIMER, tmr) & CurrentFilterMask) \
- switch(xCommandID) \
- { \
- case tmrCOMMAND_START: \
- prvTraceStoreEvent1((xReturn == pdPASS) ? PSF_EVENT_TIMER_START : PSF_EVENT_TIMER_START_FAILED, (uint32_t)tmr); \
- break; \
- case tmrCOMMAND_STOP: \
- prvTraceStoreEvent1((xReturn == pdPASS) ? PSF_EVENT_TIMER_STOP : PSF_EVENT_TIMER_STOP_FAILED, (uint32_t)tmr); \
- break; \
- case tmrCOMMAND_CHANGE_PERIOD: \
- prvTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_CHANGEPERIOD : PSF_EVENT_TIMER_CHANGEPERIOD_FAILED, (uint32_t)tmr, xOptionalValue); \
- break; \
- case tmrCOMMAND_DELETE: \
- prvTraceStoreEvent1((xReturn == pdPASS) ? PSF_EVENT_TIMER_DELETE : PSF_EVENT_TIMER_DELETE_FAILED, (uint32_t)tmr); \
- break; \
- traceTIMER_COMMAND_SEND_8_0_CASES(tmr) \
- }
-
-#undef traceTIMER_EXPIRED
-#define traceTIMER_EXPIRED(tmr) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(TIMER, tmr) & CurrentFilterMask) \
- prvTraceStoreEvent2(PSF_EVENT_TIMER_EXPIRED, (uint32_t)tmr->pxCallbackFunction, (uint32_t)tmr->pvTimerID);
-
-#endif /* #if (TRC_CFG_INCLUDE_TIMER_EVENTS == 1) */
-
-
-#if (TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS == 1)
-
-#undef tracePEND_FUNC_CALL
-#define tracePEND_FUNC_CALL(func, arg1, arg2, ret) \
- prvTraceStoreEvent1((ret == pdPASS) ? PSF_EVENT_TIMER_PENDFUNCCALL : PSF_EVENT_TIMER_PENDFUNCCALL_FAILED, (uint32_t)func);
-
-#undef tracePEND_FUNC_CALL_FROM_ISR
-#define tracePEND_FUNC_CALL_FROM_ISR(func, arg1, arg2, ret) \
- prvTraceStoreEvent1((ret == pdPASS) ? PSF_EVENT_TIMER_PENDFUNCCALL_FROMISR : PSF_EVENT_TIMER_PENDFUNCCALL_FROMISR_FAILED, (uint32_t)func);
-
-#endif /* (TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS == 1) */
-
-#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1)
-
-#undef traceEVENT_GROUP_CREATE
-#define traceEVENT_GROUP_CREATE(eg) \
- TRACE_SET_OBJECT_FILTER(EVENTGROUP, eg, CurrentFilterGroup); \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \
- prvTraceStoreEvent1(PSF_EVENT_EVENTGROUP_CREATE, (uint32_t)eg);
-
-#undef traceEVENT_GROUP_DELETE
-#define traceEVENT_GROUP_DELETE(eg) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \
- prvTraceStoreEvent1(PSF_EVENT_EVENTGROUP_DELETE, (uint32_t)eg); \
- prvTraceDeleteSymbol(eg);
-
-#undef traceEVENT_GROUP_CREATE_FAILED
-#define traceEVENT_GROUP_CREATE_FAILED() \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- prvTraceStoreEvent0(PSF_EVENT_EVENTGROUP_CREATE_FAILED);
-
-#undef traceEVENT_GROUP_SYNC_BLOCK
-#define traceEVENT_GROUP_SYNC_BLOCK(eg, bitsToSet, bitsToWaitFor) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \
- prvTraceStoreEvent2(PSF_EVENT_EVENTGROUP_SYNC_BLOCK, (uint32_t)eg, bitsToWaitFor);
-
-#undef traceEVENT_GROUP_SYNC_END
-#define traceEVENT_GROUP_SYNC_END(eg, bitsToSet, bitsToWaitFor, wasTimeout) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \
- prvTraceStoreEvent2((wasTimeout != pdTRUE) ? PSF_EVENT_EVENTGROUP_SYNC : PSF_EVENT_EVENTGROUP_SYNC_FAILED, (uint32_t)eg, bitsToWaitFor);
-
-#undef traceEVENT_GROUP_WAIT_BITS_BLOCK
-#define traceEVENT_GROUP_WAIT_BITS_BLOCK(eg, bitsToWaitFor) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \
- prvTraceStoreEvent2(PSF_EVENT_EVENTGROUP_WAITBITS_BLOCK, (uint32_t)eg, bitsToWaitFor);
-
-#undef traceEVENT_GROUP_WAIT_BITS_END
-#define traceEVENT_GROUP_WAIT_BITS_END(eg, bitsToWaitFor, wasTimeout) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \
- prvTraceStoreEvent2((wasTimeout != pdTRUE) ? PSF_EVENT_EVENTGROUP_WAITBITS : PSF_EVENT_EVENTGROUP_WAITBITS_FAILED, (uint32_t)eg, bitsToWaitFor);
-
-#undef traceEVENT_GROUP_CLEAR_BITS
-#define traceEVENT_GROUP_CLEAR_BITS(eg, bitsToClear) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \
- prvTraceStoreEvent2(PSF_EVENT_EVENTGROUP_CLEARBITS, (uint32_t)eg, bitsToClear);
-
-#undef traceEVENT_GROUP_CLEAR_BITS_FROM_ISR
-#define traceEVENT_GROUP_CLEAR_BITS_FROM_ISR(eg, bitsToClear) \
- if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \
- prvTraceStoreEvent2(PSF_EVENT_EVENTGROUP_CLEARBITS_FROMISR, (uint32_t)eg, bitsToClear);
-
-#undef traceEVENT_GROUP_SET_BITS
-#define traceEVENT_GROUP_SET_BITS(eg, bitsToSet) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \
- prvTraceStoreEvent2(PSF_EVENT_EVENTGROUP_SETBITS, (uint32_t)eg, bitsToSet);
-
-#undef traceEVENT_GROUP_SET_BITS_FROM_ISR
-#define traceEVENT_GROUP_SET_BITS_FROM_ISR(eg, bitsToSet) \
- if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \
- prvTraceStoreEvent2(PSF_EVENT_EVENTGROUP_SETBITS_FROMISR, (uint32_t)eg, bitsToSet);
-
-#endif /* (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1) */
-
-#undef traceTASK_NOTIFY_TAKE
-#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0)
-#define traceTASK_NOTIFY_TAKE() \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask){ \
- if (pxCurrentTCB->ucNotifyState == taskNOTIFICATION_RECEIVED) \
- prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_TAKE, (uint32_t)pxCurrentTCB, xTicksToWait); \
- else \
- prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_TAKE_FAILED, (uint32_t)pxCurrentTCB, xTicksToWait);}
-#else /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */
-#define traceTASK_NOTIFY_TAKE() \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask){ \
- if (pxCurrentTCB->eNotifyState == eNotified) \
- prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_TAKE, (uint32_t)pxCurrentTCB, xTicksToWait); \
- else \
- prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_TAKE_FAILED, (uint32_t)pxCurrentTCB, xTicksToWait);}
-#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */
-
-#undef traceTASK_NOTIFY_TAKE_BLOCK
-#define traceTASK_NOTIFY_TAKE_BLOCK() \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_TAKE_BLOCK, (uint32_t)pxCurrentTCB, xTicksToWait);
-
-#undef traceTASK_NOTIFY_WAIT
-#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0)
-#define traceTASK_NOTIFY_WAIT() \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask){ \
- if (pxCurrentTCB->ucNotifyState == taskNOTIFICATION_RECEIVED) \
- prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_WAIT, (uint32_t)pxCurrentTCB, xTicksToWait); \
- else \
- prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_WAIT_FAILED, (uint32_t)pxCurrentTCB, xTicksToWait);}
-#else /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */
-#define traceTASK_NOTIFY_WAIT() \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask){ \
- if (pxCurrentTCB->eNotifyState == eNotified) \
- prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_WAIT, (uint32_t)pxCurrentTCB, xTicksToWait); \
- else \
- prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_WAIT_FAILED, (uint32_t)pxCurrentTCB, xTicksToWait);}
-#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */
-
-#undef traceTASK_NOTIFY_WAIT_BLOCK
-#define traceTASK_NOTIFY_WAIT_BLOCK() \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_WAIT_BLOCK, (uint32_t)pxCurrentTCB, xTicksToWait);
-
-#undef traceTASK_NOTIFY
-#define traceTASK_NOTIFY() \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(TASK, xTaskToNotify) & CurrentFilterMask) \
- prvTraceStoreEvent1(PSF_EVENT_TASK_NOTIFY, (uint32_t)xTaskToNotify);
-
-#undef traceTASK_NOTIFY_FROM_ISR
-#define traceTASK_NOTIFY_FROM_ISR() \
- if (TRACE_GET_OBJECT_FILTER(TASK, xTaskToNotify) & CurrentFilterMask) \
- prvTraceStoreEvent1(PSF_EVENT_TASK_NOTIFY_FROM_ISR, (uint32_t)xTaskToNotify);
-
-#undef traceTASK_NOTIFY_GIVE_FROM_ISR
-#define traceTASK_NOTIFY_GIVE_FROM_ISR() \
- if (TRACE_GET_OBJECT_FILTER(TASK, xTaskToNotify) & CurrentFilterMask) \
- prvTraceStoreEvent1(PSF_EVENT_TASK_NOTIFY_GIVE_FROM_ISR, (uint32_t)xTaskToNotify);
-
-#undef traceQUEUE_REGISTRY_ADD
-#define traceQUEUE_REGISTRY_ADD(object, name) \
- prvTraceSaveSymbol(object, (const char*)name); \
- prvTraceStoreStringEvent(1, PSF_EVENT_OBJ_NAME, name, object);
-
-#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1)
-
-#undef traceSTREAM_BUFFER_CREATE
-#define traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer ) \
- TRACE_SET_OBJECT_FILTER(STREAMBUFFER, pxStreamBuffer, CurrentFilterGroup); \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, pxStreamBuffer) & CurrentFilterMask) \
- prvTraceStoreEvent2(xIsMessageBuffer == 1 ? PSF_EVENT_MESSAGEBUFFER_CREATE : PSF_EVENT_STREAMBUFFER_CREATE, (uint32_t)pxStreamBuffer, xBufferSizeBytes);
-
-#undef traceSTREAM_BUFFER_CREATE_FAILED
-#define traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- prvTraceStoreEvent2(xIsMessageBuffer == 1 ? PSF_EVENT_MESSAGEBUFFER_CREATE_FAILED : PSF_EVENT_STREAMBUFFER_CREATE_FAILED, 0 , xBufferSizeBytes);
-
-#undef traceSTREAM_BUFFER_CREATE_STATIC_FAILED
-#define traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer ) \
- traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer )
-
-#undef traceSTREAM_BUFFER_DELETE
-#define traceSTREAM_BUFFER_DELETE( xStreamBuffer ) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, pxStreamBuffer) & CurrentFilterMask) \
- prvTraceStoreEvent2(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_DELETE : PSF_EVENT_STREAMBUFFER_DELETE, (uint32_t)xStreamBuffer, prvBytesInBuffer(xStreamBuffer)); \
- prvTraceDeleteSymbol(xStreamBuffer);
-
-#undef traceSTREAM_BUFFER_RESET
-#define traceSTREAM_BUFFER_RESET( xStreamBuffer ) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \
- prvTraceStoreEvent2(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_RESET : PSF_EVENT_STREAMBUFFER_RESET, (uint32_t)xStreamBuffer, 0);
-
-#undef traceSTREAM_BUFFER_SEND
-#define traceSTREAM_BUFFER_SEND( xStreamBuffer, xReturn ) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \
- prvTraceStoreEvent2(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_SEND : PSF_EVENT_STREAMBUFFER_SEND, (uint32_t)xStreamBuffer, prvBytesInBuffer(xStreamBuffer));
-
-#undef traceBLOCKING_ON_STREAM_BUFFER_SEND
-#define traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer ) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \
- prvTraceStoreEvent1(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_SEND_BLOCK : PSF_EVENT_STREAMBUFFER_SEND_BLOCK, (uint32_t)xStreamBuffer);
-
-#undef traceSTREAM_BUFFER_SEND_FAILED
-#define traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer ) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \
- prvTraceStoreEvent1(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_SEND_FAILED : PSF_EVENT_STREAMBUFFER_SEND_FAILED, (uint32_t)xStreamBuffer);
-
-#undef traceSTREAM_BUFFER_RECEIVE
-#define traceSTREAM_BUFFER_RECEIVE( xStreamBuffer, xReceivedLength ) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \
- prvTraceStoreEvent2(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_RECEIVE: PSF_EVENT_STREAMBUFFER_RECEIVE, (uint32_t)xStreamBuffer, prvBytesInBuffer(xStreamBuffer));
-
-#undef traceBLOCKING_ON_STREAM_BUFFER_RECEIVE
-#define traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer ) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \
- prvTraceStoreEvent1(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_RECEIVE_BLOCK: PSF_EVENT_STREAMBUFFER_RECEIVE_BLOCK, (uint32_t)xStreamBuffer);
-
-#undef traceSTREAM_BUFFER_RECEIVE_FAILED
-#define traceSTREAM_BUFFER_RECEIVE_FAILED( xStreamBuffer ) \
- if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
- if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \
- prvTraceStoreEvent1(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_RECEIVE_FAILED: PSF_EVENT_STREAMBUFFER_RECEIVE_FAILED, (uint32_t)xStreamBuffer);
-
-#undef traceSTREAM_BUFFER_SEND_FROM_ISR
-#define traceSTREAM_BUFFER_SEND_FROM_ISR( xStreamBuffer, xReturn ) \
- if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \
- { \
- if ( xReturn > ( size_t ) 0 ) \
- { \
- prvTraceStoreEvent2(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_SEND_FROM_ISR : PSF_EVENT_STREAMBUFFER_SEND_FROM_ISR, (uint32_t)xStreamBuffer, prvBytesInBuffer(xStreamBuffer)); \
- } \
- else \
- { \
- prvTraceStoreEvent1(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_SEND_FROM_ISR_FAILED : PSF_EVENT_STREAMBUFFER_SEND_FROM_ISR_FAILED, (uint32_t)xStreamBuffer); \
- } \
- }
-
-#undef traceSTREAM_BUFFER_RECEIVE_FROM_ISR
-#define traceSTREAM_BUFFER_RECEIVE_FROM_ISR( xStreamBuffer, xReceivedLength ) \
-if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \
- { \
- if ( xReceivedLength > ( size_t ) 0 ) \
- { \
- prvTraceStoreEvent2(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_RECEIVE_FROM_ISR : PSF_EVENT_STREAMBUFFER_RECEIVE_FROM_ISR, (uint32_t)xStreamBuffer, prvBytesInBuffer(xStreamBuffer)); \
- } \
- else \
- { \
- prvTraceStoreEvent1(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_RECEIVE_FROM_ISR_FAILED : PSF_EVENT_STREAMBUFFER_RECEIVE_FROM_ISR_FAILED, (uint32_t)xStreamBuffer); \
- } \
- }
-
-#endif /* (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1) */
-
-#endif /* (TRC_CFG_SCHEDULING_ONLY == 0) */
-
-#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
-
-#else /* (TRC_USE_TRACEALYZER_RECORDER == 1) */
-
-/* When recorder is disabled */
-#define vTraceSetQueueName(object, name)
-#define vTraceSetSemaphoreName(object, name)
-#define vTraceSetMutexName(object, name)
-#define vTraceSetEventGroupName(object, name)
-#define vTraceSetStreamBufferName(object, name)
-#define vTraceSetMessageBufferName(object, name)
-
-#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* TRC_KERNEL_PORT_H */
+/*******************************************************************************
+ * Trace Recorder Library for Tracealyzer v4.3.11
+ * Percepio AB, www.percepio.com
+ *
+ * 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.
+ *
+ * FreeRTOS-specific definitions needed by the trace recorder
+ *
+ * <LICENSE INFO>
+ *
+ * Tabs are used for indent in this file (1 tab = 4 spaces)
+ *
+ * Copyright Percepio AB, 2018.
+ * www.percepio.com
+ ******************************************************************************/
+
+#ifndef TRC_KERNEL_PORT_H
+#define TRC_KERNEL_PORT_H
+
+#include "FreeRTOS.h" /* Defines configUSE_TRACE_FACILITY */
+#include "trcPortDefines.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define TRC_USE_TRACEALYZER_RECORDER configUSE_TRACE_FACILITY
+
+/*** FreeRTOS version codes **************************************************/
+#define FREERTOS_VERSION_NOT_SET 0
+#define TRC_FREERTOS_VERSION_7_3_X 1 /* v7.3 is earliest supported.*/
+#define TRC_FREERTOS_VERSION_7_4_X 2
+#define TRC_FREERTOS_VERSION_7_5_X 3
+#define TRC_FREERTOS_VERSION_7_6_X TRC_FREERTOS_VERSION_7_5_X
+#define TRC_FREERTOS_VERSION_8_X_X 4
+#define TRC_FREERTOS_VERSION_9_0_0 5
+#define TRC_FREERTOS_VERSION_9_0_1 6
+#define TRC_FREERTOS_VERSION_9_0_2 7
+#define TRC_FREERTOS_VERSION_10_0_0 8
+#define TRC_FREERTOS_VERSION_10_0_1 TRC_FREERTOS_VERSION_10_0_0
+#define TRC_FREERTOS_VERSION_10_1_0 TRC_FREERTOS_VERSION_10_0_0
+#define TRC_FREERTOS_VERSION_10_1_1 TRC_FREERTOS_VERSION_10_0_0
+#define TRC_FREERTOS_VERSION_10_2_0 TRC_FREERTOS_VERSION_10_0_0
+#define TRC_FREERTOS_VERSION_10_2_1 TRC_FREERTOS_VERSION_10_0_0
+#define TRC_FREERTOS_VERSION_10_3_0 9
+#define TRC_FREERTOS_VERSION_10_3_1 TRC_FREERTOS_VERSION_10_3_0
+#define TRC_FREERTOS_VERSION_10_4_0 10
+
+/* Legacy FreeRTOS version codes for backwards compatibility with old trace configurations */
+#define TRC_FREERTOS_VERSION_7_3 TRC_FREERTOS_VERSION_7_3_X
+#define TRC_FREERTOS_VERSION_7_4 TRC_FREERTOS_VERSION_7_4_X
+#define TRC_FREERTOS_VERSION_7_5_OR_7_6 TRC_FREERTOS_VERSION_7_5_X
+#define TRC_FREERTOS_VERSION_8_X TRC_FREERTOS_VERSION_8_X_X
+
+#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
+#define prvGetStreamBufferType(x) ((( StreamBuffer_t * )x )->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER)
+#else
+#define prvGetStreamBufferType(x) 0
+#endif
+
+/* Added mainly for our internal testing. This makes it easier to create test applications that
+ runs on multiple FreeRTOS versions. */
+#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_8_X_X)
+ /* FreeRTOS v7.x */
+ #define STRING_CAST(x) ( (signed char*) x )
+ #define TickType portTickType
+ #define TaskType xTaskHandle
+#else
+ /* FreeRTOS v8.0 and later */
+ #define STRING_CAST(x) x
+ #define TickType TickType_t
+ #define TaskType TaskHandle_t
+#endif
+
+
+
+#if (defined(TRC_USE_TRACEALYZER_RECORDER)) && (TRC_USE_TRACEALYZER_RECORDER == 1)
+
+#if defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0)
+ /* Required for this feature */
+#undef INCLUDE_uxTaskGetStackHighWaterMark
+#define INCLUDE_uxTaskGetStackHighWaterMark 1
+#endif /* defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0) */
+
+/*******************************************************************************
+ * INCLUDE_xTaskGetCurrentTaskHandle must be set to 1 for tracing to work properly
+ ******************************************************************************/
+#undef INCLUDE_xTaskGetCurrentTaskHandle
+#define INCLUDE_xTaskGetCurrentTaskHandle 1
+
+#if (TRC_CFG_SCHEDULING_ONLY == 0)
+/*******************************************************************************
+ * vTraceSetQueueName(void* object, const char* name)
+ *
+ * Parameter object: pointer to the Queue that shall be named
+ * Parameter name: the name to set (const string literal)
+ *
+ * Sets a name for Queue objects for display in Tracealyzer.
+ ******************************************************************************/
+void vTraceSetQueueName(void* object, const char* name);
+
+/*******************************************************************************
+ * vTraceSetSemaphoreName(void* object, const char* name)
+ *
+ * Parameter object: pointer to the Semaphore that shall be named
+ * Parameter name: the name to set (const string literal)
+ *
+ * Sets a name for Semaphore objects for display in Tracealyzer.
+ ******************************************************************************/
+void vTraceSetSemaphoreName(void* object, const char* name);
+
+/*******************************************************************************
+ * vTraceSetMutexName(void* object, const char* name)
+ *
+ * Parameter object: pointer to the Mutex that shall be named
+ * Parameter name: the name to set (const string literal)
+ *
+ * Sets a name for Semaphore objects for display in Tracealyzer.
+ ******************************************************************************/
+void vTraceSetMutexName(void* object, const char* name);
+
+#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1)
+/*******************************************************************************
+* vTraceSetEventGroupName(void* object, const char* name)
+*
+* Parameter object: pointer to the EventGroup that shall be named
+* Parameter name: the name to set (const string literal)
+*
+* Sets a name for EventGroup objects for display in Tracealyzer.
+******************************************************************************/
+void vTraceSetEventGroupName(void* object, const char* name);
+#else /* (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1) */
+#define vTraceSetEventGroupName(object, name) /* Do nothing */
+#endif /* (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1) */
+
+#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1)
+/*******************************************************************************
+* vTraceSetStreamBufferName(void* object, const char* name)
+*
+* Parameter object: pointer to the StreamBuffer that shall be named
+* Parameter name: the name to set (const string literal)
+*
+* Sets a name for StreamBuffer objects for display in Tracealyzer.
+******************************************************************************/
+void vTraceSetStreamBufferName(void* object, const char* name);
+#else /* (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1) */
+#define vTraceSetStreamBufferName(object, name) /* Do nothing */
+#endif /* (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1) */
+
+#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1)
+/*******************************************************************************
+ * vTraceSetMessageBufferName(void* object, const char* name)
+ *
+ * Parameter object: pointer to the MessageBuffer that shall be named
+ * Parameter name: the name to set (const string literal)
+ *
+ * Sets a name for MessageBuffer objects for display in Tracealyzer.
+ ******************************************************************************/
+void vTraceSetMessageBufferName(void* object, const char* name);
+#else /* (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1) */
+#define vTraceSetMessageBufferName(object, name) /* Do nothing */
+#endif /* (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1) */
+
+#if defined (TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1)
+void prvAddTaskToStackMonitor(void* task);
+void prvRemoveTaskFromStackMonitor(void* task);
+#else /* defined (TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) */
+#define prvAddTaskToStackMonitor(task)
+#define prvRemoveTaskFromStackMonitor(task)
+#endif /* defined (TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) */
+
+#else /* (TRC_CFG_SCHEDULING_ONLY == 0) */
+
+#define vTraceSetQueueName(object, name) /* Do nothing */
+#define vTraceSetSemaphoreName(object, name) /* Do nothing */
+#define vTraceSetMutexName(object, name) /* Do nothing */
+#define vTraceSetEventGroupName(object, name) /* Do nothing */
+#define vTraceSetStreamBufferName(object, name) /* Do nothing */
+#define vTraceSetMessageBufferName(object, name) /* Do nothing */
+#define prvAddTaskToStackMonitor(task) /* Do nothing */
+#define prvRemoveTaskFromStackMonitor(task) /* Do nothing */
+
+#endif /* (TRC_CFG_SCHEDULING_ONLY == 0) */
+
+/*******************************************************************************
+ * Note: Setting names for event groups is difficult to support, this has been
+ * excluded intentionally. This since we don't know if event_groups.c is
+ * included in the build, so referencing it from the recorder may cause errors.
+ ******************************************************************************/
+
+/* Gives the currently executing task (wrapper for RTOS-specific function) */
+void* prvTraceGetCurrentTaskHandle(void);
+
+#if (((TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT) && (TRC_CFG_INCLUDE_ISR_TRACING == 1)) || (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING))
+/* Tells if the scheduler currently is suspended (task-switches can't occur) */
+unsigned char prvTraceIsSchedulerSuspended(void);
+
+/*******************************************************************************
+ * INCLUDE_xTaskGetSchedulerState must be set to 1 for tracing to work properly
+ ******************************************************************************/
+#undef INCLUDE_xTaskGetSchedulerState
+#define INCLUDE_xTaskGetSchedulerState 1
+
+#endif /* (((TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT) && (TRC_CFG_INCLUDE_ISR_TRACING == 1)) || (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)) */
+
+#define TRACE_KERNEL_VERSION 0x1AA1
+#define TRACE_TICK_RATE_HZ configTICK_RATE_HZ /* Defined in "FreeRTOS.h" */
+#define TRACE_CPU_CLOCK_HZ configCPU_CLOCK_HZ /* Defined in "FreeRTOSConfig.h" */
+#define TRACE_GET_CURRENT_TASK() prvTraceGetCurrentTaskHandle()
+
+#define TRACE_GET_OS_TICKS() (uiTraceTickCount) /* Streaming only */
+
+/* If using dynamic allocation of snapshot trace buffer... */
+#define TRACE_MALLOC(size) pvPortMalloc(size)
+
+#if defined(configUSE_TIMERS)
+#if (configUSE_TIMERS == 1)
+#undef INCLUDE_xTimerGetTimerDaemonTaskHandle
+#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1
+#endif /* configUSE_TIMERS == 1*/
+#endif /* configUSE_TIMERS */
+
+/* For ARM Cortex-M devices - assumes the ARM CMSIS API is available */
+#if (defined (__CORTEX_M))
+ #define TRACE_ALLOC_CRITICAL_SECTION() uint32_t __irq_status;
+ #define TRACE_ENTER_CRITICAL_SECTION() {__irq_status = __get_PRIMASK(); __set_PRIMASK(1);} /* PRIMASK disables ALL interrupts - allows for tracing in any ISR */
+ #define TRACE_EXIT_CRITICAL_SECTION() {__set_PRIMASK(__irq_status);}
+#endif
+
+#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_CORTEX_A9) || (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XILINX_ZyncUltraScaleR5)
+
+ /**************************************************************************
+ * Disables "FreeRTOS-enabled" interrupts only , i.e. with priorities up to
+ * configMAX_API_CALL_INTERRUPT_PRIORITY. Don't add tracing in ISRs with
+ * greater priority.
+ *************************************************************************/
+
+ extern int cortex_a9_r5_enter_critical(void);
+ extern void cortex_a9_r5_exit_critical(int irq_already_masked_at_enter);
+
+ #define TRACE_ALLOC_CRITICAL_SECTION() uint32_t __irq_mask_status;
+
+ #define TRACE_ENTER_CRITICAL_SECTION() { __irq_mask_status = cortex_a9_r5_enter_critical(); }
+
+ #define TRACE_EXIT_CRITICAL_SECTION() { cortex_a9_r5_exit_critical(__irq_mask_status); }
+
+#endif
+
+#if ( (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Renesas_RX600) || (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_MICROCHIP_PIC24_PIC32))
+ #define TRACE_ALLOC_CRITICAL_SECTION() int __irq_status;
+ #define TRACE_ENTER_CRITICAL_SECTION() {__irq_status = portSET_INTERRUPT_MASK_FROM_ISR();}
+ #define TRACE_EXIT_CRITICAL_SECTION() {portCLEAR_INTERRUPT_MASK_FROM_ISR(__irq_status);}
+#endif
+
+#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Altera_NiosII)
+ #include "system.h"
+ #include "sys/alt_irq.h"
+ #define TRACE_ALLOC_CRITICAL_SECTION() alt_irq_context __irq_status;
+ #define TRACE_ENTER_CRITICAL_SECTION(){__irq_status = alt_irq_disable_all();}
+ #define TRACE_EXIT_CRITICAL_SECTION() {alt_irq_enable_all(__irq_status);}
+#endif
+
+#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Win32)
+ /* In the Win32 port, there are no real interrupts, so we can use the normal critical sections */
+ #define TRACE_ALLOC_CRITICAL_SECTION()
+ #define TRACE_ENTER_CRITICAL_SECTION() portENTER_CRITICAL()
+ #define TRACE_EXIT_CRITICAL_SECTION() portEXIT_CRITICAL()
+#endif
+
+#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_POWERPC_Z4)
+#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X)
+ /* FreeRTOS v8.0 or later */
+ #define TRACE_ALLOC_CRITICAL_SECTION() UBaseType_t __irq_status;
+ #define TRACE_ENTER_CRITICAL_SECTION() {__irq_status = portSET_INTERRUPT_MASK_FROM_ISR();}
+ #define TRACE_EXIT_CRITICAL_SECTION() {portCLEAR_INTERRUPT_MASK_FROM_ISR(__irq_status);}
+#else
+ /* FreeRTOS v7.x */
+ #define TRACE_ALLOC_CRITICAL_SECTION() unsigned portBASE_TYPE __irq_status;
+ #define TRACE_ENTER_CRITICAL_SECTION() {__irq_status = portSET_INTERRUPT_MASK_FROM_ISR();}
+ #define TRACE_EXIT_CRITICAL_SECTION() {portCLEAR_INTERRUPT_MASK_FROM_ISR(__irq_status);}
+#endif
+#endif
+
+#ifndef TRACE_ENTER_CRITICAL_SECTION
+ #error "This hardware port has no definition for critical sections! See http://percepio.com/2014/10/27/how-to-define-critical-sections-for-the-recorder/"
+#endif
+
+
+#if (TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_0_1)
+ /******************************************************************************
+ * Fix for FreeRTOS v9.0.1 to correctly identify xQueuePeek events.
+ *
+ * In FreeRTOS v9.0.1, the below trace hooks are incorrectly used from three
+ * different functions. This as the earlier function xQueueGenericReceive
+ * has been replaced by xQueuePeek, xQueueSemaphoreTake and xQueueReceive.
+ *
+ * xQueueGenericReceive had a parameter "xJustPeeking", used by the trace hooks
+ * to tell between xQueuePeek events and others. This is no longer present, so
+ * we need another way to correctly identify peek events. Since all three
+ * functions call the same trace macros, the context of these macro is unknown.
+ *
+ * We therefore check the __LINE__ macro inside of the trace macros. This gives
+ * the line number of queue.c, where the macros are used. This can be used to
+ * tell if the context is xQueuePeek or another function.
+ * __LINE__ is a standard compiler feature since ancient times, so it should
+ * work on all common compilers.
+ *
+ * This might seem as a quite brittle and unusual solution, but works in this
+ * particular case and is only for FreeRTOS v9.0.1.
+ * Future versions of FreeRTOS should not need this fix, as we have submitted
+ * a correction of queue.c with individual trace macros for each function.
+ ******************************************************************************/
+#define isQueueReceiveHookActuallyPeek (__LINE__ > 1674) /* Half way between the closes trace points */
+
+#elif (TRC_CFG_FREERTOS_VERSION <= TRC_FREERTOS_VERSION_9_0_0)
+#define isQueueReceiveHookActuallyPeek xJustPeeking
+
+#elif (TRC_CFG_FREERTOS_VERSION > TRC_FREERTOS_VERSION_9_0_1)
+#define isQueueReceiveHookActuallyPeek (__LINE__ < 0) /* instead of pdFALSE to fix a warning of "constant condition" */
+
+#endif
+
+extern uint16_t CurrentFilterMask;
+
+extern uint16_t CurrentFilterGroup;
+
+uint8_t prvTraceGetQueueType(void* handle);
+uint16_t prvTraceGetTaskNumberLow16(void* handle);
+uint16_t prvTraceGetTaskNumberHigh16(void* handle);
+void prvTraceSetTaskNumberLow16(void* handle, uint16_t value);
+void prvTraceSetTaskNumberHigh16(void* handle, uint16_t value);
+
+uint16_t prvTraceGetQueueNumberLow16(void* handle);
+uint16_t prvTraceGetQueueNumberHigh16(void* handle);
+void prvTraceSetQueueNumberLow16(void* handle, uint16_t value);
+void prvTraceSetQueueNumberHigh16(void* handle, uint16_t value);
+
+#if (TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
+uint16_t prvTraceGetTimerNumberLow16(void* handle);
+uint16_t prvTraceGetTimerNumberHigh16(void* handle);
+void prvTraceSetTimerNumberLow16(void* handle, uint16_t value);
+void prvTraceSetTimerNumberHigh16(void* handle, uint16_t value);
+#endif /* (TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
+
+#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
+uint16_t prvTraceGetEventGroupNumberLow16(void* handle);
+uint16_t prvTraceGetEventGroupNumberHigh16(void* handle);
+void prvTraceSetEventGroupNumberLow16(void* handle, uint16_t value);
+void prvTraceSetEventGroupNumberHigh16(void* handle, uint16_t value);
+#endif /* (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
+
+#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
+uint16_t prvTraceGetStreamBufferNumberLow16(void* handle);
+uint16_t prvTraceGetStreamBufferNumberHigh16(void* handle);
+void prvTraceSetStreamBufferNumberLow16(void* handle, uint16_t value);
+void prvTraceSetStreamBufferNumberHigh16(void* handle, uint16_t value);
+#endif /* (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
+
+#define TRACE_GET_TASK_FILTER(pxTask) prvTraceGetTaskNumberHigh16((void*)pxTask)
+#define TRACE_SET_TASK_FILTER(pxTask, group) prvTraceSetTaskNumberHigh16((void*)pxTask, group)
+
+#define TRACE_GET_QUEUE_FILTER(pxObject) prvTraceGetQueueNumberHigh16((void*)pxObject)
+#define TRACE_SET_QUEUE_FILTER(pxObject, group) prvTraceSetQueueNumberHigh16((void*)pxObject, group)
+
+#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
+#define TRACE_GET_EVENTGROUP_FILTER(pxObject) prvTraceGetEventGroupNumberHigh16((void*)pxObject)
+#define TRACE_SET_EVENTGROUP_FILTER(pxObject, group) prvTraceSetEventGroupNumberHigh16((void*)pxObject, group)
+#else /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
+/* FreeRTOS versions before v10.0 does not support filtering for event groups */
+#define TRACE_GET_EVENTGROUP_FILTER(pxObject) 1
+#define TRACE_SET_EVENTGROUP_FILTER(pxObject, group)
+#endif /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
+
+#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
+#define TRACE_GET_TIMER_FILTER(pxObject) prvTraceGetTimerNumberHigh16((void*)pxObject)
+#define TRACE_SET_TIMER_FILTER(pxObject, group) prvTraceSetTimerNumberHigh16((void*)pxObject, group)
+#else /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
+/* FreeRTOS versions before v10.0 does not support filtering for timers */
+#define TRACE_GET_TIMER_FILTER(pxObject) 1
+#define TRACE_SET_TIMER_FILTER(pxObject, group)
+#endif /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
+
+#define TRACE_GET_STREAMBUFFER_FILTER(pxObject) prvTraceGetStreamBufferNumberHigh16((void*)pxObject)
+#define TRACE_SET_STREAMBUFFER_FILTER(pxObject, group) prvTraceSetStreamBufferNumberHigh16((void*)pxObject, group)
+
+/* We can only support filtering if FreeRTOS is at least v8.0 */
+#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X)
+#define TRACE_GET_OBJECT_FILTER(CLASS, pxObject) TRACE_GET_##CLASS##_FILTER(pxObject)
+#define TRACE_SET_OBJECT_FILTER(CLASS, pxObject, group) TRACE_SET_##CLASS##_FILTER(pxObject, group)
+#else /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X) */
+#define TRACE_GET_OBJECT_FILTER(CLASS, pxObject) 0xFFFF
+#define TRACE_SET_OBJECT_FILTER(CLASS, pxObject, group)
+#endif /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X) */
+
+/* Helpers needed to correctly expand names */
+#define TZ__CAT2(a,b) a ## b
+#define TZ__CAT(a,b) TZ__CAT2(a, b)
+
+/**************************************************************************/
+/* Makes sure xQueueGiveFromISR also has a xCopyPosition parameter */
+/**************************************************************************/
+
+/* Expands name if this header is included... uxQueueType must be a macro that only exists in queue.c or whatever, and it must expand to nothing or to something that's valid in identifiers */
+#define xQueueGiveFromISR(a,b) TZ__CAT(xQueueGiveFromISR__, uxQueueType) (a,b)
+
+/* If in queue.c, the "uxQueueType" macro expands to "pcHead". queueSEND_TO_BACK is the value we need to send in */
+#define xQueueGiveFromISR__pcHead(__a, __b) MyWrapper_xQueueGiveFromISR(__a, __b, const BaseType_t xCopyPosition); \
+BaseType_t xQueueGiveFromISR(__a, __b) { return MyWrapper_xQueueGiveFromISR(xQueue, pxHigherPriorityTaskWoken, queueSEND_TO_BACK); } \
+BaseType_t MyWrapper_xQueueGiveFromISR(__a, __b, const BaseType_t xCopyPosition)
+
+/* If not in queue.c, "uxQueueType" isn't expanded */
+#define xQueueGiveFromISR__uxQueueType(__a, __b) xQueueGiveFromISR(__a,__b)
+
+/**************************************************************************/
+/* End of xQueueGiveFromISR fix */
+/**************************************************************************/
+
+/******************************************************************************/
+/*** Definitions for Snapshot mode ********************************************/
+/******************************************************************************/
+#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)
+
+/*** The object classes *******************************************************/
+
+#define TRACE_NCLASSES 9
+#define TRACE_CLASS_QUEUE ((traceObjectClass)0)
+#define TRACE_CLASS_SEMAPHORE ((traceObjectClass)1)
+#define TRACE_CLASS_MUTEX ((traceObjectClass)2)
+#define TRACE_CLASS_TASK ((traceObjectClass)3)
+#define TRACE_CLASS_ISR ((traceObjectClass)4)
+#define TRACE_CLASS_TIMER ((traceObjectClass)5)
+#define TRACE_CLASS_EVENTGROUP ((traceObjectClass)6)
+#define TRACE_CLASS_STREAMBUFFER ((traceObjectClass)7)
+#define TRACE_CLASS_MESSAGEBUFFER ((traceObjectClass)8)
+
+/*** Definitions for Object Table ********************************************/
+#define TRACE_KERNEL_OBJECT_COUNT ((TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER) + (TRC_CFG_NEVENTGROUP) + (TRC_CFG_NSTREAMBUFFER) + (TRC_CFG_NMESSAGEBUFFER))
+
+/* Queue properties (except name): current number of message in queue */
+#define PropertyTableSizeQueue ((TRC_CFG_NAME_LEN_QUEUE) + 1)
+
+/* Semaphore properties (except name): state (signaled = 1, cleared = 0) */
+#define PropertyTableSizeSemaphore ((TRC_CFG_NAME_LEN_SEMAPHORE) + 1)
+
+/* Mutex properties (except name): owner (task handle, 0 = free) */
+#define PropertyTableSizeMutex ((TRC_CFG_NAME_LEN_MUTEX) + 1)
+
+/* Task properties (except name): Byte 0: Current priority
+ Byte 1: state (if already active)
+ Byte 2: legacy, not used
+ Byte 3: legacy, not used */
+#define PropertyTableSizeTask ((TRC_CFG_NAME_LEN_TASK) + 4)
+
+/* ISR properties: Byte 0: priority
+ Byte 1: state (if already active) */
+#define PropertyTableSizeISR ((TRC_CFG_NAME_LEN_ISR) + 2)
+
+/* TRC_CFG_NTIMER properties: Byte 0: state (unused for now) */
+#define PropertyTableSizeTimer ((TRC_CFG_NAME_LEN_TIMER) + 1)
+
+/* TRC_CFG_NEVENTGROUP properties: Byte 0-3: state (unused for now)*/
+#define PropertyTableSizeEventGroup ((TRC_CFG_NAME_LEN_EVENTGROUP) + 4)
+
+/* TRC_CFG_NSTREAMBUFFER properties: Byte 0-3: state (unused for now)*/
+#define PropertyTableSizeStreamBuffer ((TRC_CFG_NAME_LEN_STREAMBUFFER) + 4)
+
+/* TRC_CFG_NMESSAGEBUFFER properties: Byte 0-3: state (unused for now)*/
+#define PropertyTableSizeMessageBuffer ((TRC_CFG_NAME_LEN_MESSAGEBUFFER) + 4)
+
+
+/* The layout of the byte array representing the Object Property Table */
+#define StartIndexQueue (0)
+#define StartIndexSemaphore (StartIndexQueue + (TRC_CFG_NQUEUE) * PropertyTableSizeQueue)
+#define StartIndexMutex (StartIndexSemaphore + (TRC_CFG_NSEMAPHORE) * PropertyTableSizeSemaphore)
+#define StartIndexTask (StartIndexMutex + (TRC_CFG_NMUTEX) * PropertyTableSizeMutex)
+#define StartIndexISR (StartIndexTask + (TRC_CFG_NTASK) * PropertyTableSizeTask)
+#define StartIndexTimer (StartIndexISR + (TRC_CFG_NISR) * PropertyTableSizeISR)
+#define StartIndexEventGroup (StartIndexTimer + (TRC_CFG_NTIMER) * PropertyTableSizeTimer)
+#define StartIndexStreamBuffer (StartIndexEventGroup + (TRC_CFG_NEVENTGROUP) * PropertyTableSizeEventGroup)
+#define StartIndexMessageBuffer (StartIndexStreamBuffer + (TRC_CFG_NSTREAMBUFFER) * PropertyTableSizeStreamBuffer)
+
+/* Number of bytes used by the object table */
+#define TRACE_OBJECT_TABLE_SIZE (StartIndexMessageBuffer + (TRC_CFG_NMESSAGEBUFFER) * PropertyTableSizeMessageBuffer)
+
+/* Flag to tell the context of tracePEND_FUNC_CALL_FROM_ISR */
+extern int uiInEventGroupSetBitsFromISR;
+
+/* Initialization of the object property table */
+void vTraceInitObjectPropertyTable(void);
+
+/* Initialization of the handle mechanism, see e.g, prvTraceGetObjectHandle */
+void vTraceInitObjectHandleStack(void);
+
+/* Returns the "Not enough handles" error message for the specified object class */
+const char* pszTraceGetErrorNotEnoughHandles(traceObjectClass objectclass);
+
+void* prvTraceGetCurrentTaskHandle(void);
+
+/******************************************************************************
+ * TraceQueueClassTable
+ * Translates a FreeRTOS QueueType into trace objects classes (TRACE_CLASS_).
+ * Has one entry for each QueueType, gives TRACE_CLASS ID.
+ ******************************************************************************/
+extern traceObjectClass TraceQueueClassTable[5];
+
+
+/*** Event codes for snapshot mode - must match Tracealyzer config files ******/
+
+#define NULL_EVENT (0x00UL)
+
+/*******************************************************************************
+ * EVENTGROUP_DIV
+ *
+ * Miscellaneous events.
+ ******************************************************************************/
+#define EVENTGROUP_DIV (NULL_EVENT + 1UL) /*0x01*/
+#define DIV_XPS (EVENTGROUP_DIV + 0UL) /*0x01*/
+#define DIV_TASK_READY (EVENTGROUP_DIV + 1UL) /*0x02*/
+#define DIV_NEW_TIME (EVENTGROUP_DIV + 2UL) /*0x03*/
+
+/*******************************************************************************
+ * EVENTGROUP_TS
+ *
+ * Events for storing task-switches and interrupts. The RESUME events are
+ * generated if the task/interrupt is already marked active.
+ ******************************************************************************/
+#define EVENTGROUP_TS (EVENTGROUP_DIV + 3UL) /*0x04*/
+#define TS_ISR_BEGIN (EVENTGROUP_TS + 0UL) /*0x04*/
+#define TS_ISR_RESUME (EVENTGROUP_TS + 1UL) /*0x05*/
+#define TS_TASK_BEGIN (EVENTGROUP_TS + 2UL) /*0x06*/
+#define TS_TASK_RESUME (EVENTGROUP_TS + 3UL) /*0x07*/
+
+/*******************************************************************************
+ * EVENTGROUP_OBJCLOSE_NAME
+ *
+ * About Close Events
+ * When an object is evicted from the object property table (object close), two
+ * internal events are stored (EVENTGROUP_OBJCLOSE_NAME and
+ * EVENTGROUP_OBJCLOSE_PROP), containing the handle-name mapping and object
+ * properties valid up to this point.
+ ******************************************************************************/
+#define EVENTGROUP_OBJCLOSE_NAME_TRCSUCCESS (EVENTGROUP_TS + 4UL) /*0x08*/
+
+/*******************************************************************************
+ * EVENTGROUP_OBJCLOSE_PROP
+ *
+ * The internal event carrying properties of deleted objects
+ * The handle and object class of the closed object is not stored in this event,
+ * but is assumed to be the same as in the preceding CLOSE event. Thus, these
+ * two events must be generated from within a critical section.
+ * When queues are closed, arg1 is the "state" property (i.e., number of
+ * buffered messages/signals).
+ * When actors are closed, arg1 is priority, arg2 is handle of the "instance
+ * finish" event, and arg3 is event code of the "instance finish" event.
+ * In this case, the lower three bits is the object class of the instance finish
+ * handle. The lower three bits are not used (always zero) when queues are
+ * closed since the queue type is given in the previous OBJCLOSE_NAME event.
+ ******************************************************************************/
+#define EVENTGROUP_OBJCLOSE_PROP_TRCSUCCESS (EVENTGROUP_OBJCLOSE_NAME_TRCSUCCESS + 8UL) /*0x10*/
+
+/*******************************************************************************
+ * EVENTGROUP_CREATE
+ *
+ * The events in this group are used to log Kernel object creations.
+ * The lower three bits in the event code gives the object class, i.e., type of
+ * create operation (task, queue, semaphore, etc).
+ ******************************************************************************/
+#define EVENTGROUP_CREATE_OBJ_TRCSUCCESS (EVENTGROUP_OBJCLOSE_PROP_TRCSUCCESS + 8UL) /*0x18*/
+
+/*******************************************************************************
+ * EVENTGROUP_SEND
+ *
+ * The events in this group are used to log Send/Give events on queues,
+ * semaphores and mutexes The lower three bits in the event code gives the
+ * object class, i.e., what type of object that is operated on (queue, semaphore
+ * or mutex).
+ ******************************************************************************/
+#define EVENTGROUP_SEND_TRCSUCCESS (EVENTGROUP_CREATE_OBJ_TRCSUCCESS + 8UL) /*0x20*/
+
+/*******************************************************************************
+ * EVENTGROUP_RECEIVE
+ *
+ * The events in this group are used to log Receive/Take events on queues,
+ * semaphores and mutexes. The lower three bits in the event code gives the
+ * object class, i.e., what type of object that is operated on (queue, semaphore
+ * or mutex).
+ ******************************************************************************/
+#define EVENTGROUP_RECEIVE_TRCSUCCESS (EVENTGROUP_SEND_TRCSUCCESS + 8UL) /*0x28*/
+
+/* Send/Give operations, from ISR */
+#define EVENTGROUP_SEND_FROM_ISR_TRCSUCCESS \
+ (EVENTGROUP_RECEIVE_TRCSUCCESS + 8UL) /*0x30*/
+
+/* Receive/Take operations, from ISR */
+#define EVENTGROUP_RECEIVE_FROM_ISR_TRCSUCCESS \
+ (EVENTGROUP_SEND_FROM_ISR_TRCSUCCESS + 8UL) /*0x38*/
+
+/* "Failed" event type versions of above (timeout, failed allocation, etc) */
+#define EVENTGROUP_KSE_TRCFAILED \
+ (EVENTGROUP_RECEIVE_FROM_ISR_TRCSUCCESS + 8UL) /*0x40*/
+
+/* Failed create calls - memory allocation failed */
+#define EVENTGROUP_CREATE_OBJ_TRCFAILED (EVENTGROUP_KSE_TRCFAILED) /*0x40*/
+
+/* Failed send/give - timeout! */
+#define EVENTGROUP_SEND_TRCFAILED (EVENTGROUP_CREATE_OBJ_TRCFAILED + 8UL) /*0x48*/
+
+/* Failed receive/take - timeout! */
+#define EVENTGROUP_RECEIVE_TRCFAILED (EVENTGROUP_SEND_TRCFAILED + 8UL) /*0x50*/
+
+/* Failed non-blocking send/give - queue full */
+#define EVENTGROUP_SEND_FROM_ISR_TRCFAILED (EVENTGROUP_RECEIVE_TRCFAILED + 8UL) /*0x58*/
+
+/* Failed non-blocking receive/take - queue empty */
+#define EVENTGROUP_RECEIVE_FROM_ISR_TRCFAILED \
+ (EVENTGROUP_SEND_FROM_ISR_TRCFAILED + 8UL) /*0x60*/
+
+/* Events when blocking on receive/take */
+#define EVENTGROUP_RECEIVE_TRCBLOCK \
+ (EVENTGROUP_RECEIVE_FROM_ISR_TRCFAILED + 8UL) /*0x68*/
+
+/* Events when blocking on send/give */
+#define EVENTGROUP_SEND_TRCBLOCK (EVENTGROUP_RECEIVE_TRCBLOCK + 8UL) /*0x70*/
+
+/* Events on queue peek (receive) */
+#define EVENTGROUP_PEEK_TRCSUCCESS (EVENTGROUP_SEND_TRCBLOCK + 8UL) /*0x78*/
+
+/* Events on object delete (vTaskDelete or vQueueDelete) */
+#define EVENTGROUP_DELETE_OBJ_TRCSUCCESS (EVENTGROUP_PEEK_TRCSUCCESS + 8UL) /*0x80*/
+
+/* Other events - object class is implied: TASK */
+#define EVENTGROUP_OTHERS (EVENTGROUP_DELETE_OBJ_TRCSUCCESS + 8UL) /*0x88*/
+#define TASK_DELAY_UNTIL (EVENTGROUP_OTHERS + 0UL) /*0x88*/
+#define TASK_DELAY (EVENTGROUP_OTHERS + 1UL) /*0x89*/
+#define TASK_SUSPEND (EVENTGROUP_OTHERS + 2UL) /*0x8A*/
+#define TASK_RESUME (EVENTGROUP_OTHERS + 3UL) /*0x8B*/
+#define TASK_RESUME_FROM_ISR (EVENTGROUP_OTHERS + 4UL) /*0x8C*/
+#define TASK_PRIORITY_SET (EVENTGROUP_OTHERS + 5UL) /*0x8D*/
+#define TASK_PRIORITY_INHERIT (EVENTGROUP_OTHERS + 6UL) /*0x8E*/
+#define TASK_PRIORITY_DISINHERIT (EVENTGROUP_OTHERS + 7UL) /*0x8F*/
+
+#define EVENTGROUP_MISC_PLACEHOLDER (EVENTGROUP_OTHERS + 8UL) /*0x90*/
+#define PEND_FUNC_CALL (EVENTGROUP_MISC_PLACEHOLDER+0UL) /*0x90*/
+#define PEND_FUNC_CALL_FROM_ISR (EVENTGROUP_MISC_PLACEHOLDER+1UL) /*0x91*/
+#define PEND_FUNC_CALL_TRCFAILED (EVENTGROUP_MISC_PLACEHOLDER+2UL) /*0x92*/
+#define PEND_FUNC_CALL_FROM_ISR_TRCFAILED (EVENTGROUP_MISC_PLACEHOLDER+3UL) /*0x93*/
+#define MEM_MALLOC_SIZE (EVENTGROUP_MISC_PLACEHOLDER+4UL) /*0x94*/
+#define MEM_MALLOC_ADDR (EVENTGROUP_MISC_PLACEHOLDER+5UL) /*0x95*/
+#define MEM_FREE_SIZE (EVENTGROUP_MISC_PLACEHOLDER+6UL) /*0x96*/
+#define MEM_FREE_ADDR (EVENTGROUP_MISC_PLACEHOLDER+7UL) /*0x97*/
+
+/* User events */
+#define EVENTGROUP_USEREVENT (EVENTGROUP_MISC_PLACEHOLDER + 8UL) /*0x98*/
+#define USER_EVENT (EVENTGROUP_USEREVENT + 0UL)
+
+/* Allow for 0-15 arguments (the number of args is added to event code) */
+#define USER_EVENT_LAST (EVENTGROUP_USEREVENT + 15UL) /*0xA7*/
+
+/*******************************************************************************
+ * XTS Event - eXtended TimeStamp events
+ * The timestamps used in the recorder are "differential timestamps" (DTS), i.e.
+ * the time since the last stored event. The DTS fields are either 1 or 2 bytes
+ * in the other events, depending on the bytes available in the event struct.
+ * If the time since the last event (the DTS) is larger than allowed for by
+ * the DTS field of the current event, an XTS event is inserted immediately
+ * before the original event. The XTS event contains up to 3 additional bytes
+ * of the DTS value - the higher bytes of the true DTS value. The lower 1-2
+ * bytes are stored in the normal DTS field.
+ * There are two types of XTS events, XTS8 and XTS16. An XTS8 event is stored
+ * when there is only room for 1 byte (8 bit) DTS data in the original event,
+ * which means a limit of 0xFF (255UL). The XTS16 is used when the original event
+ * has a 16 bit DTS field and thereby can handle values up to 0xFFFF (65535UL).
+ *
+ * Using a very high frequency time base can result in many XTS events.
+ * Preferably, the time between two OS ticks should fit in 16 bits, i.e.,
+ * at most 65535. If your time base has a higher frequency, you can define
+ * the TRACE
+ ******************************************************************************/
+
+#define EVENTGROUP_SYS (EVENTGROUP_USEREVENT + 16UL) /*0xA8*/
+#define XTS8 (EVENTGROUP_SYS + 0UL) /*0xA8*/
+#define XTS16 (EVENTGROUP_SYS + 1UL) /*0xA9*/
+#define EVENT_BEING_WRITTEN (EVENTGROUP_SYS + 2UL) /*0xAA*/
+#define RESERVED_DUMMY_CODE (EVENTGROUP_SYS + 3UL) /*0xAB*/
+#define LOW_POWER_BEGIN (EVENTGROUP_SYS + 4UL) /*0xAC*/
+#define LOW_POWER_END (EVENTGROUP_SYS + 5UL) /*0xAD*/
+#define XID (EVENTGROUP_SYS + 6UL) /*0xAE*/
+#define XTS16L (EVENTGROUP_SYS + 7UL) /*0xAF*/
+
+#define EVENTGROUP_TIMER (EVENTGROUP_SYS + 8UL) /*0xB0*/
+#define TIMER_CREATE (EVENTGROUP_TIMER + 0UL) /*0xB0*/
+#define TIMER_START (EVENTGROUP_TIMER + 1UL) /*0xB1*/
+#define TIMER_RST (EVENTGROUP_TIMER + 2UL) /*0xB2*/
+#define TIMER_STOP (EVENTGROUP_TIMER + 3UL) /*0xB3*/
+#define TIMER_CHANGE_PERIOD (EVENTGROUP_TIMER + 4UL) /*0xB4*/
+#define TIMER_DELETE_OBJ (EVENTGROUP_TIMER + 5UL) /*0xB5*/
+#define TIMER_START_FROM_ISR (EVENTGROUP_TIMER + 6UL) /*0xB6*/
+#define TIMER_RESET_FROM_ISR (EVENTGROUP_TIMER + 7UL) /*0xB7*/
+#define TIMER_STOP_FROM_ISR (EVENTGROUP_TIMER + 8UL) /*0xB8*/
+
+#define TIMER_CREATE_TRCFAILED (EVENTGROUP_TIMER + 9UL) /*0xB9*/
+#define TIMER_START_TRCFAILED (EVENTGROUP_TIMER + 10UL) /*0xBA*/
+#define TIMER_RESET_TRCFAILED (EVENTGROUP_TIMER + 11UL) /*0xBB*/
+#define TIMER_STOP_TRCFAILED (EVENTGROUP_TIMER + 12UL) /*0xBC*/
+#define TIMER_CHANGE_PERIOD_TRCFAILED (EVENTGROUP_TIMER + 13UL) /*0xBD*/
+#define TIMER_DELETE_TRCFAILED (EVENTGROUP_TIMER + 14UL) /*0xBE*/
+#define TIMER_START_FROM_ISR_TRCFAILED (EVENTGROUP_TIMER + 15UL) /*0xBF*/
+#define TIMER_RESET_FROM_ISR_TRCFAILED (EVENTGROUP_TIMER + 16UL) /*0xC0*/
+#define TIMER_STOP_FROM_ISR_TRCFAILED (EVENTGROUP_TIMER + 17UL) /*0xC1*/
+
+#define EVENTGROUP_EG (EVENTGROUP_TIMER + 18UL) /*0xC2*/
+#define EVENT_GROUP_CREATE (EVENTGROUP_EG + 0UL) /*0xC2*/
+#define EVENT_GROUP_CREATE_TRCFAILED (EVENTGROUP_EG + 1UL) /*0xC3*/
+#define EVENT_GROUP_SYNC_TRCBLOCK (EVENTGROUP_EG + 2UL) /*0xC4*/
+#define EVENT_GROUP_SYNC_END (EVENTGROUP_EG + 3UL) /*0xC5*/
+#define EVENT_GROUP_WAIT_BITS_TRCBLOCK (EVENTGROUP_EG + 4UL) /*0xC6*/
+#define EVENT_GROUP_WAIT_BITS_END (EVENTGROUP_EG + 5UL) /*0xC7*/
+#define EVENT_GROUP_CLEAR_BITS (EVENTGROUP_EG + 6UL) /*0xC8*/
+#define EVENT_GROUP_CLEAR_BITS_FROM_ISR (EVENTGROUP_EG + 7UL) /*0xC9*/
+#define EVENT_GROUP_SET_BITS (EVENTGROUP_EG + 8UL) /*0xCA*/
+#define EVENT_GROUP_DELETE_OBJ (EVENTGROUP_EG + 9UL) /*0xCB*/
+#define EVENT_GROUP_SYNC_END_TRCFAILED (EVENTGROUP_EG + 10UL) /*0xCC*/
+#define EVENT_GROUP_WAIT_BITS_END_TRCFAILED (EVENTGROUP_EG + 11UL) /*0xCD*/
+#define EVENT_GROUP_SET_BITS_FROM_ISR (EVENTGROUP_EG + 12UL) /*0xCE*/
+#define EVENT_GROUP_SET_BITS_FROM_ISR_TRCFAILED (EVENTGROUP_EG + 13UL) /*0xCF*/
+
+#define TASK_INSTANCE_FINISHED_NEXT_KSE (EVENTGROUP_EG + 14UL) /*0xD0*/
+#define TASK_INSTANCE_FINISHED_DIRECT (EVENTGROUP_EG + 15UL) /*0xD1*/
+
+#define TRACE_TASK_NOTIFY_GROUP (EVENTGROUP_EG + 16UL) /*0xD2*/
+#define TRACE_TASK_NOTIFY (TRACE_TASK_NOTIFY_GROUP + 0UL) /*0xD2*/
+#define TRACE_TASK_NOTIFY_TAKE (TRACE_TASK_NOTIFY_GROUP + 1UL) /*0xD3*/
+#define TRACE_TASK_NOTIFY_TAKE_TRCBLOCK (TRACE_TASK_NOTIFY_GROUP + 2UL) /*0xD4*/
+#define TRACE_TASK_NOTIFY_TAKE_TRCFAILED (TRACE_TASK_NOTIFY_GROUP + 3UL) /*0xD5*/
+#define TRACE_TASK_NOTIFY_WAIT (TRACE_TASK_NOTIFY_GROUP + 4UL) /*0xD6*/
+#define TRACE_TASK_NOTIFY_WAIT_TRCBLOCK (TRACE_TASK_NOTIFY_GROUP + 5UL) /*0xD7*/
+#define TRACE_TASK_NOTIFY_WAIT_TRCFAILED (TRACE_TASK_NOTIFY_GROUP + 6UL) /*0xD8*/
+#define TRACE_TASK_NOTIFY_FROM_ISR (TRACE_TASK_NOTIFY_GROUP + 7UL) /*0xD9*/
+#define TRACE_TASK_NOTIFY_GIVE_FROM_ISR (TRACE_TASK_NOTIFY_GROUP + 8UL) /*0xDA*/
+
+#define TIMER_EXPIRED (TRACE_TASK_NOTIFY_GROUP + 9UL) /*0xDB*/
+
+ /* Events on queue peek (receive) */
+#define EVENTGROUP_PEEK_TRCBLOCK (TRACE_TASK_NOTIFY_GROUP + 10UL) /*0xDC*/
+/* peek block on queue: 0xDC */
+/* peek block on semaphore: 0xDD */
+/* peek block on mutex: 0xDE */
+
+/* Events on queue peek (receive) */
+#define EVENTGROUP_PEEK_TRCFAILED (EVENTGROUP_PEEK_TRCBLOCK + 3UL) /*0xDF*/
+/* peek failed on queue: 0xDF */
+/* peek failed on semaphore: 0xE0 */
+/* peek failed on mutex: 0xE1 */
+
+#define EVENTGROUP_STREAMBUFFER_DIV (EVENTGROUP_PEEK_TRCFAILED + 3UL) /*0xE2*/
+#define TRACE_STREAMBUFFER_RESET (EVENTGROUP_STREAMBUFFER_DIV + 0) /*0xE2*/
+#define TRACE_MESSAGEBUFFER_RESET (EVENTGROUP_STREAMBUFFER_DIV + 1UL) /*0xE3*/
+#define TRACE_STREAMBUFFER_OBJCLOSE_NAME_TRCSUCCESS (EVENTGROUP_STREAMBUFFER_DIV + 2UL) /*0xE4*/
+#define TRACE_MESSAGEBUFFER_OBJCLOSE_NAME_TRCSUCCESS (EVENTGROUP_STREAMBUFFER_DIV + 3UL) /*0xE5*/
+#define TRACE_STREAMBUFFER_OBJCLOSE_PROP_TRCSUCCESS (EVENTGROUP_STREAMBUFFER_DIV + 4UL) /*0xE6*/
+#define TRACE_MESSAGEBUFFER_OBJCLOSE_PROP_TRCSUCCESS (EVENTGROUP_STREAMBUFFER_DIV + 5UL) /*0xE7*/
+
+#define EVENTGROUP_MALLOC_FAILED (EVENTGROUP_STREAMBUFFER_DIV + 6UL) /*0xE8*/
+#define MEM_MALLOC_SIZE_TRCFAILED (EVENTGROUP_MALLOC_FAILED + 0UL) /*0xE8*/
+#define MEM_MALLOC_ADDR_TRCFAILED (EVENTGROUP_MALLOC_FAILED + 1UL) /*0xE9*/
+
+/* The following are using previously "lost" event codes */
+#define TRACE_STREAMBUFFER_CREATE_OBJ_TRCSUCCESS (EVENTGROUP_CREATE_OBJ_TRCSUCCESS + 4UL) /*0x1C*/
+#define TRACE_STREAMBUFFER_CREATE_OBJ_TRCFAILED (EVENTGROUP_CREATE_OBJ_TRCFAILED + 4UL) /*0x44*/
+#define TRACE_STREAMBUFFER_DELETE_OBJ_TRCSUCCESS (EVENTGROUP_DELETE_OBJ_TRCSUCCESS + 4UL) /*0x84*/
+#define TRACE_STREAMBUFFER_SEND_TRCSUCCESS (EVENTGROUP_SEND_TRCSUCCESS + 3UL) /*0x23*/
+#define TRACE_STREAMBUFFER_SEND_TRCBLOCK (EVENTGROUP_SEND_TRCBLOCK + 3UL) /*0x73*/
+#define TRACE_STREAMBUFFER_SEND_TRCFAILED (EVENTGROUP_SEND_TRCFAILED + 3UL) /*0x4B*/
+#define TRACE_STREAMBUFFER_RECEIVE_TRCSUCCESS (EVENTGROUP_RECEIVE_TRCSUCCESS + 3UL) /*0x2B*/
+#define TRACE_STREAMBUFFER_RECEIVE_TRCBLOCK (EVENTGROUP_RECEIVE_TRCBLOCK + 3UL) /*0x6B*/
+#define TRACE_STREAMBUFFER_RECEIVE_TRCFAILED (EVENTGROUP_RECEIVE_TRCFAILED + 3UL) /*0x53*/
+#define TRACE_STREAMBUFFER_SEND_FROM_ISR_TRCSUCCESS (EVENTGROUP_SEND_FROM_ISR_TRCSUCCESS + 3UL) /*0x33*/
+#define TRACE_STREAMBUFFER_SEND_FROM_ISR_TRCFAILED (EVENTGROUP_SEND_FROM_ISR_TRCFAILED + 3UL) /*0x5B*/
+#define TRACE_STREAMBUFFER_RECEIVE_FROM_ISR_TRCSUCCESS (EVENTGROUP_RECEIVE_FROM_ISR_TRCSUCCESS + 3UL) /*0x3B*/
+#define TRACE_STREAMBUFFER_RECEIVE_FROM_ISR_TRCFAILED (EVENTGROUP_RECEIVE_FROM_ISR_TRCFAILED + 3UL) /*0x63*/
+
+/* The following are using previously "lost" event codes. These macros aren't even directly referenced, instead we do (equivalent STREAMBUFFER code) + 1. */
+#define TRACE_MESSAGEBUFFER_CREATE_OBJ_TRCSUCCESS (EVENTGROUP_CREATE_OBJ_TRCSUCCESS + 5UL) /*0x1D*/
+#define TRACE_MESSAGEBUFFER_CREATE_OBJ_TRCFAILED (EVENTGROUP_CREATE_OBJ_TRCFAILED + 5UL) /*0x45*/
+#define TRACE_MESSAGEBUFFER_DELETE_OBJ_TRCSUCCESS (EVENTGROUP_DELETE_OBJ_TRCSUCCESS + 5UL) /*0x85*/
+#define TRACE_MESSAGEBUFFER_SEND_TRCSUCCESS (EVENTGROUP_SEND_TRCSUCCESS + 4UL) /*0x24*/
+#define TRACE_MESSAGEBUFFER_SEND_TRCBLOCK (EVENTGROUP_SEND_TRCBLOCK + 4UL) /*0x74*/
+#define TRACE_MESSAGEBUFFER_SEND_TRCFAILED (EVENTGROUP_SEND_TRCFAILED + 4UL) /*0x4C*/
+#define TRACE_MESSAGEBUFFER_RECEIVE_TRCSUCCESS (EVENTGROUP_RECEIVE_TRCSUCCESS + 4UL) /*0x2C*/
+#define TRACE_MESSAGEBUFFER_RECEIVE_TRCBLOCK (EVENTGROUP_RECEIVE_TRCBLOCK + 4UL) /*0x6C*/
+#define TRACE_MESSAGEBUFFER_RECEIVE_TRCFAILED (EVENTGROUP_RECEIVE_TRCFAILED + 4UL) /*0x54*/
+#define TRACE_MESSAGEBUFFER_SEND_FROM_ISR_TRCSUCCESS (EVENTGROUP_SEND_FROM_ISR_TRCSUCCESS + 4UL) /*0x34*/
+#define TRACE_MESSAGEBUFFER_SEND_FROM_ISR_TRCFAILED (EVENTGROUP_SEND_FROM_ISR_TRCFAILED + 4UL) /*0x5C*/
+#define TRACE_MESSAGEBUFFER_RECEIVE_FROM_ISR_TRCSUCCESS (EVENTGROUP_RECEIVE_FROM_ISR_TRCSUCCESS + 4UL) /*0x3C*/
+#define TRACE_MESSAGEBUFFER_RECEIVE_FROM_ISR_TRCFAILED (EVENTGROUP_RECEIVE_FROM_ISR_TRCFAILED + 4UL) /*0x64*/
+
+#define TRACE_QUEUE_SEND_TO_FRONT_TRCSUCCESS (EVENTGROUP_SEND_TRCSUCCESS + 5UL) /*0x25*/
+#define TRACE_QUEUE_SEND_TO_FRONT_TRCBLOCK (EVENTGROUP_SEND_TRCBLOCK + 5UL) /*0x75*/
+#define TRACE_QUEUE_SEND_TO_FRONT_TRCFAILED (EVENTGROUP_SEND_TRCFAILED + 5UL) /*0x4D*/
+#define TRACE_QUEUE_SEND_TO_FRONT_FROM_ISR_TRCSUCCESS (EVENTGROUP_SEND_FROM_ISR_TRCSUCCESS + 5UL) /*0x35*/
+#define TRACE_QUEUE_SEND_TO_FRONT_FROM_ISR_TRCFAILED (EVENTGROUP_SEND_FROM_ISR_TRCFAILED + 5UL) /*0x5D*/
+
+#define TRACE_UNUSED_STACK (EVENTGROUP_MALLOC_FAILED + 2UL) /*0xEA*/
+
+/* LAST EVENT (0xEA) */
+
+/****************************
+* MACROS TO GET TRACE CLASS *
+****************************/
+#define TRACE_GET_TRACE_CLASS_FROM_TASK_CLASS(kernelClass) (TRACE_CLASS_TASK)
+#define TRACE_GET_TRACE_CLASS_FROM_TASK_OBJECT(pxObject) (TRACE_CLASS_TASK)
+
+#define TRACE_GET_TRACE_CLASS_FROM_QUEUE_CLASS(kernelClass) TraceQueueClassTable[kernelClass]
+#define TRACE_GET_TRACE_CLASS_FROM_QUEUE_OBJECT(pxObject) TRACE_GET_TRACE_CLASS_FROM_QUEUE_CLASS(prvTraceGetQueueType(pxObject))
+
+#define TRACE_GET_TRACE_CLASS_FROM_TIMER_CLASS(kernelClass) (TRACE_CLASS_TIMER)
+#define TRACE_GET_TRACE_CLASS_FROM_TIMER_OBJECT(pxObject) (TRACE_CLASS_TIMER)
+
+#define TRACE_GET_TRACE_CLASS_FROM_EVENTGROUP_CLASS(kernelClass) (TRACE_CLASS_EVENTGROUP)
+#define TRACE_GET_TRACE_CLASS_FROM_EVENTGROUP_OBJECT(pxObject) (TRACE_CLASS_EVENTGROUP)
+
+/* TRACE_GET_TRACE_CLASS_FROM_STREAMBUFFER_CLASS can only be accessed with a parameter indicating if it is a MessageBuffer */
+#define TRACE_GET_TRACE_CLASS_FROM_STREAMBUFFER_CLASS(xIsMessageBuffer) (xIsMessageBuffer == 1 ? TRACE_CLASS_MESSAGEBUFFER : TRACE_CLASS_STREAMBUFFER)
+#define TRACE_GET_TRACE_CLASS_FROM_STREAMBUFFER_OBJECT(pxObject) (prvGetStreamBufferType(pxObject) == 1 ? TRACE_CLASS_MESSAGEBUFFER : TRACE_CLASS_STREAMBUFFER)
+
+/* Generic versions */
+#define TRACE_GET_CLASS_TRACE_CLASS(CLASS, kernelClass) TRACE_GET_TRACE_CLASS_FROM_##CLASS##_CLASS(kernelClass)
+#define TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject) TRACE_GET_TRACE_CLASS_FROM_##CLASS##_OBJECT(pxObject)
+
+/******************************
+* MACROS TO GET OBJECT NUMBER *
+******************************/
+#define TRACE_GET_TASK_NUMBER(pxTCB) (traceHandle)(prvTraceGetTaskNumberLow16(pxTCB))
+#define TRACE_SET_TASK_NUMBER(pxTCB) prvTraceSetTaskNumberLow16(pxTCB, prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(TASK, pxTCB)));
+
+#define TRACE_GET_QUEUE_NUMBER(queue) ( ( traceHandle ) prvTraceGetQueueNumberLow16(queue) )
+#define TRACE_SET_QUEUE_NUMBER(queue) prvTraceSetQueueNumberLow16(queue, (uint16_t)prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, queue)));
+
+#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
+#define TRACE_GET_TIMER_NUMBER(tmr) ( ( traceHandle ) prvTraceGetTimerNumberLow16(tmr) )
+#define TRACE_SET_TIMER_NUMBER(tmr) prvTraceSetTimerNumberLow16(tmr, (uint16_t)prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(TIMER, tmr)));
+#else /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
+#define TRACE_GET_TIMER_NUMBER(tmr) ( ( traceHandle ) ((Timer_t*)tmr)->uxTimerNumber )
+#define TRACE_SET_TIMER_NUMBER(tmr) ((Timer_t*)tmr)->uxTimerNumber = prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(TIMER, tmr));
+#endif /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
+
+#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
+#define TRACE_GET_EVENTGROUP_NUMBER(eg) ( ( traceHandle ) prvTraceGetEventGroupNumberLow16(eg) )
+#define TRACE_SET_EVENTGROUP_NUMBER(eg) prvTraceSetEventGroupNumberLow16(eg, (uint16_t)prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(EVENTGROUP, eg)));
+#else /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
+#define TRACE_GET_EVENTGROUP_NUMBER(eg) ( ( traceHandle ) uxEventGroupGetNumber(eg) )
+#define TRACE_SET_EVENTGROUP_NUMBER(eg) ((EventGroup_t*)eg)->uxEventGroupNumber = prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(EVENTGROUP, eg));
+#endif /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
+
+
+#define TRACE_GET_STREAMBUFFER_NUMBER(sb) ( ( traceHandle ) prvTraceGetStreamBufferNumberLow16(sb) )
+#define TRACE_SET_STREAMBUFFER_NUMBER(sb) prvTraceSetStreamBufferNumberLow16(sb, (uint16_t)prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(STREAMBUFFER, sb)));
+
+/* Generic versions */
+#define TRACE_GET_OBJECT_NUMBER(CLASS, pxObject) TRACE_GET_##CLASS##_NUMBER(pxObject)
+#define TRACE_SET_OBJECT_NUMBER(CLASS, pxObject) TRACE_SET_##CLASS##_NUMBER(pxObject)
+
+/******************************
+* MACROS TO GET EVENT CODES *
+******************************/
+#define TRACE_GET_TASK_CLASS_EVENT_CODE(SERVICE, RESULT, kernelClass) (uint8_t)(EVENTGROUP_##SERVICE##_##RESULT + TRACE_GET_CLASS_TRACE_CLASS(TASK, kernelClass))
+#define TRACE_GET_QUEUE_CLASS_EVENT_CODE(SERVICE, RESULT, kernelClass) (uint8_t)(EVENTGROUP_##SERVICE##_##RESULT + TRACE_GET_CLASS_TRACE_CLASS(QUEUE, kernelClass))
+#define TRACE_GET_TIMER_CLASS_EVENT_CODE(SERVICE, RESULT, kernelClass) -- THIS IS NOT USED --
+#define TRACE_GET_EVENTGROUP_CLASS_EVENT_CODE(SERVICE, RESULT, kernelClass) -- THIS IS NOT USED --
+#define TRACE_GET_STREAMBUFFER_CLASS_EVENT_CODE(SERVICE, RESULT, isMessageBuffer) (uint8_t)(TRACE_STREAMBUFFER_##SERVICE##_##RESULT + (uint8_t)isMessageBuffer)
+
+#define TRACE_GET_TASK_OBJECT_EVENT_CODE(SERVICE, RESULT, pxTCB) (uint8_t)(EVENTGROUP_##SERVICE##_##RESULT + TRACE_CLASS_TASK)
+#define TRACE_GET_QUEUE_OBJECT_EVENT_CODE(SERVICE, RESULT, pxObject) (uint8_t)(EVENTGROUP_##SERVICE##_##RESULT + TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, pxObject))
+#define TRACE_GET_TIMER_OBJECT_EVENT_CODE(SERVICE, RESULT, UNUSED) -- THIS IS NOT USED --
+#define TRACE_GET_EVENTGROUP_OBJECT_EVENT_CODE(SERVICE, RESULT, UNUSED) -- THIS IS NOT USED --
+#define TRACE_GET_STREAMBUFFER_OBJECT_EVENT_CODE(SERVICE, RESULT, pxObject) (uint8_t)(TRACE_STREAMBUFFER_##SERVICE##_##RESULT + prvGetStreamBufferType(pxObject))
+
+/* Generic versions */
+#define TRACE_GET_CLASS_EVENT_CODE(SERVICE, RESULT, CLASS, kernelClass) TRACE_GET_##CLASS##_CLASS_EVENT_CODE(SERVICE, RESULT, kernelClass)
+#define TRACE_GET_OBJECT_EVENT_CODE(SERVICE, RESULT, CLASS, pxObject) TRACE_GET_##CLASS##_OBJECT_EVENT_CODE(SERVICE, RESULT, pxObject)
+
+/******************************
+* SPECIAL MACROS FOR TASKS *
+******************************/
+#define TRACE_GET_TASK_PRIORITY(pxTCB) ((uint8_t)pxTCB->uxPriority)
+#define TRACE_GET_TASK_NAME(pxTCB) ((char*)pxTCB->pcTaskName)
+
+/*** The trace macros for snapshot mode **************************************/
+
+/* A macro that will update the tick count when returning from tickless idle */
+#undef traceINCREASE_TICK_COUNT
+#define traceINCREASE_TICK_COUNT( xCount )
+
+/* Called for each task that becomes ready */
+#undef traceMOVED_TASK_TO_READY_STATE
+#define traceMOVED_TASK_TO_READY_STATE( pxTCB ) \
+ trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE(pxTCB);
+
+/* Called on each OS tick. Will call uiPortGetTimestamp to make sure it is called at least once every OS tick. */
+#undef traceTASK_INCREMENT_TICK
+
+#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_3_0)
+
+#define traceTASK_INCREMENT_TICK( xTickCount ) \
+ if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || xPendedTicks == 0) { trcKERNEL_HOOKS_INCREMENT_TICK(); } \
+ if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE) { trcKERNEL_HOOKS_NEW_TIME(DIV_NEW_TIME, xTickCount + 1); }
+
+#elif (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_7_5_X)
+
+#define traceTASK_INCREMENT_TICK( xTickCount ) \
+ if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || uxPendedTicks == 0) { trcKERNEL_HOOKS_INCREMENT_TICK(); } \
+ if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE) { trcKERNEL_HOOKS_NEW_TIME(DIV_NEW_TIME, xTickCount + 1); }
+
+#else
+
+#define traceTASK_INCREMENT_TICK( xTickCount ) \
+ if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || uxMissedTicks == 0) { trcKERNEL_HOOKS_INCREMENT_TICK(); } \
+ if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE) { trcKERNEL_HOOKS_NEW_TIME(DIV_NEW_TIME, xTickCount + 1); }
+
+#endif
+
+extern volatile uint32_t uiTraceSystemState;
+
+/* Called on each task-switch */
+#undef traceTASK_SWITCHED_IN
+#define traceTASK_SWITCHED_IN() \
+ uiTraceSystemState = TRC_STATE_IN_TASKSWITCH; \
+ trcKERNEL_HOOKS_TASK_SWITCH(TRACE_GET_CURRENT_TASK()); \
+ uiTraceSystemState = TRC_STATE_IN_APPLICATION;
+
+/* Called on vTaskCreate */
+#undef traceTASK_CREATE
+#define traceTASK_CREATE(pxNewTCB) \
+ if (pxNewTCB != NULL) \
+ { \
+ trcKERNEL_HOOKS_TASK_CREATE(TRACE_GET_OBJECT_EVENT_CODE(CREATE_OBJ, TRCSUCCESS, TASK, pxNewTCB), TASK, pxNewTCB); \
+ prvAddTaskToStackMonitor(pxNewTCB); \
+ }
+
+/* Called in vTaskCreate, if it fails (typically if the stack can not be allocated) */
+#undef traceTASK_CREATE_FAILED
+#define traceTASK_CREATE_FAILED() \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY(TRACE_GET_CLASS_EVENT_CODE(CREATE_OBJ, TRCFAILED, TASK, NOT_USED), 0);
+
+/* Called on vTaskDelete */
+#undef traceTASK_DELETE
+#define traceTASK_DELETE( pxTaskToDelete ) \
+ { TRACE_ALLOC_CRITICAL_SECTION(); \
+ TRACE_ENTER_CRITICAL_SECTION(); \
+ trcKERNEL_HOOKS_TASK_DELETE(TRACE_GET_OBJECT_EVENT_CODE(DELETE_OBJ, TRCSUCCESS, TASK, pxTaskToDelete), TRACE_GET_OBJECT_EVENT_CODE(OBJCLOSE_NAME, TRCSUCCESS, TASK, pxTaskToDelete), TRACE_GET_OBJECT_EVENT_CODE(OBJCLOSE_PROP, TRCSUCCESS, TASK, pxTaskToDelete), pxTaskToDelete); \
+ prvRemoveTaskFromStackMonitor(pxTaskToDelete); \
+ TRACE_EXIT_CRITICAL_SECTION(); }
+
+#if (TRC_CFG_SCHEDULING_ONLY == 0)
+
+#if defined(configUSE_TICKLESS_IDLE)
+#if (configUSE_TICKLESS_IDLE != 0)
+
+#undef traceLOW_POWER_IDLE_BEGIN
+#define traceLOW_POWER_IDLE_BEGIN() \
+ { \
+ extern uint32_t trace_disable_timestamp; \
+ prvTraceStoreLowPower(0); \
+ trace_disable_timestamp = 1; \
+ }
+
+#undef traceLOW_POWER_IDLE_END
+#define traceLOW_POWER_IDLE_END() \
+ { \
+ extern uint32_t trace_disable_timestamp; \
+ trace_disable_timestamp = 0; \
+ prvTraceStoreLowPower(1); \
+ }
+
+#endif /* (configUSE_TICKLESS_IDLE != 0) */
+#endif /* defined(configUSE_TICKLESS_IDLE) */
+
+/* Called on vTaskSuspend */
+#undef traceTASK_SUSPEND
+#define traceTASK_SUSPEND( pxTaskToSuspend ) \
+ trcKERNEL_HOOKS_TASK_SUSPEND(TASK_SUSPEND, pxTaskToSuspend);
+
+/* Called from special case with timer only */
+#undef traceTASK_DELAY_SUSPEND
+#define traceTASK_DELAY_SUSPEND( pxTaskToSuspend ) \
+ trcKERNEL_HOOKS_TASK_SUSPEND(TASK_SUSPEND, pxTaskToSuspend); \
+ trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED();
+
+/* Called on vTaskDelay - note the use of FreeRTOS variable xTicksToDelay */
+#undef traceTASK_DELAY
+#define traceTASK_DELAY() \
+ trcKERNEL_HOOKS_TASK_DELAY(TASK_DELAY, pxCurrentTCB, xTicksToDelay); \
+ trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED();
+
+/* Called on vTaskDelayUntil - note the use of FreeRTOS variable xTimeToWake */
+#undef traceTASK_DELAY_UNTIL
+#if TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0
+#define traceTASK_DELAY_UNTIL(xTimeToWake) \
+ trcKERNEL_HOOKS_TASK_DELAY(TASK_DELAY_UNTIL, pxCurrentTCB, xTimeToWake); \
+ trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED();
+#else /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */
+#define traceTASK_DELAY_UNTIL() \
+ trcKERNEL_HOOKS_TASK_DELAY(TASK_DELAY_UNTIL, pxCurrentTCB, xTimeToWake); \
+ trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED();
+#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */
+
+/* Called in xQueueCreate, and thereby for all other object based on queues, such as semaphores. */
+#undef traceQUEUE_CREATE
+#define traceQUEUE_CREATE( pxNewQueue ) \
+ trcKERNEL_HOOKS_OBJECT_CREATE(TRACE_GET_OBJECT_EVENT_CODE(CREATE_OBJ, TRCSUCCESS, QUEUE, pxNewQueue), QUEUE, pxNewQueue);
+
+/* Called in xQueueCreate, if the queue creation fails */
+#undef traceQUEUE_CREATE_FAILED
+#define traceQUEUE_CREATE_FAILED( queueType ) \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY(TRACE_GET_CLASS_EVENT_CODE(CREATE_OBJ, TRCFAILED, QUEUE, queueType), 0);
+
+/* Called on vQueueDelete */
+#undef traceQUEUE_DELETE
+#define traceQUEUE_DELETE( pxQueue ) \
+ { TRACE_ALLOC_CRITICAL_SECTION(); \
+ TRACE_ENTER_CRITICAL_SECTION(); \
+ trcKERNEL_HOOKS_OBJECT_DELETE(TRACE_GET_OBJECT_EVENT_CODE(DELETE_OBJ, TRCSUCCESS, QUEUE, pxQueue), TRACE_GET_OBJECT_EVENT_CODE(OBJCLOSE_NAME, TRCSUCCESS, QUEUE, pxQueue), TRACE_GET_OBJECT_EVENT_CODE(OBJCLOSE_PROP, TRCSUCCESS, QUEUE, pxQueue), QUEUE, pxQueue); \
+ TRACE_EXIT_CRITICAL_SECTION(); }
+
+/* This macro is not necessary as of FreeRTOS v9.0.0 */
+#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0)
+/* Called in xQueueCreateMutex, and thereby also from xSemaphoreCreateMutex and xSemaphoreCreateRecursiveMutex */
+#undef traceCREATE_MUTEX
+#define traceCREATE_MUTEX( pxNewQueue ) \
+ trcKERNEL_HOOKS_OBJECT_CREATE(TRACE_GET_OBJECT_EVENT_CODE(CREATE_OBJ, TRCSUCCESS, QUEUE, pxNewQueue), QUEUE, pxNewQueue);
+
+/* Called in xQueueCreateMutex when the operation fails (when memory allocation fails) */
+#undef traceCREATE_MUTEX_FAILED
+#define traceCREATE_MUTEX_FAILED() \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY(TRACE_GET_CLASS_EVENT_CODE(CREATE_OBJ, TRCFAILED, QUEUE, queueQUEUE_TYPE_MUTEX), 0);
+#endif /* (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0) */
+
+/* Called when the Mutex can not be given, since not holder */
+#undef traceGIVE_MUTEX_RECURSIVE_FAILED
+#define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ) \
+ trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND, TRCFAILED, QUEUE, pxMutex), QUEUE, pxMutex);
+
+/* Called when a message is sent to a queue */ /* CS IS NEW ! */
+#undef traceQUEUE_SEND
+#define traceQUEUE_SEND( pxQueue ) \
+ trcKERNEL_HOOKS_KERNEL_SERVICE(xCopyPosition == queueSEND_TO_BACK ? (TRACE_GET_OBJECT_EVENT_CODE(SEND, TRCSUCCESS, QUEUE, pxQueue)) : TRACE_QUEUE_SEND_TO_FRONT_TRCSUCCESS, QUEUE, pxQueue); \
+ trcKERNEL_HOOKS_SET_OBJECT_STATE(QUEUE, pxQueue, TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, pxQueue) == TRACE_CLASS_MUTEX ? (uint8_t)0 : (uint8_t)(pxQueue->uxMessagesWaiting + 1));
+
+/* Called when a message is sent to a queue set */
+#undef traceQUEUE_SET_SEND
+#define traceQUEUE_SET_SEND( pxQueue ) \
+ trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND, TRCSUCCESS, QUEUE, pxQueue), QUEUE, pxQueue); \
+ trcKERNEL_HOOKS_SET_OBJECT_STATE(QUEUE, pxQueue, (uint8_t)(pxQueue->uxMessagesWaiting + 1));
+
+/* Called when a message failed to be sent to a queue (timeout) */
+#undef traceQUEUE_SEND_FAILED
+#define traceQUEUE_SEND_FAILED( pxQueue ) \
+ trcKERNEL_HOOKS_KERNEL_SERVICE(xCopyPosition == queueSEND_TO_BACK ? (TRACE_GET_OBJECT_EVENT_CODE(SEND, TRCFAILED, QUEUE, pxQueue)) : TRACE_QUEUE_SEND_TO_FRONT_TRCFAILED, QUEUE, pxQueue);
+
+/* Called when the task is blocked due to a send operation on a full queue */
+#undef traceBLOCKING_ON_QUEUE_SEND
+#define traceBLOCKING_ON_QUEUE_SEND( pxQueue ) \
+ trcKERNEL_HOOKS_KERNEL_SERVICE(xCopyPosition == queueSEND_TO_BACK ? (TRACE_GET_OBJECT_EVENT_CODE(SEND, TRCBLOCK, QUEUE, pxQueue)) : TRACE_QUEUE_SEND_TO_FRONT_TRCBLOCK, QUEUE, pxQueue);
+
+/* Called when a message is received from a queue */
+#undef traceQUEUE_RECEIVE
+#define traceQUEUE_RECEIVE( pxQueue ) \
+ if (isQueueReceiveHookActuallyPeek) \
+ { \
+ trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(PEEK, TRCSUCCESS, QUEUE, pxQueue), QUEUE, pxQueue); \
+ } \
+ else \
+ { \
+ trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE, TRCSUCCESS, QUEUE, pxQueue), QUEUE, pxQueue); \
+ } \
+ trcKERNEL_HOOKS_SET_OBJECT_STATE(QUEUE, pxQueue, TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, pxQueue) == TRACE_CLASS_MUTEX ? (uint8_t)TRACE_GET_TASK_NUMBER(TRACE_GET_CURRENT_TASK()) : (uint8_t)(pxQueue->uxMessagesWaiting - 1));
+
+/* Called when a receive operation on a queue fails (timeout) */
+#undef traceQUEUE_RECEIVE_FAILED
+#define traceQUEUE_RECEIVE_FAILED( pxQueue ) \
+ if (isQueueReceiveHookActuallyPeek) \
+ { \
+ trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(PEEK, TRCFAILED, QUEUE, pxQueue), QUEUE, pxQueue); \
+ } \
+ else \
+ { \
+ trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE, TRCFAILED, QUEUE, pxQueue), QUEUE, pxQueue); \
+ }
+
+/* Called when the task is blocked due to a receive operation on an empty queue */
+#undef traceBLOCKING_ON_QUEUE_RECEIVE
+#define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ) \
+ if (isQueueReceiveHookActuallyPeek) \
+ { \
+ trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(PEEK, TRCBLOCK, QUEUE, pxQueue), QUEUE, pxQueue); \
+ } \
+ else \
+ { \
+ trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE, TRCBLOCK, QUEUE, pxQueue), QUEUE, pxQueue); \
+ } \
+ if (TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, pxQueue) != TRACE_CLASS_MUTEX) \
+ { \
+ trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); \
+ }
+
+/* Called on xQueuePeek */
+#undef traceQUEUE_PEEK
+#define traceQUEUE_PEEK( pxQueue ) \
+ trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(PEEK, TRCSUCCESS, QUEUE, pxQueue), QUEUE, pxQueue);
+
+/* Called on xQueuePeek fail/timeout (added in FreeRTOS v9.0.2) */
+#undef traceQUEUE_PEEK_FAILED
+#define traceQUEUE_PEEK_FAILED( pxQueue ) \
+ trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(PEEK, TRCFAILED, QUEUE, pxQueue), QUEUE, pxQueue);
+
+/* Called on xQueuePeek blocking (added in FreeRTOS v9.0.2) */
+#undef traceBLOCKING_ON_QUEUE_PEEK
+#define traceBLOCKING_ON_QUEUE_PEEK( pxQueue ) \
+ trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(PEEK, TRCBLOCK, QUEUE, pxQueue), QUEUE, pxQueue); \
+ if (TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, pxQueue) != TRACE_CLASS_MUTEX) \
+ { \
+ trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); \
+ }
+
+/* Called when a message is sent from interrupt context, e.g., using xQueueSendFromISR */
+#undef traceQUEUE_SEND_FROM_ISR
+#define traceQUEUE_SEND_FROM_ISR( pxQueue ) \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(xCopyPosition == queueSEND_TO_BACK ? (TRACE_GET_OBJECT_EVENT_CODE(SEND_FROM_ISR, TRCSUCCESS, QUEUE, pxQueue)) : TRACE_QUEUE_SEND_TO_FRONT_FROM_ISR_TRCSUCCESS, QUEUE, pxQueue); \
+ trcKERNEL_HOOKS_SET_OBJECT_STATE(QUEUE, pxQueue, (uint8_t)(pxQueue->uxMessagesWaiting + 1));
+
+/* Called when a message send from interrupt context fails (since the queue was full) */
+#undef traceQUEUE_SEND_FROM_ISR_FAILED
+#define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ) \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(xCopyPosition == queueSEND_TO_BACK ? (TRACE_GET_OBJECT_EVENT_CODE(SEND_FROM_ISR, TRCFAILED, QUEUE, pxQueue)) : TRACE_QUEUE_SEND_TO_FRONT_FROM_ISR_TRCFAILED, QUEUE, pxQueue);
+
+/* Called when a message is received in interrupt context, e.g., using xQueueReceiveFromISR */
+#undef traceQUEUE_RECEIVE_FROM_ISR
+#define traceQUEUE_RECEIVE_FROM_ISR( pxQueue ) \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE_FROM_ISR, TRCSUCCESS, QUEUE, pxQueue), QUEUE, pxQueue); \
+ trcKERNEL_HOOKS_SET_OBJECT_STATE(QUEUE, pxQueue, (uint8_t)(pxQueue->uxMessagesWaiting - 1));
+
+/* Called when a message receive from interrupt context fails (since the queue was empty) */
+#undef traceQUEUE_RECEIVE_FROM_ISR_FAILED
+#define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ) \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE_FROM_ISR, TRCFAILED, QUEUE, pxQueue), QUEUE, pxQueue);
+
+#undef traceQUEUE_REGISTRY_ADD
+#define traceQUEUE_REGISTRY_ADD(object, name) prvTraceSetObjectName(TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, object), TRACE_GET_OBJECT_NUMBER(QUEUE, object), name);
+
+/* Called in vTaskPrioritySet */
+#undef traceTASK_PRIORITY_SET
+#define traceTASK_PRIORITY_SET( pxTask, uxNewPriority ) \
+ trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE(TASK_PRIORITY_SET, pxTask, uxNewPriority);
+
+/* Called in vTaskPriorityInherit, which is called by Mutex operations */
+#undef traceTASK_PRIORITY_INHERIT
+#define traceTASK_PRIORITY_INHERIT( pxTask, uxNewPriority ) \
+ trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE(TASK_PRIORITY_INHERIT, pxTask, uxNewPriority);
+
+/* Called in vTaskPriorityDisinherit, which is called by Mutex operations */
+#undef traceTASK_PRIORITY_DISINHERIT
+#define traceTASK_PRIORITY_DISINHERIT( pxTask, uxNewPriority ) \
+ trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE(TASK_PRIORITY_DISINHERIT, pxTask, uxNewPriority);
+
+/* Called in vTaskResume */
+#undef traceTASK_RESUME
+#define traceTASK_RESUME( pxTaskToResume ) \
+ trcKERNEL_HOOKS_TASK_RESUME(TASK_RESUME, pxTaskToResume);
+
+/* Called in vTaskResumeFromISR */
+#undef traceTASK_RESUME_FROM_ISR
+#define traceTASK_RESUME_FROM_ISR( pxTaskToResume ) \
+ trcKERNEL_HOOKS_TASK_RESUME_FROM_ISR(TASK_RESUME_FROM_ISR, pxTaskToResume);
+
+
+#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X)
+
+#if (TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1)
+
+extern void vTraceStoreMemMangEvent(uint32_t ecode, uint32_t address, int32_t size);
+
+/* MALLOC and FREE are always stored, no matter if they happen inside filtered task */
+#undef traceMALLOC
+#define traceMALLOC( pvAddress, uiSize ) \
+ if (pvAddress != 0) \
+ { \
+ vTraceStoreMemMangEvent(MEM_MALLOC_SIZE, ( uint32_t ) pvAddress, (int32_t)uiSize); \
+ } \
+ else \
+ { \
+ vTraceStoreMemMangEvent(MEM_MALLOC_SIZE_TRCFAILED, ( uint32_t ) pvAddress, (int32_t)uiSize); \
+ }
+
+#undef traceFREE
+#define traceFREE( pvAddress, uiSize ) \
+ vTraceStoreMemMangEvent(MEM_FREE_SIZE, ( uint32_t ) pvAddress, -((int32_t)uiSize));
+
+#endif /* (TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1) */
+
+#if (TRC_CFG_INCLUDE_TIMER_EVENTS == 1)
+
+/* Called in timer.c - xTimerCreate */
+#undef traceTIMER_CREATE
+#define traceTIMER_CREATE(tmr) \
+ trcKERNEL_HOOKS_OBJECT_CREATE(TIMER_CREATE, TIMER, tmr);
+
+#undef traceTIMER_CREATE_FAILED
+#define traceTIMER_CREATE_FAILED() \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY(TIMER_CREATE_TRCFAILED, 0);
+
+/* Note that xCommandID can never be tmrCOMMAND_EXECUTE_CALLBACK (-1) since the trace macro is not called in that case */
+#undef traceTIMER_COMMAND_SEND
+#define traceTIMER_COMMAND_SEND(tmr, xCommandID, xOptionalValue, xReturn) \
+ if (xCommandID > tmrCOMMAND_START_DONT_TRACE) \
+ { \
+ if (xCommandID == tmrCOMMAND_CHANGE_PERIOD) \
+ { \
+ if (xReturn == pdPASS) { \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TIMER_CHANGE_PERIOD, TIMER, tmr, xOptionalValue); \
+ } \
+ else \
+ { \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TIMER_CHANGE_PERIOD_TRCFAILED, TIMER, tmr, xOptionalValue); \
+ } \
+ } \
+ else if ((xCommandID == tmrCOMMAND_DELETE) && (xReturn == pdPASS)) \
+ { \
+ trcKERNEL_HOOKS_OBJECT_DELETE(TIMER_DELETE_OBJ, EVENTGROUP_OBJCLOSE_NAME_TRCSUCCESS + TRACE_GET_OBJECT_TRACE_CLASS(TIMER, tmr), EVENTGROUP_OBJCLOSE_PROP_TRCSUCCESS + TRACE_GET_OBJECT_TRACE_CLASS(TIMER, tmr), TIMER, tmr); \
+ } \
+ else \
+ { \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENTGROUP_TIMER + (uint32_t)xCommandID + ((xReturn == pdPASS) ? 0 : (TIMER_CREATE_TRCFAILED - TIMER_CREATE)), TIMER, tmr, xOptionalValue); \
+ }\
+ }
+
+#undef traceTIMER_EXPIRED
+#define traceTIMER_EXPIRED(tmr) \
+ trcKERNEL_HOOKS_KERNEL_SERVICE(TIMER_EXPIRED, TIMER, tmr);
+
+#endif /* (TRC_CFG_INCLUDE_TIMER_EVENTS == 1) */
+
+#if (TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS == 1)
+
+#undef tracePEND_FUNC_CALL
+#define tracePEND_FUNC_CALL(func, arg1, arg2, ret) \
+ if (ret == pdPASS){ \
+ trcKERNEL_HOOKS_KERNEL_SERVICE(PEND_FUNC_CALL, TASK, xTimerGetTimerDaemonTaskHandle() ); \
+ } \
+ else \
+ { \
+ trcKERNEL_HOOKS_KERNEL_SERVICE(PEND_FUNC_CALL_TRCFAILED, TASK, xTimerGetTimerDaemonTaskHandle() ); \
+ }
+
+#undef tracePEND_FUNC_CALL_FROM_ISR
+#define tracePEND_FUNC_CALL_FROM_ISR(func, arg1, arg2, ret) \
+ if (! uiInEventGroupSetBitsFromISR) \
+ prvTraceStoreKernelCall(PEND_FUNC_CALL_FROM_ISR, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(xTimerGetTimerDaemonTaskHandle()) ); \
+ uiInEventGroupSetBitsFromISR = 0;
+
+#endif /* (TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS == 1) */
+
+#endif /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X) */
+
+#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1)
+
+#undef traceEVENT_GROUP_CREATE
+#define traceEVENT_GROUP_CREATE(eg) \
+ trcKERNEL_HOOKS_OBJECT_CREATE(EVENT_GROUP_CREATE, EVENTGROUP, eg);
+
+#undef traceEVENT_GROUP_CREATE_FAILED
+#define traceEVENT_GROUP_CREATE_FAILED() \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY(EVENT_GROUP_CREATE_TRCFAILED, 0);
+
+#undef traceEVENT_GROUP_DELETE
+#define traceEVENT_GROUP_DELETE(eg) \
+ { TRACE_ALLOC_CRITICAL_SECTION(); \
+ TRACE_ENTER_CRITICAL_SECTION(); \
+ trcKERNEL_HOOKS_OBJECT_DELETE(EVENT_GROUP_DELETE_OBJ, EVENTGROUP_OBJCLOSE_NAME_TRCSUCCESS + TRACE_GET_OBJECT_TRACE_CLASS(EVENTGROUP, eg), EVENTGROUP_OBJCLOSE_NAME_TRCSUCCESS + TRACE_GET_OBJECT_TRACE_CLASS(EVENTGROUP, eg), EVENTGROUP, eg); \
+ TRACE_EXIT_CRITICAL_SECTION(); }
+
+#undef traceEVENT_GROUP_SYNC_BLOCK
+#define traceEVENT_GROUP_SYNC_BLOCK(eg, bitsToSet, bitsToWaitFor) \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_SYNC_TRCBLOCK, EVENTGROUP, eg, bitsToWaitFor);
+
+#undef traceEVENT_GROUP_SYNC_END
+#define traceEVENT_GROUP_SYNC_END(eg, bitsToSet, bitsToWaitFor, wasTimeout) \
+ if (wasTimeout) \
+ { \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_SYNC_END_TRCFAILED, EVENTGROUP, eg, bitsToWaitFor); \
+ } \
+ else \
+ { \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_SYNC_END, EVENTGROUP, eg, bitsToWaitFor); \
+ }
+
+#undef traceEVENT_GROUP_WAIT_BITS_BLOCK
+#define traceEVENT_GROUP_WAIT_BITS_BLOCK(eg, bitsToWaitFor) \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_WAIT_BITS_TRCBLOCK, EVENTGROUP, eg, bitsToWaitFor); \
+ trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED();
+
+#undef traceEVENT_GROUP_WAIT_BITS_END
+#define traceEVENT_GROUP_WAIT_BITS_END(eg, bitsToWaitFor, wasTimeout) \
+ if (wasTimeout) \
+ { \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_WAIT_BITS_END_TRCFAILED, EVENTGROUP, eg, bitsToWaitFor); \
+ } \
+ else \
+ { \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_WAIT_BITS_END, EVENTGROUP, eg, bitsToWaitFor); \
+ }
+
+#undef traceEVENT_GROUP_CLEAR_BITS
+#define traceEVENT_GROUP_CLEAR_BITS(eg, bitsToClear) \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_CLEAR_BITS, EVENTGROUP, eg, bitsToClear);
+
+#undef traceEVENT_GROUP_CLEAR_BITS_FROM_ISR
+#define traceEVENT_GROUP_CLEAR_BITS_FROM_ISR(eg, bitsToClear) \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM_FROM_ISR(EVENT_GROUP_CLEAR_BITS_FROM_ISR, EVENTGROUP, eg, bitsToClear);
+
+#undef traceEVENT_GROUP_SET_BITS
+#define traceEVENT_GROUP_SET_BITS(eg, bitsToSet) \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_SET_BITS, EVENTGROUP, eg, bitsToSet);
+
+#undef traceEVENT_GROUP_SET_BITS_FROM_ISR
+#define traceEVENT_GROUP_SET_BITS_FROM_ISR(eg, bitsToSet) \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM_FROM_ISR(EVENT_GROUP_SET_BITS_FROM_ISR, EVENTGROUP, eg, bitsToSet); \
+ uiInEventGroupSetBitsFromISR = 1;
+
+#endif /* (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1) */
+
+#undef traceTASK_NOTIFY_TAKE
+#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0)
+#define traceTASK_NOTIFY_TAKE() \
+ if (pxCurrentTCB->eNotifyState == eNotified){ \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TRACE_TASK_NOTIFY_TAKE, TASK, pxCurrentTCB, xTicksToWait); \
+ } \
+ else{ \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TRACE_TASK_NOTIFY_TAKE_TRCFAILED, TASK, pxCurrentTCB, xTicksToWait); \
+ }
+#elif (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_10_4_0)
+#define traceTASK_NOTIFY_TAKE() \
+ if (pxCurrentTCB->ucNotifyState == taskNOTIFICATION_RECEIVED){ \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TRACE_TASK_NOTIFY_TAKE, TASK, pxCurrentTCB, xTicksToWait); \
+ }else{ \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TRACE_TASK_NOTIFY_TAKE_TRCFAILED, TASK, pxCurrentTCB, xTicksToWait);}
+#else /* TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0 */
+#define traceTASK_NOTIFY_TAKE(index) \
+ if (pxCurrentTCB->ucNotifyState[index] == taskNOTIFICATION_RECEIVED){ \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TRACE_TASK_NOTIFY_TAKE, TASK, pxCurrentTCB, xTicksToWait); \
+ }else{ \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TRACE_TASK_NOTIFY_TAKE_TRCFAILED, TASK, pxCurrentTCB, xTicksToWait);}
+#endif /* TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0 */
+
+#undef traceTASK_NOTIFY_TAKE_BLOCK
+#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_10_4_0)
+#define traceTASK_NOTIFY_TAKE_BLOCK() \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TRACE_TASK_NOTIFY_TAKE_TRCBLOCK, TASK, pxCurrentTCB, xTicksToWait); \
+ trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED();
+#else /* TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_10_4_0 */
+#define traceTASK_NOTIFY_TAKE_BLOCK(index) \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TRACE_TASK_NOTIFY_TAKE_TRCBLOCK, TASK, pxCurrentTCB, xTicksToWait); \
+ trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED();
+#endif /* TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_10_4_0 */
+
+#undef traceTASK_NOTIFY_WAIT
+#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0)
+#define traceTASK_NOTIFY_WAIT() \
+ if (TRACE_GET_OBJECT_FILTER(TASK, pxCurrentTCB) & CurrentFilterMask) \
+ { \
+ if (pxCurrentTCB->eNotifyState == eNotified) \
+ prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxCurrentTCB), xTicksToWait); \
+ else \
+ prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT_TRCFAILED, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxCurrentTCB), xTicksToWait); \
+ }
+#elif (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_10_4_0)
+#define traceTASK_NOTIFY_WAIT() \
+ if (TRACE_GET_OBJECT_FILTER(TASK, pxCurrentTCB) & CurrentFilterMask) \
+ { \
+ if (pxCurrentTCB->ucNotifyState == taskNOTIFICATION_RECEIVED) \
+ prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxCurrentTCB), xTicksToWait); \
+ else \
+ prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT_TRCFAILED, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxCurrentTCB), xTicksToWait); \
+ }
+#else /* TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0 */
+#define traceTASK_NOTIFY_WAIT(index) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, pxCurrentTCB) & CurrentFilterMask) \
+ { \
+ if (pxCurrentTCB->ucNotifyState[index] == taskNOTIFICATION_RECEIVED) \
+ prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxCurrentTCB), xTicksToWait); \
+ else \
+ prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT_TRCFAILED, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxCurrentTCB), xTicksToWait); \
+ }
+#endif /* TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0 */
+
+#undef traceTASK_NOTIFY_WAIT_BLOCK
+#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_10_4_0)
+#define traceTASK_NOTIFY_WAIT_BLOCK() \
+ if (TRACE_GET_OBJECT_FILTER(TASK, pxCurrentTCB) & CurrentFilterMask) \
+ prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT_TRCBLOCK, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxCurrentTCB), xTicksToWait); \
+ trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED();
+#else /* TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_10_4_0 */
+#define traceTASK_NOTIFY_WAIT_BLOCK(index) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, pxCurrentTCB) & CurrentFilterMask) \
+ prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT_TRCBLOCK, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxCurrentTCB), xTicksToWait); \
+ trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED();
+#endif /* TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_10_4_0 */
+
+#undef traceTASK_NOTIFY
+#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_10_4_0)
+#define traceTASK_NOTIFY() \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, xTaskToNotify) & CurrentFilterMask) \
+ prvTraceStoreKernelCall(TRACE_TASK_NOTIFY, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(xTaskToNotify));
+#else /* TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_10_4_0 */
+#define traceTASK_NOTIFY(index) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, xTaskToNotify) & CurrentFilterMask) \
+ prvTraceStoreKernelCall(TRACE_TASK_NOTIFY, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(xTaskToNotify));
+#endif /* TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_10_4_0 */
+
+#undef traceTASK_NOTIFY_FROM_ISR
+#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_10_4_0)
+#define traceTASK_NOTIFY_FROM_ISR() \
+ if (TRACE_GET_OBJECT_FILTER(TASK, xTaskToNotify) & CurrentFilterMask) \
+ prvTraceStoreKernelCall(TRACE_TASK_NOTIFY_FROM_ISR, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(xTaskToNotify));
+#else /* TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_10_4_0 */
+#define traceTASK_NOTIFY_FROM_ISR(index) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, xTaskToNotify) & CurrentFilterMask) \
+ prvTraceStoreKernelCall(TRACE_TASK_NOTIFY_FROM_ISR, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(xTaskToNotify));
+#endif /* TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_10_4_0 */
+
+#undef traceTASK_NOTIFY_GIVE_FROM_ISR
+#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_10_4_0)
+#define traceTASK_NOTIFY_GIVE_FROM_ISR() \
+ if (TRACE_GET_OBJECT_FILTER(TASK, xTaskToNotify) & CurrentFilterMask) \
+ prvTraceStoreKernelCall(TRACE_TASK_NOTIFY_GIVE_FROM_ISR, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(xTaskToNotify));
+#else /* TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_10_4_0 */
+#define traceTASK_NOTIFY_GIVE_FROM_ISR(index) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, xTaskToNotify) & CurrentFilterMask) \
+ prvTraceStoreKernelCall(TRACE_TASK_NOTIFY_GIVE_FROM_ISR, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(xTaskToNotify));
+#endif /* TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_10_4_0 */
+
+#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1)
+
+#undef traceSTREAM_BUFFER_CREATE
+#define traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer ) \
+ trcKERNEL_HOOKS_OBJECT_CREATE(TRACE_GET_OBJECT_EVENT_CODE(CREATE_OBJ, TRCSUCCESS, STREAMBUFFER, pxStreamBuffer), STREAMBUFFER, pxStreamBuffer);
+
+#undef traceSTREAM_BUFFER_CREATE_FAILED
+#define traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ) \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY(TRACE_GET_CLASS_EVENT_CODE(CREATE_OBJ, TRCFAILED, STREAMBUFFER, xIsMessageBuffer), 0);
+
+#undef traceSTREAM_BUFFER_CREATE_STATIC_FAILED
+#define traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer ) \
+ traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer )
+
+#undef traceSTREAM_BUFFER_DELETE
+#define traceSTREAM_BUFFER_DELETE( xStreamBuffer ) \
+ trcKERNEL_HOOKS_OBJECT_DELETE(TRACE_GET_OBJECT_EVENT_CODE(DELETE_OBJ, TRCSUCCESS, STREAMBUFFER, xStreamBuffer), TRACE_GET_OBJECT_EVENT_CODE(OBJCLOSE_NAME, TRCSUCCESS, STREAMBUFFER, xStreamBuffer), TRACE_GET_OBJECT_EVENT_CODE(OBJCLOSE_PROP, TRCSUCCESS, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer);
+
+#undef traceSTREAM_BUFFER_RESET
+#define traceSTREAM_BUFFER_RESET( xStreamBuffer ) \
+ trcKERNEL_HOOKS_KERNEL_SERVICE(prvGetStreamBufferType(xStreamBuffer) > 0 ? TRACE_MESSAGEBUFFER_RESET : TRACE_STREAMBUFFER_RESET, STREAMBUFFER, xStreamBuffer); \
+ trcKERNEL_HOOKS_SET_OBJECT_STATE(STREAMBUFFER, xStreamBuffer, 0);
+
+#undef traceSTREAM_BUFFER_SEND
+#define traceSTREAM_BUFFER_SEND( xStreamBuffer, xReturn ) \
+ trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND, TRCSUCCESS, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); \
+ trcKERNEL_HOOKS_SET_OBJECT_STATE(STREAMBUFFER, xStreamBuffer, prvBytesInBuffer(xStreamBuffer));
+
+#undef traceBLOCKING_ON_STREAM_BUFFER_SEND
+#define traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer ) \
+ trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND, TRCBLOCK, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer);
+
+#undef traceSTREAM_BUFFER_SEND_FAILED
+#define traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer ) \
+ trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND, TRCFAILED, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer);
+
+#undef traceSTREAM_BUFFER_RECEIVE
+#define traceSTREAM_BUFFER_RECEIVE( xStreamBuffer, xReceivedLength ) \
+ trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE, TRCSUCCESS, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); \
+ trcKERNEL_HOOKS_SET_OBJECT_STATE(STREAMBUFFER, xStreamBuffer, prvBytesInBuffer(xStreamBuffer));
+
+
+#undef traceBLOCKING_ON_STREAM_BUFFER_RECEIVE
+#define traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer ) \
+ trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE, TRCBLOCK, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer);
+
+#undef traceSTREAM_BUFFER_RECEIVE_FAILED
+#define traceSTREAM_BUFFER_RECEIVE_FAILED( xStreamBuffer ) \
+ trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE, TRCFAILED, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer);
+
+#undef traceSTREAM_BUFFER_SEND_FROM_ISR
+#define traceSTREAM_BUFFER_SEND_FROM_ISR( xStreamBuffer, xReturn ) \
+ if( xReturn > ( size_t ) 0 ) \
+ { \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(TRACE_GET_OBJECT_EVENT_CODE(SEND_FROM_ISR, TRCSUCCESS, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); \
+ trcKERNEL_HOOKS_SET_OBJECT_STATE(STREAMBUFFER, xStreamBuffer, prvBytesInBuffer(xStreamBuffer)); \
+ } \
+ else \
+ { \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(TRACE_GET_OBJECT_EVENT_CODE(SEND_FROM_ISR, TRCFAILED, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); \
+ }
+
+#undef traceSTREAM_BUFFER_RECEIVE_FROM_ISR
+#define traceSTREAM_BUFFER_RECEIVE_FROM_ISR( xStreamBuffer, xReceivedLength ) \
+ if( xReceivedLength > ( size_t ) 0 ) \
+ { \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE_FROM_ISR, TRCSUCCESS, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); \
+ trcKERNEL_HOOKS_SET_OBJECT_STATE(STREAMBUFFER, xStreamBuffer, prvBytesInBuffer(xStreamBuffer)); \
+ } \
+ else \
+ { \
+ trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE_FROM_ISR, TRCFAILED, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); \
+ }
+
+#endif /* (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1) */
+
+#endif /* (TRC_CFG_SCHEDULING_ONLY == 0) */
+
+#endif /*#if TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT */
+
+/******************************************************************************/
+/*** Definitions for Streaming mode *******************************************/
+/******************************************************************************/
+#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
+
+/*******************************************************************************
+* vTraceStoreKernelObjectName
+*
+* Set the name for a kernel object (defined by its address).
+******************************************************************************/
+void vTraceStoreKernelObjectName(void* object, const char* name);
+
+/*******************************************************************************
+* prvIsNewTCB
+*
+* Tells if this task is already executing, or if there has been a task-switch.
+* Assumed to be called within a trace hook in kernel context.
+*******************************************************************************/
+uint32_t prvIsNewTCB(void* pNewTCB);
+
+#define TRACE_GET_CURRENT_TASK() prvTraceGetCurrentTaskHandle()
+
+/*************************************************************************/
+/* KERNEL SPECIFIC OBJECT CONFIGURATION */
+/*************************************************************************/
+
+/*******************************************************************************
+ * The event codes - should match the offline config file.
+ ******************************************************************************/
+
+/*** Event codes for streaming - should match the Tracealyzer config file *****/
+#define PSF_EVENT_NULL_EVENT 0x00
+
+#define PSF_EVENT_TRACE_START 0x01
+#define PSF_EVENT_TS_CONFIG 0x02
+#define PSF_EVENT_OBJ_NAME 0x03
+#define PSF_EVENT_TASK_PRIORITY 0x04
+#define PSF_EVENT_TASK_PRIO_INHERIT 0x05
+#define PSF_EVENT_TASK_PRIO_DISINHERIT 0x06
+#define PSF_EVENT_DEFINE_ISR 0x07
+
+#define PSF_EVENT_TASK_CREATE 0x10
+#define PSF_EVENT_QUEUE_CREATE 0x11
+#define PSF_EVENT_SEMAPHORE_BINARY_CREATE 0x12
+#define PSF_EVENT_MUTEX_CREATE 0x13
+#define PSF_EVENT_TIMER_CREATE 0x14
+#define PSF_EVENT_EVENTGROUP_CREATE 0x15
+#define PSF_EVENT_SEMAPHORE_COUNTING_CREATE 0x16
+#define PSF_EVENT_MUTEX_RECURSIVE_CREATE 0x17
+#define PSF_EVENT_STREAMBUFFER_CREATE 0x18
+#define PSF_EVENT_MESSAGEBUFFER_CREATE 0x19
+
+#define PSF_EVENT_TASK_DELETE 0x20
+#define PSF_EVENT_QUEUE_DELETE 0x21
+#define PSF_EVENT_SEMAPHORE_DELETE 0x22
+#define PSF_EVENT_MUTEX_DELETE 0x23
+#define PSF_EVENT_TIMER_DELETE 0x24
+#define PSF_EVENT_EVENTGROUP_DELETE 0x25
+#define PSF_EVENT_STREAMBUFFER_DELETE 0x28
+#define PSF_EVENT_MESSAGEBUFFER_DELETE 0x29
+
+#define PSF_EVENT_TASK_READY 0x30
+#define PSF_EVENT_NEW_TIME 0x31
+#define PSF_EVENT_NEW_TIME_SCHEDULER_SUSPENDED 0x32
+#define PSF_EVENT_ISR_BEGIN 0x33
+#define PSF_EVENT_ISR_RESUME 0x34
+#define PSF_EVENT_TS_BEGIN 0x35
+#define PSF_EVENT_TS_RESUME 0x36
+#define PSF_EVENT_TASK_ACTIVATE 0x37
+
+#define PSF_EVENT_MALLOC 0x38
+#define PSF_EVENT_FREE 0x39
+
+#define PSF_EVENT_LOWPOWER_BEGIN 0x3A
+#define PSF_EVENT_LOWPOWER_END 0x3B
+
+#define PSF_EVENT_IFE_NEXT 0x3C
+#define PSF_EVENT_IFE_DIRECT 0x3D
+
+#define PSF_EVENT_TASK_CREATE_FAILED 0x40
+#define PSF_EVENT_QUEUE_CREATE_FAILED 0x41
+#define PSF_EVENT_SEMAPHORE_BINARY_CREATE_FAILED 0x42
+#define PSF_EVENT_MUTEX_CREATE_FAILED 0x43
+#define PSF_EVENT_TIMER_CREATE_FAILED 0x44
+#define PSF_EVENT_EVENTGROUP_CREATE_FAILED 0x45
+#define PSF_EVENT_SEMAPHORE_COUNTING_CREATE_FAILED 0x46
+#define PSF_EVENT_MUTEX_RECURSIVE_CREATE_FAILED 0x47
+#define PSF_EVENT_STREAMBUFFER_CREATE_FAILED 0x49
+#define PSF_EVENT_MESSAGEBUFFER_CREATE_FAILED 0x4A
+
+#define PSF_EVENT_TIMER_DELETE_FAILED 0x48
+
+#define PSF_EVENT_QUEUE_SEND 0x50
+#define PSF_EVENT_SEMAPHORE_GIVE 0x51
+#define PSF_EVENT_MUTEX_GIVE 0x52
+
+#define PSF_EVENT_QUEUE_SEND_FAILED 0x53
+#define PSF_EVENT_SEMAPHORE_GIVE_FAILED 0x54
+#define PSF_EVENT_MUTEX_GIVE_FAILED 0x55
+
+#define PSF_EVENT_QUEUE_SEND_BLOCK 0x56
+#define PSF_EVENT_SEMAPHORE_GIVE_BLOCK 0x57
+#define PSF_EVENT_MUTEX_GIVE_BLOCK 0x58
+
+#define PSF_EVENT_QUEUE_SEND_FROMISR 0x59
+#define PSF_EVENT_SEMAPHORE_GIVE_FROMISR 0x5A
+
+#define PSF_EVENT_QUEUE_SEND_FROMISR_FAILED 0x5C
+#define PSF_EVENT_SEMAPHORE_GIVE_FROMISR_FAILED 0x5D
+
+#define PSF_EVENT_QUEUE_RECEIVE 0x60
+#define PSF_EVENT_SEMAPHORE_TAKE 0x61
+#define PSF_EVENT_MUTEX_TAKE 0x62
+
+#define PSF_EVENT_QUEUE_RECEIVE_FAILED 0x63
+#define PSF_EVENT_SEMAPHORE_TAKE_FAILED 0x64
+#define PSF_EVENT_MUTEX_TAKE_FAILED 0x65
+
+#define PSF_EVENT_QUEUE_RECEIVE_BLOCK 0x66
+#define PSF_EVENT_SEMAPHORE_TAKE_BLOCK 0x67
+#define PSF_EVENT_MUTEX_TAKE_BLOCK 0x68
+
+#define PSF_EVENT_QUEUE_RECEIVE_FROMISR 0x69
+#define PSF_EVENT_SEMAPHORE_TAKE_FROMISR 0x6A
+
+#define PSF_EVENT_QUEUE_RECEIVE_FROMISR_FAILED 0x6C
+#define PSF_EVENT_SEMAPHORE_TAKE_FROMISR_FAILED 0x6D
+
+#define PSF_EVENT_QUEUE_PEEK 0x70
+#define PSF_EVENT_SEMAPHORE_PEEK 0x71
+#define PSF_EVENT_MUTEX_PEEK 0x72
+
+#define PSF_EVENT_QUEUE_PEEK_FAILED 0x73
+#define PSF_EVENT_SEMAPHORE_PEEK_FAILED 0x74
+#define PSF_EVENT_MUTEX_PEEK_FAILED 0x75
+
+#define PSF_EVENT_QUEUE_PEEK_BLOCK 0x76
+#define PSF_EVENT_SEMAPHORE_PEEK_BLOCK 0x77
+#define PSF_EVENT_MUTEX_PEEK_BLOCK 0x78
+
+#define PSF_EVENT_TASK_DELAY_UNTIL 0x79
+#define PSF_EVENT_TASK_DELAY 0x7A
+#define PSF_EVENT_TASK_SUSPEND 0x7B
+#define PSF_EVENT_TASK_RESUME 0x7C
+#define PSF_EVENT_TASK_RESUME_FROMISR 0x7D
+
+#define PSF_EVENT_TIMER_PENDFUNCCALL 0x80
+#define PSF_EVENT_TIMER_PENDFUNCCALL_FROMISR 0x81
+#define PSF_EVENT_TIMER_PENDFUNCCALL_FAILED 0x82
+#define PSF_EVENT_TIMER_PENDFUNCCALL_FROMISR_FAILED 0x83
+
+#define PSF_EVENT_USER_EVENT 0x90
+
+#define PSF_EVENT_TIMER_START 0xA0
+#define PSF_EVENT_TIMER_RESET 0xA1
+#define PSF_EVENT_TIMER_STOP 0xA2
+#define PSF_EVENT_TIMER_CHANGEPERIOD 0xA3
+#define PSF_EVENT_TIMER_START_FROMISR 0xA4
+#define PSF_EVENT_TIMER_RESET_FROMISR 0xA5
+#define PSF_EVENT_TIMER_STOP_FROMISR 0xA6
+#define PSF_EVENT_TIMER_CHANGEPERIOD_FROMISR 0xA7
+#define PSF_EVENT_TIMER_START_FAILED 0xA8
+#define PSF_EVENT_TIMER_RESET_FAILED 0xA9
+#define PSF_EVENT_TIMER_STOP_FAILED 0xAA
+#define PSF_EVENT_TIMER_CHANGEPERIOD_FAILED 0xAB
+#define PSF_EVENT_TIMER_START_FROMISR_FAILED 0xAC
+#define PSF_EVENT_TIMER_RESET_FROMISR_FAILED 0xAD
+#define PSF_EVENT_TIMER_STOP_FROMISR_FAILED 0xAE
+#define PSF_EVENT_TIMER_CHANGEPERIOD_FROMISR_FAILED 0xAF
+
+#define PSF_EVENT_EVENTGROUP_SYNC 0xB0
+#define PSF_EVENT_EVENTGROUP_WAITBITS 0xB1
+#define PSF_EVENT_EVENTGROUP_CLEARBITS 0xB2
+#define PSF_EVENT_EVENTGROUP_CLEARBITS_FROMISR 0xB3
+#define PSF_EVENT_EVENTGROUP_SETBITS 0xB4
+#define PSF_EVENT_EVENTGROUP_SETBITS_FROMISR 0xB5
+#define PSF_EVENT_EVENTGROUP_SYNC_BLOCK 0xB6
+#define PSF_EVENT_EVENTGROUP_WAITBITS_BLOCK 0xB7
+#define PSF_EVENT_EVENTGROUP_SYNC_FAILED 0xB8
+#define PSF_EVENT_EVENTGROUP_WAITBITS_FAILED 0xB9
+
+#define PSF_EVENT_QUEUE_SEND_FRONT 0xC0
+#define PSF_EVENT_QUEUE_SEND_FRONT_FAILED 0xC1
+#define PSF_EVENT_QUEUE_SEND_FRONT_BLOCK 0xC2
+#define PSF_EVENT_QUEUE_SEND_FRONT_FROMISR 0xC3
+#define PSF_EVENT_QUEUE_SEND_FRONT_FROMISR_FAILED 0xC4
+#define PSF_EVENT_MUTEX_GIVE_RECURSIVE 0xC5
+#define PSF_EVENT_MUTEX_GIVE_RECURSIVE_FAILED 0xC6
+#define PSF_EVENT_MUTEX_TAKE_RECURSIVE 0xC7
+#define PSF_EVENT_MUTEX_TAKE_RECURSIVE_FAILED 0xC8
+
+#define PSF_EVENT_TASK_NOTIFY 0xC9
+#define PSF_EVENT_TASK_NOTIFY_TAKE 0xCA
+#define PSF_EVENT_TASK_NOTIFY_TAKE_BLOCK 0xCB
+#define PSF_EVENT_TASK_NOTIFY_TAKE_FAILED 0xCC
+#define PSF_EVENT_TASK_NOTIFY_WAIT 0xCD
+#define PSF_EVENT_TASK_NOTIFY_WAIT_BLOCK 0xCE
+#define PSF_EVENT_TASK_NOTIFY_WAIT_FAILED 0xCF
+#define PSF_EVENT_TASK_NOTIFY_FROM_ISR 0xD0
+#define PSF_EVENT_TASK_NOTIFY_GIVE_FROM_ISR 0xD1
+
+#define PSF_EVENT_TIMER_EXPIRED 0xD2
+
+#define PSF_EVENT_STREAMBUFFER_SEND 0xD3
+#define PSF_EVENT_STREAMBUFFER_SEND_BLOCK 0xD4
+#define PSF_EVENT_STREAMBUFFER_SEND_FAILED 0xD5
+#define PSF_EVENT_STREAMBUFFER_RECEIVE 0xD6
+#define PSF_EVENT_STREAMBUFFER_RECEIVE_BLOCK 0xD7
+#define PSF_EVENT_STREAMBUFFER_RECEIVE_FAILED 0xD8
+#define PSF_EVENT_STREAMBUFFER_SEND_FROM_ISR 0xD9
+#define PSF_EVENT_STREAMBUFFER_SEND_FROM_ISR_FAILED 0xDA
+#define PSF_EVENT_STREAMBUFFER_RECEIVE_FROM_ISR 0xDB
+#define PSF_EVENT_STREAMBUFFER_RECEIVE_FROM_ISR_FAILED 0xDC
+#define PSF_EVENT_STREAMBUFFER_RESET 0xDD
+
+#define PSF_EVENT_MESSAGEBUFFER_SEND 0xDE
+#define PSF_EVENT_MESSAGEBUFFER_SEND_BLOCK 0xDF
+#define PSF_EVENT_MESSAGEBUFFER_SEND_FAILED 0xE0
+#define PSF_EVENT_MESSAGEBUFFER_RECEIVE 0xE1
+#define PSF_EVENT_MESSAGEBUFFER_RECEIVE_BLOCK 0xE2
+#define PSF_EVENT_MESSAGEBUFFER_RECEIVE_FAILED 0xE3
+#define PSF_EVENT_MESSAGEBUFFER_SEND_FROM_ISR 0xE4
+#define PSF_EVENT_MESSAGEBUFFER_SEND_FROM_ISR_FAILED 0xE5
+#define PSF_EVENT_MESSAGEBUFFER_RECEIVE_FROM_ISR 0xE6
+#define PSF_EVENT_MESSAGEBUFFER_RECEIVE_FROM_ISR_FAILED 0xE7
+#define PSF_EVENT_MESSAGEBUFFER_RESET 0xE8
+
+#define PSF_EVENT_MALLOC_FAILED 0xE9
+
+#define PSF_EVENT_UNUSED_STACK 0xEA
+
+/*** The trace macros for streaming ******************************************/
+
+/* A macro that will update the tick count when returning from tickless idle */
+#undef traceINCREASE_TICK_COUNT
+/* Note: This can handle time adjustments of max 2^32 ticks, i.e., 35 seconds at 120 MHz. Thus, tick-less idle periods longer than 2^32 ticks will appear "compressed" on the time line.*/
+#define traceINCREASE_TICK_COUNT( xCount ) { extern uint32_t uiTraceTickCount; uiTraceTickCount += xCount; }
+
+#if (TRC_CFG_INCLUDE_OSTICK_EVENTS == 1)
+#define OS_TICK_EVENT(uxSchedulerSuspended, xTickCount) if (uxSchedulerSuspended == (unsigned portBASE_TYPE) pdFALSE) { prvTraceStoreEvent1(PSF_EVENT_NEW_TIME, (uint32_t)(xTickCount + 1)); }
+#else
+#define OS_TICK_EVENT(uxSchedulerSuspended, xTickCount)
+#endif
+
+/* Called on each OS tick. Will call uiPortGetTimestamp to make sure it is called at least once every OS tick. */
+#undef traceTASK_INCREMENT_TICK
+#if TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_3_0
+
+#define traceTASK_INCREMENT_TICK( xTickCount ) \
+ if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || xPendedTicks == 0) { extern uint32_t uiTraceTickCount; uiTraceTickCount++; } \
+ OS_TICK_EVENT(uxSchedulerSuspended, xTickCount)
+
+#elif TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_7_5_X
+
+#define traceTASK_INCREMENT_TICK( xTickCount ) \
+ if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || uxPendedTicks == 0) { extern uint32_t uiTraceTickCount; uiTraceTickCount++; } \
+ OS_TICK_EVENT(uxSchedulerSuspended, xTickCount)
+
+#else
+
+#define traceTASK_INCREMENT_TICK( xTickCount ) \
+ if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || uxMissedTicks == 0) { extern uint32_t uiTraceTickCount; uiTraceTickCount++; } \
+ OS_TICK_EVENT(uxSchedulerSuspended, xTickCount)
+
+#endif
+
+extern volatile uint32_t uiTraceSystemState;
+
+/* Called on each task-switch */
+#undef traceTASK_SWITCHED_IN
+#define traceTASK_SWITCHED_IN() \
+ uiTraceSystemState = TRC_STATE_IN_TASKSWITCH; \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ { \
+ if (prvIsNewTCB(pxCurrentTCB)) \
+ { \
+ prvTraceStoreEvent2(PSF_EVENT_TASK_ACTIVATE, (uint32_t)pxCurrentTCB, pxCurrentTCB->uxPriority); \
+ } \
+ } \
+ uiTraceSystemState = TRC_STATE_IN_APPLICATION;
+
+/* Called for each task that becomes ready */
+#if (TRC_CFG_INCLUDE_READY_EVENTS == 1)
+#undef traceMOVED_TASK_TO_READY_STATE
+#define traceMOVED_TASK_TO_READY_STATE( pxTCB ) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, pxTCB) & CurrentFilterMask) \
+ prvTraceStoreEvent1(PSF_EVENT_TASK_READY, (uint32_t)pxTCB);
+#endif
+
+#undef traceTASK_CREATE
+#if TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0
+#define traceTASK_CREATE(pxNewTCB) \
+ if (pxNewTCB != NULL) \
+ { \
+ prvAddTaskToStackMonitor(pxNewTCB); \
+ prvTraceSaveObjectSymbol(pxNewTCB, pxNewTCB->pcTaskName); \
+ prvTraceSaveObjectData(pxNewTCB, pxNewTCB->uxPriority); \
+ prvTraceStoreStringEvent(1, PSF_EVENT_OBJ_NAME, pxNewTCB->pcTaskName, pxNewTCB); \
+ TRACE_SET_OBJECT_FILTER(TASK, pxNewTCB, CurrentFilterGroup); \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, pxNewTCB) & CurrentFilterMask) \
+ prvTraceStoreEvent2(PSF_EVENT_TASK_CREATE, (uint32_t)pxNewTCB, pxNewTCB->uxPriority); \
+ }
+#else /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */
+#define traceTASK_CREATE(pxNewTCB) \
+ if (pxNewTCB != NULL) \
+ { \
+ prvAddTaskToStackMonitor(pxNewTCB); \
+ prvTraceSaveObjectSymbol(pxNewTCB, (const char*)pcName); \
+ prvTraceSaveObjectData(pxNewTCB, uxPriority); \
+ prvTraceStoreStringEvent(1, PSF_EVENT_OBJ_NAME, (const char*)pcName, pxNewTCB); \
+ TRACE_SET_OBJECT_FILTER(TASK, pxNewTCB, CurrentFilterGroup); \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, pxNewTCB) & CurrentFilterMask) \
+ prvTraceStoreEvent2(PSF_EVENT_TASK_CREATE, (uint32_t)pxNewTCB, uxPriority); \
+ }
+#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */
+
+/* Called in vTaskCreate, if it fails (typically if the stack can not be allocated) */
+#undef traceTASK_CREATE_FAILED
+#define traceTASK_CREATE_FAILED() \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ prvTraceStoreEvent0(PSF_EVENT_TASK_CREATE_FAILED);
+
+/* Called on vTaskDelete */
+#undef traceTASK_DELETE // We don't allow for filtering out "delete" events. They are important and not very frequent. Moreover, we can't exclude create events, so this should be symmetrical.
+#define traceTASK_DELETE( pxTaskToDelete ) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, pxTaskToDelete) & CurrentFilterMask) \
+ prvTraceStoreEvent2(PSF_EVENT_TASK_DELETE, (uint32_t)pxTaskToDelete, (pxTaskToDelete != NULL) ? (pxTaskToDelete->uxPriority) : 0); \
+ prvTraceDeleteSymbol(pxTaskToDelete); \
+ prvTraceDeleteObjectData(pxTaskToDelete); \
+ prvRemoveTaskFromStackMonitor(pxTaskToDelete);
+
+#if (TRC_CFG_SCHEDULING_ONLY == 0)
+
+#if (defined(configUSE_TICKLESS_IDLE) && configUSE_TICKLESS_IDLE != 0)
+
+#undef traceLOW_POWER_IDLE_BEGIN
+#define traceLOW_POWER_IDLE_BEGIN() \
+ { \
+ prvTraceStoreEvent1(PSF_EVENT_LOWPOWER_BEGIN, xExpectedIdleTime); \
+ }
+
+#undef traceLOW_POWER_IDLE_END
+#define traceLOW_POWER_IDLE_END() \
+ { \
+ prvTraceStoreEvent0(PSF_EVENT_LOWPOWER_END); \
+ }
+
+#endif /* (defined(configUSE_TICKLESS_IDLE) && configUSE_TICKLESS_IDLE != 0) */
+
+/* Called on vTaskSuspend */
+#undef traceTASK_SUSPEND
+#define traceTASK_SUSPEND( pxTaskToSuspend ) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, pxTaskToSuspend) & CurrentFilterMask) \
+ prvTraceStoreEvent1(PSF_EVENT_TASK_SUSPEND, (uint32_t)pxTaskToSuspend);
+
+/* Called on vTaskDelay - note the use of FreeRTOS variable xTicksToDelay */
+#undef traceTASK_DELAY
+#define traceTASK_DELAY() \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ prvTraceStoreEvent1(PSF_EVENT_TASK_DELAY, xTicksToDelay);
+
+/* Called on vTaskDelayUntil - note the use of FreeRTOS variable xTimeToWake */
+#undef traceTASK_DELAY_UNTIL
+#if TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0
+#define traceTASK_DELAY_UNTIL(xTimeToWake) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ prvTraceStoreEvent1(PSF_EVENT_TASK_DELAY_UNTIL, (uint32_t)xTimeToWake);
+#else /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */
+#define traceTASK_DELAY_UNTIL() \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ prvTraceStoreEvent1(PSF_EVENT_TASK_DELAY_UNTIL, (uint32_t)xTimeToWake);
+#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */
+
+#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0)
+#define traceQUEUE_CREATE_HELPER() \
+ case queueQUEUE_TYPE_MUTEX: \
+ prvTraceStoreEvent1(PSF_EVENT_MUTEX_CREATE, (uint32_t)pxNewQueue); \
+ break; \
+ case queueQUEUE_TYPE_RECURSIVE_MUTEX: \
+ prvTraceStoreEvent1(PSF_EVENT_MUTEX_RECURSIVE_CREATE, (uint32_t)pxNewQueue); \
+ break;
+#else
+#define traceQUEUE_CREATE_HELPER()
+#endif /* (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0) */
+
+/* Called in xQueueCreate, and thereby for all other object based on queues, such as semaphores. */
+#undef traceQUEUE_CREATE
+#define traceQUEUE_CREATE( pxNewQueue )\
+ TRACE_SET_OBJECT_FILTER(QUEUE, pxNewQueue, CurrentFilterGroup); \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ { \
+ if (TRACE_GET_OBJECT_FILTER(QUEUE, pxNewQueue) & CurrentFilterMask) \
+ { \
+ switch (pxNewQueue->ucQueueType) \
+ { \
+ case queueQUEUE_TYPE_BASE: \
+ prvTraceStoreEvent2(PSF_EVENT_QUEUE_CREATE, (uint32_t)pxNewQueue, uxQueueLength); \
+ break; \
+ case queueQUEUE_TYPE_BINARY_SEMAPHORE: \
+ prvTraceStoreEvent1(PSF_EVENT_SEMAPHORE_BINARY_CREATE, (uint32_t)pxNewQueue); \
+ break; \
+ traceQUEUE_CREATE_HELPER() \
+ } \
+ } \
+ }
+
+#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0)
+#define traceQUEUE_CREATE_FAILED_HELPER() \
+ case queueQUEUE_TYPE_MUTEX: \
+ prvTraceStoreEvent1(PSF_EVENT_MUTEX_CREATE_FAILED, 0); \
+ break; \
+ case queueQUEUE_TYPE_RECURSIVE_MUTEX: \
+ prvTraceStoreEvent1(PSF_EVENT_MUTEX_RECURSIVE_CREATE_FAILED, 0); \
+ break;
+#else
+#define traceQUEUE_CREATE_FAILED_HELPER()
+#endif /* (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0) */
+
+/* Called in xQueueCreate, if the queue creation fails */
+#undef traceQUEUE_CREATE_FAILED
+#define traceQUEUE_CREATE_FAILED( queueType ) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ { \
+ switch (queueType) \
+ { \
+ case queueQUEUE_TYPE_BASE: \
+ prvTraceStoreEvent2(PSF_EVENT_QUEUE_CREATE_FAILED, 0, uxQueueLength); \
+ break; \
+ case queueQUEUE_TYPE_BINARY_SEMAPHORE: \
+ prvTraceStoreEvent1(PSF_EVENT_SEMAPHORE_BINARY_CREATE_FAILED, 0); \
+ break; \
+ traceQUEUE_CREATE_FAILED_HELPER() \
+ } \
+ }
+
+#undef traceQUEUE_DELETE // We don't allow for filtering out "delete" events. They are important and not very frequent. Moreover, we can't exclude create events, so this should be symmetrical.
+#define traceQUEUE_DELETE( pxQueue ) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ { \
+ if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \
+ { \
+ switch (pxQueue->ucQueueType) \
+ { \
+ case queueQUEUE_TYPE_BASE: \
+ prvTraceStoreEvent2(PSF_EVENT_QUEUE_DELETE, (uint32_t)pxQueue, (pxQueue != NULL) ? (pxQueue->uxMessagesWaiting) : 0); \
+ break; \
+ case queueQUEUE_TYPE_MUTEX: \
+ case queueQUEUE_TYPE_RECURSIVE_MUTEX: \
+ prvTraceStoreEvent2(PSF_EVENT_MUTEX_DELETE, (uint32_t)pxQueue, (pxQueue != NULL) ? (pxQueue->uxMessagesWaiting) : 0); \
+ break; \
+ case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \
+ case queueQUEUE_TYPE_BINARY_SEMAPHORE: \
+ prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_DELETE, (uint32_t)pxQueue, (pxQueue != NULL) ? (pxQueue->uxMessagesWaiting) : 0); \
+ break; \
+ } \
+ } \
+ } \
+ prvTraceDeleteSymbol(pxQueue);
+
+/* Called in xQueueCreateCountingSemaphore, if the queue creation fails */
+#undef traceCREATE_COUNTING_SEMAPHORE
+#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X)
+#define traceCREATE_COUNTING_SEMAPHORE() \
+ TRACE_SET_OBJECT_FILTER(QUEUE, xHandle, CurrentFilterGroup); \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(QUEUE, xHandle) & CurrentFilterMask) \
+ prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE, (uint32_t)xHandle, uxMaxCount)
+#elif (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_7_5_X)
+#define traceCREATE_COUNTING_SEMAPHORE() \
+ TRACE_SET_OBJECT_FILTER(QUEUE, xHandle, CurrentFilterGroup); \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(QUEUE, xHandle) & CurrentFilterMask) \
+ prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE, (uint32_t)xHandle, uxInitialCount);
+#elif (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_7_4_X)
+#define traceCREATE_COUNTING_SEMAPHORE() \
+ TRACE_SET_OBJECT_FILTER(QUEUE, xHandle, CurrentFilterGroup); \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(QUEUE, xHandle) & CurrentFilterMask) \
+ prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE, (uint32_t)xHandle, uxCountValue);
+#else
+#define traceCREATE_COUNTING_SEMAPHORE() \
+ TRACE_SET_OBJECT_FILTER(QUEUE, pxHandle, CurrentFilterGroup); \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(QUEUE, pxHandle) & CurrentFilterMask) \
+ prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE, (uint32_t)pxHandle, uxCountValue);
+#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X */
+
+#undef traceCREATE_COUNTING_SEMAPHORE_FAILED
+#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X)
+#define traceCREATE_COUNTING_SEMAPHORE_FAILED() \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE_FAILED, 0, uxMaxCount);
+#elif (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_7_5_X)
+#define traceCREATE_COUNTING_SEMAPHORE_FAILED() \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE_FAILED, 0, uxInitialCount);
+#elif (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_7_4_X)
+#define traceCREATE_COUNTING_SEMAPHORE_FAILED() \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE_FAILED, 0, uxCountValue);
+#else
+#define traceCREATE_COUNTING_SEMAPHORE_FAILED() \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE_FAILED, 0, uxCountValue);
+#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X */
+
+
+/* This macro is not necessary as of FreeRTOS v9.0.0 */
+#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0)
+/* Called in xQueueCreateMutex, and thereby also from xSemaphoreCreateMutex and xSemaphoreCreateRecursiveMutex */
+#undef traceCREATE_MUTEX
+#define traceCREATE_MUTEX( pxNewQueue ) \
+ TRACE_SET_OBJECT_FILTER(QUEUE, pxNewQueue, CurrentFilterGroup); \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ { \
+ if (TRACE_GET_OBJECT_FILTER(QUEUE, pxNewQueue) & CurrentFilterMask) \
+ { \
+ switch (pxNewQueue->ucQueueType) \
+ { \
+ case queueQUEUE_TYPE_MUTEX: \
+ prvTraceStoreEvent1(PSF_EVENT_MUTEX_CREATE, (uint32_t)pxNewQueue); \
+ break; \
+ case queueQUEUE_TYPE_RECURSIVE_MUTEX: \
+ prvTraceStoreEvent1(PSF_EVENT_MUTEX_RECURSIVE_CREATE, (uint32_t)pxNewQueue); \
+ break; \
+ } \
+ }\
+ }
+
+/* Called in xQueueCreateMutex when the operation fails (when memory allocation fails) */
+#undef traceCREATE_MUTEX_FAILED
+#define traceCREATE_MUTEX_FAILED() \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ prvTraceStoreEvent1(PSF_EVENT_MUTEX_CREATE_FAILED, 0);
+#endif /* (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0) */
+
+/* Called when a message is sent to a queue */ /* CS IS NEW ! */
+#undef traceQUEUE_SEND
+#define traceQUEUE_SEND( pxQueue ) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \
+ switch (pxQueue->ucQueueType) \
+ { \
+ case queueQUEUE_TYPE_BASE: \
+ prvTraceStoreEvent2(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND : PSF_EVENT_QUEUE_SEND_FRONT, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting + 1); \
+ break; \
+ case queueQUEUE_TYPE_BINARY_SEMAPHORE: \
+ case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \
+ prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_GIVE, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting + 1); \
+ break; \
+ case queueQUEUE_TYPE_MUTEX: \
+ case queueQUEUE_TYPE_RECURSIVE_MUTEX: \
+ prvTraceStoreEvent1(PSF_EVENT_MUTEX_GIVE, (uint32_t)pxQueue); \
+ break; \
+ }
+
+#undef traceQUEUE_SET_SEND
+#define traceQUEUE_SET_SEND( pxQueue ) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \
+ prvTraceStoreEvent2(PSF_EVENT_QUEUE_SEND, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting + 1);
+
+/* Called when a message failed to be sent to a queue (timeout) */
+#undef traceQUEUE_SEND_FAILED
+#define traceQUEUE_SEND_FAILED( pxQueue ) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \
+ switch (pxQueue->ucQueueType) \
+ { \
+ case queueQUEUE_TYPE_BASE: \
+ prvTraceStoreEvent2(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND_FAILED : PSF_EVENT_QUEUE_SEND_FRONT_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \
+ break; \
+ case queueQUEUE_TYPE_BINARY_SEMAPHORE: \
+ case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \
+ prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_GIVE_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \
+ break; \
+ case queueQUEUE_TYPE_MUTEX: \
+ case queueQUEUE_TYPE_RECURSIVE_MUTEX: \
+ prvTraceStoreEvent1(PSF_EVENT_MUTEX_GIVE_FAILED, (uint32_t)pxQueue); \
+ break; \
+ }
+
+/* Called when the task is blocked due to a send operation on a full queue */
+#undef traceBLOCKING_ON_QUEUE_SEND
+#define traceBLOCKING_ON_QUEUE_SEND( pxQueue ) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \
+ switch (pxQueue->ucQueueType) \
+ { \
+ case queueQUEUE_TYPE_BASE: \
+ prvTraceStoreEvent2(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND_BLOCK : PSF_EVENT_QUEUE_SEND_FRONT_BLOCK, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \
+ break; \
+ case queueQUEUE_TYPE_BINARY_SEMAPHORE: \
+ case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \
+ prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_GIVE_BLOCK, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \
+ break; \
+ case queueQUEUE_TYPE_MUTEX: \
+ case queueQUEUE_TYPE_RECURSIVE_MUTEX: \
+ prvTraceStoreEvent1(PSF_EVENT_MUTEX_GIVE_BLOCK, (uint32_t)pxQueue); \
+ break; \
+ }
+
+/* Called when a message is sent from interrupt context, e.g., using xQueueSendFromISR */
+#undef traceQUEUE_SEND_FROM_ISR
+#define traceQUEUE_SEND_FROM_ISR( pxQueue ) \
+ if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \
+ switch (pxQueue->ucQueueType) \
+ { \
+ case queueQUEUE_TYPE_BASE: \
+ prvTraceStoreEvent2(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND_FROMISR : PSF_EVENT_QUEUE_SEND_FRONT_FROMISR, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting + 1); \
+ break; \
+ case queueQUEUE_TYPE_BINARY_SEMAPHORE: \
+ case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \
+ prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_GIVE_FROMISR, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting + 1); \
+ break; \
+ }
+
+/* Called when a message send from interrupt context fails (since the queue was full) */
+#undef traceQUEUE_SEND_FROM_ISR_FAILED
+#define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ) \
+ if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \
+ switch (pxQueue->ucQueueType) \
+ { \
+ case queueQUEUE_TYPE_BASE: \
+ prvTraceStoreEvent2(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND_FROMISR_FAILED : PSF_EVENT_QUEUE_SEND_FRONT_FROMISR_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \
+ break; \
+ case queueQUEUE_TYPE_BINARY_SEMAPHORE: \
+ case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \
+ prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_GIVE_FROMISR_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \
+ break; \
+ }
+
+/* Called when a message is received from a queue */
+#undef traceQUEUE_RECEIVE
+#define traceQUEUE_RECEIVE( pxQueue ) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \
+ switch (pxQueue->ucQueueType) \
+ { \
+ case queueQUEUE_TYPE_BASE: \
+ if (isQueueReceiveHookActuallyPeek) \
+ prvTraceStoreEvent3(PSF_EVENT_QUEUE_PEEK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting - 1); \
+ else\
+ prvTraceStoreEvent3(PSF_EVENT_QUEUE_RECEIVE, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting - 1); \
+ break; \
+ case queueQUEUE_TYPE_BINARY_SEMAPHORE: \
+ case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \
+ if (isQueueReceiveHookActuallyPeek) \
+ prvTraceStoreEvent3(PSF_EVENT_SEMAPHORE_PEEK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting - 1); \
+ else \
+ prvTraceStoreEvent3(PSF_EVENT_SEMAPHORE_TAKE, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting - 1); \
+ break; \
+ case queueQUEUE_TYPE_MUTEX: \
+ case queueQUEUE_TYPE_RECURSIVE_MUTEX: \
+ if (isQueueReceiveHookActuallyPeek) \
+ prvTraceStoreEvent2(PSF_EVENT_MUTEX_PEEK, (uint32_t)pxQueue, xTicksToWait); \
+ else \
+ prvTraceStoreEvent2(PSF_EVENT_MUTEX_TAKE, (uint32_t)pxQueue, xTicksToWait); \
+ break; \
+ }
+
+/* Called when a receive operation on a queue fails (timeout) */
+#undef traceQUEUE_RECEIVE_FAILED
+#define traceQUEUE_RECEIVE_FAILED( pxQueue ) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \
+ switch (pxQueue->ucQueueType) \
+ { \
+ case queueQUEUE_TYPE_BASE: \
+ prvTraceStoreEvent3(isQueueReceiveHookActuallyPeek ? PSF_EVENT_QUEUE_PEEK_FAILED : PSF_EVENT_QUEUE_RECEIVE_FAILED, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \
+ break; \
+ case queueQUEUE_TYPE_BINARY_SEMAPHORE: \
+ case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \
+ prvTraceStoreEvent3(isQueueReceiveHookActuallyPeek ? PSF_EVENT_SEMAPHORE_PEEK_FAILED : PSF_EVENT_SEMAPHORE_TAKE_FAILED, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \
+ break; \
+ case queueQUEUE_TYPE_MUTEX: \
+ case queueQUEUE_TYPE_RECURSIVE_MUTEX: \
+ prvTraceStoreEvent2(isQueueReceiveHookActuallyPeek ? PSF_EVENT_MUTEX_PEEK_FAILED : PSF_EVENT_MUTEX_TAKE_FAILED, (uint32_t)pxQueue, xTicksToWait); \
+ break; \
+ }
+
+/* Called when the task is blocked due to a receive operation on an empty queue */
+#undef traceBLOCKING_ON_QUEUE_RECEIVE
+#define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \
+ switch (pxQueue->ucQueueType) \
+ { \
+ case queueQUEUE_TYPE_BASE: \
+ prvTraceStoreEvent3(isQueueReceiveHookActuallyPeek ? PSF_EVENT_QUEUE_PEEK_BLOCK : PSF_EVENT_QUEUE_RECEIVE_BLOCK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \
+ break; \
+ case queueQUEUE_TYPE_BINARY_SEMAPHORE: \
+ case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \
+ prvTraceStoreEvent3(isQueueReceiveHookActuallyPeek ? PSF_EVENT_SEMAPHORE_PEEK_BLOCK : PSF_EVENT_SEMAPHORE_TAKE_BLOCK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \
+ break; \
+ case queueQUEUE_TYPE_MUTEX: \
+ case queueQUEUE_TYPE_RECURSIVE_MUTEX: \
+ prvTraceStoreEvent2(isQueueReceiveHookActuallyPeek ? PSF_EVENT_MUTEX_PEEK_BLOCK : PSF_EVENT_MUTEX_TAKE_BLOCK, (uint32_t)pxQueue, xTicksToWait); \
+ break; \
+ }
+
+#if (TRC_CFG_FREERTOS_VERSION > TRC_FREERTOS_VERSION_9_0_1)
+/* Called when a peek operation on a queue fails (timeout) */
+#undef traceQUEUE_PEEK_FAILED
+#define traceQUEUE_PEEK_FAILED( pxQueue ) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \
+ switch (pxQueue->ucQueueType) \
+ { \
+ case queueQUEUE_TYPE_BASE: \
+ prvTraceStoreEvent3(PSF_EVENT_QUEUE_PEEK_FAILED, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \
+ break; \
+ case queueQUEUE_TYPE_BINARY_SEMAPHORE: \
+ case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \
+ prvTraceStoreEvent3(PSF_EVENT_SEMAPHORE_PEEK_FAILED, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \
+ break; \
+ case queueQUEUE_TYPE_MUTEX: \
+ case queueQUEUE_TYPE_RECURSIVE_MUTEX: \
+ prvTraceStoreEvent2(PSF_EVENT_MUTEX_PEEK_FAILED, (uint32_t)pxQueue, xTicksToWait); \
+ break; \
+ }
+
+/* Called when the task is blocked due to a peek operation on an empty queue */
+#undef traceBLOCKING_ON_QUEUE_PEEK
+#define traceBLOCKING_ON_QUEUE_PEEK( pxQueue ) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \
+ switch (pxQueue->ucQueueType) \
+ { \
+ case queueQUEUE_TYPE_BASE: \
+ prvTraceStoreEvent3(PSF_EVENT_QUEUE_PEEK_BLOCK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \
+ break; \
+ case queueQUEUE_TYPE_BINARY_SEMAPHORE: \
+ case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \
+ prvTraceStoreEvent3(PSF_EVENT_SEMAPHORE_PEEK_BLOCK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \
+ break; \
+ case queueQUEUE_TYPE_MUTEX: \
+ case queueQUEUE_TYPE_RECURSIVE_MUTEX: \
+ prvTraceStoreEvent2(PSF_EVENT_MUTEX_PEEK_BLOCK, (uint32_t)pxQueue, xTicksToWait); \
+ break; \
+ }
+
+#endif /* (TRC_CFG_FREERTOS_VERSION > TRC_FREERTOS_VERSION_9_0_1) */
+
+/* Called when a message is received in interrupt context, e.g., using xQueueReceiveFromISR */
+#undef traceQUEUE_RECEIVE_FROM_ISR
+#define traceQUEUE_RECEIVE_FROM_ISR( pxQueue ) \
+ if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \
+ switch (pxQueue->ucQueueType) \
+ { \
+ case queueQUEUE_TYPE_BASE: \
+ prvTraceStoreEvent2(PSF_EVENT_QUEUE_RECEIVE_FROMISR, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting - 1); \
+ break; \
+ case queueQUEUE_TYPE_BINARY_SEMAPHORE: \
+ case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \
+ prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_TAKE_FROMISR, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting - 1); \
+ break; \
+ }
+
+/* Called when a message receive from interrupt context fails (since the queue was empty) */
+#undef traceQUEUE_RECEIVE_FROM_ISR_FAILED
+#define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ) \
+ if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \
+ switch (pxQueue->ucQueueType) \
+ { \
+ case queueQUEUE_TYPE_BASE: \
+ prvTraceStoreEvent2(PSF_EVENT_QUEUE_RECEIVE_FROMISR_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \
+ break; \
+ case queueQUEUE_TYPE_BINARY_SEMAPHORE: \
+ case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \
+ prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_TAKE_FROMISR_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \
+ break; \
+ }
+
+/* Called on xQueuePeek */
+#undef traceQUEUE_PEEK
+#define traceQUEUE_PEEK( pxQueue ) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \
+ switch (pxQueue->ucQueueType) \
+ { \
+ case queueQUEUE_TYPE_BASE: \
+ prvTraceStoreEvent3(PSF_EVENT_QUEUE_PEEK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \
+ break; \
+ case queueQUEUE_TYPE_BINARY_SEMAPHORE: \
+ case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \
+ prvTraceStoreEvent3(PSF_EVENT_SEMAPHORE_PEEK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \
+ break; \
+ case queueQUEUE_TYPE_MUTEX: \
+ case queueQUEUE_TYPE_RECURSIVE_MUTEX: \
+ prvTraceStoreEvent1(PSF_EVENT_MUTEX_PEEK, (uint32_t)pxQueue); \
+ break; \
+ }
+
+/* Called in vTaskPrioritySet */
+#undef traceTASK_PRIORITY_SET
+#define traceTASK_PRIORITY_SET( pxTask, uxNewPriority ) \
+ prvTraceSaveObjectData(pxTask, uxNewPriority); \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, pxTask) & CurrentFilterMask) \
+ prvTraceStoreEvent2(PSF_EVENT_TASK_PRIORITY, (uint32_t)pxTask, uxNewPriority);
+
+/* Called in vTaskPriorityInherit, which is called by Mutex operations */
+#undef traceTASK_PRIORITY_INHERIT
+#define traceTASK_PRIORITY_INHERIT( pxTask, uxNewPriority ) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, pxTask) & CurrentFilterMask) \
+ prvTraceStoreEvent2(PSF_EVENT_TASK_PRIO_INHERIT, (uint32_t)pxTask, uxNewPriority);
+
+/* Called in vTaskPriorityDisinherit, which is called by Mutex operations */
+#undef traceTASK_PRIORITY_DISINHERIT
+#define traceTASK_PRIORITY_DISINHERIT( pxTask, uxNewPriority ) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, pxTask) & CurrentFilterMask) \
+ prvTraceStoreEvent2(PSF_EVENT_TASK_PRIO_DISINHERIT, (uint32_t)pxTask, uxNewPriority);
+
+/* Called in vTaskResume */
+#undef traceTASK_RESUME
+#define traceTASK_RESUME( pxTaskToResume ) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, pxTaskToResume) & CurrentFilterMask) \
+ prvTraceStoreEvent1(PSF_EVENT_TASK_RESUME, (uint32_t)pxTaskToResume);
+
+/* Called in vTaskResumeFromISR */
+#undef traceTASK_RESUME_FROM_ISR
+#define traceTASK_RESUME_FROM_ISR( pxTaskToResume ) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, pxTaskToResume) & CurrentFilterMask) \
+ prvTraceStoreEvent1(PSF_EVENT_TASK_RESUME_FROMISR, (uint32_t)pxTaskToResume);
+
+#if (TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1)
+
+extern uint32_t trcHeapCounter;
+
+#undef traceMALLOC
+#define traceMALLOC( pvAddress, uiSize ) \
+ if (pvAddress != 0) \
+ { \
+ trcHeapCounter += uiSize; \
+ } \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ { \
+ if (pvAddress != 0) \
+ { \
+ prvTraceStoreEvent2(PSF_EVENT_MALLOC, (uint32_t)pvAddress, uiSize); \
+ } \
+ else \
+ { \
+ prvTraceStoreEvent2(PSF_EVENT_MALLOC_FAILED, (uint32_t)pvAddress, uiSize); \
+ } \
+ }
+
+#undef traceFREE
+#define traceFREE( pvAddress, uiSize ) \
+ trcHeapCounter -= uiSize; \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ prvTraceStoreEvent2(PSF_EVENT_FREE, (uint32_t)pvAddress, (uint32_t)(0 - uiSize)); /* "0 -" instead of just "-" to get rid of a warning... */
+
+#endif /* (TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1) */
+
+#if (TRC_CFG_INCLUDE_TIMER_EVENTS == 1)
+
+/* Called in timer.c - xTimerCreate */
+#undef traceTIMER_CREATE
+#define traceTIMER_CREATE(tmr) \
+ TRACE_SET_OBJECT_FILTER(TIMER, tmr, CurrentFilterGroup); \
+ prvTraceSaveObjectSymbol(tmr, (const char*)tmr->pcTimerName); \
+ prvTraceStoreStringEvent(1, PSF_EVENT_OBJ_NAME, (const char*)tmr->pcTimerName, tmr); \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(TIMER, tmr) & CurrentFilterMask) \
+ prvTraceStoreEvent2(PSF_EVENT_TIMER_CREATE, (uint32_t)tmr, tmr->xTimerPeriodInTicks);
+
+#undef traceTIMER_CREATE_FAILED
+#define traceTIMER_CREATE_FAILED() \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ prvTraceStoreEvent0(PSF_EVENT_TIMER_CREATE_FAILED);
+
+#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X)
+#define traceTIMER_COMMAND_SEND_8_0_CASES(tmr) \
+ case tmrCOMMAND_RESET: \
+ prvTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_RESET : PSF_EVENT_TIMER_RESET_FAILED, (uint32_t)tmr, xOptionalValue); \
+ break; \
+ case tmrCOMMAND_START_FROM_ISR: \
+ prvTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_START_FROMISR : PSF_EVENT_TIMER_START_FROMISR_FAILED, (uint32_t)tmr, xOptionalValue); \
+ break; \
+ case tmrCOMMAND_RESET_FROM_ISR: \
+ prvTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_RESET_FROMISR : PSF_EVENT_TIMER_RESET_FROMISR_FAILED, (uint32_t)tmr, xOptionalValue); \
+ break; \
+ case tmrCOMMAND_STOP_FROM_ISR: \
+ prvTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_STOP_FROMISR : PSF_EVENT_TIMER_STOP_FROMISR_FAILED, (uint32_t)tmr, xOptionalValue); \
+ break; \
+ case tmrCOMMAND_CHANGE_PERIOD_FROM_ISR: \
+ prvTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_CHANGEPERIOD_FROMISR : PSF_EVENT_TIMER_CHANGEPERIOD_FROMISR_FAILED, (uint32_t)tmr, xOptionalValue); \
+ break;
+#else /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X */
+#define traceTIMER_COMMAND_SEND_8_0_CASES(tmr)
+#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X */
+
+/* Note that xCommandID can never be tmrCOMMAND_EXECUTE_CALLBACK (-1) since the trace macro is not called in that case */
+#undef traceTIMER_COMMAND_SEND
+#define traceTIMER_COMMAND_SEND(tmr, xCommandID, xOptionalValue, xReturn) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(TIMER, tmr) & CurrentFilterMask) \
+ switch(xCommandID) \
+ { \
+ case tmrCOMMAND_START: \
+ prvTraceStoreEvent1((xReturn == pdPASS) ? PSF_EVENT_TIMER_START : PSF_EVENT_TIMER_START_FAILED, (uint32_t)tmr); \
+ break; \
+ case tmrCOMMAND_STOP: \
+ prvTraceStoreEvent1((xReturn == pdPASS) ? PSF_EVENT_TIMER_STOP : PSF_EVENT_TIMER_STOP_FAILED, (uint32_t)tmr); \
+ break; \
+ case tmrCOMMAND_CHANGE_PERIOD: \
+ prvTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_CHANGEPERIOD : PSF_EVENT_TIMER_CHANGEPERIOD_FAILED, (uint32_t)tmr, xOptionalValue); \
+ break; \
+ case tmrCOMMAND_DELETE: \
+ prvTraceStoreEvent1((xReturn == pdPASS) ? PSF_EVENT_TIMER_DELETE : PSF_EVENT_TIMER_DELETE_FAILED, (uint32_t)tmr); \
+ break; \
+ traceTIMER_COMMAND_SEND_8_0_CASES(tmr) \
+ }
+
+#undef traceTIMER_EXPIRED
+#define traceTIMER_EXPIRED(tmr) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(TIMER, tmr) & CurrentFilterMask) \
+ prvTraceStoreEvent2(PSF_EVENT_TIMER_EXPIRED, (uint32_t)tmr->pxCallbackFunction, (uint32_t)tmr->pvTimerID);
+
+#endif /* #if (TRC_CFG_INCLUDE_TIMER_EVENTS == 1) */
+
+
+#if (TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS == 1)
+
+#undef tracePEND_FUNC_CALL
+#define tracePEND_FUNC_CALL(func, arg1, arg2, ret) \
+ prvTraceStoreEvent1((ret == pdPASS) ? PSF_EVENT_TIMER_PENDFUNCCALL : PSF_EVENT_TIMER_PENDFUNCCALL_FAILED, (uint32_t)func);
+
+#undef tracePEND_FUNC_CALL_FROM_ISR
+#define tracePEND_FUNC_CALL_FROM_ISR(func, arg1, arg2, ret) \
+ prvTraceStoreEvent1((ret == pdPASS) ? PSF_EVENT_TIMER_PENDFUNCCALL_FROMISR : PSF_EVENT_TIMER_PENDFUNCCALL_FROMISR_FAILED, (uint32_t)func);
+
+#endif /* (TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS == 1) */
+
+#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1)
+
+#undef traceEVENT_GROUP_CREATE
+#define traceEVENT_GROUP_CREATE(eg) \
+ TRACE_SET_OBJECT_FILTER(EVENTGROUP, eg, CurrentFilterGroup); \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \
+ prvTraceStoreEvent1(PSF_EVENT_EVENTGROUP_CREATE, (uint32_t)eg);
+
+#undef traceEVENT_GROUP_DELETE
+#define traceEVENT_GROUP_DELETE(eg) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \
+ prvTraceStoreEvent1(PSF_EVENT_EVENTGROUP_DELETE, (uint32_t)eg); \
+ prvTraceDeleteSymbol(eg);
+
+#undef traceEVENT_GROUP_CREATE_FAILED
+#define traceEVENT_GROUP_CREATE_FAILED() \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ prvTraceStoreEvent0(PSF_EVENT_EVENTGROUP_CREATE_FAILED);
+
+#undef traceEVENT_GROUP_SYNC_BLOCK
+#define traceEVENT_GROUP_SYNC_BLOCK(eg, bitsToSet, bitsToWaitFor) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \
+ prvTraceStoreEvent2(PSF_EVENT_EVENTGROUP_SYNC_BLOCK, (uint32_t)eg, bitsToWaitFor);
+
+#undef traceEVENT_GROUP_SYNC_END
+#define traceEVENT_GROUP_SYNC_END(eg, bitsToSet, bitsToWaitFor, wasTimeout) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \
+ prvTraceStoreEvent2((wasTimeout != pdTRUE) ? PSF_EVENT_EVENTGROUP_SYNC : PSF_EVENT_EVENTGROUP_SYNC_FAILED, (uint32_t)eg, bitsToWaitFor);
+
+#undef traceEVENT_GROUP_WAIT_BITS_BLOCK
+#define traceEVENT_GROUP_WAIT_BITS_BLOCK(eg, bitsToWaitFor) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \
+ prvTraceStoreEvent2(PSF_EVENT_EVENTGROUP_WAITBITS_BLOCK, (uint32_t)eg, bitsToWaitFor);
+
+#undef traceEVENT_GROUP_WAIT_BITS_END
+#define traceEVENT_GROUP_WAIT_BITS_END(eg, bitsToWaitFor, wasTimeout) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \
+ prvTraceStoreEvent2((wasTimeout != pdTRUE) ? PSF_EVENT_EVENTGROUP_WAITBITS : PSF_EVENT_EVENTGROUP_WAITBITS_FAILED, (uint32_t)eg, bitsToWaitFor);
+
+#undef traceEVENT_GROUP_CLEAR_BITS
+#define traceEVENT_GROUP_CLEAR_BITS(eg, bitsToClear) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \
+ prvTraceStoreEvent2(PSF_EVENT_EVENTGROUP_CLEARBITS, (uint32_t)eg, bitsToClear);
+
+#undef traceEVENT_GROUP_CLEAR_BITS_FROM_ISR
+#define traceEVENT_GROUP_CLEAR_BITS_FROM_ISR(eg, bitsToClear) \
+ if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \
+ prvTraceStoreEvent2(PSF_EVENT_EVENTGROUP_CLEARBITS_FROMISR, (uint32_t)eg, bitsToClear);
+
+#undef traceEVENT_GROUP_SET_BITS
+#define traceEVENT_GROUP_SET_BITS(eg, bitsToSet) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \
+ prvTraceStoreEvent2(PSF_EVENT_EVENTGROUP_SETBITS, (uint32_t)eg, bitsToSet);
+
+#undef traceEVENT_GROUP_SET_BITS_FROM_ISR
+#define traceEVENT_GROUP_SET_BITS_FROM_ISR(eg, bitsToSet) \
+ if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \
+ prvTraceStoreEvent2(PSF_EVENT_EVENTGROUP_SETBITS_FROMISR, (uint32_t)eg, bitsToSet);
+
+#endif /* (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1) */
+
+#undef traceTASK_NOTIFY_TAKE
+#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_4_0)
+#define traceTASK_NOTIFY_TAKE(index) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask){ \
+ if (pxCurrentTCB->ucNotifyState[index] == taskNOTIFICATION_RECEIVED) \
+ prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_TAKE, (uint32_t)pxCurrentTCB, xTicksToWait); \
+ else \
+ prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_TAKE_FAILED, (uint32_t)pxCurrentTCB, xTicksToWait);}
+#elif (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0)
+#define traceTASK_NOTIFY_TAKE() \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask){ \
+ if (pxCurrentTCB->ucNotifyState == taskNOTIFICATION_RECEIVED) \
+ prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_TAKE, (uint32_t)pxCurrentTCB, xTicksToWait); \
+ else \
+ prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_TAKE_FAILED, (uint32_t)pxCurrentTCB, xTicksToWait);}
+#else /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_4_0 */
+#define traceTASK_NOTIFY_TAKE() \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask){ \
+ if (pxCurrentTCB->eNotifyState == eNotified) \
+ prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_TAKE, (uint32_t)pxCurrentTCB, xTicksToWait); \
+ else \
+ prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_TAKE_FAILED, (uint32_t)pxCurrentTCB, xTicksToWait);}
+#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_4_0 */
+
+#undef traceTASK_NOTIFY_TAKE_BLOCK
+#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_4_0)
+#define traceTASK_NOTIFY_TAKE_BLOCK(index) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_TAKE_BLOCK, (uint32_t)pxCurrentTCB, xTicksToWait);
+#else /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_4_0 */
+#define traceTASK_NOTIFY_TAKE_BLOCK() \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_TAKE_BLOCK, (uint32_t)pxCurrentTCB, xTicksToWait);
+#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_4_0 */
+
+#undef traceTASK_NOTIFY_WAIT
+#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_4_0)
+#define traceTASK_NOTIFY_WAIT(index) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask){ \
+ if (pxCurrentTCB->ucNotifyState[index] == taskNOTIFICATION_RECEIVED) \
+ prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_WAIT, (uint32_t)pxCurrentTCB, xTicksToWait); \
+ else \
+ prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_WAIT_FAILED, (uint32_t)pxCurrentTCB, xTicksToWait);}
+#elif (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0)
+#define traceTASK_NOTIFY_WAIT() \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask){ \
+ if (pxCurrentTCB->ucNotifyState == taskNOTIFICATION_RECEIVED) \
+ prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_WAIT, (uint32_t)pxCurrentTCB, xTicksToWait); \
+ else \
+ prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_WAIT_FAILED, (uint32_t)pxCurrentTCB, xTicksToWait);}
+#else /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_4_0 */
+#define traceTASK_NOTIFY_WAIT() \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask){ \
+ if (pxCurrentTCB->eNotifyState == eNotified) \
+ prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_WAIT, (uint32_t)pxCurrentTCB, xTicksToWait); \
+ else \
+ prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_WAIT_FAILED, (uint32_t)pxCurrentTCB, xTicksToWait);}
+#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_4_0 */
+
+#undef traceTASK_NOTIFY_WAIT_BLOCK
+#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_4_0)
+#define traceTASK_NOTIFY_WAIT_BLOCK(index) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_WAIT_BLOCK, (uint32_t)pxCurrentTCB, xTicksToWait);
+#else /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_4_0 */
+#define traceTASK_NOTIFY_WAIT_BLOCK() \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_WAIT_BLOCK, (uint32_t)pxCurrentTCB, xTicksToWait);
+#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_4_0 */
+
+#undef traceTASK_NOTIFY
+#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_4_0)
+#define traceTASK_NOTIFY(index) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, xTaskToNotify) & CurrentFilterMask) \
+ prvTraceStoreEvent1(PSF_EVENT_TASK_NOTIFY, (uint32_t)xTaskToNotify);
+#else /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_4_0 */
+#define traceTASK_NOTIFY() \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, xTaskToNotify) & CurrentFilterMask) \
+ prvTraceStoreEvent1(PSF_EVENT_TASK_NOTIFY, (uint32_t)xTaskToNotify);
+#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_4_0 */
+
+#undef traceTASK_NOTIFY_FROM_ISR
+#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_4_0)
+#define traceTASK_NOTIFY_FROM_ISR(index) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, xTaskToNotify) & CurrentFilterMask) \
+ prvTraceStoreEvent1(PSF_EVENT_TASK_NOTIFY_FROM_ISR, (uint32_t)xTaskToNotify);
+#else /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_4_0 */
+#define traceTASK_NOTIFY_FROM_ISR() \
+ if (TRACE_GET_OBJECT_FILTER(TASK, xTaskToNotify) & CurrentFilterMask) \
+ prvTraceStoreEvent1(PSF_EVENT_TASK_NOTIFY_FROM_ISR, (uint32_t)xTaskToNotify);
+#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_4_0 */
+
+#undef traceTASK_NOTIFY_GIVE_FROM_ISR
+#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_4_0)
+#define traceTASK_NOTIFY_GIVE_FROM_ISR(index) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, xTaskToNotify) & CurrentFilterMask) \
+ prvTraceStoreEvent1(PSF_EVENT_TASK_NOTIFY_GIVE_FROM_ISR, (uint32_t)xTaskToNotify);
+#else /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_4_0 */
+#define traceTASK_NOTIFY_GIVE_FROM_ISR() \
+ if (TRACE_GET_OBJECT_FILTER(TASK, xTaskToNotify) & CurrentFilterMask) \
+ prvTraceStoreEvent1(PSF_EVENT_TASK_NOTIFY_GIVE_FROM_ISR, (uint32_t)xTaskToNotify);
+#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_4_0 */
+
+#undef traceQUEUE_REGISTRY_ADD
+#define traceQUEUE_REGISTRY_ADD(object, name) \
+ prvTraceSaveObjectSymbol(object, (const char*)name); \
+ prvTraceStoreStringEvent(1, PSF_EVENT_OBJ_NAME, name, object);
+
+#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1)
+
+#undef traceSTREAM_BUFFER_CREATE
+#define traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer ) \
+ TRACE_SET_OBJECT_FILTER(STREAMBUFFER, pxStreamBuffer, CurrentFilterGroup); \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, pxStreamBuffer) & CurrentFilterMask) \
+ prvTraceStoreEvent2(xIsMessageBuffer == 1 ? PSF_EVENT_MESSAGEBUFFER_CREATE : PSF_EVENT_STREAMBUFFER_CREATE, (uint32_t)pxStreamBuffer, xBufferSizeBytes);
+
+#undef traceSTREAM_BUFFER_CREATE_FAILED
+#define traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ prvTraceStoreEvent2(xIsMessageBuffer == 1 ? PSF_EVENT_MESSAGEBUFFER_CREATE_FAILED : PSF_EVENT_STREAMBUFFER_CREATE_FAILED, 0 , xBufferSizeBytes);
+
+#undef traceSTREAM_BUFFER_CREATE_STATIC_FAILED
+#define traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer ) \
+ traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer )
+
+#undef traceSTREAM_BUFFER_DELETE
+#define traceSTREAM_BUFFER_DELETE( xStreamBuffer ) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, pxStreamBuffer) & CurrentFilterMask) \
+ prvTraceStoreEvent2(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_DELETE : PSF_EVENT_STREAMBUFFER_DELETE, (uint32_t)xStreamBuffer, prvBytesInBuffer(xStreamBuffer)); \
+ prvTraceDeleteSymbol(xStreamBuffer);
+
+#undef traceSTREAM_BUFFER_RESET
+#define traceSTREAM_BUFFER_RESET( xStreamBuffer ) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \
+ prvTraceStoreEvent2(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_RESET : PSF_EVENT_STREAMBUFFER_RESET, (uint32_t)xStreamBuffer, 0);
+
+#undef traceSTREAM_BUFFER_SEND
+#define traceSTREAM_BUFFER_SEND( xStreamBuffer, xReturn ) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \
+ prvTraceStoreEvent2(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_SEND : PSF_EVENT_STREAMBUFFER_SEND, (uint32_t)xStreamBuffer, prvBytesInBuffer(xStreamBuffer));
+
+#undef traceBLOCKING_ON_STREAM_BUFFER_SEND
+#define traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer ) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \
+ prvTraceStoreEvent1(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_SEND_BLOCK : PSF_EVENT_STREAMBUFFER_SEND_BLOCK, (uint32_t)xStreamBuffer);
+
+#undef traceSTREAM_BUFFER_SEND_FAILED
+#define traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer ) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \
+ prvTraceStoreEvent1(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_SEND_FAILED : PSF_EVENT_STREAMBUFFER_SEND_FAILED, (uint32_t)xStreamBuffer);
+
+#undef traceSTREAM_BUFFER_RECEIVE
+#define traceSTREAM_BUFFER_RECEIVE( xStreamBuffer, xReceivedLength ) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \
+ prvTraceStoreEvent2(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_RECEIVE: PSF_EVENT_STREAMBUFFER_RECEIVE, (uint32_t)xStreamBuffer, prvBytesInBuffer(xStreamBuffer));
+
+#undef traceBLOCKING_ON_STREAM_BUFFER_RECEIVE
+#define traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer ) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \
+ prvTraceStoreEvent1(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_RECEIVE_BLOCK: PSF_EVENT_STREAMBUFFER_RECEIVE_BLOCK, (uint32_t)xStreamBuffer);
+
+#undef traceSTREAM_BUFFER_RECEIVE_FAILED
+#define traceSTREAM_BUFFER_RECEIVE_FAILED( xStreamBuffer ) \
+ if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
+ if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \
+ prvTraceStoreEvent1(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_RECEIVE_FAILED: PSF_EVENT_STREAMBUFFER_RECEIVE_FAILED, (uint32_t)xStreamBuffer);
+
+#undef traceSTREAM_BUFFER_SEND_FROM_ISR
+#define traceSTREAM_BUFFER_SEND_FROM_ISR( xStreamBuffer, xReturn ) \
+ if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \
+ { \
+ if ( xReturn > ( size_t ) 0 ) \
+ { \
+ prvTraceStoreEvent2(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_SEND_FROM_ISR : PSF_EVENT_STREAMBUFFER_SEND_FROM_ISR, (uint32_t)xStreamBuffer, prvBytesInBuffer(xStreamBuffer)); \
+ } \
+ else \
+ { \
+ prvTraceStoreEvent1(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_SEND_FROM_ISR_FAILED : PSF_EVENT_STREAMBUFFER_SEND_FROM_ISR_FAILED, (uint32_t)xStreamBuffer); \
+ } \
+ }
+
+#undef traceSTREAM_BUFFER_RECEIVE_FROM_ISR
+#define traceSTREAM_BUFFER_RECEIVE_FROM_ISR( xStreamBuffer, xReceivedLength ) \
+if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \
+ { \
+ if ( xReceivedLength > ( size_t ) 0 ) \
+ { \
+ prvTraceStoreEvent2(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_RECEIVE_FROM_ISR : PSF_EVENT_STREAMBUFFER_RECEIVE_FROM_ISR, (uint32_t)xStreamBuffer, prvBytesInBuffer(xStreamBuffer)); \
+ } \
+ else \
+ { \
+ prvTraceStoreEvent1(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_RECEIVE_FROM_ISR_FAILED : PSF_EVENT_STREAMBUFFER_RECEIVE_FROM_ISR_FAILED, (uint32_t)xStreamBuffer); \
+ } \
+ }
+
+#endif /* (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1) */
+
+#endif /* (TRC_CFG_SCHEDULING_ONLY == 0) */
+
+#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
+
+#else /* (TRC_USE_TRACEALYZER_RECORDER == 1) */
+
+/* When recorder is disabled */
+#define vTraceSetQueueName(object, name)
+#define vTraceSetSemaphoreName(object, name)
+#define vTraceSetMutexName(object, name)
+#define vTraceSetEventGroupName(object, name)
+#define vTraceSetStreamBufferName(object, name)
+#define vTraceSetMessageBufferName(object, name)
+
+#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TRC_KERNEL_PORT_H */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcPortDefines.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcPortDefines.h
index 258bf220a..99a2fbf50 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcPortDefines.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcPortDefines.h
@@ -1,137 +1,138 @@
-/*******************************************************************************
- * Trace Recorder Library for Tracealyzer v4.1.5
- * Percepio AB, www.percepio.com
- *
- * trcPortDefines.h
- *
- * Some common defines for 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_PORTDEFINES_H
-#define TRC_PORTDEFINES_H
-
-#define TRC_FREE_RUNNING_32BIT_INCR 1
-#define TRC_FREE_RUNNING_32BIT_DECR 2
-#define TRC_OS_TIMER_INCR 3
-#define TRC_OS_TIMER_DECR 4
-#define TRC_CUSTOM_TIMER_INCR 5
-#define TRC_CUSTOM_TIMER_DECR 6
-
-/* Start options for vTraceEnable. */
-#define TRC_INIT 0
-#define TRC_START 1
-#define TRC_START_AWAIT_HOST 2
-
-/* Command codes for TzCtrl task */
-#define CMD_SET_ACTIVE 1 /* Start (param1 = 1) or Stop (param1 = 0) */
-
-/* The final command code, used to validate commands. */
-#define CMD_LAST_COMMAND 1
-
-#define TRC_RECORDER_MODE_SNAPSHOT 0
-#define TRC_RECORDER_MODE_STREAMING 1
-
-#define TRC_RECORDER_BUFFER_ALLOCATION_STATIC (0x00)
-#define TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC (0x01)
-#define TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM (0x02)
-
-/* Filter Groups */
-#define FilterGroup0 (uint16_t)0x0001
-#define FilterGroup1 (uint16_t)0x0002
-#define FilterGroup2 (uint16_t)0x0004
-#define FilterGroup3 (uint16_t)0x0008
-#define FilterGroup4 (uint16_t)0x0010
-#define FilterGroup5 (uint16_t)0x0020
-#define FilterGroup6 (uint16_t)0x0040
-#define FilterGroup7 (uint16_t)0x0080
-#define FilterGroup8 (uint16_t)0x0100
-#define FilterGroup9 (uint16_t)0x0200
-#define FilterGroup10 (uint16_t)0x0400
-#define FilterGroup11 (uint16_t)0x0800
-#define FilterGroup12 (uint16_t)0x1000
-#define FilterGroup13 (uint16_t)0x2000
-#define FilterGroup14 (uint16_t)0x4000
-#define FilterGroup15 (uint16_t)0x8000
-
-/******************************************************************************
- * Supported ports
- *
- * TRC_HARDWARE_PORT_HWIndependent
- * A hardware independent fallback option for event timestamping. Provides low
- * resolution timestamps based on the OS tick.
- * This may be used on the Win32 port, but may also be used on embedded hardware
- * platforms. All time durations will be truncated to the OS tick frequency,
- * typically 1 KHz. This means that a task or ISR that executes in less than
- * 1 ms get an execution time of zero.
- *
- * TRC_HARDWARE_PORT_APPLICATION_DEFINED
- * Allows for defining the port macros in other source code files.
- *
- * TRC_HARDWARE_PORT_Win32
- * "Accurate" timestamping based on the Windows performance counter for Win32
- * builds. Note that this gives the host machine time, not the kernel time.
- *
- * Hardware specific ports
- * To get accurate timestamping, a hardware timer is necessary. Below are the
- * available ports. Some of these are "unofficial", meaning that
- * they have not yet been verified by Percepio but have been contributed by
- * external developers. They should work, otherwise let us know by emailing
- * support@percepio.com. Some work on any OS platform, while other are specific
- * to a certain operating system.
- *****************************************************************************/
-
-/****** Port Name ************************************* Code ** Official ** OS Platform *********/
-#define TRC_HARDWARE_PORT_APPLICATION_DEFINED 98 /* - - */
-#define TRC_HARDWARE_PORT_NOT_SET 99 /* - - */
-#define TRC_HARDWARE_PORT_HWIndependent 0 /* Yes Any */
-#define TRC_HARDWARE_PORT_Win32 1 /* Yes FreeRTOS on Win32 */
-#define TRC_HARDWARE_PORT_Atmel_AT91SAM7 2 /* No Any */
-#define TRC_HARDWARE_PORT_Atmel_UC3A0 3 /* No Any */
-#define TRC_HARDWARE_PORT_ARM_Cortex_M 4 /* Yes Any */
-#define TRC_HARDWARE_PORT_Renesas_RX600 6 /* Yes Any */
-#define TRC_HARDWARE_PORT_MICROCHIP_PIC24_PIC32 7 /* Yes Any */
-#define TRC_HARDWARE_PORT_TEXAS_INSTRUMENTS_TMS570_RM48 8 /* Yes Any */
-#define TRC_HARDWARE_PORT_TEXAS_INSTRUMENTS_MSP430 9 /* No Any */
-#define TRC_HARDWARE_PORT_XILINX_PPC405 11 /* No FreeRTOS */
-#define TRC_HARDWARE_PORT_XILINX_PPC440 12 /* No FreeRTOS */
-#define TRC_HARDWARE_PORT_XILINX_MICROBLAZE 13 /* No Any */
-#define TRC_HARDWARE_PORT_NXP_LPC210X 14 /* No Any */
-#define TRC_HARDWARE_PORT_ARM_CORTEX_A9 15 /* Yes Any */
-#define TRC_HARDWARE_PORT_POWERPC_Z4 16 /* No FreeRTOS */
-#define TRC_HARDWARE_PORT_Altera_NiosII 17 /* No Any */
-#endif /*TRC_PORTDEFINES_H*/
+/*******************************************************************************
+ * Trace Recorder Library for Tracealyzer v4.3.11
+ * Percepio AB, www.percepio.com
+ *
+ * trcPortDefines.h
+ *
+ * Some common defines for 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_PORTDEFINES_H
+#define TRC_PORTDEFINES_H
+
+#define TRC_FREE_RUNNING_32BIT_INCR 1
+#define TRC_FREE_RUNNING_32BIT_DECR 2
+#define TRC_OS_TIMER_INCR 3
+#define TRC_OS_TIMER_DECR 4
+#define TRC_CUSTOM_TIMER_INCR 5
+#define TRC_CUSTOM_TIMER_DECR 6
+
+/* Start options for vTraceEnable. */
+#define TRC_INIT 0
+#define TRC_START 1
+#define TRC_START_AWAIT_HOST 2
+
+/* Command codes for TzCtrl task */
+#define CMD_SET_ACTIVE 1 /* Start (param1 = 1) or Stop (param1 = 0) */
+
+/* The final command code, used to validate commands. */
+#define CMD_LAST_COMMAND 1
+
+#define TRC_RECORDER_MODE_SNAPSHOT 0
+#define TRC_RECORDER_MODE_STREAMING 1
+
+#define TRC_RECORDER_BUFFER_ALLOCATION_STATIC (0x00)
+#define TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC (0x01)
+#define TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM (0x02)
+
+/* Filter Groups */
+#define FilterGroup0 (uint16_t)0x0001
+#define FilterGroup1 (uint16_t)0x0002
+#define FilterGroup2 (uint16_t)0x0004
+#define FilterGroup3 (uint16_t)0x0008
+#define FilterGroup4 (uint16_t)0x0010
+#define FilterGroup5 (uint16_t)0x0020
+#define FilterGroup6 (uint16_t)0x0040
+#define FilterGroup7 (uint16_t)0x0080
+#define FilterGroup8 (uint16_t)0x0100
+#define FilterGroup9 (uint16_t)0x0200
+#define FilterGroup10 (uint16_t)0x0400
+#define FilterGroup11 (uint16_t)0x0800
+#define FilterGroup12 (uint16_t)0x1000
+#define FilterGroup13 (uint16_t)0x2000
+#define FilterGroup14 (uint16_t)0x4000
+#define FilterGroup15 (uint16_t)0x8000
+
+/******************************************************************************
+ * Supported ports
+ *
+ * TRC_HARDWARE_PORT_HWIndependent
+ * A hardware independent fallback option for event timestamping. Provides low
+ * resolution timestamps based on the OS tick.
+ * This may be used on the Win32 port, but may also be used on embedded hardware
+ * platforms. All time durations will be truncated to the OS tick frequency,
+ * typically 1 KHz. This means that a task or ISR that executes in less than
+ * 1 ms get an execution time of zero.
+ *
+ * TRC_HARDWARE_PORT_APPLICATION_DEFINED
+ * Allows for defining the port macros in other source code files.
+ *
+ * TRC_HARDWARE_PORT_Win32
+ * "Accurate" timestamping based on the Windows performance counter for Win32
+ * builds. Note that this gives the host machine time, not the kernel time.
+ *
+ * Hardware specific ports
+ * To get accurate timestamping, a hardware timer is necessary. Below are the
+ * available ports. Some of these are "unofficial", meaning that
+ * they have not yet been verified by Percepio but have been contributed by
+ * external developers. They should work, otherwise let us know by emailing
+ * support@percepio.com. Some work on any OS platform, while other are specific
+ * to a certain operating system.
+ *****************************************************************************/
+
+/****** Port Name ************************************* Code ** Official ** OS Platform *********/
+#define TRC_HARDWARE_PORT_APPLICATION_DEFINED 98 /* - - */
+#define TRC_HARDWARE_PORT_NOT_SET 99 /* - - */
+#define TRC_HARDWARE_PORT_HWIndependent 0 /* Yes Any */
+#define TRC_HARDWARE_PORT_Win32 1 /* Yes FreeRTOS on Win32 */
+#define TRC_HARDWARE_PORT_Atmel_AT91SAM7 2 /* No Any */
+#define TRC_HARDWARE_PORT_Atmel_UC3A0 3 /* No Any */
+#define TRC_HARDWARE_PORT_ARM_Cortex_M 4 /* Yes Any */
+#define TRC_HARDWARE_PORT_Renesas_RX600 6 /* Yes Any */
+#define TRC_HARDWARE_PORT_MICROCHIP_PIC24_PIC32 7 /* Yes Any */
+#define TRC_HARDWARE_PORT_TEXAS_INSTRUMENTS_TMS570_RM48 8 /* Yes Any */
+#define TRC_HARDWARE_PORT_TEXAS_INSTRUMENTS_MSP430 9 /* No Any */
+#define TRC_HARDWARE_PORT_XILINX_PPC405 11 /* No FreeRTOS */
+#define TRC_HARDWARE_PORT_XILINX_PPC440 12 /* No FreeRTOS */
+#define TRC_HARDWARE_PORT_XILINX_MICROBLAZE 13 /* No Any */
+#define TRC_HARDWARE_PORT_XILINX_ZyncUltraScaleR5 14 /* No FreeRTOS */
+#define TRC_HARDWARE_PORT_NXP_LPC210X 15 /* No Any */
+#define TRC_HARDWARE_PORT_ARM_CORTEX_A9 16 /* Yes Any */
+#define TRC_HARDWARE_PORT_POWERPC_Z4 17 /* No FreeRTOS */
+#define TRC_HARDWARE_PORT_Altera_NiosII 18 /* Yes Any (Tested with FreeRTOS) */
+#endif /*TRC_PORTDEFINES_H*/
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcRecorder.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcRecorder.h
index edcd5f0ae..3d4f3d635 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcRecorder.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcRecorder.h
@@ -1,1789 +1,1905 @@
-/*******************************************************************************
- * 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 */
+/*******************************************************************************
+ * Trace Recorder Library for Tracealyzer v4.3.11
+ * 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 <stdarg.h>
+
+#define TRC_ACKNOWLEDGED (0xABC99123)
+
+#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 /* (TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1) */
+typedef uint8_t traceHandle;
+#endif /* (TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1) */
+
+#include "trcHardwarePort.h"
+#include "trcKernelPort.h"
+
+/* Not yet available in snapshot mode */
+#define vTraceConsoleChannelPrintF(fmt, ...) (void)(fmt)
+#define prvTraceStoreEvent0(...)
+#define prvTraceStoreEvent1(...)
+#define prvTraceStoreEvent2(...)
+#define prvTraceStoreEvent3(...)
+#define prvTraceStoreEvent(...)
+#define prvTraceStoreStringEvent(...)
+
+#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT) */
+
+#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 /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
+
+#if (TRC_USE_TRACEALYZER_RECORDER == 1)
+
+#define TRC_STATE_IN_STARTUP 0
+#define TRC_STATE_IN_TASKSWITCH 1
+#define TRC_STATE_IN_APPLICATION 2
+
+/* 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, fmt, ...) (void)(chn), (void)(fmt) /* Comma operator is used to avoid "unused variable" compiler warnings in a single statement */
+#endif
+
+/******************************************************************************
+ * vTraceVPrintF
+ *
+ * vTracePrintF variant that accepts a va_list.
+ * See vTracePrintF documentation for further details.
+ *
+ ******************************************************************************/
+#if (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)
+void vTraceVPrintF(traceString eventLabel, const char* formatStr, va_list vl);
+#else
+#define vTraceVPrintF(chn, formatStr, vl) (void)(chn), (void)(formatStr), (void)(vl) /* Comma operator is used to avoid "unused variable" compiler warnings in a single statement */
+#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, str) (void)(chn), (void)(str) /* Comma operator is used to avoid "unused variable" compiler warnings in a single statement */
+#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) ((void)(x), (traceString)0) /* Comma operator in parenthesis is used to avoid "unused variable" compiler warnings and return 0 in a single statement */
+#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) /* If not CUSTOM, pRecorderData will be an undefined symbol (same as in TRC_ALLOC_CUSTOM_BUFFER), so no (void) here */
+#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) /* If not CUSTOM, bufname will be an undefined symbol (same as in vTraceSetRecorderDataBuffer), so no (void) here */
+#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 a null object as parameter */
+#undef trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT_FROM_ISR
+#define trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT_FROM_ISR(SERVICE, TRACECLASS) \
+ 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_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 a null object and other value as parameter */
+#undef trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT_WITH_PARAM_FROM_ISR
+#define trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT_WITH_PARAM_FROM_ISR(SERVICE, TRACECLASS, param) \
+ 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_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
+
+/*******************************************************************************
+* prvTraceInitTraceData
+*
+* Allocates and initializes the recorder data structure, based on the constants
+* in trcConfig.h. This allows for allocating the data on the heap, instead of
+* using a static declaration.
+******************************************************************************/
+void prvTraceInitTraceData(void);
+
+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) (void)(handle), (void)(name), (void)(priority) /* Comma operator is used to avoid "unused variable" compiler warnings in a single statement */
+
+#undef vTraceStoreISRBegin
+#define vTraceStoreISRBegin(x) (void)(x)
+
+#undef vTraceStoreISREnd
+#define vTraceStoreISREnd(x) (void)(x)
+
+#undef xTraceSetISRProperties
+#define xTraceSetISRProperties(name, priority) ((void)(name), (void)(priority), (traceHandle)0) /* Comma operator in parenthesis is used to avoid "unused variable" compiler warnings and return 0 in a single statement */
+
+#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, fmt, ...) (void)(chn), (void)(fmt) /* Comma operator is used to avoid "unused variable" compiler warnings in a single statement */
+#undef vTraceVPrintF
+#define vTraceVPrintF(chn, formatStr, vl) (void)(chn), (void)(formatStr), (void)(vl) /* Comma operator is used to avoid "unused variable" compiler warnings in a single statement */
+#undef xTraceRegisterString
+#define xTraceRegisterString(x) ((void)(x), (traceString)0) /* Comma operator in parenthesis is used to avoid "unused variable" compiler warnings and return 0 in a single statement */
+#undef xTraceRegisterChannelFormat
+#define xTraceRegisterChannelFormat(eventLabel, formatStr) ((void)(eventLabel), (void)(formatStr), 0) /* Comma operator in parenthesis is used to avoid "unused variable" compiler warnings and return 0 in a single statement */
+#undef vTraceUBData
+#define vTraceUBData(label, ...) (void)(label)
+#undef vTraceChannelPrint
+#define vTraceChannelPrint(label) (void)(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_END
+ *
+ * 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.
+ *
+ * The BLOCKING option is only used within vTraceEnable, to ensure the full
+ * header, object table and symbol table is transferred without data loss.
+ ******************************************************************************/
+#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);
+
+ /**************************************************************************
+ If your application gets stuck in TRC_STREAM_PORT_ALLOCATE_EVENT_BLOCKING,
+ it means it fails to transfer the header, object table or symbol table
+ during vTraceEnable.
+ This occurs if the trace buffer is too small to accomodate these in full,
+ i.e. before the streaming interface is started and begins to transfer.
+
+ Note that this is intentionally blocking to avoid data loss, but only
+ used within vTraceEnable.
+ **************************************************************************/
+
+ #define TRC_STREAM_PORT_ALLOCATE_EVENT_BLOCKING(_type, _ptrData, _size) \
+ _type* _ptrData; \
+ do { _ptrData = (_type*)prvPagedEventBufferGetWritePointer(_size); } while (_ptrData == NULL);
+
+#else
+ #define TRC_STREAM_PORT_ALLOCATE_EVENT(_type, _ptrData, _size) _type _tmpArray[_size / sizeof(_type)]; _type* _ptrData = _tmpArray;
+ #define TRC_STREAM_PORT_ALLOCATE_EVENT_BLOCKING(_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
+ * TRC_STREAM_PORT_COMMIT_EVENT_BLOCKING
+ *
+ * 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.
+ *
+ * The BLOCKING version is used when sending the initial trace header, which is
+ * important to receive in full. Otherwise, when using non-blocking RTT transfer
+ * this may be corrupted if using an RTT buffer smaller than the combined size
+ * of the header, object table and symbol table.
+ *
+ * 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 */
+ #define TRC_STREAM_PORT_COMMIT_EVENT_BLOCKING(_ptrData, _size) /* Not used */
+#else
+ #define TRC_STREAM_PORT_COMMIT_EVENT(_ptrData, _size) \
+ { \
+ int32_t dummy = 0; \
+ (void)dummy; \
+ if (TRC_STREAM_PORT_WRITE_DATA(_ptrData, _size, &dummy) != 0) \
+ { \
+ vTraceStop(); \
+ } \
+ }
+
+ /* Only used during vTraceEnable */
+ #define TRC_STREAM_PORT_COMMIT_EVENT_BLOCKING(_ptrData, _size) \
+ { \
+ char* ptrWrite = (char*)_ptrData; \
+ uint32_t writeSize = _size; \
+ uint32_t attemptCounter = 0; \
+ int32_t bytesWritten; \
+ int32_t status; \
+ do \
+ { \
+ bytesWritten = 0; \
+ status = TRC_STREAM_PORT_WRITE_DATA(ptrWrite, writeSize, &bytesWritten); \
+ if (status != 0) \
+ { \
+ prvTraceError(PSF_ERROR_STREAM_PORT_WRITE); \
+ break; \
+ } \
+ ptrWrite += bytesWritten; \
+ writeSize -= bytesWritten; \
+ attemptCounter++; \
+ } while (writeSize > 0); \
+ \
+ if (attemptCounter > 1) \
+ { \
+ prvTraceWarning(PSF_WARNING_STREAM_PORT_INITIAL_BLOCKING); \
+ } \
+ }
+
+#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_ERROR_STREAM_PORT_WRITE 6
+
+#define PSF_WARNING_SYMBOL_TABLE_SLOTS 7
+#define PSF_WARNING_SYMBOL_MAX_LENGTH 8
+#define PSF_WARNING_OBJECT_DATA_SLOTS 9
+#define PSF_WARNING_STRING_TOO_LONG 10
+#define PSF_WARNING_STREAM_PORT_READ 11
+#define PSF_WARNING_STREAM_PORT_WRITE 12
+#define PSF_WARNING_STREAM_PORT_INITIAL_BLOCKING 13
+#define PSF_WARNING_STACKMON_NO_SLOTS 14
+
+/******************************************************************************/
+/*** INTERNAL STREAMING FUNCTIONS *********************************************/
+/******************************************************************************/
+
+/* Saves a symbol name in the symbol table and returns the slot address */
+void* prvTraceSaveSymbol(const char *name);
+
+/* Saves a string in the symbol table for an object (task name etc.) */
+void prvTraceSaveObjectSymbol(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) (void)(x)
+
+#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/
+
+#else /* when TRC_USE_TRACEALYZER_RECORDER == 0 */
+
+#define vTraceEnable(x) (void)(x)
+#define xTraceRegisterString(x) ((void)(x), (traceString)0) /* Comma operator in parenthesis is used to avoid "unused variable" compiler warnings and return 0 in a single statement */
+#define vTracePrint(chn, ...) (void)(chn)
+#define vTracePrintF(chn, fmt, ...) (void)(chn), (void)(fmt) /* Comma operator is used to avoid "unused variable" compiler warnings in a single statement */
+#define vTraceVPrintF(chn, formatStr, vl) (void)(chn), (void)(formatStr), (void)(vl) /* Comma operator is used to avoid "unused variable" compiler warnings in a single statement */
+#define vTraceInstanceFinishedNow()
+#define vTraceInstanceFinishedNext()
+#define vTraceStoreISRBegin(x) (void)(x)
+#define vTraceStoreISREnd(x) (void)(x)
+#define xTraceSetISRProperties(a, b) ((void)(a), (void)(b), (traceHandle)0) /* Comma operator in parenthesis is used to avoid "unused variable" compiler warnings and return 0 in a single statement */
+#define vTraceStoreKernelObjectName(a, b) (void)(a), (void)(b) /* Comma operator is used to avoid "unused variable" compiler warnings in a single statement */
+#define xTraceRegisterChannelFormat(eventLabel, formatStr) ((void)(eventLabel), (void)(formatStr), 0) /* Comma operator in parenthesis is used to avoid "unused variable" compiler warnings and return 0 in a single statement */
+#define vTraceChannelPrint(label) (void)(label)
+#define vTraceUBData(label, ...) (void)(label)
+
+#define vTraceSetFilterGroup(x) (void)(x)
+#define vTraceSetFilterMask(x) (void)(x)
+
+#define prvTraceSetReadyEventsEnabled(status) (void)(status)
+
+#define vTraceExcludeTask(handle) (void)(handle)
+
+#define uiTraceStart() (1)
+#define vTraceStart()
+#define vTraceStop()
+
+#ifndef vTraceSetRecorderDataBuffer
+#define vTraceSetRecorderDataBuffer(pRecorderData) /* No (void) here - ignore parameter since undefined symbol if custom allocation is not used */
+#endif
+
+#define vTraceConsoleChannelPrintF(fmt, ...) (void)(fmt)
+
+#ifndef TRC_ALLOC_CUSTOM_BUFFER
+#define TRC_ALLOC_CUSTOM_BUFFER(bufname)
+#endif
+
+#define xTraceIsRecordingEnabled() (0)
+
+#define vTraceSetStopHook(x) (void)(x)
+
+#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TRC_RECORDER_H */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcConfig.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcConfig.h
index dceb6d85b..fa113949d 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcConfig.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcConfig.h
@@ -1,301 +1,411 @@
-/*******************************************************************************
- * Trace Recorder Library for Tracealyzer v4.1.4
- * Percepio AB, www.percepio.com
- *
- * trcConfig.h
- *
- * Main configuration parameters for the trace recorder library.
- * More settings can be found in trcStreamingConfig.h and trcSnapshotConfig.h.
- *
- * Read more at http://percepio.com/2016/10/05/rtos-tracing/
- *
- * 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_CONFIG_H
-#define TRC_CONFIG_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "trcPortDefines.h"
-
-/******************************************************************************
- * Include of processor header file
- *
- * Here you may need to include the header file for your processor. This is
- * required at least for the ARM Cortex-M port, that uses the ARM CMSIS API.
- * Try that in case of build problems. Otherwise, remove the #error line below.
- *****************************************************************************/
-#error "Trace Recorder: Please include your processor's header file here and remove this line."
-
-/*******************************************************************************
- * Configuration Macro: TRC_CFG_HARDWARE_PORT
- *
- * Specify what hardware port to use (i.e., the "timestamping driver").
- *
- * All ARM Cortex-M MCUs are supported by "TRC_HARDWARE_PORT_ARM_Cortex_M".
- * This port uses the DWT cycle counter for Cortex-M3/M4/M7 devices, which is
- * available on most such devices. In case your device don't have DWT support,
- * you will get an error message opening the trace. In that case, you may
- * force the recorder to use SysTick timestamping instead, using this define:
- *
- * #define TRC_CFG_ARM_CM_USE_SYSTICK
- *
- * For ARM Cortex-M0/M0+ devices, SysTick mode is used automatically.
- *
- * See trcHardwarePort.h for available ports and information on how to
- * define your own port, if not already present.
- ******************************************************************************/
-#define TRC_CFG_HARDWARE_PORT TRC_HARDWARE_PORT_NOT_SET
-
-/*******************************************************************************
- * Configuration Macro: TRC_CFG_RECORDER_MODE
- *
- * Specify what recording mode to use. Snapshot means that the data is saved in
- * an internal RAM buffer, for later upload. Streaming means that the data is
- * transferred continuously to the host PC.
- *
- * For more information, see http://percepio.com/2016/10/05/rtos-tracing/
- * and the Tracealyzer User Manual.
- *
- * Values:
- * TRC_RECORDER_MODE_SNAPSHOT
- * TRC_RECORDER_MODE_STREAMING
- ******************************************************************************/
-#define TRC_CFG_RECORDER_MODE TRC_RECORDER_MODE_SNAPSHOT
-
-/******************************************************************************
- * TRC_CFG_FREERTOS_VERSION
- *
- * Specify what version of FreeRTOS that is used (don't change unless using the
- * trace recorder library with an older version of FreeRTOS).
- *
- * TRC_FREERTOS_VERSION_7_3 If using FreeRTOS v7.3.x
- * TRC_FREERTOS_VERSION_7_4 If using FreeRTOS v7.4.x
- * TRC_FREERTOS_VERSION_7_5_OR_7_6 If using FreeRTOS v7.5.0 - v7.6.0
- * TRC_FREERTOS_VERSION_8_X If using FreeRTOS v8.X.X
- * TRC_FREERTOS_VERSION_9_0_0 If using FreeRTOS v9.0.0
- * TRC_FREERTOS_VERSION_9_0_1 If using FreeRTOS v9.0.1
- * TRC_FREERTOS_VERSION_9_0_2 If using FreeRTOS v9.0.2
- * TRC_FREERTOS_VERSION_10_0_0 If using FreeRTOS v10.0.0 or later
- *****************************************************************************/
-#define TRC_CFG_FREERTOS_VERSION TRC_FREERTOS_VERSION_10_0_0
-
-/*******************************************************************************
- * TRC_CFG_SCHEDULING_ONLY
- *
- * Macro which should be defined as an integer value.
- *
- * If this setting is enabled (= 1), only scheduling events are recorded.
- * If disabled (= 0), all events are recorded (unless filtered in other ways).
- *
- * Default value is 0 (= include additional events).
- ******************************************************************************/
-#define TRC_CFG_SCHEDULING_ONLY 0
-
- /******************************************************************************
- * TRC_CFG_INCLUDE_MEMMANG_EVENTS
- *
- * Macro which should be defined as either zero (0) or one (1).
- *
- * This controls if malloc and free calls should be traced. Set this to zero (0)
- * to exclude malloc/free calls, or one (1) to include such events in the trace.
- *
- * Default value is 1.
- *****************************************************************************/
-#define TRC_CFG_INCLUDE_MEMMANG_EVENTS 1
-
- /******************************************************************************
- * TRC_CFG_INCLUDE_USER_EVENTS
- *
- * Macro which should be defined as either zero (0) or one (1).
- *
- * If this is zero (0), all code related to User Events is excluded in order
- * to reduce code size. Any attempts of storing User Events are then silently
- * ignored.
- *
- * User Events are application-generated events, like "printf" but for the
- * trace log, generated using vTracePrint and vTracePrintF.
- * The formatting is done on host-side, by Tracealyzer. User Events are
- * therefore much faster than a console printf and can often be used
- * in timing critical code without problems.
- *
- * Note: In streaming mode, User Events are used to provide error messages
- * and warnings from the recorder (in case of incorrect configuration) for
- * display in Tracealyzer. Disabling user events will also disable these
- * warnings. You can however still catch them by calling xTraceGetLastError
- * or by putting breakpoints in prvTraceError and prvTraceWarning.
- *
- * Default value is 1.
- *****************************************************************************/
-#define TRC_CFG_INCLUDE_USER_EVENTS 1
-
- /*****************************************************************************
- * TRC_CFG_INCLUDE_ISR_TRACING
- *
- * Macro which should be defined as either zero (0) or one (1).
- *
- * If this is zero (0), the code for recording Interrupt Service Routines is
- * excluded, in order to reduce code size.
- *
- * Default value is 1.
- *
- * Note: tracing ISRs requires that you insert calls to vTraceStoreISRBegin
- * and vTraceStoreISREnd in your interrupt handlers.
- *****************************************************************************/
-#define TRC_CFG_INCLUDE_ISR_TRACING 1
-
- /*****************************************************************************
- * TRC_CFG_INCLUDE_READY_EVENTS
- *
- * Macro which should be defined as either zero (0) or one (1).
- *
- * If one (1), events are recorded when tasks enter scheduling state "ready".
- * This allows Tracealyzer to show the initial pending time before tasks enter
- * the execution state, and present accurate response times.
- * If zero (0), "ready events" are not created, which allows for recording
- * longer traces in the same amount of RAM.
- *
- * Default value is 1.
- *****************************************************************************/
-#define TRC_CFG_INCLUDE_READY_EVENTS 1
-
- /*****************************************************************************
- * TRC_CFG_INCLUDE_OSTICK_EVENTS
- *
- * Macro which should be defined as either zero (0) or one (1).
- *
- * If this is one (1), events will be generated whenever the OS clock is
- * increased. If zero (0), OS tick events are not generated, which allows for
- * recording longer traces in the same amount of RAM.
- *
- * Default value is 1.
- *****************************************************************************/
-#define TRC_CFG_INCLUDE_OSTICK_EVENTS 1
-
- /*****************************************************************************
- * TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS
- *
- * Macro which should be defined as either zero (0) or one (1).
- *
- * If this is zero (0), the trace will exclude any "event group" events.
- *
- * Default value is 0 (excluded) since dependent on event_groups.c
- *****************************************************************************/
-#define TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS 0
-
- /*****************************************************************************
- * TRC_CFG_INCLUDE_TIMER_EVENTS
- *
- * Macro which should be defined as either zero (0) or one (1).
- *
- * If this is zero (0), the trace will exclude any Timer events.
- *
- * Default value is 0 since dependent on timers.c
- *****************************************************************************/
-#define TRC_CFG_INCLUDE_TIMER_EVENTS 0
-
- /*****************************************************************************
- * TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS
- *
- * Macro which should be defined as either zero (0) or one (1).
- *
- * If this is zero (0), the trace will exclude any "pending function call"
- * events, such as xTimerPendFunctionCall().
- *
- * Default value is 0 since dependent on timers.c
- *****************************************************************************/
-#define TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS 0
-
-/*******************************************************************************
- * Configuration Macro: TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS
- *
- * Macro which should be defined as either zero (0) or one (1).
- *
- * If this is zero (0), the trace will exclude any stream buffer or message
- * buffer events.
- *
- * Default value is 0 since dependent on stream_buffer.c (new in FreeRTOS v10)
- ******************************************************************************/
-#define TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS 0
-
-/*******************************************************************************
- * Configuration Macro: TRC_CFG_RECORDER_BUFFER_ALLOCATION
- *
- * Specifies how the recorder buffer is allocated (also in case of streaming, in
- * port using the recorder's internal temporary buffer)
- *
- * Values:
- * TRC_RECORDER_BUFFER_ALLOCATION_STATIC - Static allocation (internal)
- * TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC - Malloc in vTraceEnable
- * TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM - Use vTraceSetRecorderDataBuffer
- *
- * Static and dynamic mode does the allocation for you, either in compile time
- * (static) or in runtime (malloc).
- * The custom mode allows you to control how and where the allocation is made,
- * for details see TRC_ALLOC_CUSTOM_BUFFER and vTraceSetRecorderDataBuffer().
- ******************************************************************************/
-#define TRC_CFG_RECORDER_BUFFER_ALLOCATION TRC_RECORDER_BUFFER_ALLOCATION_STATIC
-
-/******************************************************************************
- * TRC_CFG_MAX_ISR_NESTING
- *
- * Defines how many levels of interrupt nesting the recorder can handle, in
- * case multiple ISRs are traced and ISR nesting is possible. If this
- * is exceeded, the particular ISR will not be traced and the recorder then
- * logs an error message. This setting is used to allocate an internal stack
- * for keeping track of the previous execution context (4 byte per entry).
- *
- * This value must be a non-zero positive constant, at least 1.
- *
- * Default value: 8
- *****************************************************************************/
-#define TRC_CFG_MAX_ISR_NESTING 8
-
-/* Specific configuration, depending on Streaming/Snapshot mode */
-#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)
-#include "trcSnapshotConfig.h"
-#elif (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
-#include "trcStreamingConfig.h"
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _TRC_CONFIG_H */
+/*******************************************************************************
+ * Trace Recorder Library for Tracealyzer v4.3.11
+ * Percepio AB, www.percepio.com
+ *
+ * trcConfig.h
+ *
+ * Main configuration parameters for the trace recorder library.
+ * More settings can be found in trcStreamingConfig.h and trcSnapshotConfig.h.
+ *
+ * Read more at http://percepio.com/2016/10/05/rtos-tracing/
+ *
+ * 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_CONFIG_H
+#define TRC_CONFIG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "trcPortDefines.h"
+
+/******************************************************************************
+ * Include of processor header file
+ *
+ * Here you may need to include the header file for your processor. This is
+ * required at least for the ARM Cortex-M port, that uses the ARM CMSIS API.
+ * Try that in case of build problems. Otherwise, remove the #error line below.
+ *****************************************************************************/
+#error "Trace Recorder: Please include your processor's header file here and remove this line."
+
+/*******************************************************************************
+ * Configuration Macro: TRC_CFG_HARDWARE_PORT
+ *
+ * Specify what hardware port to use (i.e., the "timestamping driver").
+ *
+ * All ARM Cortex-M MCUs are supported by "TRC_HARDWARE_PORT_ARM_Cortex_M".
+ * This port uses the DWT cycle counter for Cortex-M3/M4/M7 devices, which is
+ * available on most such devices. In case your device don't have DWT support,
+ * you will get an error message opening the trace. In that case, you may
+ * force the recorder to use SysTick timestamping instead, using this define:
+ *
+ * #define TRC_CFG_ARM_CM_USE_SYSTICK
+ *
+ * For ARM Cortex-M0/M0+ devices, SysTick mode is used automatically.
+ *
+ * See trcHardwarePort.h for available ports and information on how to
+ * define your own port, if not already present.
+ ******************************************************************************/
+#define TRC_CFG_HARDWARE_PORT TRC_HARDWARE_PORT_NOT_SET
+
+/*******************************************************************************
+ * Configuration Macro: TRC_CFG_RECORDER_MODE
+ *
+ * Specify what recording mode to use. Snapshot means that the data is saved in
+ * an internal RAM buffer, for later upload. Streaming means that the data is
+ * transferred continuously to the host PC.
+ *
+ * For more information, see http://percepio.com/2016/10/05/rtos-tracing/
+ * and the Tracealyzer User Manual.
+ *
+ * Values:
+ * TRC_RECORDER_MODE_SNAPSHOT
+ * TRC_RECORDER_MODE_STREAMING
+ ******************************************************************************/
+#define TRC_CFG_RECORDER_MODE TRC_RECORDER_MODE_SNAPSHOT
+
+/******************************************************************************
+ * TRC_CFG_FREERTOS_VERSION
+ *
+ * Specify what version of FreeRTOS that is used (don't change unless using the
+ * trace recorder library with an older version of FreeRTOS).
+ *
+ * TRC_FREERTOS_VERSION_7_3_X If using FreeRTOS v7.3.X
+ * TRC_FREERTOS_VERSION_7_4_X If using FreeRTOS v7.4.X
+ * TRC_FREERTOS_VERSION_7_5_X If using FreeRTOS v7.5.X
+ * TRC_FREERTOS_VERSION_7_6_X If using FreeRTOS v7.6.X
+ * TRC_FREERTOS_VERSION_8_X_X If using FreeRTOS v8.X.X
+ * TRC_FREERTOS_VERSION_9_0_0 If using FreeRTOS v9.0.0
+ * TRC_FREERTOS_VERSION_9_0_1 If using FreeRTOS v9.0.1
+ * TRC_FREERTOS_VERSION_9_0_2 If using FreeRTOS v9.0.2
+ * TRC_FREERTOS_VERSION_10_0_0 If using FreeRTOS v10.0.0
+ * TRC_FREERTOS_VERSION_10_0_1 If using FreeRTOS v10.0.1
+ * TRC_FREERTOS_VERSION_10_1_0 If using FreeRTOS v10.1.0
+ * TRC_FREERTOS_VERSION_10_1_1 If using FreeRTOS v10.1.1
+ * TRC_FREERTOS_VERSION_10_2_0 If using FreeRTOS v10.2.0
+ * TRC_FREERTOS_VERSION_10_2_1 If using FreeRTOS v10.2.1
+ * TRC_FREERTOS_VERSION_10_3_0 If using FreeRTOS v10.3.0
+ * TRC_FREERTOS_VERSION_10_3_1 If using FreeRTOS v10.3.1
+ * TRC_FREERTOS_VERSION_10_4_0 If using FreeRTOS v10.4.0 or later
+ *****************************************************************************/
+#define TRC_CFG_FREERTOS_VERSION FREERTOS_VERSION_NOT_SET
+
+/*******************************************************************************
+ * TRC_CFG_SCHEDULING_ONLY
+ *
+ * Macro which should be defined as an integer value.
+ *
+ * If this setting is enabled (= 1), only scheduling events are recorded.
+ * If disabled (= 0), all events are recorded (unless filtered in other ways).
+ *
+ * Default value is 0 (= include additional events).
+ ******************************************************************************/
+#define TRC_CFG_SCHEDULING_ONLY 0
+
+ /******************************************************************************
+ * TRC_CFG_INCLUDE_MEMMANG_EVENTS
+ *
+ * Macro which should be defined as either zero (0) or one (1).
+ *
+ * This controls if malloc and free calls should be traced. Set this to zero (0)
+ * to exclude malloc/free calls, or one (1) to include such events in the trace.
+ *
+ * Default value is 1.
+ *****************************************************************************/
+#define TRC_CFG_INCLUDE_MEMMANG_EVENTS 1
+
+ /******************************************************************************
+ * TRC_CFG_INCLUDE_USER_EVENTS
+ *
+ * Macro which should be defined as either zero (0) or one (1).
+ *
+ * If this is zero (0), all code related to User Events is excluded in order
+ * to reduce code size. Any attempts of storing User Events are then silently
+ * ignored.
+ *
+ * User Events are application-generated events, like "printf" but for the
+ * trace log, generated using vTracePrint and vTracePrintF.
+ * The formatting is done on host-side, by Tracealyzer. User Events are
+ * therefore much faster than a console printf and can often be used
+ * in timing critical code without problems.
+ *
+ * Note: In streaming mode, User Events are used to provide error messages
+ * and warnings from the recorder (in case of incorrect configuration) for
+ * display in Tracealyzer. Disabling user events will also disable these
+ * warnings. You can however still catch them by calling xTraceGetLastError
+ * or by putting breakpoints in prvTraceError and prvTraceWarning.
+ *
+ * Default value is 1.
+ *****************************************************************************/
+#define TRC_CFG_INCLUDE_USER_EVENTS 1
+
+ /*****************************************************************************
+ * TRC_CFG_INCLUDE_ISR_TRACING
+ *
+ * Macro which should be defined as either zero (0) or one (1).
+ *
+ * If this is zero (0), the code for recording Interrupt Service Routines is
+ * excluded, in order to reduce code size. This means that any calls to
+ * vTraceStoreISRBegin/vTraceStoreISREnd will be ignored.
+ * This does not completely disable ISR tracing, in cases where an ISR is
+ * calling a traced kernel service. These events will still be recorded and
+ * show up in anonymous ISR instances in Tracealyzer, with names such as
+ * "ISR sending to <queue name>".
+ * To disable such tracing, please refer to vTraceSetFilterGroup and
+ * vTraceSetFilterMask.
+ *
+ * Default value is 1.
+ *
+ * Note: tracing ISRs requires that you insert calls to vTraceStoreISRBegin
+ * and vTraceStoreISREnd in your interrupt handlers.
+ *****************************************************************************/
+#define TRC_CFG_INCLUDE_ISR_TRACING 1
+
+ /*****************************************************************************
+ * TRC_CFG_INCLUDE_READY_EVENTS
+ *
+ * Macro which should be defined as either zero (0) or one (1).
+ *
+ * If one (1), events are recorded when tasks enter scheduling state "ready".
+ * This allows Tracealyzer to show the initial pending time before tasks enter
+ * the execution state, and present accurate response times.
+ * If zero (0), "ready events" are not created, which allows for recording
+ * longer traces in the same amount of RAM.
+ *
+ * Default value is 1.
+ *****************************************************************************/
+#define TRC_CFG_INCLUDE_READY_EVENTS 1
+
+ /*****************************************************************************
+ * TRC_CFG_INCLUDE_OSTICK_EVENTS
+ *
+ * Macro which should be defined as either zero (0) or one (1).
+ *
+ * If this is one (1), events will be generated whenever the OS clock is
+ * increased. If zero (0), OS tick events are not generated, which allows for
+ * recording longer traces in the same amount of RAM.
+ *
+ * Default value is 1.
+ *****************************************************************************/
+#define TRC_CFG_INCLUDE_OSTICK_EVENTS 1
+
+ /*****************************************************************************
+ * TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS
+ *
+ * Macro which should be defined as either zero (0) or one (1).
+ *
+ * If this is zero (0), the trace will exclude any "event group" events.
+ *
+ * Default value is 0 (excluded) since dependent on event_groups.c
+ *****************************************************************************/
+#define TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS 0
+
+ /*****************************************************************************
+ * TRC_CFG_INCLUDE_TIMER_EVENTS
+ *
+ * Macro which should be defined as either zero (0) or one (1).
+ *
+ * If this is zero (0), the trace will exclude any Timer events.
+ *
+ * Default value is 0 since dependent on timers.c
+ *****************************************************************************/
+#define TRC_CFG_INCLUDE_TIMER_EVENTS 0
+
+ /*****************************************************************************
+ * TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS
+ *
+ * Macro which should be defined as either zero (0) or one (1).
+ *
+ * If this is zero (0), the trace will exclude any "pending function call"
+ * events, such as xTimerPendFunctionCall().
+ *
+ * Default value is 0 since dependent on timers.c
+ *****************************************************************************/
+#define TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS 0
+
+/*******************************************************************************
+ * Configuration Macro: TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS
+ *
+ * Macro which should be defined as either zero (0) or one (1).
+ *
+ * If this is zero (0), the trace will exclude any stream buffer or message
+ * buffer events.
+ *
+ * Default value is 0 since dependent on stream_buffer.c (new in FreeRTOS v10)
+ ******************************************************************************/
+#define TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS 0
+
+ /******************************************************************************
+ * TRC_CFG_ENABLE_STACK_MONITOR
+ *
+ * If enabled (1), the recorder periodically reports the unused stack space of
+ * all active tasks.
+ * The stack monitoring runs in the Tracealyzer Control task, TzCtrl. This task
+ * is always created by the recorder when in streaming mode.
+ * In snapshot mode, the TzCtrl task is only used for stack monitoring and is
+ * not created unless this is enabled.
+ *****************************************************************************/
+#define TRC_CFG_ENABLE_STACK_MONITOR 1
+
+ /******************************************************************************
+ * TRC_CFG_STACK_MONITOR_MAX_TASKS
+ *
+ * Macro which should be defined as a non-zero integer value.
+ *
+ * This controls how many tasks that can be monitored by the stack monitor.
+ * If this is too small, some tasks will be excluded and a warning is shown.
+ *
+ * Default value is 10.
+ *****************************************************************************/
+#define TRC_CFG_STACK_MONITOR_MAX_TASKS 10
+
+ /******************************************************************************
+ * TRC_CFG_STACK_MONITOR_MAX_REPORTS
+ *
+ * Macro which should be defined as a non-zero integer value.
+ *
+ * This defines how many tasks that will be subject to stack usage analysis for
+ * each execution of the Tracealyzer Control task (TzCtrl). Note that the stack
+ * monitoring cycles between the tasks, so this does not affect WHICH tasks that
+ * are monitored, but HOW OFTEN each task stack is analyzed.
+ *
+ * This setting can be combined with TRC_CFG_CTRL_TASK_DELAY to tune the
+ * frequency of the stack monitoring. This is motivated since the stack analysis
+ * can take some time to execute.
+ * However, note that the stack analysis runs in a separate task (TzCtrl) that
+ * can be executed on low priority. This way, you can avoid that the stack
+ * analysis disturbs any time-sensitive tasks.
+ *
+ * Default value is 1.
+ *****************************************************************************/
+#define TRC_CFG_STACK_MONITOR_MAX_REPORTS 1
+
+ /*******************************************************************************
+ * Configuration Macro: TRC_CFG_CTRL_TASK_PRIORITY
+ *
+ * The scheduling priority of the Tracealyzer Control (TzCtrl) task.
+ *
+ * In streaming mode, TzCtrl is used to receive start/stop commands from
+ * Tracealyzer and in some cases also to transmit the trace data (for stream
+ * ports that uses the internal buffer, like TCP/IP). For such stream ports,
+ * make sure the TzCtrl priority is high enough to ensure reliable periodic
+ * execution and transfer of the data, but low enough to avoid disturbing any
+ * time-sensitive functions.
+ *
+ * In Snapshot mode, TzCtrl is only used for the stack usage monitoring and is
+ * not created if stack monitoring is disabled. TRC_CFG_CTRL_TASK_PRIORITY should
+ * be low, to avoid disturbing any time-sensitive tasks.
+ ******************************************************************************/
+#define TRC_CFG_CTRL_TASK_PRIORITY 1
+
+ /*******************************************************************************
+ * Configuration Macro: TRC_CFG_CTRL_TASK_DELAY
+ *
+ * The delay between loops of the TzCtrl task (see TRC_CFG_CTRL_TASK_PRIORITY),
+ * which affects the frequency of the stack monitoring.
+ *
+ * In streaming mode, this also affects the trace data transfer if you are using
+ * a stream port leveraging the internal buffer (like TCP/IP). A shorter delay
+ * increases the CPU load of TzCtrl somewhat, but may improve the performance of
+ * of the trace streaming, especially if the trace buffer is small.
+ ******************************************************************************/
+#define TRC_CFG_CTRL_TASK_DELAY 10
+
+ /*******************************************************************************
+ * Configuration Macro: TRC_CFG_CTRL_TASK_STACK_SIZE
+ *
+ * The stack size of the Tracealyzer Control (TzCtrl) task.
+ * See TRC_CFG_CTRL_TASK_PRIORITY for further information about TzCtrl.
+ ******************************************************************************/
+#define TRC_CFG_CTRL_TASK_STACK_SIZE (configMINIMAL_STACK_SIZE * 2)
+
+/*******************************************************************************
+ * Configuration Macro: TRC_CFG_RECORDER_BUFFER_ALLOCATION
+ *
+ * Specifies how the recorder buffer is allocated (also in case of streaming, in
+ * port using the recorder's internal temporary buffer)
+ *
+ * Values:
+ * TRC_RECORDER_BUFFER_ALLOCATION_STATIC - Static allocation (internal)
+ * TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC - Malloc in vTraceEnable
+ * TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM - Use vTraceSetRecorderDataBuffer
+ *
+ * Static and dynamic mode does the allocation for you, either in compile time
+ * (static) or in runtime (malloc).
+ * The custom mode allows you to control how and where the allocation is made,
+ * for details see TRC_ALLOC_CUSTOM_BUFFER and vTraceSetRecorderDataBuffer().
+ ******************************************************************************/
+#define TRC_CFG_RECORDER_BUFFER_ALLOCATION TRC_RECORDER_BUFFER_ALLOCATION_STATIC
+
+/******************************************************************************
+ * TRC_CFG_MAX_ISR_NESTING
+ *
+ * Defines how many levels of interrupt nesting the recorder can handle, in
+ * case multiple ISRs are traced and ISR nesting is possible. If this
+ * is exceeded, the particular ISR will not be traced and the recorder then
+ * logs an error message. This setting is used to allocate an internal stack
+ * for keeping track of the previous execution context (4 byte per entry).
+ *
+ * This value must be a non-zero positive constant, at least 1.
+ *
+ * Default value: 8
+ *****************************************************************************/
+#define TRC_CFG_MAX_ISR_NESTING 8
+
+/******************************************************************************
+ * TRC_CFG_ACKNOWLEDGE_QUEUE_SET_SEND
+ *
+ * When using FreeRTOS v10.3.0 or v10.3.1, please make sure that the trace
+ * point in prvNotifyQueueSetContainer() in queue.c is renamed from
+ * traceQUEUE_SEND to traceQUEUE_SET_SEND in order to tell them apart from
+ * other traceQUEUE_SEND trace points. Then set this to TRC_ACKNOWLEDGED.
+ *****************************************************************************/
+#define TRC_CFG_ACKNOWLEDGE_QUEUE_SET_SEND 0 /* TRC_ACKNOWLEDGED */
+
+/* Specific configuration, depending on Streaming/Snapshot mode */
+#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)
+#include "trcSnapshotConfig.h"
+#elif (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
+#include "trcStreamingConfig.h"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TRC_CONFIG_H */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcSnapshotConfig.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcSnapshotConfig.h
index 5ce12fcaa..601dfda68 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcSnapshotConfig.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcSnapshotConfig.h
@@ -1,377 +1,377 @@
-/*******************************************************************************
- * Trace Recorder Library for Tracealyzer v4.1.4
- * Percepio AB, www.percepio.com
- *
- * trcSnapshotConfig.h
- *
- * Configuration parameters for trace recorder library in snapshot mode.
- * Read more at http://percepio.com/2016/10/05/rtos-tracing/
- *
- * 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_SNAPSHOT_CONFIG_H
-#define TRC_SNAPSHOT_CONFIG_H
-
-#define TRC_SNAPSHOT_MODE_RING_BUFFER (0x01)
-#define TRC_SNAPSHOT_MODE_STOP_WHEN_FULL (0x02)
-
-/******************************************************************************
- * TRC_CFG_SNAPSHOT_MODE
- *
- * Macro which should be defined as one of:
- * - TRC_SNAPSHOT_MODE_RING_BUFFER
- * - TRC_SNAPSHOT_MODE_STOP_WHEN_FULL
- * Default is TRC_SNAPSHOT_MODE_RING_BUFFER.
- *
- * With TRC_CFG_SNAPSHOT_MODE set to TRC_SNAPSHOT_MODE_RING_BUFFER, the
- * events are stored in a ring buffer, i.e., where the oldest events are
- * overwritten when the buffer becomes full. This allows you to get the last
- * events leading up to an interesting state, e.g., an error, without having
- * to store the whole run since startup.
- *
- * When TRC_CFG_SNAPSHOT_MODE is TRC_SNAPSHOT_MODE_STOP_WHEN_FULL, the
- * recording is stopped when the buffer becomes full. This is useful for
- * recording events following a specific state, e.g., the startup sequence.
- *****************************************************************************/
-#define TRC_CFG_SNAPSHOT_MODE TRC_SNAPSHOT_MODE_RING_BUFFER
-
-/*******************************************************************************
- * TRC_CFG_EVENT_BUFFER_SIZE
- *
- * Macro which should be defined as an integer value.
- *
- * This defines the capacity of the event buffer, i.e., the number of records
- * it may store. Most events use one record (4 byte), although some events
- * require multiple 4-byte records. You should adjust this to the amount of RAM
- * available in the target system.
- *
- * Default value is 1000, which means that 4000 bytes is allocated for the
- * event buffer.
- ******************************************************************************/
-#define TRC_CFG_EVENT_BUFFER_SIZE 1000
-
-/*******************************************************************************
- * TRC_CFG_NTASK, TRC_CFG_NISR, TRC_CFG_NQUEUE, TRC_CFG_NSEMAPHORE...
- *
- * A group of macros which should be defined as integer values, zero or larger.
- *
- * These define the capacity of the Object Property Table, i.e., the maximum
- * number of objects active at any given point, within each object class (e.g.,
- * task, queue, semaphore, ...).
- *
- * If tasks or other objects are deleted in your system, this
- * setting does not limit the total amount of objects created, only the number
- * of objects that have been successfully created but not yet deleted.
- *
- * Using too small values will cause vTraceError to be called, which stores an
- * error message in the trace that is shown when opening the trace file. The
- * error message can also be retrieved using xTraceGetLastError.
- *
- * It can be wise to start with large values for these constants,
- * unless you are very confident on these numbers. Then do a recording and
- * check the actual usage by selecting View menu -> Trace Details ->
- * Resource Usage -> Object Table.
- ******************************************************************************/
-#define TRC_CFG_NTASK 15
-#define TRC_CFG_NISR 5
-#define TRC_CFG_NQUEUE 10
-#define TRC_CFG_NSEMAPHORE 10
-#define TRC_CFG_NMUTEX 10
-#define TRC_CFG_NTIMER 5
-#define TRC_CFG_NEVENTGROUP 5
-#define TRC_CFG_NSTREAMBUFFER 5
-#define TRC_CFG_NMESSAGEBUFFER 5
-
-/******************************************************************************
- * TRC_CFG_INCLUDE_FLOAT_SUPPORT
- *
- * Macro which should be defined as either zero (0) or one (1).
- *
- * If this is zero (0), the support for logging floating point values in
- * vTracePrintF is stripped out, in case floating point values are not used or
- * supported by the platform used.
- *
- * Floating point values are only used in vTracePrintF and its subroutines, to
- * allow for storing float (%f) or double (%lf) arguments.
- *
- * vTracePrintF can be used with integer and string arguments in either case.
- *
- * Default value is 0.
- *****************************************************************************/
-#define TRC_CFG_INCLUDE_FLOAT_SUPPORT 0
-
-/*******************************************************************************
- * TRC_CFG_SYMBOL_TABLE_SIZE
- *
- * Macro which should be defined as an integer value.
- *
- * This defines the capacity of the symbol table, in bytes. This symbol table
- * stores User Events labels and names of deleted tasks, queues, or other kernel
- * objects. If you don't use User Events or delete any kernel
- * objects you set this to a very low value. The minimum recommended value is 4.
- * A size of zero (0) is not allowed since a zero-sized array may result in a
- * 32-bit pointer, i.e., using 4 bytes rather than 0.
- *
- * Default value is 800.
- ******************************************************************************/
-#define TRC_CFG_SYMBOL_TABLE_SIZE 800
-
-#if (TRC_CFG_SYMBOL_TABLE_SIZE == 0)
-#error "TRC_CFG_SYMBOL_TABLE_SIZE may not be zero!"
-#endif
-
-/******************************************************************************
- * TRC_CFG_NAME_LEN_TASK, TRC_CFG_NAME_LEN_QUEUE, ...
- *
- * Macros that specify the maximum lengths (number of characters) for names of
- * kernel objects, such as tasks and queues. If longer names are used, they will
- * be truncated when stored in the recorder.
- *****************************************************************************/
-#define TRC_CFG_NAME_LEN_TASK 15
-#define TRC_CFG_NAME_LEN_ISR 15
-#define TRC_CFG_NAME_LEN_QUEUE 15
-#define TRC_CFG_NAME_LEN_SEMAPHORE 15
-#define TRC_CFG_NAME_LEN_MUTEX 15
-#define TRC_CFG_NAME_LEN_TIMER 15
-#define TRC_CFG_NAME_LEN_EVENTGROUP 15
-#define TRC_CFG_NAME_LEN_STREAMBUFFER 15
-#define TRC_CFG_NAME_LEN_MESSAGEBUFFER 15
-
-/******************************************************************************
- *** ADVANCED SETTINGS ********************************************************
- ******************************************************************************
- * The remaining settings are not necessary to modify but allows for optimizing
- * the recorder setup for your specific needs, e.g., to exclude events that you
- * are not interested in, in order to get longer traces.
- *****************************************************************************/
-
-/******************************************************************************
-* TRC_CFG_HEAP_SIZE_BELOW_16M
-*
-* An integer constant that can be used to reduce the buffer usage of memory
-* allocation events (malloc/free). This value should be 1 if the heap size is
-* below 16 MB (2^24 byte), and you can live with reported addresses showing the
-* lower 24 bits only. If 0, you get the full 32-bit addresses.
-*
-* Default value is 0.
-******************************************************************************/
-#define TRC_CFG_HEAP_SIZE_BELOW_16M 0
-
-/******************************************************************************
- * TRC_CFG_USE_IMPLICIT_IFE_RULES
- *
- * Macro which should be defined as either zero (0) or one (1).
- * Default is 1.
- *
- * Tracealyzer groups the events into "instances" based on Instance Finish
- * Events (IFEs), produced either by default rules or calls to the recorder
- * functions vTraceInstanceFinishedNow and vTraceInstanceFinishedNext.
- *
- * If TRC_CFG_USE_IMPLICIT_IFE_RULES is one (1), the default IFE rules is
- * used, resulting in a "typical" grouping of events into instances.
- * If these rules don't give appropriate instances in your case, you can
- * override the default rules using vTraceInstanceFinishedNow/Next for one
- * or several tasks. The default IFE rules are then disabled for those tasks.
- *
- * If TRC_CFG_USE_IMPLICIT_IFE_RULES is zero (0), the implicit IFE rules are
- * disabled globally. You must then call vTraceInstanceFinishedNow or
- * vTraceInstanceFinishedNext to manually group the events into instances,
- * otherwise the tasks will appear a single long instance.
- *
- * The default IFE rules count the following events as "instance finished":
- * - Task delay, delay until
- * - Task suspend
- * - Blocking on "input" operations, i.e., when the task is waiting for the
- * next a message/signal/event. But only if this event is blocking.
- *
- * For details, see trcSnapshotKernelPort.h and look for references to the
- * macro trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED.
- *****************************************************************************/
-#define TRC_CFG_USE_IMPLICIT_IFE_RULES 1
-
-/******************************************************************************
- * TRC_CFG_USE_16BIT_OBJECT_HANDLES
- *
- * Macro which should be defined as either zero (0) or one (1).
- *
- * If set to 0 (zero), the recorder uses 8-bit handles to identify kernel
- * objects such as tasks and queues. This limits the supported number of
- * concurrently active objects to 255 of each type (tasks, queues, mutexes,
- * etc.) Note: 255, not 256, since handle 0 is reserved.
- *
- * If set to 1 (one), the recorder uses 16-bit handles to identify kernel
- * objects such as tasks and queues. This limits the supported number of
- * concurrent objects to 65535 of each type (object class). However, since the
- * object property table is limited to 64 KB, the practical limit is about
- * 3000 objects in total.
- *
- * Default is 0 (8-bit handles)
- *
- * NOTE: An object with handle above 255 will use an extra 4-byte record in
- * the event buffer whenever the object is referenced. Moreover, some internal
- * tables in the recorder gets slightly larger when using 16-bit handles.
- *****************************************************************************/
-#define TRC_CFG_USE_16BIT_OBJECT_HANDLES 0
-
-/******************************************************************************
- * TRC_CFG_USE_TRACE_ASSERT
- *
- * Macro which should be defined as either zero (0) or one (1).
- * Default is 1.
- *
- * If this is one (1), the TRACE_ASSERT macro (used at various locations in the
- * trace recorder) will verify that a relevant condition is true.
- * If the condition is false, prvTraceError() will be called, which stops the
- * recording and stores an error message that is displayed when opening the
- * trace in Tracealyzer.
- *
- * This is used on several places in the recorder code for sanity checks on
- * parameters. Can be switched off to reduce the footprint of the tracing, but
- * we recommend to have it enabled initially.
- *****************************************************************************/
-#define TRC_CFG_USE_TRACE_ASSERT 1
-
-/*******************************************************************************
- * TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER
- *
- * Macro which should be defined as an integer value.
- *
- * Set TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER to 1 to enable the
- * separate user event buffer (UB).
- * In this mode, user events are stored separately from other events,
- * e.g., RTOS events. Thereby you can get a much longer history of
- * user events as they don't need to share the buffer space with more
- * frequent events.
- *
- * The UB is typically used with the snapshot ring-buffer mode, so the
- * recording can continue when the main buffer gets full. And since the
- * main buffer then overwrites the earliest events, Tracealyzer displays
- * "Unknown Actor" instead of task scheduling for periods with UB data only.
- *
- * In UB mode, user events are structured as UB channels, which contains
- * a channel name and a default format string. Register a UB channel using
- * xTraceRegisterUBChannel.
- *
- * Events and data arguments are written using vTraceUBEvent and
- * vTraceUBData. They are designed to provide efficient logging of
- * repeating events, using the same format string within each channel.
- *
- * Examples:
- *
- * traceString chn1 = xTraceRegisterString("Channel 1");
- * traceString fmt1 = xTraceRegisterString("Event!");
- * traceUBChannel UBCh1 = xTraceRegisterUBChannel(chn1, fmt1);
- *
- * traceString chn2 = xTraceRegisterString("Channel 2");
- * traceString fmt2 = xTraceRegisterString("X: %d, Y: %d");
- * traceUBChannel UBCh2 = xTraceRegisterUBChannel(chn2, fmt2);
- *
- * // Result in "[Channel 1] Event!"
- * vTraceUBEvent(UBCh1);
- *
- * // Result in "[Channel 2] X: 23, Y: 19"
- * vTraceUBData(UBCh2, 23, 19);
- *
- * You can also use the other user event functions, like vTracePrintF.
- * as they are then rerouted to the UB instead of the main event buffer.
- * vTracePrintF then looks up the correct UB channel based on the
- * provided channel name and format string, or creates a new UB channel
- * if no match is found. The format string should therefore not contain
- * "random" messages but mainly format specifiers. Random strings should
- * be stored using %s and with the string as an argument.
- *
- * // Creates a new UB channel ("Channel 2", "%Z: %d")
- * vTracePrintF(chn2, "%Z: %d", value1);
- *
- * // Finds the existing UB channel
- * vTracePrintF(chn2, "%Z: %d", value2);
-
- ******************************************************************************/
-#define TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER 0
-
-/*******************************************************************************
- * TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE
- *
- * Macro which should be defined as an integer value.
- *
- * This defines the capacity of the user event buffer (UB), in number of slots.
- * A single user event can use multiple slots, depending on the arguments.
- *
- * Only applicable if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is 1.
- ******************************************************************************/
-#define TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE 200
-
-/*******************************************************************************
- * TRC_CFG_UB_CHANNELS
- *
- * Macro which should be defined as an integer value.
- *
- * This defines the number of User Event Buffer Channels (UB channels).
- * These are used to structure the events when using the separate user
- * event buffer, and contains both a User Event Channel (the name) and
- * a default format string for the channel.
- *
- * Only applicable if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is 1.
- ******************************************************************************/
-#define TRC_CFG_UB_CHANNELS 32
-
-/*******************************************************************************
- * TRC_CFG_ISR_TAILCHAINING_THRESHOLD
- *
- * Macro which should be defined as an integer value.
- *
- * If tracing multiple ISRs, this setting allows for accurate display of the
- * context-switching also in cases when the ISRs execute in direct sequence.
- *
- * vTraceStoreISREnd normally assumes that the ISR returns to the previous
- * context, i.e., a task or a preempted ISR. But if another traced ISR
- * executes in direct sequence, Tracealyzer may incorrectly display a minimal
- * fragment of the previous context in between the ISRs.
- *
- * By using TRC_CFG_ISR_TAILCHAINING_THRESHOLD you can avoid this. This is
- * however a threshold value that must be measured for your specific setup.
- * See http://percepio.com/2014/03/21/isr_tailchaining_threshold/
- *
- * The default setting is 0, meaning "disabled" and that you may get an
- * extra fragments of the previous context in between tail-chained ISRs.
- *
- * Note: This setting has separate definitions in trcSnapshotConfig.h and
- * trcStreamingConfig.h, since it is affected by the recorder mode.
- ******************************************************************************/
-#define TRC_CFG_ISR_TAILCHAINING_THRESHOLD 0
-
-#endif /*TRC_SNAPSHOT_CONFIG_H*/
+/*******************************************************************************
+ * Trace Recorder Library for Tracealyzer v4.3.11
+ * Percepio AB, www.percepio.com
+ *
+ * trcSnapshotConfig.h
+ *
+ * Configuration parameters for trace recorder library in snapshot mode.
+ * Read more at http://percepio.com/2016/10/05/rtos-tracing/
+ *
+ * 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_SNAPSHOT_CONFIG_H
+#define TRC_SNAPSHOT_CONFIG_H
+
+#define TRC_SNAPSHOT_MODE_RING_BUFFER (0x01)
+#define TRC_SNAPSHOT_MODE_STOP_WHEN_FULL (0x02)
+
+/******************************************************************************
+ * TRC_CFG_SNAPSHOT_MODE
+ *
+ * Macro which should be defined as one of:
+ * - TRC_SNAPSHOT_MODE_RING_BUFFER
+ * - TRC_SNAPSHOT_MODE_STOP_WHEN_FULL
+ * Default is TRC_SNAPSHOT_MODE_RING_BUFFER.
+ *
+ * With TRC_CFG_SNAPSHOT_MODE set to TRC_SNAPSHOT_MODE_RING_BUFFER, the
+ * events are stored in a ring buffer, i.e., where the oldest events are
+ * overwritten when the buffer becomes full. This allows you to get the last
+ * events leading up to an interesting state, e.g., an error, without having
+ * to store the whole run since startup.
+ *
+ * When TRC_CFG_SNAPSHOT_MODE is TRC_SNAPSHOT_MODE_STOP_WHEN_FULL, the
+ * recording is stopped when the buffer becomes full. This is useful for
+ * recording events following a specific state, e.g., the startup sequence.
+ *****************************************************************************/
+#define TRC_CFG_SNAPSHOT_MODE TRC_SNAPSHOT_MODE_RING_BUFFER
+
+/*******************************************************************************
+ * TRC_CFG_EVENT_BUFFER_SIZE
+ *
+ * Macro which should be defined as an integer value.
+ *
+ * This defines the capacity of the event buffer, i.e., the number of records
+ * it may store. Most events use one record (4 byte), although some events
+ * require multiple 4-byte records. You should adjust this to the amount of RAM
+ * available in the target system.
+ *
+ * Default value is 1000, which means that 4000 bytes is allocated for the
+ * event buffer.
+ ******************************************************************************/
+#define TRC_CFG_EVENT_BUFFER_SIZE 1000
+
+/*******************************************************************************
+ * TRC_CFG_NTASK, TRC_CFG_NISR, TRC_CFG_NQUEUE, TRC_CFG_NSEMAPHORE...
+ *
+ * A group of macros which should be defined as integer values, zero or larger.
+ *
+ * These define the capacity of the Object Property Table, i.e., the maximum
+ * number of objects active at any given point, within each object class (e.g.,
+ * task, queue, semaphore, ...).
+ *
+ * If tasks or other objects are deleted in your system, this
+ * setting does not limit the total amount of objects created, only the number
+ * of objects that have been successfully created but not yet deleted.
+ *
+ * Using too small values will cause vTraceError to be called, which stores an
+ * error message in the trace that is shown when opening the trace file. The
+ * error message can also be retrieved using xTraceGetLastError.
+ *
+ * It can be wise to start with large values for these constants,
+ * unless you are very confident on these numbers. Then do a recording and
+ * check the actual usage by selecting View menu -> Trace Details ->
+ * Resource Usage -> Object Table.
+ ******************************************************************************/
+#define TRC_CFG_NTASK 15
+#define TRC_CFG_NISR 5
+#define TRC_CFG_NQUEUE 10
+#define TRC_CFG_NSEMAPHORE 10
+#define TRC_CFG_NMUTEX 10
+#define TRC_CFG_NTIMER 5
+#define TRC_CFG_NEVENTGROUP 5
+#define TRC_CFG_NSTREAMBUFFER 5
+#define TRC_CFG_NMESSAGEBUFFER 5
+
+/******************************************************************************
+ * TRC_CFG_INCLUDE_FLOAT_SUPPORT
+ *
+ * Macro which should be defined as either zero (0) or one (1).
+ *
+ * If this is zero (0), the support for logging floating point values in
+ * vTracePrintF is stripped out, in case floating point values are not used or
+ * supported by the platform used.
+ *
+ * Floating point values are only used in vTracePrintF and its subroutines, to
+ * allow for storing float (%f) or double (%lf) arguments.
+ *
+ * vTracePrintF can be used with integer and string arguments in either case.
+ *
+ * Default value is 0.
+ *****************************************************************************/
+#define TRC_CFG_INCLUDE_FLOAT_SUPPORT 0
+
+/*******************************************************************************
+ * TRC_CFG_SYMBOL_TABLE_SIZE
+ *
+ * Macro which should be defined as an integer value.
+ *
+ * This defines the capacity of the symbol table, in bytes. This symbol table
+ * stores User Events labels and names of deleted tasks, queues, or other kernel
+ * objects. If you don't use User Events or delete any kernel
+ * objects you set this to a very low value. The minimum recommended value is 4.
+ * A size of zero (0) is not allowed since a zero-sized array may result in a
+ * 32-bit pointer, i.e., using 4 bytes rather than 0.
+ *
+ * Default value is 800.
+ ******************************************************************************/
+#define TRC_CFG_SYMBOL_TABLE_SIZE 800
+
+#if (TRC_CFG_SYMBOL_TABLE_SIZE == 0)
+#error "TRC_CFG_SYMBOL_TABLE_SIZE may not be zero!"
+#endif
+
+/******************************************************************************
+ * TRC_CFG_NAME_LEN_TASK, TRC_CFG_NAME_LEN_QUEUE, ...
+ *
+ * Macros that specify the maximum lengths (number of characters) for names of
+ * kernel objects, such as tasks and queues. If longer names are used, they will
+ * be truncated when stored in the recorder.
+ *****************************************************************************/
+#define TRC_CFG_NAME_LEN_TASK 15
+#define TRC_CFG_NAME_LEN_ISR 15
+#define TRC_CFG_NAME_LEN_QUEUE 15
+#define TRC_CFG_NAME_LEN_SEMAPHORE 15
+#define TRC_CFG_NAME_LEN_MUTEX 15
+#define TRC_CFG_NAME_LEN_TIMER 15
+#define TRC_CFG_NAME_LEN_EVENTGROUP 15
+#define TRC_CFG_NAME_LEN_STREAMBUFFER 15
+#define TRC_CFG_NAME_LEN_MESSAGEBUFFER 15
+
+/******************************************************************************
+ *** ADVANCED SETTINGS ********************************************************
+ ******************************************************************************
+ * The remaining settings are not necessary to modify but allows for optimizing
+ * the recorder setup for your specific needs, e.g., to exclude events that you
+ * are not interested in, in order to get longer traces.
+ *****************************************************************************/
+
+/******************************************************************************
+* TRC_CFG_HEAP_SIZE_BELOW_16M
+*
+* An integer constant that can be used to reduce the buffer usage of memory
+* allocation events (malloc/free). This value should be 1 if the heap size is
+* below 16 MB (2^24 byte), and you can live with reported addresses showing the
+* lower 24 bits only. If 0, you get the full 32-bit addresses.
+*
+* Default value is 0.
+******************************************************************************/
+#define TRC_CFG_HEAP_SIZE_BELOW_16M 0
+
+/******************************************************************************
+ * TRC_CFG_USE_IMPLICIT_IFE_RULES
+ *
+ * Macro which should be defined as either zero (0) or one (1).
+ * Default is 1.
+ *
+ * Tracealyzer groups the events into "instances" based on Instance Finish
+ * Events (IFEs), produced either by default rules or calls to the recorder
+ * functions vTraceInstanceFinishedNow and vTraceInstanceFinishedNext.
+ *
+ * If TRC_CFG_USE_IMPLICIT_IFE_RULES is one (1), the default IFE rules is
+ * used, resulting in a "typical" grouping of events into instances.
+ * If these rules don't give appropriate instances in your case, you can
+ * override the default rules using vTraceInstanceFinishedNow/Next for one
+ * or several tasks. The default IFE rules are then disabled for those tasks.
+ *
+ * If TRC_CFG_USE_IMPLICIT_IFE_RULES is zero (0), the implicit IFE rules are
+ * disabled globally. You must then call vTraceInstanceFinishedNow or
+ * vTraceInstanceFinishedNext to manually group the events into instances,
+ * otherwise the tasks will appear a single long instance.
+ *
+ * The default IFE rules count the following events as "instance finished":
+ * - Task delay, delay until
+ * - Task suspend
+ * - Blocking on "input" operations, i.e., when the task is waiting for the
+ * next a message/signal/event. But only if this event is blocking.
+ *
+ * For details, see trcSnapshotKernelPort.h and look for references to the
+ * macro trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED.
+ *****************************************************************************/
+#define TRC_CFG_USE_IMPLICIT_IFE_RULES 1
+
+/******************************************************************************
+ * TRC_CFG_USE_16BIT_OBJECT_HANDLES
+ *
+ * Macro which should be defined as either zero (0) or one (1).
+ *
+ * If set to 0 (zero), the recorder uses 8-bit handles to identify kernel
+ * objects such as tasks and queues. This limits the supported number of
+ * concurrently active objects to 255 of each type (tasks, queues, mutexes,
+ * etc.) Note: 255, not 256, since handle 0 is reserved.
+ *
+ * If set to 1 (one), the recorder uses 16-bit handles to identify kernel
+ * objects such as tasks and queues. This limits the supported number of
+ * concurrent objects to 65535 of each type (object class). However, since the
+ * object property table is limited to 64 KB, the practical limit is about
+ * 3000 objects in total.
+ *
+ * Default is 0 (8-bit handles)
+ *
+ * NOTE: An object with handle above 255 will use an extra 4-byte record in
+ * the event buffer whenever the object is referenced. Moreover, some internal
+ * tables in the recorder gets slightly larger when using 16-bit handles.
+ *****************************************************************************/
+#define TRC_CFG_USE_16BIT_OBJECT_HANDLES 0
+
+/******************************************************************************
+ * TRC_CFG_USE_TRACE_ASSERT
+ *
+ * Macro which should be defined as either zero (0) or one (1).
+ * Default is 1.
+ *
+ * If this is one (1), the TRACE_ASSERT macro (used at various locations in the
+ * trace recorder) will verify that a relevant condition is true.
+ * If the condition is false, prvTraceError() will be called, which stops the
+ * recording and stores an error message that is displayed when opening the
+ * trace in Tracealyzer.
+ *
+ * This is used on several places in the recorder code for sanity checks on
+ * parameters. Can be switched off to reduce the footprint of the tracing, but
+ * we recommend to have it enabled initially.
+ *****************************************************************************/
+#define TRC_CFG_USE_TRACE_ASSERT 1
+
+/*******************************************************************************
+ * TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER
+ *
+ * Macro which should be defined as an integer value.
+ *
+ * Set TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER to 1 to enable the
+ * separate user event buffer (UB).
+ * In this mode, user events are stored separately from other events,
+ * e.g., RTOS events. Thereby you can get a much longer history of
+ * user events as they don't need to share the buffer space with more
+ * frequent events.
+ *
+ * The UB is typically used with the snapshot ring-buffer mode, so the
+ * recording can continue when the main buffer gets full. And since the
+ * main buffer then overwrites the earliest events, Tracealyzer displays
+ * "Unknown Actor" instead of task scheduling for periods with UB data only.
+ *
+ * In UB mode, user events are structured as UB channels, which contains
+ * a channel name and a default format string. Register a UB channel using
+ * xTraceRegisterUBChannel.
+ *
+ * Events and data arguments are written using vTraceUBEvent and
+ * vTraceUBData. They are designed to provide efficient logging of
+ * repeating events, using the same format string within each channel.
+ *
+ * Examples:
+ *
+ * traceString chn1 = xTraceRegisterString("Channel 1");
+ * traceString fmt1 = xTraceRegisterString("Event!");
+ * traceUBChannel UBCh1 = xTraceRegisterUBChannel(chn1, fmt1);
+ *
+ * traceString chn2 = xTraceRegisterString("Channel 2");
+ * traceString fmt2 = xTraceRegisterString("X: %d, Y: %d");
+ * traceUBChannel UBCh2 = xTraceRegisterUBChannel(chn2, fmt2);
+ *
+ * // Result in "[Channel 1] Event!"
+ * vTraceUBEvent(UBCh1);
+ *
+ * // Result in "[Channel 2] X: 23, Y: 19"
+ * vTraceUBData(UBCh2, 23, 19);
+ *
+ * You can also use the other user event functions, like vTracePrintF.
+ * as they are then rerouted to the UB instead of the main event buffer.
+ * vTracePrintF then looks up the correct UB channel based on the
+ * provided channel name and format string, or creates a new UB channel
+ * if no match is found. The format string should therefore not contain
+ * "random" messages but mainly format specifiers. Random strings should
+ * be stored using %s and with the string as an argument.
+ *
+ * // Creates a new UB channel ("Channel 2", "%Z: %d")
+ * vTracePrintF(chn2, "%Z: %d", value1);
+ *
+ * // Finds the existing UB channel
+ * vTracePrintF(chn2, "%Z: %d", value2);
+
+ ******************************************************************************/
+#define TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER 0
+
+/*******************************************************************************
+ * TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE
+ *
+ * Macro which should be defined as an integer value.
+ *
+ * This defines the capacity of the user event buffer (UB), in number of slots.
+ * A single user event can use multiple slots, depending on the arguments.
+ *
+ * Only applicable if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is 1.
+ ******************************************************************************/
+#define TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE 200
+
+/*******************************************************************************
+ * TRC_CFG_UB_CHANNELS
+ *
+ * Macro which should be defined as an integer value.
+ *
+ * This defines the number of User Event Buffer Channels (UB channels).
+ * These are used to structure the events when using the separate user
+ * event buffer, and contains both a User Event Channel (the name) and
+ * a default format string for the channel.
+ *
+ * Only applicable if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is 1.
+ ******************************************************************************/
+#define TRC_CFG_UB_CHANNELS 32
+
+/*******************************************************************************
+ * TRC_CFG_ISR_TAILCHAINING_THRESHOLD
+ *
+ * Macro which should be defined as an integer value.
+ *
+ * If tracing multiple ISRs, this setting allows for accurate display of the
+ * context-switching also in cases when the ISRs execute in direct sequence.
+ *
+ * vTraceStoreISREnd normally assumes that the ISR returns to the previous
+ * context, i.e., a task or a preempted ISR. But if another traced ISR
+ * executes in direct sequence, Tracealyzer may incorrectly display a minimal
+ * fragment of the previous context in between the ISRs.
+ *
+ * By using TRC_CFG_ISR_TAILCHAINING_THRESHOLD you can avoid this. This is
+ * however a threshold value that must be measured for your specific setup.
+ * See http://percepio.com/2014/03/21/isr_tailchaining_threshold/
+ *
+ * The default setting is 0, meaning "disabled" and that you may get an
+ * extra fragments of the previous context in between tail-chained ISRs.
+ *
+ * Note: This setting has separate definitions in trcSnapshotConfig.h and
+ * trcStreamingConfig.h, since it is affected by the recorder mode.
+ ******************************************************************************/
+#define TRC_CFG_ISR_TAILCHAINING_THRESHOLD 0
+
+#endif /*TRC_SNAPSHOT_CONFIG_H*/
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcStreamingConfig.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcStreamingConfig.h
index f578f10ec..9ad2ce577 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcStreamingConfig.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcStreamingConfig.h
@@ -1,170 +1,144 @@
-/*******************************************************************************
- * Trace Recorder Library for Tracealyzer v4.1.4
- * Percepio AB, www.percepio.com
- *
- * trcStreamingConfig.h
- *
- * Configuration parameters for the trace recorder library in streaming mode.
- * Read more at http://percepio.com/2016/10/05/rtos-tracing/
- *
- * 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_STREAMING_CONFIG_H
-#define TRC_STREAMING_CONFIG_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*******************************************************************************
- * Configuration Macro: TRC_CFG_SYMBOL_TABLE_SLOTS
- *
- * The maximum number of symbols names that can be stored. This includes:
- * - Task names
- * - Named ISRs (vTraceSetISRProperties)
- * - Named kernel objects (vTraceStoreKernelObjectName)
- * - User event channels (xTraceRegisterString)
- *
- * If this value is too small, not all symbol names will be stored and the
- * trace display will be affected. In that case, there will be warnings
- * (as User Events) from TzCtrl task, that monitors this.
- ******************************************************************************/
-#define TRC_CFG_SYMBOL_TABLE_SLOTS 40
-
-/*******************************************************************************
- * Configuration Macro: TRC_CFG_SYMBOL_MAX_LENGTH
- *
- * The maximum length of symbol names, including:
- * - Task names
- * - Named ISRs (vTraceSetISRProperties)
- * - Named kernel objects (vTraceStoreKernelObjectName)
- * - User event channel names (xTraceRegisterString)
- *
- * If longer symbol names are used, they will be truncated by the recorder,
- * which will affect the trace display. In that case, there will be warnings
- * (as User Events) from TzCtrl task, that monitors this.
- ******************************************************************************/
-#define TRC_CFG_SYMBOL_MAX_LENGTH 25
-
-/*******************************************************************************
- * Configuration Macro: TRC_CFG_OBJECT_DATA_SLOTS
- *
- * The maximum number of object data entries (used for task priorities) that can
- * be stored at the same time. Must be sufficient for all tasks, otherwise there
- * will be warnings (as User Events) from TzCtrl task, that monitors this.
- ******************************************************************************/
-#define TRC_CFG_OBJECT_DATA_SLOTS 40
-
-/*******************************************************************************
- * Configuration Macro: TRC_CFG_CTRL_TASK_STACK_SIZE
- *
- * The stack size of the TzCtrl task, that receive commands.
- * We are aiming to remove this extra task in future versions.
- ******************************************************************************/
-#define TRC_CFG_CTRL_TASK_STACK_SIZE (configMINIMAL_STACK_SIZE * 2)
-
-/*******************************************************************************
- * Configuration Macro: TRC_CFG_CTRL_TASK_PRIORITY
- *
- * The priority of the TzCtrl task, that receive commands from Tracealyzer.
- * Most stream ports also rely on the TzCtrl task to transmit the data from the
- * internal buffer to the stream interface (all except for the J-Link port).
- * For such ports, make sure the TzCtrl priority is high enough to ensure
- * reliable periodic execution and transfer of the data.
- ******************************************************************************/
-#define TRC_CFG_CTRL_TASK_PRIORITY 1
-
-/*******************************************************************************
- * Configuration Macro: TRC_CFG_CTRL_TASK_DELAY
- *
- * The delay between every loop of the TzCtrl task. A high delay will reduce the
- * CPU load, but may cause missed events if the TzCtrl task is performing the
- * trace transfer.
- ******************************************************************************/
-#define TRC_CFG_CTRL_TASK_DELAY ((10 * configTICK_RATE_HZ) / 1000)
-
-/*******************************************************************************
- * Configuration Macro: TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT
- *
- * Specifies the number of pages used by the paged event buffer.
- * This may need to be increased if there are a lot of missed events.
- *
- * Note: not used by the J-Link RTT stream port (see trcStreamingPort.h instead)
- ******************************************************************************/
-#define TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT 2
-
-/*******************************************************************************
- * Configuration Macro: TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE
- *
- * Specifies the size of each page in the paged event buffer. This can be tuned
- * to match any internal low-level buffers used by the streaming interface, like
- * the Ethernet MTU (Maximum Transmission Unit).
- *
- * Note: not used by the J-Link RTT stream port (see trcStreamingPort.h instead)
- ******************************************************************************/
-#define TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE 2500
-
-/*******************************************************************************
- * TRC_CFG_ISR_TAILCHAINING_THRESHOLD
- *
- * Macro which should be defined as an integer value.
- *
- * If tracing multiple ISRs, this setting allows for accurate display of the
- * context-switching also in cases when the ISRs execute in direct sequence.
- *
- * vTraceStoreISREnd normally assumes that the ISR returns to the previous
- * context, i.e., a task or a preempted ISR. But if another traced ISR
- * executes in direct sequence, Tracealyzer may incorrectly display a minimal
- * fragment of the previous context in between the ISRs.
- *
- * By using TRC_CFG_ISR_TAILCHAINING_THRESHOLD you can avoid this. This is
- * however a threshold value that must be measured for your specific setup.
- * See http://percepio.com/2014/03/21/isr_tailchaining_threshold/
- *
- * The default setting is 0, meaning "disabled" and that you may get an
- * extra fragments of the previous context in between tail-chained ISRs.
- *
- * Note: This setting has separate definitions in trcSnapshotConfig.h and
- * trcStreamingConfig.h, since it is affected by the recorder mode.
- ******************************************************************************/
-#define TRC_CFG_ISR_TAILCHAINING_THRESHOLD 0
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* TRC_STREAMING_CONFIG_H */
+/*******************************************************************************
+ * Trace Recorder Library for Tracealyzer v4.3.11
+ * Percepio AB, www.percepio.com
+ *
+ * trcStreamingConfig.h
+ *
+ * Configuration parameters for the trace recorder library in streaming mode.
+ * Read more at http://percepio.com/2016/10/05/rtos-tracing/
+ *
+ * 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_STREAMING_CONFIG_H
+#define TRC_STREAMING_CONFIG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+ * Configuration Macro: TRC_CFG_SYMBOL_TABLE_SLOTS
+ *
+ * The maximum number of symbols names that can be stored. This includes:
+ * - Task names
+ * - Named ISRs (vTraceSetISRProperties)
+ * - Named kernel objects (vTraceStoreKernelObjectName)
+ * - User event channels (xTraceRegisterString)
+ *
+ * If this value is too small, not all symbol names will be stored and the
+ * trace display will be affected. In that case, there will be warnings
+ * (as User Events) from TzCtrl task, that monitors this.
+ ******************************************************************************/
+#define TRC_CFG_SYMBOL_TABLE_SLOTS 40
+
+/*******************************************************************************
+ * Configuration Macro: TRC_CFG_SYMBOL_MAX_LENGTH
+ *
+ * The maximum length of symbol names, including:
+ * - Task names
+ * - Named ISRs (vTraceSetISRProperties)
+ * - Named kernel objects (vTraceStoreKernelObjectName)
+ * - User event channel names (xTraceRegisterString)
+ *
+ * If longer symbol names are used, they will be truncated by the recorder,
+ * which will affect the trace display. In that case, there will be warnings
+ * (as User Events) from TzCtrl task, that monitors this.
+ ******************************************************************************/
+#define TRC_CFG_SYMBOL_MAX_LENGTH 25
+
+/*******************************************************************************
+ * Configuration Macro: TRC_CFG_OBJECT_DATA_SLOTS
+ *
+ * The maximum number of object data entries (used for task priorities) that can
+ * be stored at the same time. Must be sufficient for all tasks, otherwise there
+ * will be warnings (as User Events) from TzCtrl task, that monitors this.
+ ******************************************************************************/
+#define TRC_CFG_OBJECT_DATA_SLOTS 40
+
+/*******************************************************************************
+ * Configuration Macro: TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT
+ *
+ * Specifies the number of pages used by the paged event buffer.
+ * This may need to be increased if there are a lot of missed events.
+ *
+ * Note: not used by the J-Link RTT stream port (see trcStreamingPort.h instead)
+ ******************************************************************************/
+#define TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT 10
+
+/*******************************************************************************
+ * Configuration Macro: TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE
+ *
+ * Specifies the size of each page in the paged event buffer. This can be tuned
+ * to match any internal low-level buffers used by the streaming interface, like
+ * the Ethernet MTU (Maximum Transmission Unit). However, since the currently
+ * active page can't be transfered, having more but smaller pages is more
+ * efficient with respect memory usage, than having a few large pages.
+ *
+ * Note: not used by the J-Link RTT stream port (see trcStreamingPort.h instead)
+ ******************************************************************************/
+#define TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE 500
+
+/*******************************************************************************
+ * TRC_CFG_ISR_TAILCHAINING_THRESHOLD
+ *
+ * Macro which should be defined as an integer value.
+ *
+ * If tracing multiple ISRs, this setting allows for accurate display of the
+ * context-switching also in cases when the ISRs execute in direct sequence.
+ *
+ * vTraceStoreISREnd normally assumes that the ISR returns to the previous
+ * context, i.e., a task or a preempted ISR. But if another traced ISR
+ * executes in direct sequence, Tracealyzer may incorrectly display a minimal
+ * fragment of the previous context in between the ISRs.
+ *
+ * By using TRC_CFG_ISR_TAILCHAINING_THRESHOLD you can avoid this. This is
+ * however a threshold value that must be measured for your specific setup.
+ * See http://percepio.com/2014/03/21/isr_tailchaining_threshold/
+ *
+ * The default setting is 0, meaning "disabled" and that you may get an
+ * extra fragments of the previous context in between tail-chained ISRs.
+ *
+ * Note: This setting has separate definitions in trcSnapshotConfig.h and
+ * trcStreamingConfig.h, since it is affected by the recorder mode.
+ ******************************************************************************/
+#define TRC_CFG_ISR_TAILCHAINING_THRESHOLD 0
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TRC_STREAMING_CONFIG_H */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/readme.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/readme.txt
deleted file mode 100644
index 79b64006d..000000000
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/readme.txt
+++ /dev/null
@@ -1,152 +0,0 @@
--------------------------------------------------------------------------------
- Tracealyzer for FreeRTOS - Trace Recorder Library v3.1.1
--------------------------------------------------------------------------------
-
-Tracealyzer for FreeRTOS is a sophisticated tool for tracing and visualization
-of FreeRTOS-based systems. Tracealyzer gives an unprecedented insight into the
-runtime behavior, which speeds up debugging, validation and optimization.
-
-To learn more about this, see
-
- - Getting Started (videos etc): http://percepio.com/gettingstarted/tz-freertos/
-
- - User Manual (incl. Recorder API): http://percepio.com/docs/FreeRTOS/manual
-
- - FAQ: http://percepio.com/category/faq/
-
-In case you have any questions, don't hesitate to contact support@percepio.com
-
--------------------------------------------------------------------------------
-
-Changes, v3.1.1 -> v3.1.2
-
-- Fixed two bugs related to User Events, one in vTracePrintF and other in vTracePrint.
-
-- Fixed a build problem related to a single reference of the old FreeRTOS type "xTaskHandle", in trcKernelPort.c.
- Changed to "TaskHandle_t", unless if using an older FreeRTOS kernel or the "compatibility mode".
-
-- Removed traceCREATE_MUTEX hook for FreeRTOS v9 or later (no longer required)
-
-- Updated the User Manual regarding snapshot trace via IAR Embedded Workbench.
-
-- Renamed vTraceGetTraceBuffer to xTraceGetTraceBuffer, since returning a pointer.
-
--------------------------------------------------------------------------------
-
-Changes, v3.1.0 -> v3.1.1
-
-After the major changes in the v3.1.0 trace recorder library, this update
-corrects a number of minor issues. Only minor functional improvements.
-
-- You can now use TRC_ALLOC_CUSTOM_BUFFER to declare a trace buffer on a custom
- location (using linker directives).
- The related function vTraceSetRecorderDataBuffer has been promoted to the
- Common API (previously only supported in snapshot mode, but custom allocation
- is now generally supported also in streaming mode).
-
-- Removed TRC_CFG_USE_LINKER_PRAGMA. No longer necessary thanks to the custom
- allocation mode.
-
-- Added support for timestamping from custom periodic timers, required for
- accurate timestamping on Cortex-M0/M0+ devices when using tickless idle.
- Only for streaming mode so far. See TRC_CUSTOM_TIMER_INCR / DECR.
-
-- ARM Cortex-M port: Made sure the DWT unit is initialized properly, in case
- the debugger doesn't handle this.
-
-- ARM Cortex-M port: Added possibility to use Systick timestamping also on
- Cortex-M3/M4/M7 devices (that otherwise use DWT timestamping by default).
- To use this option, define the macro TRC_CFG_ARM_CM_USE_SYSTICK.
-
-- J-Link streaming: The default RTT buffer has been changed from 0 to 1.
-
-- J-Link streaming: The RTT buffer settings for buffer 1 and higher, are now
- found in trcStreamingPort.h. Note: These settings don't apply to buffer 0.
-
-- vTracePrint has been optimized for better performance in string logging.
-
-- Minor performance improvement related to symbol table transfer in streaming mode.
-
-- Timer names now registered also in streaming mode.
-
-- Timer start and stop event are now traced.
-
-- Implemented support for queue registry (traceQUEUE_REGISTRY_ADD) also for streaming.
-
-- Fixed a bug related to repeated calls of vTraceEnable.
-
-- Fixed a bug where task-switches seemed to occur even though the scheduler was disabled.
-
-- Renamed HARDWARE_PORT_TEXAS_INSTRUMENTS_TMS570_RM48, added prefix TRC.
-
-- Fixed several language issues in the comments and documentation.
-
-- Fixed several minor issues and warnings from different compilers
- (including PowerPC/gcc) and configurations.
-
--------------------------------------------------------------------------------
-
-Changes, v3.0.9 -> v3.1.0
-
-- Merge of previously separated snapshot and streaming recorders into a single
- recorder supporting both streaming and snapshot as different modes.
-
-- New common API for supporting both streaming and snapshot modes.
-
-- New integration guide, see the User Manual.
-
-- Major improvement of API documentation in source files and User Manual.
-
-- New concept of "stream ports", giving a better structure defining streaming
- interfaces, and restructured the J-Link and TCP/IP streaming as stream ports.
-
-- Added a stream port for USB CDC connections, with STM32 as example.
- Since Tracealyzer now can receive serial data on Windows COM ports, this is
- really easy to use.
-
-- Added a warning (#error) for cases where FreeRTOS tickless idle mode is used
- together with timestamping using SysTick or other periodic interrupt timers,
- Tracing with tickless idle requires an independent time source to correctly
- capture the length of the idle periods.
-
-- Major changes in the recorder API. Important examples are:
-
- * Some configuration macros have changed names, e.g. for "hardware port".
- Make sure to remove any old "trcConfig.h" files if upgrading from an
- earlier version!
-
- * Recorder configuration in trcConfig.h has been minimized and now only
- includes the important settings that are independent of recorder mode.
- Advanced settings for each mode are found in trcSnapshotConfig.h and
- trcStreamingConfig.h.
-
- * vTraceEnable replaces Trace_Init and vTraceInitTraceData, as well as
- vTraceStart and uiTraceStart.
-
- * vTraceStop now part of the common API and thereby available also in
- streaming. And since vTraceEnable can start the streaming directly
- you have the option control the tracing from target, e.g., for
- streaming to a device file system.
-
- * vTraceStoreKernelObjectName from old streaming recorder has been replaced
- by vTraceSetQueueName, vTraceSetSemaphoreName, etc.
-
- * vTraceSetISRProperties now returns a "traceHandle" that should be passed as
- parameter to vTraceStoreISRBegin and vTraceStoreISREnd.
-
- * xTraceRegisterString has replaced the old functions xTraceOpenLabel and
- vTraceStoreUserEventChannelName. This now returns a "traceString" for use
- as "channel" parameter in vTracePrintF, and in other places where strings
- are stored.
-
- * Removed vTraceStoreISREndManual and vTraceStoreISREndAuto, use
- vTraceStoreISREnd instead.
-
- * Renamed the functions for saving User Events in a separate buffer:
- - xTraceRegisterChannelFormat -> xTraceRegisterUBChannel
- - vTraceChannelPrintF -> vTraceUBData
- - vTraceChannelUserEvent -> vTraceUBEvent
-
-
--------------------------------------------------------------------------------
-Copyright Percepio AB, 2017. \ No newline at end of file
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/AFR_WIFI_LOCAL/Readme-Streamport.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/AFR_WIFI_LOCAL/Readme-Streamport.txt
new file mode 100644
index 000000000..8774f20f5
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/AFR_WIFI_LOCAL/Readme-Streamport.txt
@@ -0,0 +1,22 @@
+Tracealyzer Stream Port for Amazon FreeRTOS TCP/WIFI
+----------------------------------------------------
+
+This directory contains a "stream port" for the Tracealyzer recorder library,
+i.e., the specific code needed to use a particular interface for streaming a
+Tracealyzer RTOS trace. The stream port is defined by a set of macros in
+trcStreamingPort.h, found in the "include" directory.
+
+This particular stream port is for streaming via a TCP socket in Amazon
+FreeRTOS (AFR) directly to a host computer on the local network, typically
+using Wifi. Read more in trcStreamingPort.h.
+
+To use this stream port, make sure that include/trcStreamingPort.h is found
+by the compiler (i.e., add this folder to your project's include paths) and
+add all included source files to your build. Make sure no other versions of
+trcStreamingPort.h are included by mistake!
+
+See also http://percepio.com/2016/10/05/rtos-tracing
+and https://percepio.com/2018/10/11/tuning-your-custom-trace-streaming/
+
+Percepio AB
+www.percepio.com \ No newline at end of file
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/AFR_WIFI_LOCAL/include/trcStreamingPort.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/AFR_WIFI_LOCAL/include/trcStreamingPort.h
new file mode 100644
index 000000000..4d4322d92
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/AFR_WIFI_LOCAL/include/trcStreamingPort.h
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Trace Recorder Library for Tracealyzer v4.3.11
+ * Percepio AB, www.percepio.com
+ *
+ * trcStreamingPort.c
+ *
+ * This stream port provides trace streaming using the Amazon FreeRTOS sockets
+ * layer and is intended for streaming over Wifi directly to a computer on the
+ * local Wifi network.
+ *
+ * Note that this does NOT use the TLS encryption available in Amazon
+ * FreeRTOS, due to performance and memory usage concerns. However, it does not
+ * use any AWS services either, and is intended for your local network only.
+ *
+ * This should be started using vTraceEnable(TRC_START) and this call should be
+ * made AFTER the kernel has started and the Wifi interface is ready.
+ *
+ * In the Tracealyzer setting -> "PSF Streaming Settings" make sure that the
+ * "Target Connection" setting is "TCP (Target Initiated)".
+ *
+ * To use this, make sure to start the trace recording in Tracealyzer before
+ * you start your target system. This ensures that Tracealyzer is ready when
+ * the target system connects.
+ *
+ * And don't forget to enter the IP address of the Tracealyzer host computer
+ * in trcStreamingPort.h.
+ *
+ * NOTES:
+ *
+ * 1: The tracing will increase the stack usage of you application, so you
+ * may want to increase configMINIMAL_STACK_SIZE in your FreeRTOSConfig.h.
+ *
+ * 2: To reduce the amount of trace data, we recommend disabling the tracing
+ * of OS Ticks and memory allocation events.
+ * See TRC_CFG_INCLUDE_OSTICK_EVENTS in trcConfig.h.
+ *
+ * 3: The transmission of trace data is done in the TzCtrl task. To avoid that
+ * the trace streaming is blocked during the (long) MQTT connection phase,
+ * make sure the scheduling priority of TzCtrl is higher than the MQTT task.
+ * Otherwise, if you prefer to run the TzCtrl task at lower priority to avoid
+ * interfering with your application, wait with the vTraceEnable call until
+ * after the MQTT connection is established.
+ * See TRC_CFG_CTRL_TASK_PRIORITY in trcStreamingConfig.h.
+ *
+ * 4: The Wifi transmission of trace data often uses FreeRTOS functions, that
+ * are traced and thus produce additional trace data. This may cause a fast
+ * increase in trace data rate, that may saturate the trace buffer and cause
+ * data loss (i.e. incomplete traces).
+ * To eliminate this effect and reduce the amount of trace data produced, we
+ * recommend excluding all FreeRTOS objects that are used by Wifi stack.
+ * This is done using vTraceSetFilterGroup and vTraceSetFilterMask:
+ *
+ * // Just before wifi initialization:
+ *
+ * // All objects created after this point are assigned to group 15.
+ * vTraceSetFilterGroup(FilterGroup15);
+ *
+ * // Only trace objects assigned to group 0 (the default group).
+ * vTraceSetFilterMask(FilterGroup0);
+ *
+ * // The wifi stack initialization... (creates semaphores etc.)
+ * if ( eWifi_Connected == prvWifiConnect() )
+ * {
+ * yMainState = eMain_StartApplication;
+ *
+ * // When connected, restore the FilterGroup setting to Group 0, so
+ * // that later created objects are included, like the TzCtrl task
+ * // created in vTraceEnable. Excluding tasks is not recommended!
+ * vTraceSetFilterGroup(FilterGroup0);
+ *
+ * // Then call vTraceEnable to start the tracing.
+ * vTraceEnable(TRC_START);
+ * }
+ *
+ * 5: If you still get "red sections" in Tracealyzer (lost data), you need
+ * to adjust the other settings in trcStreamingConfig.h.
+ *
+ * - TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT
+ * Increase this, as long as you have memory to spare.
+ *
+ * - TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE
+ * Increase this, as long as you have memory to spare.
+ * But don't exceed the maximum payload size of the Wifi chip, which
+ * is often limited to 1000-1500 bytes. Some chips crash if you try to
+ * send to large chunks...
+ *
+ * - TRC_CFG_CTRL_TASK_DELAY
+ * Decrease this to flush the trace buffer more frequently.
+ *
+ * See also http://percepio.com/2016/10/05/rtos-tracing
+ * and https://percepio.com/2018/10/11/tuning-your-custom-trace-streaming/
+ *
+ * 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_STREAMING_PORT_H
+#define TRC_STREAMING_PORT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define HOST_IPADDRESS_0 192
+#define HOST_IPADDRESS_1 168
+#define HOST_IPADDRESS_2 10
+#define HOST_IPADDRESS_3 116
+#define HOST_PORT 12000
+
+void prvInitSocket(void);
+int32_t prvReadFromSocket(void* ptrData, uint32_t size, int32_t* ptrBytesRead);
+int32_t prvWriteToSocket(void* ptrData, uint32_t size, int32_t* ptrBytesWritten);
+
+#define TRC_STREAM_PORT_INIT() \
+ TRC_STREAM_PORT_MALLOC(); \
+ prvInitSocket();
+
+#define TRC_STREAM_PORT_USE_INTERNAL_BUFFER 1
+
+#define TRC_STREAM_PORT_WRITE_DATA(_ptrData, _size, _ptrBytesWritten) prvWriteToSocket(_ptrData, _size, _ptrBytesWritten)
+
+#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) prvReadFromSocket(_ptrData, _size, _ptrBytesRead)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TRC_STREAMING_PORT_H */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/AFR_WIFI_LOCAL/trcStreamingPort.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/AFR_WIFI_LOCAL/trcStreamingPort.c
new file mode 100644
index 000000000..1edee04c3
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/AFR_WIFI_LOCAL/trcStreamingPort.c
@@ -0,0 +1,191 @@
+/*******************************************************************************
+ * Trace Recorder Library for Tracealyzer v4.3.11
+ * Percepio AB, www.percepio.com
+ *
+ * trcStreamingPort.c
+ *
+ * This stream port provides trace streaming using the Amazon FreeRTOS sockets
+ * layer and is intended for streaming over Wifi directly to a computer on the
+ * local Wifi network.
+ *
+ * Note that this does NOT use the TLS encryption available in Amazon
+ * FreeRTOS, due to performance and memory usage concerns. However, it does not
+ * use any AWS services either, and is intended for your local network only.
+ *
+ * This should be started using vTraceEnable(TRC_START) and this call should be
+ * made AFTER the kernel has started and the Wifi interface is ready.
+ *
+ * In the Tracealyzer setting -> "PSF Streaming Settings" make sure that the
+ * "Target Connection" setting is "TCP (Target Initiated)".
+ *
+ * To use this, make sure to start the trace recording in Tracealyzer before
+ * you start your target system. This ensures that Tracealyzer is ready when
+ * the target system connects.
+ *
+ * And don't forget to enter the IP address of the Tracealyzer host computer
+ * in trcStreamingPort.h.
+ *
+ * NOTES:
+ *
+ * 1: The tracing will increase the stack usage of you application, so you
+ * may want to increase configMINIMAL_STACK_SIZE in your FreeRTOSConfig.h.
+ *
+ * 2: To reduce the amount of trace data, we recommend disabling the tracing
+ * of OS Ticks and memory allocation events.
+ * See TRC_CFG_INCLUDE_OSTICK_EVENTS in trcConfig.h.
+ *
+ * 3: The transmission of trace data is done in the TzCtrl task. To avoid that
+ * the trace streaming is blocked during the (long) MQTT connection phase,
+ * make sure the scheduling priority of TzCtrl is higher than the MQTT task.
+ * Otherwise, if you prefer to run the TzCtrl task at lower priority to avoid
+ * interfering with your application, wait with the vTraceEnable call until
+ * after the MQTT connection is established.
+ * See TRC_CFG_CTRL_TASK_PRIORITY in trcStreamingConfig.h.
+ *
+ * 4: The Wifi transmission of trace data often uses FreeRTOS functions, that
+ * are traced and thus produce additional trace data. This may cause a fast
+ * increase in trace data rate, that may saturate the trace buffer and cause
+ * data loss (i.e. incomplete traces).
+ * To eliminate this effect and reduce the amount of trace data produced, we
+ * recommend excluding all FreeRTOS objects that are used by Wifi stack.
+ * This is done using vTraceSetFilterGroup and vTraceSetFilterMask:
+ *
+ * // Just before wifi initialization:
+ *
+ * // All objects created after this point are assigned to group 15.
+ * vTraceSetFilterGroup(FilterGroup15);
+ *
+ * // Only trace objects assigned to group 0 (the default group).
+ * vTraceSetFilterMask(FilterGroup0);
+ *
+ * // The wifi stack initialization... (creates semaphores etc.)
+ * if ( eWifi_Connected == prvWifiConnect() )
+ * {
+ * yMainState = eMain_StartApplication;
+ *
+ * // When connected, restore the FilterGroup setting to Group 0, so
+ * // that later created objects are included, like the TzCtrl task
+ * // created in vTraceEnable. Excluding tasks is not recommended!
+ * vTraceSetFilterGroup(FilterGroup0);
+ *
+ * // Then call vTraceEnable to start the tracing.
+ * vTraceEnable(TRC_START);
+ * }
+ *
+ * 5: If you still get "red sections" in Tracealyzer (lost data), you need
+ * to adjust the other settings in trcStreamingConfig.h.
+ *
+ * - TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT
+ * Increase this, as long as you have memory to spare.
+ *
+ * - TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE
+ * Increase this, as long as you have memory to spare.
+ * But don't exceed the maximum payload size of the Wifi chip, which
+ * is often limited to 1000-1500 bytes. Some chips crash if you try to
+ * send to large chunks...
+ *
+ * - TRC_CFG_CTRL_TASK_DELAY
+ * Decrease this to flush the trace buffer more frequently.
+ *
+ * See also http://percepio.com/2016/10/05/rtos-tracing
+ * and https://percepio.com/2018/10/11/tuning-your-custom-trace-streaming/
+ *
+ * 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
+ ******************************************************************************/
+#include "trcRecorder.h"
+
+#if (TRC_USE_TRACEALYZER_RECORDER == 1)
+#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
+
+#include "aws_secure_sockets.h"
+#include "trcExtensions.h"
+
+SocketsSockaddr_t addr = {sizeof(SocketsSockaddr_t), SOCKETS_AF_INET, 0, 0};
+
+#define IPv4(a,b,c,d) (uint32_t)((d << 24) + (c << 16) + (b << 8) + a)
+
+Socket_t sock = NULL;
+
+void prvInitSocket(void)
+{
+ int32_t status;
+
+ SOCKETS_Init();
+
+ sock = SOCKETS_Socket(SOCKETS_AF_INET, SOCKETS_SOCK_STREAM, SOCKETS_IPPROTO_TCP);
+
+ configPRINTF( ( "Connecting to %d.%d.%d.%d, port %d\r\n", HOST_IPADDRESS_0, HOST_IPADDRESS_1, HOST_IPADDRESS_2, HOST_IPADDRESS_3, HOST_PORT) );
+
+ addr.ulAddress = IPv4(HOST_IPADDRESS_0, HOST_IPADDRESS_1, HOST_IPADDRESS_2, HOST_IPADDRESS_3);
+ addr.usPort = SOCKETS_htons(HOST_PORT);
+
+ status = SOCKETS_Connect(sock, &addr, sizeof( SocketsSockaddr_t ) );
+
+ if (status != SOCKETS_ERROR_NONE)
+ {
+ //prvTraceError(PSF_ERROR_STREAM_PORT_FAIL);
+ configPRINTF( ( "Failed to connect, status: %d\r\n", status) );
+ }
+ else
+ {
+ configPRINTF( ( "Connected.\r\n") );
+ }
+}
+
+
+int32_t prvWriteToSocket(void* ptrData, uint32_t size, int32_t* ptrBytesWritten)
+{
+ uint32_t bytesWritten = SOCKETS_Send(sock, ptrData, size, 0);
+
+ if (ptrBytesWritten != NULL)
+ *ptrBytesWritten = (int32_t)bytesWritten;
+
+ if (bytesWritten != size)
+ {
+ return -1;
+ }
+
+ return 0;
+}
+
+int32_t prvReadFromSocket(void* ptrData, uint32_t size, int32_t* ptrBytesRead)
+{
+ // Not yet implemented, since not necessary.
+ return 0;
+}
+
+#endif
+#endif
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/Readme-ARM_ITM.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/Readme-ARM_ITM.txt
index 0802b5331..be48c6df3 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/Readme-ARM_ITM.txt
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/Readme-ARM_ITM.txt
@@ -1,28 +1,32 @@
-Tracealyzer Stream Port for ARM Cortex-M ITM
---------------------------------------------
-2018-05-04
-
-This directory contains a "stream port" for the Tracealyzer recorder library,
-i.e., the specific code needed to use a particular interface for streaming a
-Tracealyzer RTOS trace. The stream port is defined by a set of macros in
-trcStreamingPort.h, found in the "include" directory.
-
-This particular stream port targets ARM's ITM interface, which together with
-a fast debug probe such as a Keil ULINKpro or ULINKplus provides excellent
-performance. This stream port does not use any RAM buffer for the trace, but
-writes the data directly to the ITM registers. This is very fast.
-
-To setup Keil uVision for ITM tracing with a Keil ULINKpro (or ULINKplus),
-see Percepio Application Note PA-021 https://percepio.com/2018/05/04/keil-itm-support/
-
-Learning more:
- - Tracealyzer User Manual (Help -> User Manual)
- - https://percepio.com/gettingstarted
- - Percepio Application Note PA-021 https://percepio.com/2018/05/04/keil-itm-support/
- - About ITM trace, https://percepio.com/2016/06/09/arm-itm/
- - About the recorder and custom streaming, http://percepio.com/2016/10/05/rtos-tracing
-
-For questions, please contact support@percepio.com
-
-Percepio AB
+Tracealyzer Stream Port for ARM Cortex-M ITM
+--------------------------------------------
+2018-05-04
+
+This directory contains a "stream port" for the Tracealyzer recorder library,
+i.e., the specific code needed to use a particular interface for streaming a
+Tracealyzer RTOS trace. The stream port is defined by a set of macros in
+trcStreamingPort.h, found in the "include" directory.
+
+This particular stream port targets ARM's ITM interface, which together with
+a fast debug probe such as a Keil ULINKpro or ULINKplus provides excellent
+performance. This stream port does not use any RAM buffer for the trace, but
+writes the data directly to the ITM registers. This is very fast.
+
+To setup Keil uVision for ITM tracing with a Keil ULINKpro (or ULINKplus),
+see Percepio Application Note PA-021, https://percepio.com/2018/05/04/keil-itm-support/
+
+To setup IAR Embedded Workbench for ITM tracing with an IAR I-Jet,
+see Percepio Application Note PA-023, https://percepio.com/iar
+
+Learning more:
+ - Tracealyzer User Manual (Help -> User Manual)
+ - https://percepio.com/gettingstarted
+ - Percepio Application Note PA-021 (Keil), https://percepio.com/2018/05/04/keil-itm-support/
+ - Percepio Application Note PA-023 (IAR), https://percepio.com/iar
+ - About ITM trace, https://percepio.com/2016/06/09/arm-itm/
+ - About the recorder and custom streaming, http://percepio.com/2016/10/05/rtos-tracing
+
+For questions, please contact support@percepio.com
+
+Percepio AB
www.percepio.com \ No newline at end of file
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/include/trcStreamingPort.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/include/trcStreamingPort.h
index ca20ae753..c14c4e1f9 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/include/trcStreamingPort.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/include/trcStreamingPort.h
@@ -1,91 +1,137 @@
-/*******************************************************************************
- * Trace Recorder Library for Tracealyzer v4.1.5
- * Percepio AB, www.percepio.com
- *
- * trcStreamingPort.h
- *
- * The interface definitions for trace streaming ("stream ports").
- * This "stream port" sets up the recorder to use ARM ITM as streaming channel.
- *
- * 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_STREAMING_PORT_H
-#define TRC_STREAMING_PORT_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-int32_t itm_write(void* ptrData, uint32_t size, int32_t* ptrBytesWritten);
-int32_t read_from_host(void* ptrData, uint32_t size, int32_t* ptrBytesRead);
-
-/*******************************************************************************
- * TRC_CFG_ITM_PORT
- *
- * Possible values: 0 - 31
- *
- * What ITM port to use for the ITM software events. Make sure the IDE is
- * configured for the same channel.
- *
- * Default: 1 (0 is typically terminal output and 31 is used by Keil)
- *
- ******************************************************************************/
-#define TRC_CFG_ITM_PORT 1
-
-#if (TRC_CFG_ITM_PORT < 0) || (TRC_CFG_ITM_PORT > 31)
-#error "Bad ITM port selected."
-#endif
-
-// Not used for ITM - no RAM buffer...
-#define TRC_STREAM_PORT_ALLOCATE_FIELDS()
-
-// Not used for ITM - assume the IDE configures the ITM setup
-#define TRC_STREAM_PORT_INIT()
-
-/* Important for the ITM port - no RAM buffer, direct writes. In most other ports this can be skipped (default is 1) */
-#define TRC_STREAM_PORT_USE_INTERNAL_BUFFER 0
-
-#define TRC_STREAM_PORT_WRITE_DATA(_ptrData, _size, _ptrBytesWritten) itm_write(_ptrData, _size, _ptrBytesWritten)
-
-#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) read_from_host(_ptrData, _size, _ptrBytesRead)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* TRC_STREAMING_PORT_H */
+/*******************************************************************************
+ * Trace Recorder Library for Tracealyzer v4.3.11
+ * Percepio AB, www.percepio.com
+ *
+ * trcStreamingPort.h
+ *
+ * The interface definitions for trace streaming ("stream ports").
+ * This "stream port" sets up the recorder to use ARM ITM as streaming channel.
+ *
+ * To setup Keil uVision for ITM tracing with a Keil ULINKpro (or ULINKplus),
+ * see Percepio Application Note PA-021, available at
+ * https://percepio.com/2018/05/04/keil-itm-support/
+ *
+ * To setup IAR Embedded Workbench for ITM tracing with an IAR I-Jet,
+ * see Percepio Application Note PA-023, https://percepio.com/iar
+ *
+ * NOTE: This stream port may block the application in case the ITM port
+ * is not ready for more data (the TPIU FIFO has become full). This is
+ * necessary to avoid data loss, as the TPIU FIFO is often quite small.
+ *
+ * --- Direct vs. Indirect ITM streaming ---
+ * Direct streaming: By default, this stream port writes directly to the ITM
+ * register mode without any RAM buffer. This assumes you have a fast debug
+ * probe, like aKeil ULINKpro or IAR I-Jet, to avoid excessive blocking.
+ * In case the ITM blocking appears to disturb your application, make sure your
+ * debugger is configured for maximum performance, as described in the above
+ * Application Nodes.
+ *
+ * Indirect streaming: If direct streaming gives too much overhead, you may
+ * instead try indirect ITM streaming. This is done by enabling the internal
+ * RAM buffer, like below. This reconfigures the recorder to store the events
+ * in the internal RAM buffer instead of writing them directly to the ITM port.
+ *
+ * Set TRC_STREAM_PORT_USE_INTERNAL_BUFFER to 1 to use the indirect mode.
+ *
+ * This increases RAM usage but eliminates peaks in the trace data rate.
+ * Moreover, the ITM writes are then performed in a separate task (TzCtrl).
+ * You find relevant settings (buffer size etc.) in trcStreamingConfig.h.
+ *
+ * See also https://percepio.com/2018/10/11/tuning-your-custom-trace-streaming
+ *
+ * --- One-way vs. Two-way Communication ---
+ * The ITM port only provides one-way communication, from target to host.
+ * This is sufficient if you start the tracing from the target application,
+ * using vTraceEnable(TRC_START). Just make sure to start the Tracealyzer
+ * recording before you start the target system.
+ *
+ * In case you prefer to interactively start and stop the tracing from the host
+ * computer, you need two-way communication to send commands to the recorder.
+ * This is possible by writing such "start" and "stop" commands to a special
+ * buffer, monitored by the recorder library, using the debugger IDE.
+ * See trcStreamingPort.c and also the example macro for Keil uVision
+ * (Keil-uVision-Tracealyzer-ITM-Exporter.ini).
+ *
+ *
+ * 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_STREAMING_PORT_H
+#define TRC_STREAMING_PORT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+int32_t itm_write(void* ptrData, uint32_t size, int32_t* ptrBytesWritten);
+int32_t read_from_host(void* ptrData, uint32_t size, int32_t* ptrBytesRead);
+
+/*******************************************************************************
+ * TRC_CFG_ITM_PORT
+ *
+ * Possible values: 0 - 31
+ *
+ * What ITM port to use for the ITM software events. Make sure the IDE is
+ * configured for the same channel.
+ *
+ * Default: 1 (0 is typically terminal output and 31 is used by Keil)
+ *
+ ******************************************************************************/
+#define TRC_CFG_ITM_PORT 1
+
+#if (TRC_CFG_ITM_PORT < 0) || (TRC_CFG_ITM_PORT > 31)
+#error "Bad ITM port selected."
+#endif
+
+// Not used for ITM - no RAM buffer...
+#define TRC_STREAM_PORT_ALLOCATE_FIELDS()
+
+// Not used for ITM - assume the IDE configures the ITM setup
+#define TRC_STREAM_PORT_INIT()
+
+/* Important for the ITM port - no RAM buffer, direct writes. In most other ports this can be skipped (default is 1) */
+#define TRC_STREAM_PORT_USE_INTERNAL_BUFFER 0
+
+#define TRC_STREAM_PORT_WRITE_DATA(_ptrData, _size, _ptrBytesWritten) itm_write(_ptrData, _size, _ptrBytesWritten)
+
+#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) read_from_host(_ptrData, _size, _ptrBytesRead)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TRC_STREAMING_PORT_H */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/trcStreamingPort.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/trcStreamingPort.c
index 0d36b4ab3..4b51d7f0e 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/trcStreamingPort.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/trcStreamingPort.c
@@ -1,71 +1,169 @@
-
-#include "trcRecorder.h"
-
-#if (TRC_USE_TRACEALYZER_RECORDER == 1)
-#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
-
-static void itm_write_32(uint32_t data);
-
-volatile int32_t tz_host_command_bytes_to_read = 0; // This is set by the Tracealyzer host application (to the number of bytes written), after having written to tz_host_commands. Set to zero by the read function after the message in tz_host_commands has been read.
-volatile char tz_host_command_data[32];
-
-/* This reads "command" data from a RAM buffer, written by a host macro in the debugger */
-int32_t read_from_host(void* ptrData, uint32_t size, int32_t* ptrBytesRead)
-{
- if ( tz_host_command_bytes_to_read > 0)
- {
- int i;
- uint8_t * bytesBuffer = (uint8_t*) ptrData;
-
- if (ptrBytesRead != NULL)
- *ptrBytesRead = (int32_t)tz_host_command_bytes_to_read;
-
- if (tz_host_command_bytes_to_read != size)
- {
- return -1;
- }
-
- for (i=0; i < tz_host_command_bytes_to_read; i++)
- {
- bytesBuffer[i] = tz_host_command_data[i];
- }
-
- tz_host_command_bytes_to_read = 0;
- }
-
- return 0;
-}
-
-static void itm_write_32(uint32_t data)
-{
- if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk) && // Trace enabled
- (ITM->TCR & ITM_TCR_ITMENA_Msk) && // ITM enabled
- (ITM->TER & (1UL << TRC_CFG_ITM_PORT))) // ITM port enabled
- {
- while (ITM->PORT[TRC_CFG_ITM_PORT].u32 == 0); // Block until room in ITM FIFO - This stream port is always in "blocking mode", since intended for high-speed ITM!
- ITM->PORT[TRC_CFG_ITM_PORT].u32 = data; // Write the data
- }
-}
-
-/* This is assumed to execute from within the recorder, with interrupts disabled */
-int32_t itm_write(void* ptrData, uint32_t size, int32_t* ptrBytesWritten)
-{
- uint32_t bytesWritten = 0;
- uint32_t* ptr32 = (uint32_t*)ptrData;
-
- if (size % 4 != 0) return -2;
-
- while(bytesWritten < size)
- {
- itm_write_32(*ptr32);
- ptr32++;
- bytesWritten += 4;
- }
-
- *ptrBytesWritten = bytesWritten;
-
- return 0;
-}
-
-#endif
-#endif
+/*******************************************************************************
+ * Trace Recorder Library for Tracealyzer v4.3.11
+ * Percepio AB, www.percepio.com
+ *
+ * trcStreamingPort.c
+ *
+ * Supporting functions for trace streaming, used by the "stream ports"
+ * for reading and writing data to the interface.
+ * Existing ports can easily be modified to fit another setup, e.g., a
+ * different TCP/IP stack, or to define your own stream port.
+ *
+ * This stream port is for ITM streaming on Arm Cortex-M devices.
+ *
+ * To setup Keil uVision for ITM tracing with a Keil ULINKpro (or ULINKplus),
+ * see Percepio Application Note PA-021, available at
+ * https://percepio.com/2018/05/04/keil-itm-support/
+ *
+ * To setup IAR Embedded Workbench for ITM tracing with an IAR I-Jet,
+ * see Percepio Application Note PA-023, https://percepio.com/iar
+ *
+ * NOTE: This stream port may block the application in case the ITM port
+ * is not ready for more data (the TPIU FIFO has become full). This is
+ * necessary to avoid data loss, as the TPIU FIFO is often quite small.
+ *
+ * --- Direct vs. Indirect ITM streaming ---
+ * Direct streaming: By default, this stream port writes directly to the ITM
+ * register mode without any RAM buffer. This assumes you have a fast debug
+ * probe, like aKeil ULINKpro or IAR I-Jet, to avoid excessive blocking.
+ * In case the ITM blocking appears to disturb your application, make sure your
+ * debugger is configured for maximum performance, as described in the above
+ * Application Nodes.
+ *
+ * Indirect streaming: If direct streaming gives too much overhead, you may
+ * instead try indirect ITM streaming. This is done by enabling the internal
+ * RAM buffer, like below. This reconfigures the recorder to store the events
+ * in the internal RAM buffer instead of writing them directly to the ITM port.
+ *
+ * Set TRC_STREAM_PORT_USE_INTERNAL_BUFFER to 1 to use the indirect mode.
+ *
+ * This increases RAM usage but eliminates peaks in the trace data rate.
+ * Moreover, the ITM writes are then performed in a separate task (TzCtrl).
+ * You find relevant settings (buffer size etc.) in trcStreamingConfig.h.
+ *
+ * See also https://percepio.com/2018/10/11/tuning-your-custom-trace-streaming
+ *
+ * --- One-way vs. Two-way Communication ---
+ * The ITM port only provides one-way communication, from target to host.
+ * This is sufficient if you start the tracing from the target application,
+ * using vTraceEnable(TRC_START). Just make sure to start the Tracealyzer
+ * recording before you start the target system.
+ *
+ * In case you prefer to interactively start and stop the tracing from the host
+ * computer, you need two-way communication to send commands to the recorder.
+ * This is possible by writing such "start" and "stop" commands to a special
+ * buffer, monitored by the recorder library, using the debugger IDE.
+ * See trcStreamingPort.c and also the example macro for Keil uVision
+ * (Keil-uVision-Tracealyzer-ITM-Exporter.ini).
+ *
+ * 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
+ ******************************************************************************/
+
+#include "trcRecorder.h"
+
+#if (TRC_USE_TRACEALYZER_RECORDER == 1)
+#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
+
+static void itm_write_32(uint32_t data);
+
+/* These variables are used for reading commands from the host, using read_from_host().
+ * This is not required if using vTraceEnable(TRC_START).
+ * A debugger IDE may write to these functions using a macro.
+ * An example for Keil is included (Keil-uVision-Tracealyzer-ITM-Exporter.ini). */
+
+volatile int32_t tz_host_command_bytes_to_read = 0;
+volatile char tz_host_command_data[32];
+
+/* This reads "command" data from a RAM buffer, written by a host macro in the debugger */
+int32_t read_from_host(void* ptrData, uint32_t size, int32_t* ptrBytesRead)
+{
+ if ( tz_host_command_bytes_to_read > 0)
+ {
+ int i;
+ uint8_t * bytesBuffer = (uint8_t*) ptrData;
+
+ if (ptrBytesRead != NULL)
+ *ptrBytesRead = (int32_t)tz_host_command_bytes_to_read;
+
+ if (tz_host_command_bytes_to_read != size)
+ {
+ return -1;
+ }
+
+ for (i=0; i < tz_host_command_bytes_to_read; i++)
+ {
+ bytesBuffer[i] = tz_host_command_data[i];
+ }
+
+ tz_host_command_bytes_to_read = 0;
+ }
+
+ return 0;
+}
+
+static void itm_write_32(uint32_t data)
+{
+ if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk) && // Trace enabled
+ (ITM->TCR & ITM_TCR_ITMENA_Msk) && // ITM enabled
+ (ITM->TER & (1UL << TRC_CFG_ITM_PORT))) // ITM port enabled
+ {
+ while (ITM->PORT[TRC_CFG_ITM_PORT].u32 == 0); // Block until room in ITM FIFO - This stream port is always in "blocking mode", since intended for high-speed ITM!
+ ITM->PORT[TRC_CFG_ITM_PORT].u32 = data; // Write the data
+ }
+}
+
+/* This is assumed to execute from within the recorder, with interrupts disabled */
+int32_t itm_write(void* ptrData, uint32_t size, int32_t* ptrBytesWritten)
+{
+ uint32_t bytesWritten = 0;
+ uint32_t* ptr32 = (uint32_t*)ptrData;
+
+ if (size % 4 != 0) return -2;
+
+ while(bytesWritten < size)
+ {
+ itm_write_32(*ptr32);
+ ptr32++;
+ bytesWritten += 4;
+ }
+
+ *ptrBytesWritten = bytesWritten;
+
+ return 0;
+}
+
+#endif
+#endif
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/Readme-Streamport.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/Readme-Streamport.txt
index afc5a0951..c88517ef1 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/Readme-Streamport.txt
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/Readme-Streamport.txt
@@ -1,19 +1,19 @@
-Tracealyzer Stream Port for Files
--------------------------------------------------
-
-This directory contains a "stream port" for the Tracealyzer recorder library,
-i.e., the specific code needed to use a particular interface for streaming a
-Tracealyzer RTOS trace. The stream port is defined by a set of macros in
-trcStreamingPort.h, found in the "include" directory.
-
-This particular stream port is for streaming to a file via stdio.h (fwrite).
-
-To use this stream port, make sure that include/trcStreamingPort.h is found
-by the compiler (i.e., add this folder to your project's include paths) and
-add all included source files to your build. Make sure no other versions of
-trcStreamingPort.h are included by mistake!
-
-See also http://percepio.com/2016/10/05/rtos-tracing.
-
-Percepio AB
+Tracealyzer Stream Port for Files
+-------------------------------------------------
+
+This directory contains a "stream port" for the Tracealyzer recorder library,
+i.e., the specific code needed to use a particular interface for streaming a
+Tracealyzer RTOS trace. The stream port is defined by a set of macros in
+trcStreamingPort.h, found in the "include" directory.
+
+This particular stream port is for streaming to a file via stdio.h (fwrite).
+
+To use this stream port, make sure that include/trcStreamingPort.h is found
+by the compiler (i.e., add this folder to your project's include paths) and
+add all included source files to your build. Make sure no other versions of
+trcStreamingPort.h are included by mistake!
+
+See also http://percepio.com/2016/10/05/rtos-tracing.
+
+Percepio AB
www.percepio.com \ No newline at end of file
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/include/trcStreamingPort.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/include/trcStreamingPort.h
index 2897b7ce2..0deb9ad1c 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/include/trcStreamingPort.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/include/trcStreamingPort.h
@@ -1,87 +1,87 @@
-/*******************************************************************************
- * Trace Recorder Library for Tracealyzer v4.1.5
- * Percepio AB, www.percepio.com
- *
- * trcStreamingPort.h
- *
- * The interface definitions for trace streaming ("stream ports").
- * This "stream port" sets up the recorder to stream the trace to file.
- *
- * 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_STREAMING_PORT_H
-#define TRC_STREAMING_PORT_H
-
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int32_t writeToFile(void* data, uint32_t size, int32_t *ptrBytesWritten);
-
-void closeFile(void);
-
-void openFile(char* fileName);
-
-/* This define will determine whether to use the internal PagedEventBuffer or not.
-If file writing creates additional trace events (i.e. it uses semaphores or mutexes),
-then the paged event buffer must be enabled to avoid infinite recursion. */
-#define TRC_STREAM_PORT_USE_INTERNAL_BUFFER 1
-
-#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) 0 /* Does not read commands from Tz (yet) */
-
-#define TRC_STREAM_PORT_WRITE_DATA(_ptrData, _size, _ptrBytesSent) writeToFile(_ptrData, _size, _ptrBytesSent)
-
-#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 or static allocation. Not used. */
-#endif
-#define TRC_STREAM_PORT_INIT() \
- TRC_STREAM_PORT_MALLOC(); \
- openFile("trace.psf")
-
-#define TRC_STREAM_PORT_ON_TRACE_END() closeFile()
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* TRC_STREAMING_PORT_H */
+/*******************************************************************************
+ * Trace Recorder Library for Tracealyzer v4.3.11
+ * Percepio AB, www.percepio.com
+ *
+ * trcStreamingPort.h
+ *
+ * The interface definitions for trace streaming ("stream ports").
+ * This "stream port" sets up the recorder to stream the trace to file.
+ *
+ * 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_STREAMING_PORT_H
+#define TRC_STREAMING_PORT_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int32_t writeToFile(void* data, uint32_t size, int32_t *ptrBytesWritten);
+
+void closeFile(void);
+
+void openFile(char* fileName);
+
+/* This define will determine whether to use the internal PagedEventBuffer or not.
+If file writing creates additional trace events (i.e. it uses semaphores or mutexes),
+then the paged event buffer must be enabled to avoid infinite recursion. */
+#define TRC_STREAM_PORT_USE_INTERNAL_BUFFER 1
+
+#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) 0 /* Does not read commands from Tz (yet) */
+
+#define TRC_STREAM_PORT_WRITE_DATA(_ptrData, _size, _ptrBytesSent) writeToFile(_ptrData, _size, _ptrBytesSent)
+
+#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 or static allocation. Not used. */
+#endif
+#define TRC_STREAM_PORT_INIT() \
+ TRC_STREAM_PORT_MALLOC(); \
+ openFile("trace.psf")
+
+#define TRC_STREAM_PORT_ON_TRACE_END() closeFile()
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TRC_STREAMING_PORT_H */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/trcStreamingPort.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/trcStreamingPort.c
index a019791cd..03a5a9a6f 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/trcStreamingPort.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/trcStreamingPort.c
@@ -1,103 +1,103 @@
-/*******************************************************************************
- * Trace Recorder Library for Tracealyzer v4.1.5
- * Percepio AB, www.percepio.com
- *
- * trcStreamingPort.c
- *
- * Supporting functions for trace streaming, used by the "stream ports"
- * for reading and writing data to the interface.
- * Existing ports can easily be modified to fit another setup, e.g., a
- * different TCP/IP stack, or to define your own stream port.
- *
- * 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
- ******************************************************************************/
-
-#include "trcRecorder.h"
-
-#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
-#if (TRC_USE_TRACEALYZER_RECORDER == 1)
-
-FILE* traceFile = NULL;
-
-void openFile(char* fileName)
-{
- if (traceFile == NULL)
- {
- errno_t err = fopen_s(&traceFile, fileName, "wb");
- if (err != 0)
- {
- printf("Could not open trace file, error code %d.\n", err);
- exit(-1);
- }
- else {
- printf("Trace file created.\n");
- }
- }
-}
-
-int32_t writeToFile(void* data, uint32_t size, int32_t *ptrBytesWritten)
-{
- int32_t written = 0;
- if (traceFile != NULL)
- {
- written = fwrite(data, 1, size, traceFile);
- }
- else
- {
- written = 0;
- }
-
- if (ptrBytesWritten != 0)
- *ptrBytesWritten = written;
-
- if ((int32_t)size == written)
- return 0;
- else
- return -1;
-}
-
-void closeFile(void)
-{
- if (traceFile != NULL)
- {
- fclose(traceFile);
- traceFile = NULL;
- printf("Trace file closed.\n");
- }
-}
-
-#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/
-#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/
+/*******************************************************************************
+ * Trace Recorder Library for Tracealyzer v4.3.11
+ * Percepio AB, www.percepio.com
+ *
+ * trcStreamingPort.c
+ *
+ * Supporting functions for trace streaming, used by the "stream ports"
+ * for reading and writing data to the interface.
+ * Existing ports can easily be modified to fit another setup, e.g., a
+ * different TCP/IP stack, or to define your own stream port.
+ *
+ * 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
+ ******************************************************************************/
+
+#include "trcRecorder.h"
+
+#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
+#if (TRC_USE_TRACEALYZER_RECORDER == 1)
+
+FILE* traceFile = NULL;
+
+void openFile(char* fileName)
+{
+ if (traceFile == NULL)
+ {
+ errno_t err = fopen_s(&traceFile, fileName, "wb");
+ if (err != 0)
+ {
+ printf("Could not open trace file, error code %d.\n", err);
+ exit(-1);
+ }
+ else {
+ printf("Trace file created.\n");
+ }
+ }
+}
+
+int32_t writeToFile(void* data, uint32_t size, int32_t *ptrBytesWritten)
+{
+ int32_t written = 0;
+ if (traceFile != NULL)
+ {
+ written = fwrite(data, 1, size, traceFile);
+ }
+ else
+ {
+ written = 0;
+ }
+
+ if (ptrBytesWritten != 0)
+ *ptrBytesWritten = written;
+
+ if ((int32_t)size == written)
+ return 0;
+ else
+ return -1;
+}
+
+void closeFile(void)
+{
+ if (traceFile != NULL)
+ {
+ fclose(traceFile);
+ traceFile = NULL;
+ printf("Trace file closed.\n");
+ }
+}
+
+#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/
+#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/Readme-Streamport.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/Readme-Streamport.txt
index cae5e8ecc..0dcd1591e 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/Readme-Streamport.txt
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/Readme-Streamport.txt
@@ -1,22 +1,22 @@
-Tracealyzer Stream Port for SEGGER J-Link
------------------------------------------
-
-This directory contains a "stream port" for the Tracealyzer recorder library,
-i.e., the specific code needed to use a particular interface for streaming a
-Tracealyzer RTOS trace. The stream port is defined by a set of macros in
-trcStreamingPort.h, found in the "include" directory.
-
-This particular stream port targets SEGGER J-Link debug probes, using the RTT
-interface provided by SEGGER.
-
-To use this stream port, make sure that include/trcStreamingPort.h is found
-by the compiler (i.e., add this folder to your project's include paths) and
-add all included source files to your build. Make sure no other versions of
-trcStreamingPort.h are included by mistake!
-
-Note that this stream port also contains SEGGER's RTT driver.
-
-See also http://percepio.com/2016/10/05/rtos-tracing.
-
-Percepio AB
+Tracealyzer Stream Port for SEGGER J-Link
+-----------------------------------------
+
+This directory contains a "stream port" for the Tracealyzer recorder library,
+i.e., the specific code needed to use a particular interface for streaming a
+Tracealyzer RTOS trace. The stream port is defined by a set of macros in
+trcStreamingPort.h, found in the "include" directory.
+
+This particular stream port targets SEGGER J-Link debug probes, using the RTT
+interface provided by SEGGER.
+
+To use this stream port, make sure that include/trcStreamingPort.h is found
+by the compiler (i.e., add this folder to your project's include paths) and
+add all included source files to your build. Make sure no other versions of
+trcStreamingPort.h are included by mistake!
+
+Note that this stream port also contains SEGGER's RTT driver.
+
+See also http://percepio.com/2016/10/05/rtos-tracing.
+
+Percepio AB
www.percepio.com \ No newline at end of file
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/include/SEGGER_RTT_Conf.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/include/SEGGER_RTT_Conf.h
index 4f7f4cc3c..4bb1fdb5a 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/include/SEGGER_RTT_Conf.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/include/SEGGER_RTT_Conf.h
@@ -78,6 +78,10 @@ Revision: $Rev: 3892 $
#define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP // Mode for pre-initialized terminal channel (buffer 0)
+// This can be used to place the RTT control block in the right memory range, if no found automatically.
+// This example is for NXP LPC54018, needs to be adapted for each MCU family.
+//#define SEGGER_RTT_SECTION ".data.$RAM2"
+
//
// Target is not allowed to perform other RTT operations while string still has not been stored completely.
// Otherwise we would probably end up with a mixed string in the buffer.
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/include/trcStreamingPort.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/include/trcStreamingPort.h
index b1074b424..6ad22d507 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/include/trcStreamingPort.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/include/trcStreamingPort.h
@@ -1,196 +1,196 @@
-/*******************************************************************************
- * Trace Recorder Library for Tracealyzer v4.1.5
- * Percepio AB, www.percepio.com
- *
- * trcStreamingPort.h
- *
- * The interface definitions for trace streaming ("stream ports").
- * This "stream port" sets up the recorder to use SEGGER RTT as streaming channel.
- *
- * Note that this stream port is more complex than the typical case, since
- * the J-Link interface uses a separate RAM buffer in SEGGER_RTT.c, instead
- * of the default buffer included in the recorder core. The other stream ports
- * offer more typical examples of how to define a custom streaming interface.
- *
- * 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_STREAMING_PORT_H
-#define TRC_STREAMING_PORT_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*******************************************************************************
- * Configuration Macro: TRC_CFG_RTT_BUFFER_SIZE_UP
- *
- * Defines the size of the "up" RTT buffer (target -> host) to use for writing
- * the trace data, for RTT buffer 1 or higher.
- *
- * This setting is ignored for RTT buffer 0, which can't be reconfigured
- * in runtime and therefore hard-coded to use the defines in SEGGER_RTT_Conf.h.
- *
- * Default buffer size for Tracealyzer is 5000 bytes.
- *
- * If you have a stand-alone J-Link probe, the can be decreased to around 1 KB.
- * But integrated J-Link OB interfaces are slower and needs about 5-10 KB,
- * depending on the amount of data produced.
- ******************************************************************************/
-#define TRC_CFG_RTT_BUFFER_SIZE_UP 5000
-
-/*******************************************************************************
- * Configuration Macro: TRC_CFG_RTT_BUFFER_SIZE_DOWN
- *
- * Defines the size of the "down" RTT buffer (host -> target) to use for reading
- * commands from Tracealyzer, for RTT buffer 1 or higher.
- *
- * Default buffer size for Tracealyzer is 32 bytes.
- *
- * This setting is ignored for RTT buffer 0, which can't be reconfigured
- * in runtime and therefore hard-coded to use the defines in SEGGER_RTT_Conf.h.
- ******************************************************************************/
-#define TRC_CFG_RTT_BUFFER_SIZE_DOWN 32
-
-/*******************************************************************************
- * Configuration Macro: TRC_CFG_RTT_UP_BUFFER_INDEX
- *
- * Defines the RTT buffer to use for writing the trace data. Make sure that
- * the PC application has the same setting (File->Settings).
- *
- * Default: 1
- *
- * We don't recommend using RTT buffer 0, since mainly intended for terminals.
- * If you prefer to use buffer 0, it must be configured in SEGGER_RTT_Conf.h.
- ******************************************************************************/
-#define TRC_CFG_RTT_UP_BUFFER_INDEX 1
-
-/*******************************************************************************
- * Configuration Macro: TRC_CFG_RTT_DOWN_BUFFER_INDEX
- *
- * Defines the RTT buffer to use for reading the trace data. Make sure that
- * the PC application has the same setting (File->Settings).
- *
- * Default: 1
- *
- * We don't recommend using RTT buffer 0, since mainly intended for terminals.
- * If you prefer to use buffer 0, it must be configured in SEGGER_RTT_Conf.h.
- ******************************************************************************/
-#define TRC_CFG_RTT_DOWN_BUFFER_INDEX 1
-
-/*******************************************************************************
- * TRC_CFG_RTT_MODE
- * This stream port for J-Link streaming relies on SEGGER RTT, that contains an
- * internal RAM buffer read by the J-Link probes during execution.
- *
- * Possible values:
- * - SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL
- * - SEGGER_RTT_MODE_NO_BLOCK_SKIP (default)
- *
- * Using SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL ensure that you get a
- * complete and valid trace. This may however cause blocking if your streaming
- * interface isn't fast enough, which may disturb the real-time behavior.
- *
- * We therefore recommend SEGGER_RTT_MODE_NO_BLOCK_SKIP. In this mode,
- * Tracealyzer will report lost events if the transfer is not
- * fast enough. In that case, try increasing the size of the "up buffer".
- ******************************************************************************/
-#define TRC_CFG_RTT_MODE SEGGER_RTT_MODE_NO_BLOCK_SKIP
-
-#include "SEGGER_RTT_Conf.h"
-#include "SEGGER_RTT.h"
-
-#if (TRC_CFG_RTT_UP_BUFFER_INDEX >= SEGGER_RTT_MAX_NUM_UP_BUFFERS)
-#error "TRC_CFG_RTT_UP_BUFFER_INDEX must be smaller than SEGGER_RTT_MAX_NUM_UP_BUFFERS"
-#endif
-
-#if (TRC_CFG_RTT_DOWN_BUFFER_INDEX >= SEGGER_RTT_MAX_NUM_DOWN_BUFFERS)
-#error "TRC_CFG_RTT_DOWN_BUFFER_INDEX must be smaller than SEGGER_RTT_MAX_NUM_DOWN_BUFFERS"
-#endif
-
-/* If index is defined as 0, the internal RTT buffers will be used instead of this. */
-#if TRC_CFG_RTT_UP_BUFFER_INDEX == 0
-#define TRC_RTT_ALLOC_UP() static char* _TzTraceData = NULL; /* Not actually used. Ignore allocation method. */
-#define TRC_STREAM_PORT_MALLOC() /* Static allocation. Not used. */
-#else
-#if TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_STATIC
-#define TRC_RTT_ALLOC_UP() char _TzTraceData[TRC_CFG_RTT_BUFFER_SIZE_UP]; /* Static allocation */
-#define TRC_STREAM_PORT_MALLOC() /* Static allocation. Not used. */
-#endif
-#if TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC
-#define TRC_RTT_ALLOC_UP() char* _TzTraceData = NULL; /* Dynamic allocation */
-#define TRC_STREAM_PORT_MALLOC() _TzTraceData = TRC_PORT_MALLOC(TRC_CFG_RTT_BUFFER_SIZE_UP);
-#endif
-#if TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM
-#define TRC_RTT_ALLOC_UP() char* _TzTraceData = NULL; /* Custom allocation, user needs to call vTraceSetRecorderDataBuffer before vTraceEnable, to assign this */
-#define TRC_STREAM_PORT_MALLOC() /* Not used in custom mode */
-#endif
-#endif
-
-/* Down-buffer. If index is defined as 0, the internal RTT buffers will be used instead of this. */ \
-#if TRC_CFG_RTT_DOWN_BUFFER_INDEX == 0
-#define TRC_RTT_ALLOC_DOWN() static char* _TzCtrlData = NULL; /* Not actually used. Ignore allocation method. */
-#else
-#define TRC_RTT_ALLOC_DOWN() static char _TzCtrlData[TRC_CFG_RTT_BUFFER_SIZE_DOWN]; /* Always static allocation, since usually small. */
-#endif
-
-#define TRC_STREAM_PORT_ALLOCATE_FIELDS() \
- TRC_RTT_ALLOC_UP() /* Macro that will result in proper UP buffer allocation */ \
- TRC_RTT_ALLOC_DOWN() /* Macro that will result in proper DOWN buffer allocation */
-
-int32_t readFromRTT(void* ptrData, uint32_t size, int32_t* ptrBytesRead);
-
-int32_t writeToRTT(void* ptrData, uint32_t size, int32_t* ptrBytesWritten);
-
-
-#define TRC_STREAM_PORT_INIT() \
- TRC_STREAM_PORT_MALLOC(); /*Dynamic allocation or empty if static */ \
- SEGGER_RTT_ConfigUpBuffer(TRC_CFG_RTT_UP_BUFFER_INDEX, "TzData", _TzTraceData, TRC_CFG_RTT_BUFFER_SIZE_UP, TRC_CFG_RTT_MODE ); \
- SEGGER_RTT_ConfigDownBuffer(TRC_CFG_RTT_DOWN_BUFFER_INDEX, "TzCtrl", _TzCtrlData, TRC_CFG_RTT_BUFFER_SIZE_DOWN, TRC_CFG_RTT_MODE);
-
-/* Important for the J-Link port, in most other ports this can be skipped (default is 1) */
-#define TRC_STREAM_PORT_USE_INTERNAL_BUFFER 0
-
-#define TRC_STREAM_PORT_WRITE_DATA(_ptrData, _size, _ptrBytesWritten) writeToRTT(_ptrData, _size, _ptrBytesWritten)
-
-#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) readFromRTT(_ptrData, _size, _ptrBytesRead)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* TRC_STREAMING_PORT_H */
+/*******************************************************************************
+ * Trace Recorder Library for Tracealyzer v4.3.11
+ * Percepio AB, www.percepio.com
+ *
+ * trcStreamingPort.h
+ *
+ * The interface definitions for trace streaming ("stream ports").
+ * This "stream port" sets up the recorder to use SEGGER RTT as streaming channel.
+ *
+ * Note that this stream port is more complex than the typical case, since
+ * the J-Link interface uses a separate RAM buffer in SEGGER_RTT.c, instead
+ * of the default buffer included in the recorder core. The other stream ports
+ * offer more typical examples of how to define a custom streaming interface.
+ *
+ * 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_STREAMING_PORT_H
+#define TRC_STREAMING_PORT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*******************************************************************************
+ * Configuration Macro: TRC_CFG_RTT_BUFFER_SIZE_UP
+ *
+ * Defines the size of the "up" RTT buffer (target -> host) to use for writing
+ * the trace data, for RTT buffer 1 or higher.
+ *
+ * This setting is ignored for RTT buffer 0, which can't be reconfigured
+ * in runtime and therefore hard-coded to use the defines in SEGGER_RTT_Conf.h.
+ *
+ * Default buffer size for Tracealyzer is 5000 bytes.
+ *
+ * If you have a stand-alone J-Link probe, the can be decreased to around 1 KB.
+ * But integrated J-Link OB interfaces are slower and needs about 5-10 KB,
+ * depending on the amount of data produced.
+ ******************************************************************************/
+#define TRC_CFG_RTT_BUFFER_SIZE_UP 5000
+
+/*******************************************************************************
+ * Configuration Macro: TRC_CFG_RTT_BUFFER_SIZE_DOWN
+ *
+ * Defines the size of the "down" RTT buffer (host -> target) to use for reading
+ * commands from Tracealyzer, for RTT buffer 1 or higher.
+ *
+ * Default buffer size for Tracealyzer is 32 bytes.
+ *
+ * This setting is ignored for RTT buffer 0, which can't be reconfigured
+ * in runtime and therefore hard-coded to use the defines in SEGGER_RTT_Conf.h.
+ ******************************************************************************/
+#define TRC_CFG_RTT_BUFFER_SIZE_DOWN 32
+
+/*******************************************************************************
+ * Configuration Macro: TRC_CFG_RTT_UP_BUFFER_INDEX
+ *
+ * Defines the RTT buffer to use for writing the trace data. Make sure that
+ * the PC application has the same setting (File->Settings).
+ *
+ * Default: 1
+ *
+ * We don't recommend using RTT buffer 0, since mainly intended for terminals.
+ * If you prefer to use buffer 0, it must be configured in SEGGER_RTT_Conf.h.
+ ******************************************************************************/
+#define TRC_CFG_RTT_UP_BUFFER_INDEX 1
+
+/*******************************************************************************
+ * Configuration Macro: TRC_CFG_RTT_DOWN_BUFFER_INDEX
+ *
+ * Defines the RTT buffer to use for reading the trace data. Make sure that
+ * the PC application has the same setting (File->Settings).
+ *
+ * Default: 1
+ *
+ * We don't recommend using RTT buffer 0, since mainly intended for terminals.
+ * If you prefer to use buffer 0, it must be configured in SEGGER_RTT_Conf.h.
+ ******************************************************************************/
+#define TRC_CFG_RTT_DOWN_BUFFER_INDEX 1
+
+/*******************************************************************************
+ * TRC_CFG_RTT_MODE
+ * This stream port for J-Link streaming relies on SEGGER RTT, that contains an
+ * internal RAM buffer read by the J-Link probes during execution.
+ *
+ * Possible values:
+ * - SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL
+ * - SEGGER_RTT_MODE_NO_BLOCK_SKIP (default)
+ *
+ * Using SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL ensure that you get a
+ * complete and valid trace. This may however cause blocking if your streaming
+ * interface isn't fast enough, which may disturb the real-time behavior.
+ *
+ * We therefore recommend SEGGER_RTT_MODE_NO_BLOCK_SKIP. In this mode,
+ * Tracealyzer will report lost events if the transfer is not
+ * fast enough. In that case, try increasing the size of the "up buffer".
+ ******************************************************************************/
+#define TRC_CFG_RTT_MODE SEGGER_RTT_MODE_NO_BLOCK_SKIP
+
+#include "SEGGER_RTT_Conf.h"
+#include "SEGGER_RTT.h"
+
+#if (TRC_CFG_RTT_UP_BUFFER_INDEX >= SEGGER_RTT_MAX_NUM_UP_BUFFERS)
+#error "TRC_CFG_RTT_UP_BUFFER_INDEX must be smaller than SEGGER_RTT_MAX_NUM_UP_BUFFERS"
+#endif
+
+#if (TRC_CFG_RTT_DOWN_BUFFER_INDEX >= SEGGER_RTT_MAX_NUM_DOWN_BUFFERS)
+#error "TRC_CFG_RTT_DOWN_BUFFER_INDEX must be smaller than SEGGER_RTT_MAX_NUM_DOWN_BUFFERS"
+#endif
+
+/* If index is defined as 0, the internal RTT buffers will be used instead of this. */
+#if TRC_CFG_RTT_UP_BUFFER_INDEX == 0
+#define TRC_RTT_ALLOC_UP() static char* _TzTraceData = NULL; /* Not actually used. Ignore allocation method. */
+#define TRC_STREAM_PORT_MALLOC() /* Static allocation. Not used. */
+#else
+#if TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_STATIC
+#define TRC_RTT_ALLOC_UP() char _TzTraceData[TRC_CFG_RTT_BUFFER_SIZE_UP]; /* Static allocation */
+#define TRC_STREAM_PORT_MALLOC() /* Static allocation. Not used. */
+#endif
+#if TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC
+#define TRC_RTT_ALLOC_UP() char* _TzTraceData = NULL; /* Dynamic allocation */
+#define TRC_STREAM_PORT_MALLOC() _TzTraceData = TRC_PORT_MALLOC(TRC_CFG_RTT_BUFFER_SIZE_UP);
+#endif
+#if TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM
+#define TRC_RTT_ALLOC_UP() char* _TzTraceData = NULL; /* Custom allocation, user needs to call vTraceSetRecorderDataBuffer before vTraceEnable, to assign this */
+#define TRC_STREAM_PORT_MALLOC() /* Not used in custom mode */
+#endif
+#endif
+
+/* Down-buffer. If index is defined as 0, the internal RTT buffers will be used instead of this. */ \
+#if TRC_CFG_RTT_DOWN_BUFFER_INDEX == 0
+#define TRC_RTT_ALLOC_DOWN() static char* _TzCtrlData = NULL; /* Not actually used. Ignore allocation method. */
+#else
+#define TRC_RTT_ALLOC_DOWN() static char _TzCtrlData[TRC_CFG_RTT_BUFFER_SIZE_DOWN]; /* Always static allocation, since usually small. */
+#endif
+
+#define TRC_STREAM_PORT_ALLOCATE_FIELDS() \
+ TRC_RTT_ALLOC_UP() /* Macro that will result in proper UP buffer allocation */ \
+ TRC_RTT_ALLOC_DOWN() /* Macro that will result in proper DOWN buffer allocation */
+
+int32_t readFromRTT(void* ptrData, uint32_t size, int32_t* ptrBytesRead);
+
+int32_t writeToRTT(void* ptrData, uint32_t size, int32_t* ptrBytesWritten);
+
+
+#define TRC_STREAM_PORT_INIT() \
+ TRC_STREAM_PORT_MALLOC(); /*Dynamic allocation or empty if static */ \
+ SEGGER_RTT_ConfigUpBuffer(TRC_CFG_RTT_UP_BUFFER_INDEX, "TzData", _TzTraceData, TRC_CFG_RTT_BUFFER_SIZE_UP, TRC_CFG_RTT_MODE ); \
+ SEGGER_RTT_ConfigDownBuffer(TRC_CFG_RTT_DOWN_BUFFER_INDEX, "TzCtrl", _TzCtrlData, TRC_CFG_RTT_BUFFER_SIZE_DOWN, TRC_CFG_RTT_MODE);
+
+/* Important for the J-Link port, in most other ports this can be skipped (default is 1) */
+#define TRC_STREAM_PORT_USE_INTERNAL_BUFFER 0
+
+#define TRC_STREAM_PORT_WRITE_DATA(_ptrData, _size, _ptrBytesWritten) writeToRTT(_ptrData, _size, _ptrBytesWritten)
+
+#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) readFromRTT(_ptrData, _size, _ptrBytesRead)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TRC_STREAMING_PORT_H */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/trcStreamingPort.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/trcStreamingPort.c
index d279f83b9..d4d7ec118 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/trcStreamingPort.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/trcStreamingPort.c
@@ -1,44 +1,83 @@
-
-#include "trcRecorder.h"
-
-#if (TRC_USE_TRACEALYZER_RECORDER == 1)
-#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
-
-int32_t readFromRTT(void* ptrData, uint32_t size, int32_t* ptrBytesRead)
-{
- uint32_t bytesRead = 0;
-
- if (SEGGER_RTT_HASDATA(TRC_CFG_RTT_DOWN_BUFFER_INDEX))
- {
- bytesRead = SEGGER_RTT_Read((TRC_CFG_RTT_DOWN_BUFFER_INDEX), (char*)ptrData, size);
-
- if (ptrBytesRead != NULL)
- *ptrBytesRead = (int32_t)bytesRead;
-
- if (bytesRead != size)
- {
- return -1;
- }
-
- }
-
- return 0;
-}
-
-int32_t writeToRTT(void* ptrData, uint32_t size, int32_t* ptrBytesWritten)
-{
- uint32_t bytesWritten = SEGGER_RTT_Write((TRC_CFG_RTT_UP_BUFFER_INDEX), (const char*)ptrData, size);
-
- if (ptrBytesWritten != NULL)
- *ptrBytesWritten = (int32_t)bytesWritten;
-
- if (bytesWritten != size)
- {
- return -1;
- }
-
- return 0;
-}
-
-#endif
-#endif
+/*******************************************************************************
+ * Trace Recorder Library for Tracealyzer v4.3.11
+ * Percepio AB, www.percepio.com
+ *
+ * trcStreamingPort.c
+ *
+ * Supporting functions for trace streaming, used by the "stream ports"
+ * for reading and writing data to the interface.
+ *
+ * Note that this stream port is more complex than the typical case, since
+ * the J-Link interface uses a separate RAM buffer in SEGGER_RTT.c, instead
+ * of the default buffer included in the recorder core. The other stream ports
+ * offer more typical examples of how to define a custom streaming interface.
+ *
+ * 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
+ ******************************************************************************/
+
+#include "trcRecorder.h"
+
+#if (TRC_USE_TRACEALYZER_RECORDER == 1)
+#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
+
+int32_t readFromRTT(void* ptrData, uint32_t size, int32_t* ptrBytesRead)
+{
+ uint32_t bytesRead = 0;
+
+ if (SEGGER_RTT_HASDATA(TRC_CFG_RTT_DOWN_BUFFER_INDEX))
+ {
+ bytesRead = SEGGER_RTT_Read((TRC_CFG_RTT_DOWN_BUFFER_INDEX), (char*)ptrData, size);
+
+ if (ptrBytesRead != NULL)
+ *ptrBytesRead = (int32_t)bytesRead;
+
+ }
+
+ return 0;
+}
+
+int32_t writeToRTT(void* ptrData, uint32_t size, int32_t* ptrBytesWritten)
+{
+ uint32_t bytesWritten = SEGGER_RTT_Write((TRC_CFG_RTT_UP_BUFFER_INDEX), (const char*)ptrData, size);
+
+ if (ptrBytesWritten != NULL)
+ *ptrBytesWritten = (int32_t)bytesWritten;
+
+ return 0;
+}
+
+#endif
+#endif
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/Readme-Streamport.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/Readme-Streamport.txt
index f8f097baa..c2d9ce78d 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/Readme-Streamport.txt
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/Readme-Streamport.txt
@@ -1,22 +1,50 @@
-Tracealyzer Stream Port for TCP/IP (lwIP example)
--------------------------------------------------
-
-This directory contains a "stream port" for the Tracealyzer recorder library,
-i.e., the specific code needed to use a particular interface for streaming a
-Tracealyzer RTOS trace. The stream port is defined by a set of macros in
-trcStreamingPort.h, found in the "include" directory.
-
-This particular stream port targets TCP/IP. This example assumes lwIP but is
-easy to modify for other TCP/IP stacks.
-
-To use this stream port, make sure that include/trcStreamingPort.h is found
-by the compiler (i.e., add this folder to your project's include paths) and
-add all included source files to your build. Make sure no other versions of
-trcStreamingPort.h are included by mistake!
-
-Note that lwIP is not included, but assumed to exist in the project already.
-
-See also http://percepio.com/2016/10/05/rtos-tracing.
-
-Percepio AB
+Tracealyzer Stream Port for TCP/IP (lwIP example)
+-------------------------------------------------
+
+This directory contains a "stream port" for the Tracealyzer recorder library,
+i.e., the specific code needed to use a particular interface for streaming a
+Tracealyzer RTOS trace. The stream port is defined by a set of macros in
+trcStreamingPort.h, found in the "include" directory.
+
+This particular stream port targets TCP/IP. This example assumes lwIP but is
+easy to modify for other TCP/IP stacks.
+
+Instructions:
+
+1. Integrate the trace recorder and configure it for streaming, as described
+ in the Tracealyzer User Manual. For FreeRTOS this is found at:
+ https://percepio.com/docs/FreeRTOS/manual/index.html#Creating_and_Loading_Traces___Introduction
+
+2. Make sure all .c and .h files from this stream port folder is included in
+ your build, and that no other variant of trcStreamingPort.h is included.
+
+3. In lwipopts.h, make sure you have this line:
+
+ #define LWIP_SOCKET 1
+
+4. Make sure that vTraceEnable(TRC_INIT) is called during the startup, before
+ any RTOS calls are made.
+
+5. In Tracealyzer, open File -> Settings -> PSF Streaming Settings and
+ select Target Connection: TCP. Enter the IP address of the target system
+ and the port number (by default 12000).
+
+6. Start your target system, wait a few seconds to ensure that the lwIP is operational,
+ then select Start Recording in Tracealyzer.
+
+Troubleshooting:
+
+- If the tracing suddenly stops, check the "errno" value in trcSocketSend (trcStreamingPort.c).
+You can see the error code definitions in lwip/errno.h. If errno is ENOMEM, may you need to
+increase MEM_SIZE in lwipopts.h.
+
+- Since lwIP performs a lot of semaphore and mutex operations, we recommend filtering out
+such events from the trace, at least those caused by the transmission of trace data in the
+TzCtrl task. This can be done using vTraceSetFilterGroup() and vTraceSetFilterMask().
+
+Note that lwIP is not included in the stream port, but assumed to exist in the project already.
+
+See also http://percepio.com/2016/10/05/rtos-tracing.
+
+Percepio AB
www.percepio.com \ No newline at end of file
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/include/trcStreamingPort.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/include/trcStreamingPort.h
index 51e52e862..b305df4f5 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/include/trcStreamingPort.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/include/trcStreamingPort.h
@@ -1,66 +1,68 @@
-/*******************************************************************************
- * Trace Recorder Library for Tracealyzer v4.1.5
- * Percepio AB, www.percepio.com
- *
- * trcStreamingPort.h
- *
- * The interface definitions for trace streaming ("stream ports").
- * This "stream port" sets up the recorder to use TCP/IP as streaming channel.
- * The example is for lwIP.
- *
- * 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_STREAMING_PORT_H
-#define TRC_STREAMING_PORT_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int32_t trcTcpRead(void* data, uint32_t size, int32_t *ptrBytesRead);
-
-int32_t trcTcpWrite(void* data, uint32_t size, int32_t *ptrBytesWritten);
-
-#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) trcTcpRead(_ptrData, _size, _ptrBytesRead)
-
-#define TRC_STREAM_PORT_WRITE_DATA(_ptrData, _size, _ptrBytesSent) trcTcpWrite(_ptrData, _size, _ptrBytesSent)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* TRC_STREAMING_PORT_H */
+/*******************************************************************************
+ * Trace Recorder Library for Tracealyzer v4.3.11
+ * Percepio AB, www.percepio.com
+ *
+ * trcStreamingPort.h
+ *
+ * The interface definitions for trace streaming ("stream ports").
+ * This "stream port" sets up the recorder to use TCP/IP as streaming channel.
+ * The example is for lwIP.
+ *
+ * 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_STREAMING_PORT_H
+#define TRC_STREAMING_PORT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define TRC_STREAM_PORT_USE_INTERNAL_BUFFER 1
+
+int32_t trcTcpRead(void* data, uint32_t size, int32_t *ptrBytesRead);
+
+int32_t trcTcpWrite(void* data, uint32_t size, int32_t *ptrBytesWritten);
+
+#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) trcTcpRead(_ptrData, _size, _ptrBytesRead)
+
+#define TRC_STREAM_PORT_WRITE_DATA(_ptrData, _size, _ptrBytesSent) trcTcpWrite(_ptrData, _size, _ptrBytesSent)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TRC_STREAMING_PORT_H */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/trcStreamingPort.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/trcStreamingPort.c
index d420d121a..df92f6f0a 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/trcStreamingPort.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/trcStreamingPort.c
@@ -1,186 +1,180 @@
-/*******************************************************************************
- * Trace Recorder Library for Tracealyzer v4.1.5
- * Percepio AB, www.percepio.com
- *
- * trcStreamingPort.c
- *
- * Supporting functions for trace streaming, used by the "stream ports"
- * for reading and writing data to the interface.
- * Existing ports can easily be modified to fit another setup, e.g., a
- * different TCP/IP stack, or to define your own stream port.
- *
- * 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
- ******************************************************************************/
-
-#include "trcRecorder.h"
-
-#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
-#if (TRC_USE_TRACEALYZER_RECORDER == 1)
-
-/* TCP/IP includes - for lwIP in this case */
-#include "lwip/tcpip.h"
-#include "lwip/sockets.h"
-
-int errno;
-
-#define TRC_TCPIP_PORT 12000
-
-int sock = -1, new_sd = -1;
-int flags = 0;
-int remoteSize;
-struct sockaddr_in address, remote;
-
-int32_t trcSocketSend( void* data, int32_t size, int32_t* bytesWritten )
-{
- if (new_sd < 0)
- return -1;
-
- if (bytesWritten == NULL)
- return -1;
-
- *bytesWritten = send( new_sd, data, size, 0 );
- if (*bytesWritten < 0)
- {
- /* EWOULDBLOCK may be expected when buffers are full */
- if (errno != 0 && errno != EWOULDBLOCK)
- {
- closesocket(new_sd);
- new_sd = -1;
- return -1;
- }
- else
- *bytesWritten = 0;
- }
-
- return 0;
-}
-
-int32_t trcSocketReceive( void* data, int32_t size, int32_t* bytesRead )
-{
- if (new_sd < 0)
- return -1;
-
- *bytesRead = recv( new_sd, data, size, 0 );
- if ( *bytesRead < 0 )
- {
- /* EWOULDBLOCK may be expected when there is no data to receive */
- if (errno != 0 && errno != EWOULDBLOCK)
- {
- closesocket(new_sd);
- new_sd = -1;
- return -1;
- }
- else
- *bytesRead = 0;
- }
-
- return 0;
-}
-
-int32_t trcSocketInitializeListener()
-{
- if (sock >= 0)
- return 0;
-
- sock = lwip_socket(AF_INET, SOCK_STREAM, 0);
-
- if (sock < 0)
- return -1;
-
- address.sin_family = AF_INET;
- address.sin_port = htons( TRC_TCPIP_PORT );
- address.sin_addr.s_addr = INADDR_ANY;
-
- if (bind(sock, (struct sockaddr *)&address, sizeof (address)) < 0)
- {
- closesocket(sock);
- sock = -1;
- return -1;
- }
-
- if (lwip_listen(sock, 5) < 0)
- {
- closesocket(sock);
- sock = -1;
- return -1;
- }
-
- return 0;
-}
-
-int32_t trcSocketAccept()
-{
- if (sock < 0)
- return -1;
-
- if (new_sd >= 0)
- return 0;
-
- remoteSize = sizeof( remote );
- new_sd = accept( sock, (struct sockaddr *)&remote, (socklen_t*)&remoteSize );
-
- flags = fcntl( new_sd, F_GETFL, 0 );
- fcntl( new_sd, F_SETFL, flags | O_NONBLOCK );
-
- if( new_sd < 0 )
- {
- closesocket(new_sd);
- new_sd = -1;
- closesocket(sock);
- sock = -1;
- return -1;
- }
-
- return 0;
-}
-/************** MODIFY THE ABOVE PART TO USE YOUR TPC/IP STACK ****************/
-
-int32_t trcTcpWrite(void* data, uint32_t size, int32_t *ptrBytesWritten)
-{
- return trcSocketSend(data, size, ptrBytesWritten);
-}
-
-int32_t trcTcpRead(void* data, uint32_t size, int32_t *ptrBytesRead)
-{
- trcSocketInitializeListener();
-
- trcSocketAccept();
-
- return trcSocketReceive(data, size, ptrBytesRead);
-}
-
-#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/
-#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/
+/*******************************************************************************
+ * Trace Recorder Library for Tracealyzer v4.3.11
+ * Percepio AB, www.percepio.com
+ *
+ * trcStreamingPort.c
+ *
+ * Supporting functions for trace streaming, used by the "stream ports"
+ * for reading and writing data to the interface.
+ * Existing ports can easily be modified to fit another setup, e.g., a
+ * different TCP/IP stack, or to define your own stream port.
+ *
+ * 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
+ ******************************************************************************/
+
+#include "trcRecorder.h"
+
+#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
+#if (TRC_USE_TRACEALYZER_RECORDER == 1)
+
+/* TCP/IP includes - for lwIP in this case */
+#include "lwip/tcpip.h"
+#include "lwip/sockets.h"
+#include "lwip/errno.h"
+
+#define TRC_TCPIP_PORT 12000
+
+int sock = -1, new_sd = -1;
+int flags = 0;
+int remoteSize;
+struct sockaddr_in address, remote;
+
+int32_t trcSocketSend( void* data, int32_t size, int32_t* bytesWritten )
+{
+ if (new_sd < 0)
+ return -1;
+
+ if (bytesWritten == NULL)
+ return -1;
+
+ *bytesWritten = send( new_sd, data, size, 0 );
+ if (*bytesWritten < 0)
+ {
+ /* EWOULDBLOCK may be expected when buffers are full */
+ if ((errno != 0) && (errno != EWOULDBLOCK))
+ {
+ closesocket(new_sd);
+ new_sd = -1;
+ return -1;
+ }
+ else
+ *bytesWritten = 0;
+ }
+
+ return 0;
+}
+
+int32_t trcSocketReceive( void* data, int32_t size, int32_t* bytesRead )
+{
+ if (new_sd < 0)
+ return -1;
+
+ *bytesRead = recv( new_sd, data, size, 0 );
+ /* EWOULDBLOCK may be expected when there is no data to receive */
+ if (errno != 0 && errno != EWOULDBLOCK)
+ {
+ closesocket(new_sd);
+ new_sd = -1;
+ return -1;
+ }
+
+ return 0;
+}
+
+int32_t trcSocketInitializeListener()
+{
+ if (sock >= 0)
+ return 0;
+
+ sock = lwip_socket(AF_INET, SOCK_STREAM, 0);
+
+ if (sock < 0)
+ return -1;
+
+ address.sin_family = AF_INET;
+ address.sin_port = htons( TRC_TCPIP_PORT );
+ address.sin_addr.s_addr = INADDR_ANY;
+
+ if (bind(sock, (struct sockaddr *)&address, sizeof (address)) < 0)
+ {
+ closesocket(sock);
+ sock = -1;
+ return -1;
+ }
+
+ if (lwip_listen(sock, 5) < 0)
+ {
+ closesocket(sock);
+ sock = -1;
+ return -1;
+ }
+
+ return 0;
+}
+
+int32_t trcSocketAccept()
+{
+ if (sock < 0)
+ return -1;
+
+ if (new_sd >= 0)
+ return 0;
+
+ remoteSize = sizeof( remote );
+ new_sd = accept( sock, (struct sockaddr *)&remote, (socklen_t*)&remoteSize );
+
+ if( new_sd < 0 )
+ {
+ closesocket(new_sd);
+ new_sd = -1;
+ closesocket(sock);
+ sock = -1;
+ return -1;
+ }
+
+ flags = fcntl( new_sd, F_GETFL, 0 );
+ fcntl( new_sd, F_SETFL, flags | O_NONBLOCK );
+
+ return 0;
+}
+/************** MODIFY THE ABOVE PART TO USE YOUR TPC/IP STACK ****************/
+
+int32_t trcTcpWrite(void* data, uint32_t size, int32_t *ptrBytesWritten)
+{
+ return trcSocketSend(data, size, ptrBytesWritten);
+}
+
+int32_t trcTcpRead(void* data, uint32_t size, int32_t *ptrBytesRead)
+{
+ trcSocketInitializeListener();
+
+ trcSocketAccept();
+
+ return trcSocketReceive(data, size, ptrBytesRead);
+}
+
+#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/
+#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP_Win32/Readme-Streamport.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP_Win32/Readme-Streamport.txt
new file mode 100644
index 000000000..b61ecff8f
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP_Win32/Readme-Streamport.txt
@@ -0,0 +1,38 @@
+Tracealyzer Stream Port for TCP/IP (Win32 example)
+-------------------------------------------------
+
+This directory contains a "stream port" for the Tracealyzer recorder library,
+i.e., the I/O code needed for streaming a Tracealyzer RTOS trace over specific
+interface. The stream port is defined by a set of macros in trcStreamingPort.h,
+found in the "include" directory.
+
+This particular stream port is for streaming over TCP/IP on Windows, intended
+for the FreeRTOS Windows port (WIN32-MSVC). To try it:
+
+1. Open the WIN32-MSVC demo project found in the FreeRTOS demo folder. You
+need will Visual Studio, but there are free versions (Express or Community).
+
+2. Make sure the project includes a recent version or the recorder library
+(v3.1.x).
+
+3. Make sure the recorder library is configured for streaming mode (see
+trcConfig.h).
+
+4. Make sure the project's include paths contains trcStreamingPort.h found in
+this include folder (and not any other stream port), and the related code
+in this folder.
+
+5. Build and start the Win32 demo application. It should begin waiting for
+a connection.
+
+6. In Tracealyzer, open File -> Settings... -> Streaming Trace Settings.
+Specify target connection: TCP, host: 127.0.0.1 (i.e. localhost) and port 8888.
+
+7. In Tracealyzer, now open File -> Connect to Target System... and there
+click "Start Recording". Now you should see a live CPU load graph and some
+counters. Let it record for a few seconds, then click "Stop Recording" and then "View Trace".
+
+See also http://percepio.com/2016/10/05/rtos-tracing.
+
+Percepio AB
+www.percepio.com \ No newline at end of file
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP_Win32/include/trcStreamingPort.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP_Win32/include/trcStreamingPort.h
new file mode 100644
index 000000000..594ba2150
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP_Win32/include/trcStreamingPort.h
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Trace Recorder Library for Tracealyzer v4.3.11
+ * Percepio AB, www.percepio.com
+ *
+ * trcStreamingPort.h
+ *
+ * The interface definitions for trace streaming ("stream ports").
+ * This "stream port" sets up the recorder to use TCP/IP as streaming channel.
+ * The example is for Windows sockets (Winsock), for use with Windows ports.
+ *
+ * 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_STREAMING_PORT_H
+#define TRC_STREAMING_PORT_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int32_t readFromSocket(void* data, uint32_t size, int32_t *ptrBytesRead);
+int32_t writeToSocket(void* data, uint32_t size, int32_t *ptrBytesWritten);
+
+/* This port supports both direct write and buffered mode ...*/
+#define TRC_STREAM_PORT_USE_INTERNAL_BUFFER 0
+
+#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) readFromSocket(_ptrData, _size, _ptrBytesRead)
+
+#if (TRC_STREAM_PORT_USE_INTERNAL_BUFFER == 1)
+ #define TRC_STREAM_PORT_WRITE_DATA(_ptrData, _size, _ptrBytesWritten) writeToSocket(_ptrData, _size, _ptrBytesWritten)
+#else
+ /* In the direct mode, _ptrBytesWritten is not used, so it is assumed that "all or nothing" is written. */
+ #define TRC_STREAM_PORT_WRITE_DATA(_ptrData, _size, UNUSED) writeToSocket(_ptrData, _size, NULL)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TRC_STREAMING_PORT_H */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP_Win32/trcStreamingPort.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP_Win32/trcStreamingPort.c
new file mode 100644
index 000000000..d6eb0e3b7
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP_Win32/trcStreamingPort.c
@@ -0,0 +1,210 @@
+/*******************************************************************************
+ * Trace Recorder Library for Tracealyzer v4.3.11
+ * Percepio AB, www.percepio.com
+ *
+ * trcStreamingPort.c
+ *
+ * Supporting functions for trace streaming, used by the "stream ports"
+ * for reading and writing data to the interface.
+ * Existing ports can easily be modified to fit another setup, e.g., a
+ * different TCP/IP stack, or to define your own stream port.
+ *
+ * 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
+ ******************************************************************************/
+
+#include<stdio.h>
+#include<winsock2.h>
+
+#include "trcRecorder.h"
+
+#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
+#if (TRC_USE_TRACEALYZER_RECORDER == 1)
+
+
+#pragma comment(lib,"ws2_32.lib") //Winsock Library
+
+SOCKET server_socket = (UINT_PTR)NULL, trace_socket = (UINT_PTR)NULL;
+struct sockaddr_in server, client;
+
+int initServerSocketIfNeeded(void);
+int initWinsockIfNeeded(void);
+
+int initWinsockIfNeeded(void)
+{
+ WSADATA wsa;
+
+ if (server_socket)
+ return 0;
+
+ if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
+ {
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int initServerSocketIfNeeded(void)
+{
+ if (initWinsockIfNeeded() < 0)
+ {
+ return -1;
+ }
+
+ if (server_socket)
+ return 0;
+
+ if ((server_socket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
+ {
+ return -1;
+ }
+
+ server.sin_family = AF_INET;
+ server.sin_addr.s_addr = INADDR_ANY;
+ server.sin_port = htons(8888);
+
+ if (bind(server_socket, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
+ {
+ closesocket(server_socket);
+ WSACleanup();
+ server_socket = (UINT_PTR)NULL;
+ return -1;
+ }
+
+ if (listen(server_socket, 3) < 0)
+ {
+ closesocket(server_socket);
+ WSACleanup();
+ server_socket = (UINT_PTR)NULL;
+ return -1;
+ }
+
+ return 0;
+}
+
+int initTraceSocketIfNeeded(void)
+{
+ int c;
+
+ if (!server_socket)
+ return -1;
+
+ if (trace_socket)
+ return 0;
+
+ c = sizeof(struct sockaddr_in);
+ trace_socket = accept(server_socket, (struct sockaddr *)&client, &c);
+ if (trace_socket == INVALID_SOCKET)
+ {
+ trace_socket = (UINT_PTR)NULL;
+
+ closesocket(server_socket);
+ WSACleanup();
+ server_socket = (UINT_PTR)NULL;
+
+ return -1;
+ }
+
+ return 0;
+}
+
+int32_t writeToSocket(void* data, uint32_t size, int32_t *ptrBytesWritten)
+{
+ int ret;
+
+ if (!trace_socket)
+ {
+ if (ptrBytesWritten != NULL)
+ {
+ *ptrBytesWritten = 0;
+ }
+ return -1;
+ }
+ ret = send(trace_socket, data, size, 0);
+ if (ret <= 0)
+ {
+ if (ptrBytesWritten != NULL)
+ {
+ *ptrBytesWritten = 0;
+ }
+
+ closesocket(trace_socket);
+ trace_socket = (UINT_PTR)NULL;
+ return ret;
+ }
+
+ if (ptrBytesWritten != NULL)
+ {
+ *ptrBytesWritten = ret;
+ }
+
+ return 0;
+}
+
+int32_t readFromSocket(void* data, uint32_t bufsize, int32_t *ptrBytesRead)
+{
+ unsigned long bytesAvailable = 0;
+
+ if (initServerSocketIfNeeded() < 0)
+ return -1;
+
+ if (initTraceSocketIfNeeded() < 0)
+ return -1;
+
+ if (ioctlsocket(trace_socket, FIONREAD, &bytesAvailable) != NO_ERROR)
+ {
+ closesocket(trace_socket);
+ trace_socket = (UINT_PTR)NULL;
+ return -1;
+ }
+
+ if (bytesAvailable > 0)
+ {
+ *ptrBytesRead = recv(trace_socket, data, bufsize, 0);
+ if (*ptrBytesRead == SOCKET_ERROR)
+ {
+ closesocket(trace_socket);
+ trace_socket = (UINT_PTR)NULL;
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/
+#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/USB_CDC/Readme-Streamport.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/USB_CDC/Readme-Streamport.txt
index 260f12ace..a23151805 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/USB_CDC/Readme-Streamport.txt
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/USB_CDC/Readme-Streamport.txt
@@ -1,27 +1,27 @@
-Tracealyzer Stream Port for USB CDC (STM32 example)
----------------------------------------------------
-
-This directory contains a "stream port" for the Tracealyzer recorder library,
-i.e., the specific code needed to use a particular interface for streaming a
-Tracealyzer RTOS trace. The stream port is defined by a set of macros in
-trcStreamingPort.h, found in the "include" directory.
-
-This particular stream port targets USB CDC. This is an example for the STM32 USB
-stack (from the STM32CubeMX code generation tool, v1.4.1) and has been tested on
-a STM32F767ZI device on a Nucleo board. See this blog post:
-
-http://percepio.com/2017/02/03/usb-trace-streaming-st-nucleo-f767zi-board/
-
-However, it should be straight-forward to modify this for other USB stacks.
-
-To use this stream port, make sure that include/trcStreamingPort.h is found
-by the compiler (i.e., add this folder to your project's include paths) and
-add all included source files to your build. Make sure no other versions of
-trcStreamingPort.h are included by mistake!
-
-Note that the USB stack not included, but assumed to exist in the project already.
-
-See also http://percepio.com/2016/10/05/rtos-tracing.
-
-Percepio AB
+Tracealyzer Stream Port for USB CDC (STM32 example)
+---------------------------------------------------
+
+This directory contains a "stream port" for the Tracealyzer recorder library,
+i.e., the specific code needed to use a particular interface for streaming a
+Tracealyzer RTOS trace. The stream port is defined by a set of macros in
+trcStreamingPort.h, found in the "include" directory.
+
+This particular stream port targets USB CDC. This is an example for the STM32 USB
+stack (from the STM32CubeMX code generation tool, v1.4.1) and has been tested on
+a STM32F767ZI device on a Nucleo board. See this blog post:
+
+http://percepio.com/2017/02/03/usb-trace-streaming-st-nucleo-f767zi-board/
+
+However, it should be straight-forward to modify this for other USB stacks.
+
+To use this stream port, make sure that include/trcStreamingPort.h is found
+by the compiler (i.e., add this folder to your project's include paths) and
+add all included source files to your build. Make sure no other versions of
+trcStreamingPort.h are included by mistake!
+
+Note that the USB stack not included, but assumed to exist in the project already.
+
+See also http://percepio.com/2016/10/05/rtos-tracing.
+
+Percepio AB
www.percepio.com \ No newline at end of file
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/USB_CDC/include/trcStreamingPort.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/USB_CDC/include/trcStreamingPort.h
index 6940b4d6d..082eebf51 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/USB_CDC/include/trcStreamingPort.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/USB_CDC/include/trcStreamingPort.h
@@ -1,83 +1,83 @@
-/*******************************************************************************
- * Trace Recorder Library for Tracealyzer v4.1.5
- * Percepio AB, www.percepio.com
- *
- * trcStreamingPort.h
- *
- * The interface definitions for trace streaming ("stream ports").
- * This "stream port" sets up the recorder to use USB CDC as streaming channel.
- * The example is for STM32 using STM32Cube.
- *
- * 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_STREAMING_PORT_H
-#define TRC_STREAMING_PORT_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Include files as needed, in this case it is files from STM32Cube FW_F7 V1.4.1 */
-#include "usb_device.h"
-#include "usbd_cdc.h"
-#include "usbd_CDC_if.h"
-#include "usb_device.h"
-
-/* Tested on STM32 devices using Keil/CMSIS USB stack */
-
-extern USBD_CDC_ItfTypeDef USBD_Interface_fops_FS;
-
-uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len);
-
-int32_t trcCDCReceive(void *data, uint32_t size, int32_t* NumBytes);
-
-int32_t trcCDCTransmit(void* data, uint32_t size, int32_t * noOfBytesSent );
-
-#define TRC_STREAM_PORT_INIT() \
- MX_USB_DEVICE_Init(); \
- TRC_STREAM_PORT_MALLOC(); /*Dynamic allocation or empty if static */
-
-#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) trcCDCReceive(_ptrData, _size, _ptrBytesRead)
-
-#define TRC_STREAM_PORT_WRITE_DATA(_ptrData, _size, _ptrBytesSent) trcCDCTransmit(_ptrData, _size, _ptrBytesSent)
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* TRC_STREAMING_PORT_H */
+/*******************************************************************************
+ * Trace Recorder Library for Tracealyzer v4.3.11
+ * Percepio AB, www.percepio.com
+ *
+ * trcStreamingPort.h
+ *
+ * The interface definitions for trace streaming ("stream ports").
+ * This "stream port" sets up the recorder to use USB CDC as streaming channel.
+ * The example is for STM32 using STM32Cube.
+ *
+ * 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_STREAMING_PORT_H
+#define TRC_STREAMING_PORT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Include files as needed, in this case it is files from STM32Cube FW_F7 V1.4.1 */
+#include "usb_device.h"
+#include "usbd_cdc.h"
+#include "usbd_CDC_if.h"
+#include "usb_device.h"
+
+/* Tested on STM32 devices using Keil/CMSIS USB stack */
+
+extern USBD_CDC_ItfTypeDef USBD_Interface_fops_FS;
+
+uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len);
+
+int32_t trcCDCReceive(void *data, uint32_t size, int32_t* NumBytes);
+
+int32_t trcCDCTransmit(void* data, uint32_t size, int32_t * noOfBytesSent );
+
+#define TRC_STREAM_PORT_INIT() \
+ MX_USB_DEVICE_Init(); \
+ TRC_STREAM_PORT_MALLOC(); /*Dynamic allocation or empty if static */
+
+#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) trcCDCReceive(_ptrData, _size, _ptrBytesRead)
+
+#define TRC_STREAM_PORT_WRITE_DATA(_ptrData, _size, _ptrBytesSent) trcCDCTransmit(_ptrData, _size, _ptrBytesSent)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TRC_STREAMING_PORT_H */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/USB_CDC/trcStreamingPort.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/USB_CDC/trcStreamingPort.c
index 800022a1b..351d83325 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/USB_CDC/trcStreamingPort.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/USB_CDC/trcStreamingPort.c
@@ -1,246 +1,291 @@
-
-#include "trcRecorder.h"
-
-#if (TRC_USE_TRACEALYZER_RECORDER == 1)
-#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
-
-#include "stdint.h"
-
-/* Include files as needed, in this case it is files from STM32Cube FW_F7 V1.4.1 */
-#include "usb_device.h"
-#include "usbd_cdc.h"
-#include "usbd_CDC_if.h"
-#include "usb_device.h"
-
-#define BUFSIZE 64
-
-typedef struct{
- uint32_t idx;
- uint8_t data[BUFSIZE];
-}recBuf;
-
-/* Define size for the receive and transmit buffer over CDC */
-#define APP_RX_DATA_SIZE 8
-#define APP_TX_DATA_SIZE 64
-
-/* Received Data over USB are stored in this buffer */
-uint8_t UserRxBufferFS[APP_RX_DATA_SIZE];
-
-/* Send Data over USB CDC are stored in this buffer */
-uint8_t UserTxBufferFS[APP_TX_DATA_SIZE];
-
-extern USBD_HandleTypeDef hUsbDeviceFS;
-
-extern PCD_HandleTypeDef hpcd_USB_OTG_FS;
-
-recBuf commandBuffer;
-
-static int8_t CDC_Init_FS (void);
-static int8_t CDC_DeInit_FS (void);
-static int8_t CDC_Control_FS (uint8_t cmd, uint8_t* pbuf, uint16_t length);
-static int8_t CDC_Receive_FS (uint8_t* pbuf, uint32_t *Len);
-
-USBD_CDC_ItfTypeDef USBD_Interface_fops_FS =
-{
- CDC_Init_FS,
- CDC_DeInit_FS,
- CDC_Control_FS,
- CDC_Receive_FS
-};
-
-/* Private functions ---------------------------------------------------------*/
-/**
- * @brief CDC_Init_FS
- * Initializes the CDC media low layer over the FS USB IP
- * @param None
- * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
- */
-static int8_t CDC_Init_FS(void)
-{
- /* Set Application Buffers */
- USBD_CDC_SetTxBuffer(&hUsbDeviceFS, UserTxBufferFS, 0);
- USBD_CDC_SetRxBuffer(&hUsbDeviceFS, UserRxBufferFS);
- return (USBD_OK);
-}
-
-/**
- * @brief CDC_DeInit_FS
- * DeInitializes the CDC media low layer
- * @param None
- * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
- */
-static int8_t CDC_DeInit_FS(void)
-{
- return (USBD_OK);
-}
-
-/**
- * @brief CDC_Control_FS
- * Manage the CDC class requests
- * @param cmd: Command code
- * @param pbuf: Buffer containing command data (request parameters)
- * @param length: Number of data to be sent (in bytes)
- * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
- */
-static int8_t CDC_Control_FS (uint8_t cmd, uint8_t* pbuf, uint16_t length)
-{
- switch (cmd)
- {
- case CDC_SEND_ENCAPSULATED_COMMAND:
- break;
-
- case CDC_GET_ENCAPSULATED_RESPONSE:
- break;
-
- case CDC_SET_COMM_FEATURE:
- break;
-
- case CDC_GET_COMM_FEATURE:
- break;
-
- case CDC_CLEAR_COMM_FEATURE:
- break;
-
- /*******************************************************************************/
- /* Line Coding Structure */
- /*-----------------------------------------------------------------------------*/
- /* Offset | Field | Size | Value | Description */
- /* 0 | dwDTERate | 4 | Number |Data terminal rate, in bits per second*/
- /* 4 | bCharFormat | 1 | Number | Stop bits */
- /* 0 - 1 Stop bit */
- /* 1 - 1.5 Stop bits */
- /* 2 - 2 Stop bits */
- /* 5 | bParityType | 1 | Number | Parity */
- /* 0 - None */
- /* 1 - Odd */
- /* 2 - Even */
- /* 3 - Mark */
- /* 4 - Space */
- /* 6 | bDataBits | 1 | Number Data bits (5, 6, 7, 8 or 16). */
- /*******************************************************************************/
- case CDC_SET_LINE_CODING:
- break;
-
- case CDC_GET_LINE_CODING:
- break;
-
- case CDC_SET_CONTROL_LINE_STATE:
- break;
-
- case CDC_SEND_BREAK:
- break;
-
- default:
- break;
- }
- return (USBD_OK);
-}
-
-/**
- * @brief CDC_Receive_FS
- * Data received over USB OUT endpoint are sent over CDC interface
- * through this function.
- *
- * @note
- * This function will block any OUT packet reception on USB endpoint
- * until exiting this function. If you exit this function before transfer
- * is complete on CDC interface (i.e. using DMA controller) it will result
- * in receiving more data while previous ones are still not sent.
- *
- * @param Buf: Buffer of data to be received
- * @param Len: Number of data received (in bytes)
- * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
- */
-static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len)
-{
- for( uint32_t i=0;i<* Len;i++)
- {
- commandBuffer.data[commandBuffer.idx]=Buf[i];
- commandBuffer.idx++;
- }
- USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
- USBD_CDC_ReceivePacket(&hUsbDeviceFS);
-
- return (USBD_OK);
-}
-
-/**
- * @brief CDC_Transmit_FS
- * Data send over USB IN endpoint are sent over CDC interface
- * through this function.
- * @note
- *
- *
- * @param Buf: Buffer of data to be send
- * @param Len: Number of data to be send (in bytes)
- * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL or USBD_BUSY
- */
-uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
-{
- uint8_t result = USBD_OK;
- USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData;
- if (hcdc->TxState != 0){
- return USBD_BUSY;
- }
- USBD_CDC_SetTxBuffer(&hUsbDeviceFS, Buf, Len);
- result = USBD_CDC_TransmitPacket(&hUsbDeviceFS);
- return result;
-}
-
-/* The READ function, used in trcStreamingPort.h */
-int32_t trcCDCReceive(void *data, uint32_t size, int32_t* NumBytes)
-{
- uint32_t i,diff;
-
- if(commandBuffer.idx>0)
- {
- if (size >= commandBuffer.idx) // more than what is stored, number of bytes will be .idx
- {
- memcpy(data,commandBuffer.data, commandBuffer.idx);
- *NumBytes=commandBuffer.idx;
- commandBuffer.idx=0; // Make the buffer ready for a new command
- }
- else //If some data in the buffer is not read
- {
- diff = commandBuffer.idx-size;
- memcpy(data,commandBuffer.data, size);
- for(i=0;i<diff;i++)
- {
- commandBuffer.data[i]=commandBuffer.data[i+size];
- }
- *NumBytes=size;
- commandBuffer.idx=diff;
- }
- }
- else
- {
- *NumBytes=0;
- }
- return 0;
-}
-
-/* The WRITE function, used in trcStreamingPort.h */
-int32_t trcCDCTransmit(void* data, uint32_t size, int32_t * noOfBytesSent )
-{
- int32_t result;
- result=CDC_Transmit_FS(data, size);
- *noOfBytesSent = size;
-
- /* Return value should be 0 on success (not sure what the value of USBD_OK is) */
- if (result == USBD_OK)
- return 0;
- else
- return -1;
-}
-
-/**
-* @brief This function handles USB On The Go FS global interrupt.
-*/
-void OTG_FS_IRQHandler(void)
-{
- HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS);
-}
-
-#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/
-#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/
-
+/*******************************************************************************
+ * Trace Recorder Library for Tracealyzer v4.3.11
+ * Percepio AB, www.percepio.com
+ *
+ * trcStreamingPort.c
+ *
+ * Supporting functions for trace streaming ("stream ports").
+ * This "stream port" sets up the recorder to use USB CDC as streaming channel.
+ * The example is for STM32 using STM32Cube.
+ *
+ * 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
+ ******************************************************************************/
+
+#include "trcRecorder.h"
+
+#if (TRC_USE_TRACEALYZER_RECORDER == 1)
+#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
+
+#include "stdint.h"
+
+/* Include files as needed, in this case it is files from STM32Cube FW_F7 V1.4.1 */
+#include "usb_device.h"
+#include "usbd_cdc.h"
+#include "usbd_CDC_if.h"
+#include "usb_device.h"
+
+#define BUFSIZE 64
+
+typedef struct{
+ uint32_t idx;
+ uint8_t data[BUFSIZE];
+}recBuf;
+
+/* Define size for the receive and transmit buffer over CDC */
+#define APP_RX_DATA_SIZE 8
+#define APP_TX_DATA_SIZE 64
+
+/* Received Data over USB are stored in this buffer */
+uint8_t UserRxBufferFS[APP_RX_DATA_SIZE];
+
+/* Send Data over USB CDC are stored in this buffer */
+uint8_t UserTxBufferFS[APP_TX_DATA_SIZE];
+
+extern USBD_HandleTypeDef hUsbDeviceFS;
+
+extern PCD_HandleTypeDef hpcd_USB_OTG_FS;
+
+recBuf commandBuffer;
+
+static int8_t CDC_Init_FS (void);
+static int8_t CDC_DeInit_FS (void);
+static int8_t CDC_Control_FS (uint8_t cmd, uint8_t* pbuf, uint16_t length);
+static int8_t CDC_Receive_FS (uint8_t* pbuf, uint32_t *Len);
+
+USBD_CDC_ItfTypeDef USBD_Interface_fops_FS =
+{
+ CDC_Init_FS,
+ CDC_DeInit_FS,
+ CDC_Control_FS,
+ CDC_Receive_FS
+};
+
+/* Private functions ---------------------------------------------------------*/
+/**
+ * @brief CDC_Init_FS
+ * Initializes the CDC media low layer over the FS USB IP
+ * @param None
+ * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t CDC_Init_FS(void)
+{
+ /* Set Application Buffers */
+ USBD_CDC_SetTxBuffer(&hUsbDeviceFS, UserTxBufferFS, 0);
+ USBD_CDC_SetRxBuffer(&hUsbDeviceFS, UserRxBufferFS);
+ return (USBD_OK);
+}
+
+/**
+ * @brief CDC_DeInit_FS
+ * DeInitializes the CDC media low layer
+ * @param None
+ * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t CDC_DeInit_FS(void)
+{
+ return (USBD_OK);
+}
+
+/**
+ * @brief CDC_Control_FS
+ * Manage the CDC class requests
+ * @param cmd: Command code
+ * @param pbuf: Buffer containing command data (request parameters)
+ * @param length: Number of data to be sent (in bytes)
+ * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t CDC_Control_FS (uint8_t cmd, uint8_t* pbuf, uint16_t length)
+{
+ switch (cmd)
+ {
+ case CDC_SEND_ENCAPSULATED_COMMAND:
+ break;
+
+ case CDC_GET_ENCAPSULATED_RESPONSE:
+ break;
+
+ case CDC_SET_COMM_FEATURE:
+ break;
+
+ case CDC_GET_COMM_FEATURE:
+ break;
+
+ case CDC_CLEAR_COMM_FEATURE:
+ break;
+
+ /*******************************************************************************/
+ /* Line Coding Structure */
+ /*-----------------------------------------------------------------------------*/
+ /* Offset | Field | Size | Value | Description */
+ /* 0 | dwDTERate | 4 | Number |Data terminal rate, in bits per second*/
+ /* 4 | bCharFormat | 1 | Number | Stop bits */
+ /* 0 - 1 Stop bit */
+ /* 1 - 1.5 Stop bits */
+ /* 2 - 2 Stop bits */
+ /* 5 | bParityType | 1 | Number | Parity */
+ /* 0 - None */
+ /* 1 - Odd */
+ /* 2 - Even */
+ /* 3 - Mark */
+ /* 4 - Space */
+ /* 6 | bDataBits | 1 | Number Data bits (5, 6, 7, 8 or 16). */
+ /*******************************************************************************/
+ case CDC_SET_LINE_CODING:
+ break;
+
+ case CDC_GET_LINE_CODING:
+ break;
+
+ case CDC_SET_CONTROL_LINE_STATE:
+ break;
+
+ case CDC_SEND_BREAK:
+ break;
+
+ default:
+ break;
+ }
+ return (USBD_OK);
+}
+
+/**
+ * @brief CDC_Receive_FS
+ * Data received over USB OUT endpoint are sent over CDC interface
+ * through this function.
+ *
+ * @note
+ * This function will block any OUT packet reception on USB endpoint
+ * until exiting this function. If you exit this function before transfer
+ * is complete on CDC interface (i.e. using DMA controller) it will result
+ * in receiving more data while previous ones are still not sent.
+ *
+ * @param Buf: Buffer of data to be received
+ * @param Len: Number of data received (in bytes)
+ * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len)
+{
+ for( uint32_t i=0;i<* Len;i++)
+ {
+ commandBuffer.data[commandBuffer.idx]=Buf[i];
+ commandBuffer.idx++;
+ }
+ USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
+ USBD_CDC_ReceivePacket(&hUsbDeviceFS);
+
+ return (USBD_OK);
+}
+
+/**
+ * @brief CDC_Transmit_FS
+ * Data send over USB IN endpoint are sent over CDC interface
+ * through this function.
+ * @note
+ *
+ *
+ * @param Buf: Buffer of data to be send
+ * @param Len: Number of data to be send (in bytes)
+ * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL or USBD_BUSY
+ */
+uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
+{
+ uint8_t result = USBD_OK;
+ USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData;
+ if (hcdc->TxState != 0){
+ return USBD_BUSY;
+ }
+ USBD_CDC_SetTxBuffer(&hUsbDeviceFS, Buf, Len);
+ result = USBD_CDC_TransmitPacket(&hUsbDeviceFS);
+ return result;
+}
+
+/* The READ function, used in trcStreamingPort.h */
+int32_t trcCDCReceive(void *data, uint32_t size, int32_t* NumBytes)
+{
+ uint32_t i,diff;
+
+ if(commandBuffer.idx>0)
+ {
+ if (size >= commandBuffer.idx) // more than what is stored, number of bytes will be .idx
+ {
+ memcpy(data,commandBuffer.data, commandBuffer.idx);
+ *NumBytes=commandBuffer.idx;
+ commandBuffer.idx=0; // Make the buffer ready for a new command
+ }
+ else //If some data in the buffer is not read
+ {
+ diff = commandBuffer.idx-size;
+ memcpy(data,commandBuffer.data, size);
+ for(i=0;i<diff;i++)
+ {
+ commandBuffer.data[i]=commandBuffer.data[i+size];
+ }
+ *NumBytes=size;
+ commandBuffer.idx=diff;
+ }
+ }
+ else
+ {
+ *NumBytes=0;
+ }
+ return 0;
+}
+
+/* The WRITE function, used in trcStreamingPort.h */
+int32_t trcCDCTransmit(void* data, uint32_t size, int32_t * noOfBytesSent )
+{
+ int32_t result;
+ result=CDC_Transmit_FS(data, size);
+ *noOfBytesSent = size;
+
+ /* Return value should be 0 on success (not sure what the value of USBD_OK is) */
+ if (result == USBD_OK)
+ return 0;
+ else
+ return -1;
+}
+
+/**
+* @brief This function handles USB On The Go FS global interrupt.
+*/
+void OTG_FS_IRQHandler(void)
+{
+ HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS);
+}
+
+#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/
+#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/tracealyzer_readme.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/tracealyzer_readme.txt
index 09daa78f4..c707f1e0e 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/tracealyzer_readme.txt
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/tracealyzer_readme.txt
@@ -1,337 +1,413 @@
--------------------------------------------------------------------------------
- Tracealyzer Recorder Library for FreeRTOS
--------------------------------------------------------------------------------
-
-Tracealyzer is a sophisticated tool for tracing and visualization
-of FreeRTOS-based software systems.
-
-Tracealyzer gives an unprecedented insight into the runtime behavior, which
-speeds up debugging, validation and optimization.
-
-This, the Trace Recorder Library, is the target-side part of Tracealyzer, that
-performs the actual tracing. The resulting data can then be viewed in the
-Tracealyzer PC application, found at https://percepio.com/tracealyzer
-
-To learn more, see these links.
-
- - Getting Started (videos etc): https://percepio.com/gettingstarted
-
- - FAQ: https://percepio.com/category/faq
-
-In case you have any questions, don't hesitate to contact support@percepio.com
-
-Tracealyzer supports FreeRTOS v7.3 and newer, including Amazon FreeRTOS.
-
--------------------------------------------------------------------------------
-Changes, v4.1.4 -> v4.1.5
-
-- Fixed a bug in the ITM stream port, that required Port 0 to be enabled.
-- Added missing include of stdio.h (needed by vTraceConsoleChannelPrintF).
-- Moved standard includes from trcRecorder.h into the .c files needing them.
-
--------------------------------------------------------------------------------
-
-Changes, v4.1.2 -> v4.1.4
-
-- Fixed a compile error when certain FreeRTOS settings were used
-- Disabled filter support for FreeRTOS v7.3 since it uses "char" for object id
-
--------------------------------------------------------------------------------
-
-Changes, v4.1.0 -> v4.1.2
-
-- Added vTraceConsoleChannelPrintF(...)
-
--------------------------------------------------------------------------------
-
-Changes, v4.0.3 -> v4.1.0
-
-- Improved performance of User Events
-- Fixed handling of format strings ending with '%'
-- Improved handling of creative user configuration macros
-
--------------------------------------------------------------------------------
-
-Changes, v4.0.2 -> v4.0.3
-
-- Minor fix for TCP/IP stream port.
-- Corrected default RTT mode setting.
-
--------------------------------------------------------------------------------
-
-Changes, v4.0.1 -> v4.0.2
-
-- Memory allocation trace events now ignore filters.
-
--------------------------------------------------------------------------------
-
-Changes, v4.0.0 -> v4.0.1
-
-- Minor fixes to default values.
-
--------------------------------------------------------------------------------
-
-Changes, v3.3.0 -> v4.0.0
-
-- Fixed some issues with filters.
-
--------------------------------------------------------------------------------
-
-Changes, v3.2.0 -> v3.3.0
-
-- Added support for FreeRTOS v10, including the new object types Message Buffer
- and Stream Buffer.
-
-- Improved the object-level filtering to also support Timer, Event Group,
- Message Buffer and Stream Buffer objects.
-
-- Fixed a few remaining build problems with older FreeRTOS versions (v7.x).
-
-- vTraceStoreISRBegin now reports an error on invalid handles, i.e., if the
- initialization of the handle (xTraceSetISRProperties) had not been made.
-
--------------------------------------------------------------------------------
-
-Changes, v3.1.2 -> v3.2.0
-
-- Added new filtering system - that works in both snapshot and streaming mode.
- Filtering was previously not supported in streaming mode, but can be very
- useful for slower streaming interfaces. By exluding irrelevant events, the
- amount of data produced can be reduced a lot.
-
- * New functions vTraceSetFilterGroup and vTraceSetFilterMask allows for
- excluding all events from specific objects (like a semaphore or queue).
-
- * Added new "generic" filters (preprocessor level) to trcConfig.h, that
- exclude all events of a particular types.
- - TRC_CFG_INCLUDE_NOTIFY_EVENTS
- - TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS
- - TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS
- - TRC_CFG_INCLUDE_TIMER_EVENTS
-
- * Upgraded some previous filters from "Snapshot only" to the Common API
- and thereby moved them from trcSnapshotConfig.h to trcConfig.h.
- - TRC_CFG_SCHEDULING_ONLY
- - TRC_CFG_INCLUDE_MEMMANG_EVENTS
- - TRC_CFG_INCLUDE_USER_EVENTS
- - TRC_CFG_INCLUDE_ISR_TRACING
- - TRC_CFG_INCLUDE_READY_EVENTS
- - TRC_CFG_INCLUDE_OSTICK_EVENTS
-
- * Removed the old filter system from trcSnapshotRecorder.c.
-
-- Improved streaming interface - Now only two (2) macros are needed to be
- defined in most cases, read and write. This makes it a lot easier to make
- custom stream ports.
-
- * Many definitions that were identical in most stream ports, have been
- replaced by default definitions in the recorder core. If needed, they
- can be overriden by custom definitions in trcStreamingPort.h.
-
- * Stream ports are now assumed to use recorder's internal event buffer.
- Other stream ports that writes directly to the streaming interface
- (like J-Link) should define TRC_STREAM_PORT_USE_INTERNAL_BUFFER
- as zero (0) to make it work correctly.
-
- * Macro TRC_STREAM_PORT_PERIODIC_SEND_DATA has been replaced by
- TRC_STREAM_PORT_WRITE_DATA. Together with TRC_STREAM_PORT_READ_DATA,
- this is all that is necessary for a typical stream port.
-
- * Return values from the stream port macros READ_DATA and WRITE_DATA are
- now checked. Expects 0 on success, anything else produces a warning
- that can be retrived using xTraceGetLastError() and also seen in
- Tracealyzer if a trace was produced.
-
- * Stream ports should no longer call prvPagedEventBufferInit explicitly
- (e.g. in TRC_STREAM_PORT_ON_TRACE_BEGIN). This is now called
- automatically if TRC_STREAM_PORT_USE_INTERNAL_BUFFER == 1.
-
- * Macros TRC_STREAM_PORT_ON_TRACE_BEGIN and TRC_STREAM_PORT_ON_TRACE_END
- are now unused by default and don't need to be defined.
- You can however use them to hook in some own function at these events.
-
-- Added two new stream ports
-
- * TCPIP-Win32: allows for testing the streaming on Windows ports of your
- RTOS, using Winsock.
-
- * File: example of streaming to a local file system (tested on Windows,
- but easy to modify).
-
-- Added support for FreeRTOS v9.0.1
-
- * Replaced FreeRTOS version code TRC_FREERTOS_VERSION_9_X with
- - TRC_FREERTOS_VERSION_9_0_0
- - TRC_FREERTOS_VERSION_9_0_1
-
- * Using TRC_FREERTOS_VERSION_9_X is no longer allowed.
-
-- Added additional events for xQueuePeek, for blocking and timeouts events.
-
-- Added event for traceTIMER_EXPIRED, showing when the timer callback
- function is called.
-
-- Improved diagnostics in streaming mode, in case of errors in the recorder.
-
- * Added prvTraceWarning() - registers a "warning" error code, without
- stopping the recorder. Called if READ_DATA or WRITE_DATA returns a
- non-zero value, and in several other cases where the recorder
- configuration is incorrect (e.g., too small symbol table).
-
- * Added several new warning codes (PSF_WARNING_XYZ), corresponding to the
- issues detected by prvCheckRecorderStatus.
-
- * Fixed duplicate definitions of warning messages, so the warnings reported
- to Tracealyzer are the same as those provided in xTraceGetLastError().
-
- * Added better explainations of warning/error messages in the body of
- xTraceGetLastError (in streaming mode).
-
-- Added xTraceIsRecordingEnabled() to Common API.
-
-- Added "unofficial" hardware port for Altera Nios-II.
- This is a user contribition, not yet verified by Percerpio.
-
-- Fixed bug in vTraceEnable - option TRC_START_AWAIT_HOST was ignored if already initialized.
-
-- Fixed a few remaining compiler warnings.
-
-- Changed order of some settings in trcConfig.h - moved advanced stuff to the
- bottom.
-
-- Removed SEGGER_RTT_Printf.c from the J-Link stream port since not required
- for Tracealyzer.
-
--------------------------------------------------------------------------------
-
-Changes, v3.1.1 -> v3.1.2
-- Fixed two bugs related to User Events, one in vTracePrintF and other in vTracePrint.
-
-- Fixed a build problem related to a single reference of the old FreeRTOS type "xTaskHandle", in trcKernelPort.c.
- Changed to "TaskHandle_t", unless if using an older FreeRTOS kernel or the "compatibility mode".
-
-- Removed traceCREATE_MUTEX hook for FreeRTOS v9 or later (no longer required)
-
-- Updated the User Manual regarding snapshot trace via IAR Embedded Workbench.
-
-- Renamed vTraceGetTraceBuffer to xTraceGetTraceBuffer, since returning a pointer.
-
--------------------------------------------------------------------------------
-
-Changes, v3.1.0 -> v3.1.1
-
-After the major changes in the v3.1.0 trace recorder library, this update
-corrects a number of minor issues. Only minor functional improvements.
-
-- You can now use TRC_ALLOC_CUSTOM_BUFFER to declare a trace buffer on a custom
- location (using linker directives).
- The related function vTraceSetRecorderDataBuffer has been promoted to the
- Common API (previously only supported in snapshot mode, but custom allocation
- is now generally supported also in streaming mode).
-
-- Removed TRC_CFG_USE_LINKER_PRAGMA. No longer necessary thanks to the custom
- allocation mode.
-
-- Added support for timestamping from custom periodic timers, required for
- accurate timestamping on Cortex-M0/M0+ devices when using tickless idle.
- Only for streaming mode so far. See TRC_CUSTOM_TIMER_INCR / DECR.
-
-- ARM Cortex-M port: Made sure the DWT unit is initialized properly, in case
- the debugger doesn't handle this.
-
-- ARM Cortex-M port: Added possibility to use Systick timestamping also on
- Cortex-M3/M4/M7 devices (that otherwise use DWT timestamping by default).
- To use this option, define the macro TRC_CFG_ARM_CM_USE_SYSTICK.
-
-- J-Link streaming: The default RTT buffer has been changed from 0 to 1.
-
-- J-Link streaming: The RTT buffer settings for buffer 1 and higher, are now
- found in trcStreamingPort.h. Note: These settings don't apply to buffer 0.
-
-- vTracePrint has been optimized for better performance in string logging.
-
-- Minor performance improvement related to symbol table transfer in streaming mode.
-
-- Timer names now registered also in streaming mode.
-
-- Timer start and stop event are now traced.
-
-- Implemented support for queue registry (traceQUEUE_REGISTRY_ADD) also for streaming.
-
-- Fixed a bug related to repeated calls of vTraceEnable.
-
-- Fixed a bug where task-switches seemed to occur even though the scheduler was disabled.
-
-- Renamed HARDWARE_PORT_TEXAS_INSTRUMENTS_TMS570_RM48, added prefix TRC.
-
-- Fixed several language issues in the comments and documentation.
-
-- Fixed several minor issues and warnings from different compilers
- (including PowerPC/gcc) and configurations.
-
--------------------------------------------------------------------------------
-
-Changes, v3.0.9 -> v3.1.0
-
-- Merge of previously separated snapshot and streaming recorders into a single
- recorder supporting both streaming and snapshot as different modes.
-
-- New common API for supporting both streaming and snapshot modes.
-
-- New integration guide, see the User Manual.
-
-- Major improvement of API documentation in source files and User Manual.
-
-- New concept of "stream ports", giving a better structure defining streaming
- interfaces, and restructured the J-Link and TCP/IP streaming as stream ports.
-
-- Added a stream port for USB CDC connections, with STM32 as example.
- Since Tracealyzer now can receive serial data on Windows COM ports, this is
- really easy to use.
-
-- Added a warning (#error) for cases where FreeRTOS tickless idle mode is used
- together with timestamping using SysTick or other periodic interrupt timers,
- Tracing with tickless idle requires an independent time source to correctly
- capture the length of the idle periods.
-
-- Major changes in the recorder API. Important examples are:
-
- * Some configuration macros have changed names, e.g. for "hardware port".
- Make sure to remove any old "trcConfig.h" files if upgrading from an
- earlier version!
-
- * Recorder configuration in trcConfig.h has been minimized and now only
- includes the important settings that are independent of recorder mode.
- Advanced settings for each mode are found in trcSnapshotConfig.h and
- trcStreamingConfig.h.
-
- * vTraceEnable replaces Trace_Init and vTraceInitTraceData, as well as
- vTraceStart and uiTraceStart.
-
- * vTraceStop now part of the common API and thereby available also in
- streaming. And since vTraceEnable can start the streaming directly
- you have the option control the tracing from target, e.g., for
- streaming to a device file system.
-
- * vTraceStoreKernelObjectName from old streaming recorder has been replaced
- by vTraceSetQueueName, vTraceSetSemaphoreName, etc.
-
- * vTraceSetISRProperties now returns a "traceHandle" that should be passed as
- parameter to vTraceStoreISRBegin and vTraceStoreISREnd.
-
- * xTraceRegisterString has replaced the old functions xTraceOpenLabel and
- vTraceStoreUserEventChannelName. This now returns a "traceString" for use
- as "channel" parameter in vTracePrintF, and in other places where strings
- are stored.
-
- * Removed vTraceStoreISREndManual and vTraceStoreISREndAuto, use
- vTraceStoreISREnd instead.
-
- * Renamed the functions for saving User Events in a separate buffer:
- - xTraceRegisterChannelFormat -> xTraceRegisterUBChannel
- - vTraceChannelPrintF -> vTraceUBData
- - vTraceChannelUserEvent -> vTraceUBEvent
-
-
--------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+ Tracealyzer Recorder Library for FreeRTOS
+-------------------------------------------------------------------------------
+
+Tracealyzer is a sophisticated tool for tracing and visualization
+of FreeRTOS-based software systems.
+
+Tracealyzer gives an unprecedented insight into the runtime behavior, which
+speeds up debugging, validation and optimization.
+
+This, the Trace Recorder Library, is the target-side part of Tracealyzer, that
+performs the actual tracing. The resulting data can then be viewed in the
+Tracealyzer PC application, found at https://percepio.com/tracealyzer
+
+To learn more, see these links.
+
+ - Getting Started (videos etc): https://percepio.com/gettingstarted
+
+ - FAQ: https://percepio.com/category/faq
+
+In case you have any questions, don't hesitate to contact support@percepio.com
+
+Tracealyzer supports FreeRTOS v7.3 and newer, including Amazon FreeRTOS.
+
+-------------------------------------------------------------------------------
+
+Changes, v4.3.10 -> v4.3.11
+- Adapted for new Task Notify changes
+
+-------------------------------------------------------------------------------
+
+Changes, v4.3.8 -> v4.3.10
+- Fixed accidental C99 reliance
+
+-------------------------------------------------------------------------------
+
+Changes, v4.3.7 -> v4.3.8
+- Modified how FreeRTOS versions are configured in the trace library.
+- traceQUEUE_SET_SEND() was added.
+- Now informs users of FreeRTOS v10.3.X that the trace point traceQUEUE_SEND in
+ prvNotifyQueueSetContainer() should be changed to traceQUEUE_SET_SEND.
+
+-------------------------------------------------------------------------------
+
+Changes, v4.3.5 -> v4.3.7
+- Fixed issue where ISR naming would not always work.
+- Fixed "errno" issue with certain compilers when using lwip streaming port.
+- Recorder now makes sure all streaming trace header info is successfully sent
+ before moving on.
+- Recorder warns if TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT > 128 since code
+ isn't designed for that.
+- Made sure uiTraceSystemState is always declared in snapshot recorder.
+
+-------------------------------------------------------------------------------
+
+Changes, v4.3.1 -> v4.3.5
+- A previously removed define is no longer used when configSUPPORT_STATIC_ALLOCATION is 1
+
+-------------------------------------------------------------------------------
+
+Changes, v4.3.0 -> v4.3.1
+- Name string no longer has to have unique address when calling xTraceSetISRProperties()
+
+-------------------------------------------------------------------------------
+
+Changes, v4.2.12 -> v4.3.0
+- Improved Streaming stability in regards to starting/stopping.
+- Added support for STACK usage reports.
+- Added vTraceVPrintF() that accepts a va_list as argument.
+
+-------------------------------------------------------------------------------
+
+Changes, v4.2.2 -> v4.2.12
+
+- Changed a call to vTracePrintF() into vTracePrint().
+
+-------------------------------------------------------------------------------
+
+Changes, v4.2.1 -> v4.2.2
+
+- TRC_STREAM_PORT_WRITE_DATA() no longer has to deal with null pointers. Better
+ for custom StreamPort implementations.
+
+-------------------------------------------------------------------------------
+
+Changes, v4.1.7 -> v4.2.1
+
+- Added support for initial heap usage at trace start in Streaming mode.
+- Fixed bug regarding failed malloc calls in Streaming mode.
+- Added support for tracing failed malloc calls in Snapshot mode.
+- Better way of setting initial task "(startup)" in Streaming mode.
+
+-------------------------------------------------------------------------------
+
+Changes, v4.1.5 -> v4.1.7
+
+- vQueueSendToFront() and vQueueSendToFrontFromISR() are now traced properly in
+ Snaphot mode.
+
+-------------------------------------------------------------------------------
+
+Changes, v4.1.4 -> v4.1.5
+
+- Fixed a bug in the ITM stream port, that required Port 0 to be enabled.
+- Added missing include of stdio.h (needed by vTraceConsoleChannelPrintF).
+- Moved standard includes from trcRecorder.h into the .c files needing them.
+
+-------------------------------------------------------------------------------
+
+Changes, v4.1.2 -> v4.1.4
+
+- Fixed a compile error when certain FreeRTOS settings were used
+- Disabled filter support for FreeRTOS v7.3 since it uses "char" for object id
+
+-------------------------------------------------------------------------------
+
+Changes, v4.1.0 -> v4.1.2
+
+- Added vTraceConsoleChannelPrintF(...)
+
+-------------------------------------------------------------------------------
+
+Changes, v4.0.3 -> v4.1.0
+
+- Improved performance of User Events
+- Fixed handling of format strings ending with '%'
+- Improved handling of creative user configuration macros
+
+-------------------------------------------------------------------------------
+
+Changes, v4.0.2 -> v4.0.3
+
+- Minor fix for TCP/IP stream port.
+- Corrected default RTT mode setting.
+
+-------------------------------------------------------------------------------
+
+Changes, v4.0.1 -> v4.0.2
+
+- Memory allocation trace events now ignore filters.
+
+-------------------------------------------------------------------------------
+
+Changes, v4.0.0 -> v4.0.1
+
+- Minor fixes to default values.
+
+-------------------------------------------------------------------------------
+
+Changes, v3.3.0 -> v4.0.0
+
+- Fixed some issues with filters.
+
+-------------------------------------------------------------------------------
+
+Changes, v3.2.0 -> v3.3.0
+
+- Added support for FreeRTOS v10, including the new object types Message Buffer
+ and Stream Buffer.
+
+- Improved the object-level filtering to also support Timer, Event Group,
+ Message Buffer and Stream Buffer objects.
+
+- Fixed a few remaining build problems with older FreeRTOS versions (v7.x).
+
+- vTraceStoreISRBegin now reports an error on invalid handles, i.e., if the
+ initialization of the handle (xTraceSetISRProperties) had not been made.
+
+-------------------------------------------------------------------------------
+
+Changes, v3.1.2 -> v3.2.0
+
+- Added new filtering system - that works in both snapshot and streaming mode.
+ Filtering was previously not supported in streaming mode, but can be very
+ useful for slower streaming interfaces. By exluding irrelevant events, the
+ amount of data produced can be reduced a lot.
+
+ * New functions vTraceSetFilterGroup and vTraceSetFilterMask allows for
+ excluding all events from specific objects (like a semaphore or queue).
+
+ * Added new "generic" filters (preprocessor level) to trcConfig.h, that
+ exclude all events of a particular types.
+ - TRC_CFG_INCLUDE_NOTIFY_EVENTS
+ - TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS
+ - TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS
+ - TRC_CFG_INCLUDE_TIMER_EVENTS
+
+ * Upgraded some previous filters from "Snapshot only" to the Common API
+ and thereby moved them from trcSnapshotConfig.h to trcConfig.h.
+ - TRC_CFG_SCHEDULING_ONLY
+ - TRC_CFG_INCLUDE_MEMMANG_EVENTS
+ - TRC_CFG_INCLUDE_USER_EVENTS
+ - TRC_CFG_INCLUDE_ISR_TRACING
+ - TRC_CFG_INCLUDE_READY_EVENTS
+ - TRC_CFG_INCLUDE_OSTICK_EVENTS
+
+ * Removed the old filter system from trcSnapshotRecorder.c.
+
+- Improved streaming interface - Now only two (2) macros are needed to be
+ defined in most cases, read and write. This makes it a lot easier to make
+ custom stream ports.
+
+ * Many definitions that were identical in most stream ports, have been
+ replaced by default definitions in the recorder core. If needed, they
+ can be overriden by custom definitions in trcStreamingPort.h.
+
+ * Stream ports are now assumed to use recorder's internal event buffer.
+ Other stream ports that writes directly to the streaming interface
+ (like J-Link) should define TRC_STREAM_PORT_USE_INTERNAL_BUFFER
+ as zero (0) to make it work correctly.
+
+ * Macro TRC_STREAM_PORT_PERIODIC_SEND_DATA has been replaced by
+ TRC_STREAM_PORT_WRITE_DATA. Together with TRC_STREAM_PORT_READ_DATA,
+ this is all that is necessary for a typical stream port.
+
+ * Return values from the stream port macros READ_DATA and WRITE_DATA are
+ now checked. Expects 0 on success, anything else produces a warning
+ that can be retrived using xTraceGetLastError() and also seen in
+ Tracealyzer if a trace was produced.
+
+ * Stream ports should no longer call prvPagedEventBufferInit explicitly
+ (e.g. in TRC_STREAM_PORT_ON_TRACE_BEGIN). This is now called
+ automatically if TRC_STREAM_PORT_USE_INTERNAL_BUFFER == 1.
+
+ * Macros TRC_STREAM_PORT_ON_TRACE_BEGIN and TRC_STREAM_PORT_ON_TRACE_END
+ are now unused by default and don't need to be defined.
+ You can however use them to hook in some own function at these events.
+
+- Added two new stream ports
+
+ * TCPIP-Win32: allows for testing the streaming on Windows ports of your
+ RTOS, using Winsock.
+
+ * File: example of streaming to a local file system (tested on Windows,
+ but easy to modify).
+
+- Added support for FreeRTOS v9.0.1
+
+ * Replaced FreeRTOS version code TRC_FREERTOS_VERSION_9_X with
+ - TRC_FREERTOS_VERSION_9_0_0
+ - TRC_FREERTOS_VERSION_9_0_1
+
+ * Using TRC_FREERTOS_VERSION_9_X is no longer allowed.
+
+- Added additional events for xQueuePeek, for blocking and timeouts events.
+
+- Added event for traceTIMER_EXPIRED, showing when the timer callback
+ function is called.
+
+- Improved diagnostics in streaming mode, in case of errors in the recorder.
+
+ * Added prvTraceWarning() - registers a "warning" error code, without
+ stopping the recorder. Called if READ_DATA or WRITE_DATA returns a
+ non-zero value, and in several other cases where the recorder
+ configuration is incorrect (e.g., too small symbol table).
+
+ * Added several new warning codes (PSF_WARNING_XYZ), corresponding to the
+ issues detected by prvCheckRecorderStatus.
+
+ * Fixed duplicate definitions of warning messages, so the warnings reported
+ to Tracealyzer are the same as those provided in xTraceGetLastError().
+
+ * Added better explainations of warning/error messages in the body of
+ xTraceGetLastError (in streaming mode).
+
+- Added xTraceIsRecordingEnabled() to Common API.
+
+- Added "unofficial" hardware port for Altera Nios-II.
+ This is a user contribition, not yet verified by Percerpio.
+
+- Fixed bug in vTraceEnable - option TRC_START_AWAIT_HOST was ignored if already initialized.
+
+- Fixed a few remaining compiler warnings.
+
+- Changed order of some settings in trcConfig.h - moved advanced stuff to the
+ bottom.
+
+- Removed SEGGER_RTT_Printf.c from the J-Link stream port since not required
+ for Tracealyzer.
+
+-------------------------------------------------------------------------------
+
+Changes, v3.1.1 -> v3.1.2
+- Fixed two bugs related to User Events, one in vTracePrintF and other in vTracePrint.
+
+- Fixed a build problem related to a single reference of the old FreeRTOS type "xTaskHandle", in trcKernelPort.c.
+ Changed to "TaskHandle_t", unless if using an older FreeRTOS kernel or the "compatibility mode".
+
+- Removed traceCREATE_MUTEX hook for FreeRTOS v9 or later (no longer required)
+
+- Updated the User Manual regarding snapshot trace via IAR Embedded Workbench.
+
+- Renamed vTraceGetTraceBuffer to xTraceGetTraceBuffer, since returning a pointer.
+
+-------------------------------------------------------------------------------
+
+Changes, v3.1.0 -> v3.1.1
+
+After the major changes in the v3.1.0 trace recorder library, this update
+corrects a number of minor issues. Only minor functional improvements.
+
+- You can now use TRC_ALLOC_CUSTOM_BUFFER to declare a trace buffer on a custom
+ location (using linker directives).
+ The related function vTraceSetRecorderDataBuffer has been promoted to the
+ Common API (previously only supported in snapshot mode, but custom allocation
+ is now generally supported also in streaming mode).
+
+- Removed TRC_CFG_USE_LINKER_PRAGMA. No longer necessary thanks to the custom
+ allocation mode.
+
+- Added support for timestamping from custom periodic timers, required for
+ accurate timestamping on Cortex-M0/M0+ devices when using tickless idle.
+ Only for streaming mode so far. See TRC_CUSTOM_TIMER_INCR / DECR.
+
+- ARM Cortex-M port: Made sure the DWT unit is initialized properly, in case
+ the debugger doesn't handle this.
+
+- ARM Cortex-M port: Added possibility to use Systick timestamping also on
+ Cortex-M3/M4/M7 devices (that otherwise use DWT timestamping by default).
+ To use this option, define the macro TRC_CFG_ARM_CM_USE_SYSTICK.
+
+- J-Link streaming: The default RTT buffer has been changed from 0 to 1.
+
+- J-Link streaming: The RTT buffer settings for buffer 1 and higher, are now
+ found in trcStreamingPort.h. Note: These settings don't apply to buffer 0.
+
+- vTracePrint has been optimized for better performance in string logging.
+
+- Minor performance improvement related to symbol table transfer in streaming mode.
+
+- Timer names now registered also in streaming mode.
+
+- Timer start and stop event are now traced.
+
+- Implemented support for queue registry (traceQUEUE_REGISTRY_ADD) also for streaming.
+
+- Fixed a bug related to repeated calls of vTraceEnable.
+
+- Fixed a bug where task-switches seemed to occur even though the scheduler was disabled.
+
+- Renamed HARDWARE_PORT_TEXAS_INSTRUMENTS_TMS570_RM48, added prefix TRC.
+
+- Fixed several language issues in the comments and documentation.
+
+- Fixed several minor issues and warnings from different compilers
+ (including PowerPC/gcc) and configurations.
+
+-------------------------------------------------------------------------------
+
+Changes, v3.0.9 -> v3.1.0
+
+- Merge of previously separated snapshot and streaming recorders into a single
+ recorder supporting both streaming and snapshot as different modes.
+
+- New common API for supporting both streaming and snapshot modes.
+
+- New integration guide, see the User Manual.
+
+- Major improvement of API documentation in source files and User Manual.
+
+- New concept of "stream ports", giving a better structure defining streaming
+ interfaces, and restructured the J-Link and TCP/IP streaming as stream ports.
+
+- Added a stream port for USB CDC connections, with STM32 as example.
+ Since Tracealyzer now can receive serial data on Windows COM ports, this is
+ really easy to use.
+
+- Added a warning (#error) for cases where FreeRTOS tickless idle mode is used
+ together with timestamping using SysTick or other periodic interrupt timers,
+ Tracing with tickless idle requires an independent time source to correctly
+ capture the length of the idle periods.
+
+- Major changes in the recorder API. Important examples are:
+
+ * Some configuration macros have changed names, e.g. for "hardware port".
+ Make sure to remove any old "trcConfig.h" files if upgrading from an
+ earlier version!
+
+ * Recorder configuration in trcConfig.h has been minimized and now only
+ includes the important settings that are independent of recorder mode.
+ Advanced settings for each mode are found in trcSnapshotConfig.h and
+ trcStreamingConfig.h.
+
+ * vTraceEnable replaces Trace_Init and vTraceInitTraceData, as well as
+ vTraceStart and uiTraceStart.
+
+ * vTraceStop now part of the common API and thereby available also in
+ streaming. And since vTraceEnable can start the streaming directly
+ you have the option control the tracing from target, e.g., for
+ streaming to a device file system.
+
+ * vTraceStoreKernelObjectName from old streaming recorder has been replaced
+ by vTraceSetQueueName, vTraceSetSemaphoreName, etc.
+
+ * vTraceSetISRProperties now returns a "traceHandle" that should be passed as
+ parameter to vTraceStoreISRBegin and vTraceStoreISREnd.
+
+ * xTraceRegisterString has replaced the old functions xTraceOpenLabel and
+ vTraceStoreUserEventChannelName. This now returns a "traceString" for use
+ as "channel" parameter in vTracePrintF, and in other places where strings
+ are stored.
+
+ * Removed vTraceStoreISREndManual and vTraceStoreISREndAuto, use
+ vTraceStoreISREnd instead.
+
+ * Renamed the functions for saving User Events in a separate buffer:
+ - xTraceRegisterChannelFormat -> xTraceRegisterUBChannel
+ - vTraceChannelPrintF -> vTraceUBData
+ - vTraceChannelUserEvent -> vTraceUBEvent
+
+
+-------------------------------------------------------------------------------
Copyright Percepio AB, 2018. \ No newline at end of file
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcKernelPort.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcKernelPort.c
index d41b52687..374e9a6d5 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcKernelPort.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcKernelPort.c
@@ -1,833 +1,1083 @@
-/*******************************************************************************
- * Trace Recorder Library for Tracealyzer v4.1.5
- * Percepio AB, www.percepio.com
- *
- * trcKernelPort.c
- *
- * The FreeRTOS-specific parts 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
- ******************************************************************************/
-
-#include "FreeRTOS.h"
-
-#if (!defined(TRC_USE_TRACEALYZER_RECORDER) && configUSE_TRACE_FACILITY == 1)
-#error Trace Recorder: You need to include trcRecorder.h at the end of your FreeRTOSConfig.h!
-#endif
-
-#if (defined(TRC_USE_TRACEALYZER_RECORDER) && TRC_USE_TRACEALYZER_RECORDER == 1)
-
-#ifndef TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS
- /* TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS is missing in trcConfig.h. */
-#error "TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS must be defined in trcConfig.h."
-#endif
-
-#ifndef TRC_CFG_INCLUDE_TIMER_EVENTS
- /* TRC_CFG_INCLUDE_TIMER_EVENTS is missing in trcConfig.h. */
-#error "TRC_CFG_INCLUDE_TIMER_EVENTS must be defined in trcConfig.h."
-#endif
-
-#ifndef TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS
- /* TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS is missing in trcConfig.h. */
-#error "TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS must be defined in trcConfig.h."
-#endif
-
-#ifndef TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS
- /* TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS is missing in trcConfig.h. Define this as 1 if using FreeRTOS v10 or later and like to trace stream buffer or message buffer events, otherwise 0. */
-#error "TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS must be defined in trcConfig.h."
-#endif
-
-#if (configUSE_TICKLESS_IDLE != 0 && (TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR))
- /*
- The below error message is to alert you on the following issue:
-
- The hardware port selected in trcConfig.h uses the operating system timer for the
- timestamping, i.e., the periodic interrupt timer that drives the OS tick interrupt.
-
- When using "tickless idle" mode, the recorder needs an independent time source in
- order to correctly record the durations of the idle times. Otherwise, the trace may appear
- to have a different length than in reality, and the reported CPU load is also affected.
-
- You may override this warning by defining the TRC_CFG_ACKNOWLEDGE_TICKLESS_IDLE_WARNING
- macro in your trcConfig.h file. But then the time scale may be incorrect during
- tickless idle periods.
-
- To get this correct, override the default timestamping by setting TRC_CFG_HARDWARE_PORT
- in trcConfig.h to TRC_HARDWARE_PORT_APPLICATION_DEFINED and define the HWTC macros
- accordingly, using a free running counter or an independent periodic interrupt timer.
- See trcHardwarePort.h for details.
-
- For ARM Cortex-M3, M4 and M7 MCUs this is not an issue, since the recorder uses the
- DWT cycle counter for timestamping in these cases.
- */
-
- #ifndef TRC_CFG_ACKNOWLEDGE_TICKLESS_IDLE_WARNING
- #error Trace Recorder: This timestamping mode is not recommended with Tickless Idle.
- #endif
-#endif /* (configUSE_TICKLESS_IDLE != 0 && (TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR)) */
-
-#include "task.h"
-#include "queue.h"
-
-#if (TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X)
-/* If the project does not include the FreeRTOS timers, TRC_CFG_INCLUDE_TIMER_EVENTS must be set to 0 */
-#include "timers.h"
-#endif /* (TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X) */
-
-#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X)
-/* If the project does not include the FreeRTOS event groups, TRC_CFG_INCLUDE_TIMER_EVENTS must be set to 0 */
-#include "event_groups.h"
-#endif /* (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X) */
-
-#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
-/* If the project does not include the FreeRTOS stream buffers, TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS must be set to 0 */
-#include "stream_buffer.h"
-#endif /* (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
-
-uint32_t prvTraceGetQueueNumber(void* handle);
-
-#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_8_X)
-
-extern unsigned char ucQueueGetQueueNumber( xQueueHandle pxQueue );
-extern void vQueueSetQueueNumber( xQueueHandle pxQueue, unsigned char ucQueueNumber );
-extern unsigned char ucQueueGetQueueType( xQueueHandle pxQueue );
-
-uint32_t prvTraceGetQueueNumber(void* handle)
-{
- return (uint32_t)ucQueueGetQueueNumber(handle);
-}
-#else
-uint32_t prvTraceGetQueueNumber(void* handle)
-{
- return (uint32_t)uxQueueGetQueueNumber(handle);
-}
-#endif /* (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_8_X) */
-
-uint8_t prvTraceGetQueueType(void* handle)
-{
- // This is either declared in header file in FreeRTOS 8 and later, or as extern above
- return ucQueueGetQueueType(handle);
-}
-
-/* Tasks */
-uint16_t prvTraceGetTaskNumberLow16(void* handle)
-{
- return TRACE_GET_LOW16(uxTaskGetTaskNumber(handle));
-}
-
-uint16_t prvTraceGetTaskNumberHigh16(void* handle)
-{
- return TRACE_GET_HIGH16(uxTaskGetTaskNumber(handle));
-}
-
-void prvTraceSetTaskNumberLow16(void* handle, uint16_t value)
-{
- vTaskSetTaskNumber(handle, TRACE_SET_LOW16(uxTaskGetTaskNumber(handle), value));
-}
-
-void prvTraceSetTaskNumberHigh16(void* handle, uint16_t value)
-{
- vTaskSetTaskNumber(handle, TRACE_SET_HIGH16(uxTaskGetTaskNumber(handle), value));
-}
-
-uint16_t prvTraceGetQueueNumberLow16(void* handle)
-{
- return TRACE_GET_LOW16(prvTraceGetQueueNumber(handle));
-}
-
-uint16_t prvTraceGetQueueNumberHigh16(void* handle)
-{
- return TRACE_GET_HIGH16(prvTraceGetQueueNumber(handle));
-}
-
-void prvTraceSetQueueNumberLow16(void* handle, uint16_t value)
-{
- vQueueSetQueueNumber(handle, TRACE_SET_LOW16(prvTraceGetQueueNumber(handle), value));
-}
-
-void prvTraceSetQueueNumberHigh16(void* handle, uint16_t value)
-{
- vQueueSetQueueNumber(handle, TRACE_SET_HIGH16(prvTraceGetQueueNumber(handle), value));
-}
-
-#if (TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
-
-uint16_t prvTraceGetTimerNumberLow16(void* handle)
-{
- return TRACE_GET_LOW16(uxTimerGetTimerNumber(handle));
-}
-
-uint16_t prvTraceGetTimerNumberHigh16(void* handle)
-{
- return TRACE_GET_HIGH16(uxTimerGetTimerNumber(handle));
-}
-
-void prvTraceSetTimerNumberLow16(void* handle, uint16_t value)
-{
- vTimerSetTimerNumber(handle, TRACE_SET_LOW16(uxTimerGetTimerNumber(handle), value));
-}
-
-void prvTraceSetTimerNumberHigh16(void* handle, uint16_t value)
-{
- vTimerSetTimerNumber(handle, TRACE_SET_HIGH16(uxTimerGetTimerNumber(handle), value));
-}
-#endif /* (TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
-
-#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
-
-uint16_t prvTraceGetEventGroupNumberLow16(void* handle)
-{
- return TRACE_GET_LOW16(uxEventGroupGetNumber(handle));
-}
-
-uint16_t prvTraceGetEventGroupNumberHigh16(void* handle)
-{
- return TRACE_GET_HIGH16(uxEventGroupGetNumber(handle));
-}
-
-void prvTraceSetEventGroupNumberLow16(void* handle, uint16_t value)
-{
- vEventGroupSetNumber(handle, TRACE_SET_LOW16(uxEventGroupGetNumber(handle), value));
-}
-
-void prvTraceSetEventGroupNumberHigh16(void* handle, uint16_t value)
-{
- vEventGroupSetNumber(handle, TRACE_SET_HIGH16(uxEventGroupGetNumber(handle), value));
-}
-#endif /* (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
-
-#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
-
-uint16_t prvTraceGetStreamBufferNumberLow16(void* handle)
-{
- return TRACE_GET_LOW16(uxStreamBufferGetStreamBufferNumber(handle));
-}
-
-uint16_t prvTraceGetStreamBufferNumberHigh16(void* handle)
-{
- return TRACE_GET_HIGH16(uxStreamBufferGetStreamBufferNumber(handle));
-}
-
-void prvTraceSetStreamBufferNumberLow16(void* handle, uint16_t value)
-{
- vStreamBufferSetStreamBufferNumber(handle, TRACE_SET_LOW16(uxStreamBufferGetStreamBufferNumber(handle), value));
-}
-
-void prvTraceSetStreamBufferNumberHigh16(void* handle, uint16_t value)
-{
- vStreamBufferSetStreamBufferNumber(handle, TRACE_SET_HIGH16(uxStreamBufferGetStreamBufferNumber(handle), value));
-}
-#endif /* (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
-
-#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
-
-static void* pCurrentTCB = NULL;
-#if (defined(configENABLE_BACKWARD_COMPATIBILITY) && configENABLE_BACKWARD_COMPATIBILITY == 0)
-/* We're explicitly not using compatibility mode */
-static TaskHandle_t HandleTzCtrl = NULL; /* TzCtrl task TCB */
-#else
-/* We're using compatibility mode, or we're running an old kernel */
-static xTaskHandle HandleTzCtrl = NULL; /* TzCtrl task TCB */
-#endif
-
-#if defined(configSUPPORT_STATIC_ALLOCATION)
-#if (configSUPPORT_STATIC_ALLOCATION == 1)
-static StackType_t stackTzCtrl[TRC_CFG_CTRL_TASK_STACK_SIZE];
-static StaticTask_t tcbTzCtrl;
-#endif
-#endif
-
-/* Monitored by TzCtrl task, that give warnings as User Events */
-extern volatile uint32_t NoRoomForSymbol;
-extern volatile uint32_t NoRoomForObjectData;
-extern volatile uint32_t LongestSymbolName;
-extern volatile uint32_t MaxBytesTruncated;
-
-/* Keeps track of previous values, to only react on changes. */
-static uint32_t NoRoomForSymbol_last = 0;
-static uint32_t NoRoomForObjectData_last = 0;
-static uint32_t LongestSymbolName_last = 0;
-static uint32_t MaxBytesTruncated_last = 0;
-
-/* User Event Channel for giving warnings regarding NoRoomForSymbol etc. */
-traceString trcWarningChannel;
-
-#define TRC_PORT_MALLOC(size) pvPortMalloc(size)
-
-TRC_STREAM_PORT_ALLOCATE_FIELDS()
-
-/* Called by TzCtrl task periodically (Normally every 100 ms) */
-static void prvCheckRecorderStatus(void);
-
-extern void prvTraceWarning(int errCode);
-
-/* The TzCtrl task - receives commands from Tracealyzer (start/stop) */
-static portTASK_FUNCTION( TzCtrl, pvParameters );
-
-/*******************************************************************************
- * vTraceEnable
- *
- * Function that enables the tracing and creates the control task. It will halt
- * execution until a Start command has been received if haltUntilStart is true.
- *
- ******************************************************************************/
-void vTraceEnable(int startOption)
-{
- int32_t bytes = 0;
- int32_t status;
- extern uint32_t RecorderEnabled;
- TracealyzerCommandType msg;
-
- /* Only do this first time...*/
- if (HandleTzCtrl == NULL)
- {
- TRC_STREAM_PORT_INIT();
-
- /* Note: Requires that TRC_CFG_INCLUDE_USER_EVENTS is 1. */
- trcWarningChannel = xTraceRegisterString("Warnings from Recorder");
-
- /* Creates the TzCtrl task - receives trace commands (start, stop, ...) */
- #if defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION == 1)
- HandleTzCtrl = xTaskCreateStatic(TzCtrl, STRING_CAST("TzCtrl"), TRC_CFG_CTRL_TASK_STACK_SIZE, NULL, TRC_CFG_CTRL_TASK_PRIORITY, stackTzCtrl, &tcbTzCtrl);
- #else
- xTaskCreate( TzCtrl, STRING_CAST("TzCtrl"), TRC_CFG_CTRL_TASK_STACK_SIZE, NULL, TRC_CFG_CTRL_TASK_PRIORITY, &HandleTzCtrl );
- #endif
-
- if (HandleTzCtrl == NULL)
- {
- prvTraceError(PSF_ERROR_TZCTRLTASK_NOT_CREATED);
- }
- }
-
- if (startOption == TRC_START_AWAIT_HOST)
- {
- /* We keep trying to read commands until the recorder has been started */
- do
- {
- bytes = 0;
-
- status = TRC_STREAM_PORT_READ_DATA(&msg, sizeof(TracealyzerCommandType), (int32_t*)&bytes);
-
- if (status != 0)
- {
- prvTraceWarning(PSF_WARNING_STREAM_PORT_READ);
- }
-
- if ((status == 0) && (bytes == sizeof(TracealyzerCommandType)))
- {
- if (prvIsValidCommand(&msg))
- {
- if (msg.cmdCode == CMD_SET_ACTIVE && msg.param1 == 1)
- {
- /* On start, init and reset the timestamping */
- TRC_PORT_SPECIFIC_INIT();
- }
-
- prvProcessCommand(&msg);
- }
- }
- }
- while (RecorderEnabled == 0);
- }
- else if (startOption == TRC_START)
- {
- /* We start streaming directly - this assumes that the interface is ready! */
- TRC_PORT_SPECIFIC_INIT();
-
- msg.cmdCode = CMD_SET_ACTIVE;
- msg.param1 = 1;
- prvProcessCommand(&msg);
- }
- else
- {
- /* On TRC_INIT */
- TRC_PORT_SPECIFIC_INIT();
- }
-}
-
-#if (TRC_CFG_SCHEDULING_ONLY == 0)
-/*******************************************************************************
- * vTraceSetQueueName(void* object, const char* name)
- *
- * Parameter object: pointer to the Queue that shall be named
- * Parameter name: the name to set (const string literal)
- *
- * Sets a name for Queue objects for display in Tracealyzer.
- ******************************************************************************/
-void vTraceSetQueueName(void* object, const char* name)
-{
- vTraceStoreKernelObjectName(object, name);
-}
-
-/*******************************************************************************
- * vTraceSetSemaphoreName(void* object, const char* name)
- *
- * Parameter object: pointer to the Semaphore that shall be named
- * Parameter name: the name to set (const string literal)
- *
- * Sets a name for Semaphore objects for display in Tracealyzer.
- ******************************************************************************/
-void vTraceSetSemaphoreName(void* object, const char* name)
-{
- vTraceStoreKernelObjectName(object, name);
-}
-
-/*******************************************************************************
- * vTraceSetMutexName(void* object, const char* name)
- *
- * Parameter object: pointer to the Mutex that shall be named
- * Parameter name: the name to set (const string literal)
- *
- * Sets a name for Mutex objects for display in Tracealyzer.
- ******************************************************************************/
-void vTraceSetMutexName(void* object, const char* name)
-{
- vTraceStoreKernelObjectName(object, name);
-}
-
-#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X)
-/*******************************************************************************
-* vTraceSetEventGroupName(void* object, const char* name)
-*
-* Parameter object: pointer to the vTraceSetEventGroupName that shall be named
-* Parameter name: the name to set (const string literal)
-*
-* Sets a name for EventGroup objects for display in Tracealyzer.
-******************************************************************************/
-void vTraceSetEventGroupName(void* object, const char* name)
-{
- vTraceStoreKernelObjectName(object, name);
-}
-#endif /* (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X) */
-
-#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
-/*******************************************************************************
-* vTraceSetStreamBufferName(void* object, const char* name)
-*
-* Parameter object: pointer to the StreamBuffer that shall be named
-* Parameter name: the name to set (const string literal)
-*
-* Sets a name for StreamBuffer objects for display in Tracealyzer.
-******************************************************************************/
-void vTraceSetStreamBufferName(void* object, const char* name)
-{
- vTraceStoreKernelObjectName(object, name);
-}
-
-/*******************************************************************************
-* vTraceSetMessageBufferName(void* object, const char* name)
-*
-* Parameter object: pointer to the MessageBuffer that shall be named
-* Parameter name: the name to set (const string literal)
-*
-* Sets a name for MessageBuffer objects for display in Tracealyzer.
-******************************************************************************/
-void vTraceSetMessageBufferName(void* object, const char* name)
-{
- vTraceStoreKernelObjectName(object, name);
-}
-#endif /* (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
-
-#endif /* (TRC_CFG_SCHEDULING_ONLY == 0) */
-
-/*******************************************************************************
- * prvGetCurrentTaskHandle
- *
- * Function that returns the handle to the currently executing task.
- *
- ******************************************************************************/
-void* prvTraceGetCurrentTaskHandle(void)
-{
- return xTaskGetCurrentTaskHandle();
-}
-
-/*******************************************************************************
- * prvIsNewTCB
- *
- * Tells if this task is already executing, or if there has been a task-switch.
- * Assumed to be called within a trace hook in kernel context.
- ******************************************************************************/
-uint32_t prvIsNewTCB(void* pNewTCB)
-{
- if (pCurrentTCB != pNewTCB)
- {
- pCurrentTCB = pNewTCB;
- return 1;
- }
- return 0;
-}
-
-/*******************************************************************************
- * prvTraceIsSchedulerSuspended
- *
- * Returns true if the RTOS scheduler currently is disabled, thus preventing any
- * task-switches from occurring. Only called from vTraceStoreISREnd.
- ******************************************************************************/
-unsigned char prvTraceIsSchedulerSuspended(void)
-{
- /* Assumed to be available in FreeRTOS. According to the FreeRTOS docs,
- INCLUDE_xTaskGetSchedulerState or configUSE_TIMERS must be set to 1 in
- FreeRTOSConfig.h for this function to be available. */
-
- return xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED;
-}
-
-
-/*******************************************************************************
- * prvCheckRecorderStatus
- *
- * Called by TzCtrl task periodically (every 100 ms - seems reasonable).
- * Checks a number of diagnostic variables and give warnings as user events,
- * in most cases including a suggested solution.
- ******************************************************************************/
-static void prvCheckRecorderStatus(void)
-{
- if (NoRoomForSymbol > NoRoomForSymbol_last)
- {
- if (NoRoomForSymbol > 0)
- {
- prvTraceWarning(PSF_WARNING_SYMBOL_TABLE_SLOTS);
- }
- NoRoomForSymbol_last = NoRoomForSymbol;
- }
-
- if (NoRoomForObjectData > NoRoomForObjectData_last)
- {
- if (NoRoomForObjectData > 0)
- {
- prvTraceWarning(PSF_WARNING_OBJECT_DATA_SLOTS);
- }
- NoRoomForObjectData_last = NoRoomForObjectData;
- }
-
- if (LongestSymbolName > LongestSymbolName_last)
- {
- if (LongestSymbolName > (TRC_CFG_SYMBOL_MAX_LENGTH))
- {
- prvTraceWarning(PSF_WARNING_SYMBOL_MAX_LENGTH);
- }
- LongestSymbolName_last = LongestSymbolName;
- }
-
- if (MaxBytesTruncated > MaxBytesTruncated_last)
- {
- if (MaxBytesTruncated > 0)
- {
- prvTraceWarning(PSF_WARNING_STRING_TOO_LONG);
- }
- MaxBytesTruncated_last = MaxBytesTruncated;
- }
-}
-
-/*******************************************************************************
- * TzCtrl
- *
- * Task for sending the trace data from the internal buffer to the stream
- * interface (assuming TRC_STREAM_PORT_USE_INTERNAL_BUFFER == 1) and for
- * receiving commands from Tracealyzer. Also does some diagnostics.
- ******************************************************************************/
-static portTASK_FUNCTION( TzCtrl, pvParameters )
-{
- TracealyzerCommandType msg;
- int32_t bytes = 0;
- int32_t status = 0;
- (void)pvParameters;
-
- while (1)
- {
- do
- {
- /* Listen for new commands */
- bytes = 0;
- status = TRC_STREAM_PORT_READ_DATA(&msg, sizeof(TracealyzerCommandType), (int32_t*)&bytes);
-
- if (status != 0)
- {
- prvTraceWarning(PSF_WARNING_STREAM_PORT_READ);
- }
-
- if ((status == 0) && (bytes == sizeof(TracealyzerCommandType)))
- {
- if (prvIsValidCommand(&msg))
- {
- prvProcessCommand(&msg); /* Start or Stop currently... */
- }
- }
-
-/* If the internal buffer is disabled, the COMMIT macro instead sends the data directly
- from the "event functions" (using TRC_STREAM_PORT_WRITE_DATA). */
-#if (TRC_STREAM_PORT_USE_INTERNAL_BUFFER == 1)
- /* If there is a buffer page, this sends it to the streaming interface using TRC_STREAM_PORT_WRITE_DATA. */
- bytes = prvPagedEventBufferTransfer();
-#endif
-
- /* If there was data sent or received (bytes != 0), loop around and repeat, if there is more data to send or receive.
- Otherwise, step out of this loop and sleep for a while. */
-
- } while (bytes != 0);
-
- prvCheckRecorderStatus();
-
- vTaskDelay(TRC_CFG_CTRL_TASK_DELAY);
- }
-}
-
-#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/
-
-
-#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)
-
-/* Internal flag to tell the context of tracePEND_FUNC_CALL_FROM_ISR */
-int uiInEventGroupSetBitsFromISR = 0;
-
-/******************************************************************************
- * TraceQueueClassTable
- * Translates a FreeRTOS QueueType into trace objects classes (TRACE_CLASS_).
- * Has one entry for each QueueType, gives TRACE_CLASS ID.
- ******************************************************************************/
-traceObjectClass TraceQueueClassTable[5] = {
- TRACE_CLASS_QUEUE,
- TRACE_CLASS_MUTEX,
- TRACE_CLASS_SEMAPHORE,
- TRACE_CLASS_SEMAPHORE,
- TRACE_CLASS_MUTEX
-};
-
-#if (TRC_CFG_SCHEDULING_ONLY == 0)
-/*******************************************************************************
- * vTraceSetQueueName(void* object, const char* name)
- *
- * Parameter object: pointer to the Queue that shall be named
- * Parameter name: the name to set (const string literal)
- *
- * Sets a name for Queue objects for display in Tracealyzer.
- ******************************************************************************/
-void vTraceSetQueueName(void* object, const char* name)
-{
- prvTraceSetObjectName(TRACE_CLASS_QUEUE, TRACE_GET_OBJECT_NUMBER(QUEUE, object), name);
-}
-
-/*******************************************************************************
- * vTraceSetSemaphoreName(void* object, const char* name)
- *
- * Parameter object: pointer to the Semaphore that shall be named
- * Parameter name: the name to set (const string literal)
- *
- * Sets a name for Semaphore objects for display in Tracealyzer.
- ******************************************************************************/
-void vTraceSetSemaphoreName(void* object, const char* name)
-{
- prvTraceSetObjectName(TRACE_CLASS_SEMAPHORE, TRACE_GET_OBJECT_NUMBER(QUEUE, object), name);
-}
-
-/*******************************************************************************
- * vTraceSetMutexName(void* object, const char* name)
- *
- * Parameter object: pointer to the Mutex that shall be named
- * Parameter name: the name to set (const string literal)
- *
- * Sets a name for Semaphore objects for display in Tracealyzer.
- ******************************************************************************/
-void vTraceSetMutexName(void* object, const char* name)
-{
- prvTraceSetObjectName(TRACE_CLASS_MUTEX, TRACE_GET_OBJECT_NUMBER(QUEUE, object), name);
-}
-
-#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X)
-/*******************************************************************************
-* vTraceSetEventGroupName(void* object, const char* name)
-*
-* Parameter object: pointer to the EventGroup that shall be named
-* Parameter name: the name to set (const string literal)
-*
-* Sets a name for EventGroup objects for display in Tracealyzer.
-******************************************************************************/
-void vTraceSetEventGroupName(void* object, const char* name)
-{
- prvTraceSetObjectName(TRACE_CLASS_EVENTGROUP, TRACE_GET_OBJECT_NUMBER(EVENTGROUP, object), name);
-}
-#endif /* (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X) */
-
-#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
-/*******************************************************************************
-* vTraceSetStreamBufferName(void* object, const char* name)
-*
-* Parameter object: pointer to the StreamBuffer that shall be named
-* Parameter name: the name to set (const string literal)
-*
-* Sets a name for StreamBuffer objects for display in Tracealyzer.
-******************************************************************************/
-void vTraceSetStreamBufferName(void* object, const char* name)
-{
- prvTraceSetObjectName(TRACE_CLASS_STREAMBUFFER, TRACE_GET_OBJECT_NUMBER(STREAMBUFFER, object), name);
-}
-
-/*******************************************************************************
-* vTraceSetMessageBufferName(void* object, const char* name)
-*
-* Parameter object: pointer to the MessageBuffer that shall be named
-* Parameter name: the name to set (const string literal)
-*
-* Sets a name for MessageBuffer objects for display in Tracealyzer.
-******************************************************************************/
-void vTraceSetMessageBufferName(void* object, const char* name)
-{
- prvTraceSetObjectName(TRACE_CLASS_MESSAGEBUFFER, TRACE_GET_OBJECT_NUMBER(STREAMBUFFER, object), name);
-}
-#endif /* (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
-
-#endif /* (TRC_CFG_SCHEDULING_ONLY == 0) */
-
-void* prvTraceGetCurrentTaskHandle()
-{
- return xTaskGetCurrentTaskHandle();
-}
-
-/* Initialization of the object property table */
-void vTraceInitObjectPropertyTable()
-{
- RecorderDataPtr->ObjectPropertyTable.NumberOfObjectClasses = TRACE_NCLASSES;
- RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[0] = TRC_CFG_NQUEUE;
- RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[1] = TRC_CFG_NSEMAPHORE;
- RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[2] = TRC_CFG_NMUTEX;
- RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[3] = TRC_CFG_NTASK;
- RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[4] = TRC_CFG_NISR;
- RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[5] = TRC_CFG_NTIMER;
- RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[6] = TRC_CFG_NEVENTGROUP;
- RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[7] = TRC_CFG_NSTREAMBUFFER;
- RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[8] = TRC_CFG_NMESSAGEBUFFER;
- RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[0] = TRC_CFG_NAME_LEN_QUEUE;
- RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[1] = TRC_CFG_NAME_LEN_SEMAPHORE;
- RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[2] = TRC_CFG_NAME_LEN_MUTEX;
- RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[3] = TRC_CFG_NAME_LEN_TASK;
- RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[4] = TRC_CFG_NAME_LEN_ISR;
- RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[5] = TRC_CFG_NAME_LEN_TIMER;
- RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[6] = TRC_CFG_NAME_LEN_EVENTGROUP;
- RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[7] = TRC_CFG_NAME_LEN_STREAMBUFFER;
- RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[8] = TRC_CFG_NAME_LEN_MESSAGEBUFFER;
- RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[0] = PropertyTableSizeQueue;
- RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[1] = PropertyTableSizeSemaphore;
- RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[2] = PropertyTableSizeMutex;
- RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[3] = PropertyTableSizeTask;
- RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[4] = PropertyTableSizeISR;
- RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[5] = PropertyTableSizeTimer;
- RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[6] = PropertyTableSizeEventGroup;
- RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[7] = PropertyTableSizeStreamBuffer;
- RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[8] = PropertyTableSizeMessageBuffer;
- RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[0] = StartIndexQueue;
- RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[1] = StartIndexSemaphore;
- RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[2] = StartIndexMutex;
- RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[3] = StartIndexTask;
- RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[4] = StartIndexISR;
- RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[5] = StartIndexTimer;
- RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[6] = StartIndexEventGroup;
- RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[7] = StartIndexStreamBuffer;
- RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[8] = StartIndexMessageBuffer;
- RecorderDataPtr->ObjectPropertyTable.ObjectPropertyTableSizeInBytes = TRACE_OBJECT_TABLE_SIZE;
-}
-
-/* Initialization of the handle mechanism, see e.g, prvTraceGetObjectHandle */
-void vTraceInitObjectHandleStack()
-{
- objectHandleStacks.indexOfNextAvailableHandle[0] = objectHandleStacks.lowestIndexOfClass[0] = 0;
- objectHandleStacks.indexOfNextAvailableHandle[1] = objectHandleStacks.lowestIndexOfClass[1] = (TRC_CFG_NQUEUE);
- objectHandleStacks.indexOfNextAvailableHandle[2] = objectHandleStacks.lowestIndexOfClass[2] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE);
- objectHandleStacks.indexOfNextAvailableHandle[3] = objectHandleStacks.lowestIndexOfClass[3] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX);
- objectHandleStacks.indexOfNextAvailableHandle[4] = objectHandleStacks.lowestIndexOfClass[4] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK);
- objectHandleStacks.indexOfNextAvailableHandle[5] = objectHandleStacks.lowestIndexOfClass[5] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR);
- objectHandleStacks.indexOfNextAvailableHandle[6] = objectHandleStacks.lowestIndexOfClass[6] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER);
- objectHandleStacks.indexOfNextAvailableHandle[7] = objectHandleStacks.lowestIndexOfClass[7] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER) + (TRC_CFG_NEVENTGROUP);
- objectHandleStacks.indexOfNextAvailableHandle[8] = objectHandleStacks.lowestIndexOfClass[8] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER) + (TRC_CFG_NEVENTGROUP) + (TRC_CFG_NSTREAMBUFFER);
-
- objectHandleStacks.highestIndexOfClass[0] = (TRC_CFG_NQUEUE) - 1;
- objectHandleStacks.highestIndexOfClass[1] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) - 1;
- objectHandleStacks.highestIndexOfClass[2] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) - 1;
- objectHandleStacks.highestIndexOfClass[3] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) - 1;
- objectHandleStacks.highestIndexOfClass[4] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) - 1;
- objectHandleStacks.highestIndexOfClass[5] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER) - 1;
- objectHandleStacks.highestIndexOfClass[6] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER) + (TRC_CFG_NEVENTGROUP) - 1;
- objectHandleStacks.highestIndexOfClass[7] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER) + (TRC_CFG_NEVENTGROUP) + (TRC_CFG_NSTREAMBUFFER) - 1;
- objectHandleStacks.highestIndexOfClass[8] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER) + (TRC_CFG_NEVENTGROUP) + (TRC_CFG_NSTREAMBUFFER) + (TRC_CFG_NMESSAGEBUFFER) - 1;
-}
-
-/* Returns the "Not enough handles" error message for this object class */
-const char* pszTraceGetErrorNotEnoughHandles(traceObjectClass objectclass)
-{
- switch(objectclass)
- {
- case TRACE_CLASS_TASK:
- return "Not enough TASK handles - increase TRC_CFG_NTASK in trcSnapshotConfig.h";
- case TRACE_CLASS_ISR:
- return "Not enough ISR handles - increase TRC_CFG_NISR in trcSnapshotConfig.h";
- case TRACE_CLASS_SEMAPHORE:
- return "Not enough SEMAPHORE handles - increase TRC_CFG_NSEMAPHORE in trcSnapshotConfig.h";
- case TRACE_CLASS_MUTEX:
- return "Not enough MUTEX handles - increase TRC_CFG_NMUTEX in trcSnapshotConfig.h";
- case TRACE_CLASS_QUEUE:
- return "Not enough QUEUE handles - increase TRC_CFG_NQUEUE in trcSnapshotConfig.h";
- case TRACE_CLASS_TIMER:
- return "Not enough TIMER handles - increase TRC_CFG_NTIMER in trcSnapshotConfig.h";
- case TRACE_CLASS_EVENTGROUP:
- return "Not enough EVENTGROUP handles - increase TRC_CFG_NEVENTGROUP in trcSnapshotConfig.h";
- case TRACE_CLASS_STREAMBUFFER:
- return "Not enough STREAMBUFFER handles - increase TRC_CFG_NSTREAMBUFFER in trcSnapshotConfig.h";
- case TRACE_CLASS_MESSAGEBUFFER:
- return "Not enough MESSAGEBUFFER handles - increase TRC_CFG_NMESSAGEBUFFER in trcSnapshotConfig.h";
- default:
- return "pszTraceGetErrorHandles: Invalid objectclass!";
- }
-}
-
-/*******************************************************************************
- * prvTraceIsSchedulerSuspended
- *
- * Returns true if the RTOS scheduler currently is disabled, thus preventing any
- * task-switches from occurring. Only called from vTraceStoreISREnd.
- ******************************************************************************/
-#if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
-unsigned char prvTraceIsSchedulerSuspended(void)
-{
- /* Assumed to be available in FreeRTOS. According to the FreeRTOS docs,
- INCLUDE_xTaskGetSchedulerState or configUSE_TIMERS must be set to 1 in
- FreeRTOSConfig.h for this function to be available. */
-
- return xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED;
-}
-#endif
-
-#endif /* Snapshot mode */
-
-#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/
+/*******************************************************************************
+ * Trace Recorder Library for Tracealyzer v4.3.11
+ * Percepio AB, www.percepio.com
+ *
+ * trcKernelPort.c
+ *
+ * The FreeRTOS-specific parts 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
+ ******************************************************************************/
+
+#include "FreeRTOS.h"
+
+#if (!defined(TRC_USE_TRACEALYZER_RECORDER) && configUSE_TRACE_FACILITY == 1)
+#error Trace Recorder: You need to include trcRecorder.h at the end of your FreeRTOSConfig.h!
+#endif
+
+#if (defined(TRC_USE_TRACEALYZER_RECORDER) && TRC_USE_TRACEALYZER_RECORDER == 1)
+
+#ifndef TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS
+ /* TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS is missing in trcConfig.h. */
+#error "TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS must be defined in trcConfig.h."
+#endif
+
+#ifndef TRC_CFG_INCLUDE_TIMER_EVENTS
+ /* TRC_CFG_INCLUDE_TIMER_EVENTS is missing in trcConfig.h. */
+#error "TRC_CFG_INCLUDE_TIMER_EVENTS must be defined in trcConfig.h."
+#endif
+
+#ifndef TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS
+ /* TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS is missing in trcConfig.h. */
+#error "TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS must be defined in trcConfig.h."
+#endif
+
+#ifndef TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS
+ /* TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS is missing in trcConfig.h. Define this as 1 if using FreeRTOS v10 or later and like to trace stream buffer or message buffer events, otherwise 0. */
+#error "TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS must be defined in trcConfig.h."
+#endif
+
+#if (configUSE_TICKLESS_IDLE != 0 && (TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR))
+ /*
+ The below error message is to alert you on the following issue:
+
+ The hardware port selected in trcConfig.h uses the operating system timer for the
+ timestamping, i.e., the periodic interrupt timer that drives the OS tick interrupt.
+
+ When using "tickless idle" mode, the recorder needs an independent time source in
+ order to correctly record the durations of the idle times. Otherwise, the trace may appear
+ to have a different length than in reality, and the reported CPU load is also affected.
+
+ You may override this warning by defining the TRC_CFG_ACKNOWLEDGE_TICKLESS_IDLE_WARNING
+ macro in your trcConfig.h file. But then the time scale may be incorrect during
+ tickless idle periods.
+
+ To get this correct, override the default timestamping by setting TRC_CFG_HARDWARE_PORT
+ in trcConfig.h to TRC_HARDWARE_PORT_APPLICATION_DEFINED and define the HWTC macros
+ accordingly, using a free running counter or an independent periodic interrupt timer.
+ See trcHardwarePort.h for details.
+
+ For ARM Cortex-M3, M4 and M7 MCUs this is not an issue, since the recorder uses the
+ DWT cycle counter for timestamping in these cases.
+ */
+
+ #ifndef TRC_CFG_ACKNOWLEDGE_TICKLESS_IDLE_WARNING
+ #error Trace Recorder: This timestamping mode is not recommended with Tickless Idle.
+ #endif
+#endif /* (configUSE_TICKLESS_IDLE != 0 && (TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR)) */
+
+#include "task.h"
+#include "queue.h"
+
+#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) || (defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0))
+
+static TaskType HandleTzCtrl = NULL; /* TzCtrl task TCB */
+
+#if defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION == 1)
+
+#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0)
+static StackType_t stackTzCtrl[TRC_CFG_CTRL_TASK_STACK_SIZE];
+static StaticTask_t tcbTzCtrl;
+#else
+#error "configSUPPORT_STATIC_ALLOCATION not supported before FreeRTOS v9"
+#endif
+
+#endif /* defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION == 1) */
+
+
+/* The TzCtrl task - receives commands from Tracealyzer (start/stop) */
+static portTASK_FUNCTION(TzCtrl, pvParameters);
+
+#if defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0)
+void prvReportStackUsage(void);
+#else /* defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0) */
+#define prvReportStackUsage()
+#endif /* defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0) */
+
+#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) || (defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0)) */
+
+#if (TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X)
+/* If the project does not include the FreeRTOS timers, TRC_CFG_INCLUDE_TIMER_EVENTS must be set to 0 */
+#include "timers.h"
+#endif /* (TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X) */
+
+#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X)
+/* If the project does not include the FreeRTOS event groups, TRC_CFG_INCLUDE_TIMER_EVENTS must be set to 0 */
+#include "event_groups.h"
+#endif /* (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X) */
+
+#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
+/* If the project does not include the FreeRTOS stream buffers, TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS must be set to 0 */
+#include "stream_buffer.h"
+#endif /* (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
+
+#if (TRC_CFG_ACKNOWLEDGE_QUEUE_SET_SEND != TRC_ACKNOWLEDGED) && (TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_10_3_0 || TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_10_3_1) && (configUSE_QUEUE_SETS == 1)
+#error "When using FreeRTOS v10.3.0 or v10.3.1, please make sure that the trace point in prvNotifyQueueSetContainer() in queue.c is renamed from traceQUEUE_SEND to traceQUEUE_SET_SEND in order to tell them apart from other traceQUEUE_SEND trace points. Then set TRC_CFG_ACKNOWLEDGE_QUEUE_SET_SEND in trcConfig.h to TRC_ACKNOWLEDGED to get rid of this error."
+#endif /* (TRC_CFG_ACKNOWLEDGE_QUEUE_SET_SEND != TRC_ACKNOWLEDGED) && (TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_10_3_0 || TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_10_3_1) && (configUSE_QUEUE_SETS == 1) */
+
+uint32_t prvTraceGetQueueNumber(void* handle);
+
+#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_8_X_X)
+
+extern unsigned char ucQueueGetQueueNumber( xQueueHandle pxQueue );
+extern void vQueueSetQueueNumber( xQueueHandle pxQueue, unsigned char ucQueueNumber );
+extern unsigned char ucQueueGetQueueType( xQueueHandle pxQueue );
+
+uint32_t prvTraceGetQueueNumber(void* handle)
+{
+ return (uint32_t)ucQueueGetQueueNumber(handle);
+}
+#else
+uint32_t prvTraceGetQueueNumber(void* handle)
+{
+ return (uint32_t)uxQueueGetQueueNumber(handle);
+}
+#endif /* (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_8_X_X) */
+
+uint8_t prvTraceGetQueueType(void* handle)
+{
+ // This is either declared in header file in FreeRTOS 8 and later, or as extern above
+ return ucQueueGetQueueType(handle);
+}
+
+/* Tasks */
+uint16_t prvTraceGetTaskNumberLow16(void* handle)
+{
+ return TRACE_GET_LOW16(uxTaskGetTaskNumber(handle));
+}
+
+uint16_t prvTraceGetTaskNumberHigh16(void* handle)
+{
+ return TRACE_GET_HIGH16(uxTaskGetTaskNumber(handle));
+}
+
+void prvTraceSetTaskNumberLow16(void* handle, uint16_t value)
+{
+ vTaskSetTaskNumber(handle, TRACE_SET_LOW16(uxTaskGetTaskNumber(handle), value));
+}
+
+void prvTraceSetTaskNumberHigh16(void* handle, uint16_t value)
+{
+ vTaskSetTaskNumber(handle, TRACE_SET_HIGH16(uxTaskGetTaskNumber(handle), value));
+}
+
+uint16_t prvTraceGetQueueNumberLow16(void* handle)
+{
+ return TRACE_GET_LOW16(prvTraceGetQueueNumber(handle));
+}
+
+uint16_t prvTraceGetQueueNumberHigh16(void* handle)
+{
+ return TRACE_GET_HIGH16(prvTraceGetQueueNumber(handle));
+}
+
+void prvTraceSetQueueNumberLow16(void* handle, uint16_t value)
+{
+ vQueueSetQueueNumber(handle, TRACE_SET_LOW16(prvTraceGetQueueNumber(handle), value));
+}
+
+void prvTraceSetQueueNumberHigh16(void* handle, uint16_t value)
+{
+ vQueueSetQueueNumber(handle, TRACE_SET_HIGH16(prvTraceGetQueueNumber(handle), value));
+}
+
+#if (TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
+
+uint16_t prvTraceGetTimerNumberLow16(void* handle)
+{
+ return TRACE_GET_LOW16(uxTimerGetTimerNumber(handle));
+}
+
+uint16_t prvTraceGetTimerNumberHigh16(void* handle)
+{
+ return TRACE_GET_HIGH16(uxTimerGetTimerNumber(handle));
+}
+
+void prvTraceSetTimerNumberLow16(void* handle, uint16_t value)
+{
+ vTimerSetTimerNumber(handle, TRACE_SET_LOW16(uxTimerGetTimerNumber(handle), value));
+}
+
+void prvTraceSetTimerNumberHigh16(void* handle, uint16_t value)
+{
+ vTimerSetTimerNumber(handle, TRACE_SET_HIGH16(uxTimerGetTimerNumber(handle), value));
+}
+#endif /* (TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
+
+#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
+
+uint16_t prvTraceGetEventGroupNumberLow16(void* handle)
+{
+ return TRACE_GET_LOW16(uxEventGroupGetNumber(handle));
+}
+
+uint16_t prvTraceGetEventGroupNumberHigh16(void* handle)
+{
+ return TRACE_GET_HIGH16(uxEventGroupGetNumber(handle));
+}
+
+void prvTraceSetEventGroupNumberLow16(void* handle, uint16_t value)
+{
+ vEventGroupSetNumber(handle, TRACE_SET_LOW16(uxEventGroupGetNumber(handle), value));
+}
+
+void prvTraceSetEventGroupNumberHigh16(void* handle, uint16_t value)
+{
+ vEventGroupSetNumber(handle, TRACE_SET_HIGH16(uxEventGroupGetNumber(handle), value));
+}
+#endif /* (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
+
+#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
+
+uint16_t prvTraceGetStreamBufferNumberLow16(void* handle)
+{
+ return TRACE_GET_LOW16(uxStreamBufferGetStreamBufferNumber(handle));
+}
+
+uint16_t prvTraceGetStreamBufferNumberHigh16(void* handle)
+{
+ return TRACE_GET_HIGH16(uxStreamBufferGetStreamBufferNumber(handle));
+}
+
+void prvTraceSetStreamBufferNumberLow16(void* handle, uint16_t value)
+{
+ vStreamBufferSetStreamBufferNumber(handle, TRACE_SET_LOW16(uxStreamBufferGetStreamBufferNumber(handle), value));
+}
+
+void prvTraceSetStreamBufferNumberHigh16(void* handle, uint16_t value)
+{
+ vStreamBufferSetStreamBufferNumber(handle, TRACE_SET_HIGH16(uxStreamBufferGetStreamBufferNumber(handle), value));
+}
+#endif /* (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
+
+
+#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_CORTEX_A9)
+
+#define CS_TYPE_NONE 0
+#define CS_TYPE_TASK 1
+#define CS_TYPE_ISR_MASK_CHANGED 2
+#define CS_TYPE_ISR_MASK_NOT_CHANGED 3
+
+#define CS_TYPE_INVALID 0xFFFFFFFF
+
+int cortex_a9_r5_enter_critical(void)
+{
+ uint32_t cs_type = CS_TYPE_INVALID;
+
+ if ((prvGetCPSR() & 0x001F) == 0x13) // CSPR (ASPR) mode = SVC
+ {
+ /* Executing in an ISR other than the context-switch (where interrupts might have been enabled, motivating a critical section). */
+ if (ulPortSetInterruptMask() == pdTRUE)
+ {
+ cs_type = CS_TYPE_ISR_MASK_NOT_CHANGED;
+ }
+ else
+ {
+ cs_type = CS_TYPE_ISR_MASK_CHANGED;
+ }
+ }
+ else if (uiTraceSystemState == TRC_STATE_IN_TASKSWITCH)
+ {
+ // In the context-switch code. All interrupts are already masked here, so don't modify the mask.
+ cs_type = CS_TYPE_NONE;
+ }
+ else if (uiTraceSystemState != TRC_STATE_IN_TASKSWITCH)
+ {
+ // Not within ISR or task-switch context, use a regular critical section.
+ vPortEnterCritical();
+ cs_type = CS_TYPE_TASK;
+ }
+
+ return cs_type;
+}
+
+void cortex_a9_r5_exit_critical(int cs_type)
+{
+ switch (cs_type)
+ {
+ case CS_TYPE_TASK:
+ vPortExitCritical();
+ break;
+
+ case CS_TYPE_ISR_MASK_CHANGED:
+ vPortClearInterruptMask(pdFALSE); // pdFALSE means it will reset the IRQ mask.
+ break;
+
+ case CS_TYPE_ISR_MASK_NOT_CHANGED:
+ case CS_TYPE_NONE:
+ // No action in these two cases.
+ break;
+
+ default:
+ // Error, should not be possible;
+ for (;;);
+ }
+}
+#endif
+
+#if defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0)
+
+typedef struct {
+ void* tcb;
+ uint32_t uiPreviousLowMark;
+} TaskStackMonitorEntry_t;
+
+TaskStackMonitorEntry_t tasksInStackMonitor[TRC_CFG_STACK_MONITOR_MAX_TASKS] = { { NULL } };
+
+int tasksNotIncluded = 0;
+
+void prvAddTaskToStackMonitor(void* task)
+{
+ int i;
+ int foundEmptySlot = 0;
+
+ // find an empty slot
+ for (i = 0; i < TRC_CFG_STACK_MONITOR_MAX_TASKS; i++)
+ {
+ if (tasksInStackMonitor[i].tcb == NULL)
+ {
+ tasksInStackMonitor[i].tcb = task;
+ tasksInStackMonitor[i].uiPreviousLowMark = 0xFFFFFFFF;
+ foundEmptySlot = 1;
+ break;
+ }
+ }
+
+ if (foundEmptySlot == 0)
+ {
+ tasksNotIncluded++;
+ }
+}
+
+void prvRemoveTaskFromStackMonitor(void* task)
+{
+ int i;
+
+ for (i = 0; i < TRC_CFG_STACK_MONITOR_MAX_TASKS; i++)
+ {
+ if (tasksInStackMonitor[i].tcb == task)
+ {
+ tasksInStackMonitor[i].tcb = NULL;
+ tasksInStackMonitor[i].uiPreviousLowMark = 0;
+ }
+ }
+}
+
+void prvReportStackUsage()
+{
+ static int i = 0; /* Static index used to loop over the monitored tasks */
+ int count = 0; /* The number of generated reports */
+ int initial = i; /* Used to make sure we break if we are back at the inital value */
+
+ do
+ {
+ /* Check the current spot */
+ if (tasksInStackMonitor[i].tcb != NULL)
+ {
+ /* Get the amount of unused stack */
+ uint32_t unusedStackSpace = uxTaskGetStackHighWaterMark((TaskType)tasksInStackMonitor[i].tcb);
+
+ /* Store for later use */
+ if (tasksInStackMonitor[i].uiPreviousLowMark > unusedStackSpace)
+ tasksInStackMonitor[i].uiPreviousLowMark = unusedStackSpace;
+
+#if TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT
+ prvTraceStoreKernelCallWithParam(TRACE_UNUSED_STACK, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(tasksInStackMonitor[i].tcb), tasksInStackMonitor[i].uiPreviousLowMark);
+#else /* TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT */
+ prvTraceStoreEvent2(PSF_EVENT_UNUSED_STACK, (uint32_t)tasksInStackMonitor[i].tcb, tasksInStackMonitor[i].uiPreviousLowMark);
+#endif /* TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT */
+
+ count++;
+ }
+
+ i = (i + 1) % TRC_CFG_STACK_MONITOR_MAX_TASKS; // Move i beyond this task
+ } while (count < TRC_CFG_STACK_MONITOR_MAX_REPORTS && i != initial);
+}
+#endif /* defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0) */
+
+#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
+
+static void* pCurrentTCB = NULL;
+
+/* Monitored by TzCtrl task, that give warnings as User Events */
+extern volatile uint32_t NoRoomForSymbol;
+extern volatile uint32_t NoRoomForObjectData;
+extern volatile uint32_t LongestSymbolName;
+extern volatile uint32_t MaxBytesTruncated;
+
+/* User Event Channel for giving warnings regarding NoRoomForSymbol etc. */
+traceString trcWarningChannel;
+
+#define TRC_PORT_MALLOC(size) pvPortMalloc(size)
+
+TRC_STREAM_PORT_ALLOCATE_FIELDS()
+
+/* Called by TzCtrl task periodically (Normally every 100 ms) */
+static void prvCheckRecorderStatus(void);
+
+extern void prvTraceWarning(int errCode);
+
+/*******************************************************************************
+ * vTraceEnable
+ *
+ * Function that enables the tracing and creates the control task. It will halt
+ * execution until a Start command has been received if haltUntilStart is true.
+ *
+ ******************************************************************************/
+void vTraceEnable(int startOption)
+{
+ int32_t bytes = 0;
+ int32_t status;
+ extern uint32_t RecorderEnabled;
+ TracealyzerCommandType msg;
+
+ /* Only do this first time...*/
+ if (HandleTzCtrl == NULL)
+ {
+ TRC_STREAM_PORT_INIT();
+
+ /* The #WFR channel means "Warnings from Recorder" and
+ * is used to store warnings and errors from the recorder.
+ * The abbreviation #WFR is used instead of the longer full name,
+ * to avoid truncation by small slots in the symbol table.
+ * This is translated in Tracealyzer and shown as the full name,
+ * "Warnings from Recorder".
+ *
+ * Note: Requires that TRC_CFG_INCLUDE_USER_EVENTS is 1. */
+
+ trcWarningChannel = xTraceRegisterString("#WFR");
+
+ /* Creates the TzCtrl task - receives trace commands (start, stop, ...) */
+ #if defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION == 1)
+ HandleTzCtrl = xTaskCreateStatic(TzCtrl, STRING_CAST("TzCtrl"), TRC_CFG_CTRL_TASK_STACK_SIZE, NULL, TRC_CFG_CTRL_TASK_PRIORITY, stackTzCtrl, &tcbTzCtrl);
+ #else
+ xTaskCreate( TzCtrl, STRING_CAST("TzCtrl"), TRC_CFG_CTRL_TASK_STACK_SIZE, NULL, TRC_CFG_CTRL_TASK_PRIORITY, &HandleTzCtrl );
+ #endif
+
+ if (HandleTzCtrl == NULL)
+ {
+ prvTraceError(PSF_ERROR_TZCTRLTASK_NOT_CREATED);
+ }
+ }
+
+ if (startOption == TRC_START_AWAIT_HOST)
+ {
+ /* We keep trying to read commands until the recorder has been started */
+ do
+ {
+ bytes = 0;
+
+ status = TRC_STREAM_PORT_READ_DATA(&msg, sizeof(TracealyzerCommandType), (int32_t*)&bytes);
+
+ if (status != 0)
+ {
+ prvTraceWarning(PSF_WARNING_STREAM_PORT_READ);
+ }
+
+ if ((status == 0) && (bytes == sizeof(TracealyzerCommandType)))
+ {
+ if (prvIsValidCommand(&msg))
+ {
+ if (msg.cmdCode == CMD_SET_ACTIVE && msg.param1 == 1)
+ {
+ /* On start, init and reset the timestamping */
+ TRC_PORT_SPECIFIC_INIT();
+ }
+
+ prvProcessCommand(&msg);
+ }
+ }
+ }
+ while (RecorderEnabled == 0);
+ }
+ else if (startOption == TRC_START)
+ {
+ /* We start streaming directly - this assumes that the interface is ready! */
+ TRC_PORT_SPECIFIC_INIT();
+
+ msg.cmdCode = CMD_SET_ACTIVE;
+ msg.param1 = 1;
+ prvProcessCommand(&msg);
+ }
+ else
+ {
+ /* On TRC_INIT */
+ TRC_PORT_SPECIFIC_INIT();
+ }
+}
+
+#if (TRC_CFG_SCHEDULING_ONLY == 0)
+/*******************************************************************************
+ * vTraceSetQueueName(void* object, const char* name)
+ *
+ * Parameter object: pointer to the Queue that shall be named
+ * Parameter name: the name to set (const string literal)
+ *
+ * Sets a name for Queue objects for display in Tracealyzer.
+ ******************************************************************************/
+void vTraceSetQueueName(void* object, const char* name)
+{
+ vTraceStoreKernelObjectName(object, name);
+}
+
+/*******************************************************************************
+ * vTraceSetSemaphoreName(void* object, const char* name)
+ *
+ * Parameter object: pointer to the Semaphore that shall be named
+ * Parameter name: the name to set (const string literal)
+ *
+ * Sets a name for Semaphore objects for display in Tracealyzer.
+ ******************************************************************************/
+void vTraceSetSemaphoreName(void* object, const char* name)
+{
+ vTraceStoreKernelObjectName(object, name);
+}
+
+/*******************************************************************************
+ * vTraceSetMutexName(void* object, const char* name)
+ *
+ * Parameter object: pointer to the Mutex that shall be named
+ * Parameter name: the name to set (const string literal)
+ *
+ * Sets a name for Mutex objects for display in Tracealyzer.
+ ******************************************************************************/
+void vTraceSetMutexName(void* object, const char* name)
+{
+ vTraceStoreKernelObjectName(object, name);
+}
+
+#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X)
+/*******************************************************************************
+* vTraceSetEventGroupName(void* object, const char* name)
+*
+* Parameter object: pointer to the vTraceSetEventGroupName that shall be named
+* Parameter name: the name to set (const string literal)
+*
+* Sets a name for EventGroup objects for display in Tracealyzer.
+******************************************************************************/
+void vTraceSetEventGroupName(void* object, const char* name)
+{
+ vTraceStoreKernelObjectName(object, name);
+}
+#endif /* (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X) */
+
+#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
+/*******************************************************************************
+* vTraceSetStreamBufferName(void* object, const char* name)
+*
+* Parameter object: pointer to the StreamBuffer that shall be named
+* Parameter name: the name to set (const string literal)
+*
+* Sets a name for StreamBuffer objects for display in Tracealyzer.
+******************************************************************************/
+void vTraceSetStreamBufferName(void* object, const char* name)
+{
+ vTraceStoreKernelObjectName(object, name);
+}
+
+/*******************************************************************************
+* vTraceSetMessageBufferName(void* object, const char* name)
+*
+* Parameter object: pointer to the MessageBuffer that shall be named
+* Parameter name: the name to set (const string literal)
+*
+* Sets a name for MessageBuffer objects for display in Tracealyzer.
+******************************************************************************/
+void vTraceSetMessageBufferName(void* object, const char* name)
+{
+ vTraceStoreKernelObjectName(object, name);
+}
+#endif /* (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
+
+#endif /* (TRC_CFG_SCHEDULING_ONLY == 0) */
+
+/*******************************************************************************
+ * prvGetCurrentTaskHandle
+ *
+ * Function that returns the handle to the currently executing task.
+ *
+ ******************************************************************************/
+void* prvTraceGetCurrentTaskHandle(void)
+{
+ return xTaskGetCurrentTaskHandle();
+}
+
+/*******************************************************************************
+ * prvIsNewTCB
+ *
+ * Tells if this task is already executing, or if there has been a task-switch.
+ * Assumed to be called within a trace hook in kernel context.
+ ******************************************************************************/
+uint32_t prvIsNewTCB(void* pNewTCB)
+{
+ if (pCurrentTCB != pNewTCB)
+ {
+ pCurrentTCB = pNewTCB;
+ return 1;
+ }
+ return 0;
+}
+
+/*******************************************************************************
+ * prvTraceIsSchedulerSuspended
+ *
+ * Returns true if the RTOS scheduler currently is disabled, thus preventing any
+ * task-switches from occurring. Only called from vTraceStoreISREnd.
+ ******************************************************************************/
+unsigned char prvTraceIsSchedulerSuspended(void)
+{
+ /* Assumed to be available in FreeRTOS. According to the FreeRTOS docs,
+ INCLUDE_xTaskGetSchedulerState or configUSE_TIMERS must be set to 1 in
+ FreeRTOSConfig.h for this function to be available. */
+
+ return xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED;
+}
+
+/*******************************************************************************
+ * prvCheckRecorderStatus
+ *
+ * Called by TzCtrl task periodically (every 100 ms - seems reasonable).
+ * Checks a number of diagnostic variables and give warnings as user events,
+ * in most cases including a suggested solution.
+ ******************************************************************************/
+static void prvCheckRecorderStatus(void)
+{
+#if defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0)
+ if (tasksNotIncluded > 0)
+ {
+ prvTraceWarning(PSF_WARNING_STACKMON_NO_SLOTS);
+ tasksNotIncluded = 0;
+ }
+#endif /* defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0) */
+
+ if (NoRoomForSymbol > 0)
+ {
+ prvTraceWarning(PSF_WARNING_SYMBOL_TABLE_SLOTS);
+ NoRoomForSymbol = 0;
+ }
+
+ if (NoRoomForObjectData > 0)
+ {
+ prvTraceWarning(PSF_WARNING_OBJECT_DATA_SLOTS);
+ NoRoomForObjectData = 0;
+ }
+
+ if (LongestSymbolName > (TRC_CFG_SYMBOL_MAX_LENGTH))
+ {
+ prvTraceWarning(PSF_WARNING_SYMBOL_MAX_LENGTH);
+ LongestSymbolName = 0;
+ }
+
+ if (MaxBytesTruncated > 0)
+ {
+ prvTraceWarning(PSF_WARNING_STRING_TOO_LONG);
+ MaxBytesTruncated = 0;
+ }
+}
+
+/*******************************************************************************
+ * TzCtrl
+ *
+ * Task for sending the trace data from the internal buffer to the stream
+ * interface (assuming TRC_STREAM_PORT_USE_INTERNAL_BUFFER == 1) and for
+ * receiving commands from Tracealyzer. Also does some diagnostics.
+ ******************************************************************************/
+static portTASK_FUNCTION( TzCtrl, pvParameters )
+{
+ TracealyzerCommandType msg;
+ int32_t bytes = 0;
+ int32_t status = 0;
+ (void)pvParameters;
+
+ while (1)
+ {
+ do
+ {
+ /* Listen for new commands */
+ bytes = 0;
+ status = TRC_STREAM_PORT_READ_DATA(&msg, sizeof(TracealyzerCommandType), (int32_t*)&bytes);
+
+ if (status != 0)
+ {
+ /* The connection has failed, stop tracing */
+ vTraceStop();
+ }
+
+ if ((status == 0) && (bytes == sizeof(TracealyzerCommandType)))
+ {
+ if (prvIsValidCommand(&msg))
+ {
+ prvProcessCommand(&msg); /* Start or Stop currently... */
+ }
+ }
+
+/* If the internal buffer is disabled, the COMMIT macro instead sends the data directly
+ from the "event functions" (using TRC_STREAM_PORT_WRITE_DATA). */
+#if (TRC_STREAM_PORT_USE_INTERNAL_BUFFER == 1)
+ /* If there is a buffer page, this sends it to the streaming interface using TRC_STREAM_PORT_WRITE_DATA. */
+ bytes = prvPagedEventBufferTransfer();
+#endif
+
+ /* If there was data sent or received (bytes != 0), loop around and repeat, if there is more data to send or receive.
+ Otherwise, step out of this loop and sleep for a while. */
+
+ } while (bytes != 0);
+
+ if (xTraceIsRecordingEnabled())
+ {
+ prvCheckRecorderStatus();
+ prvReportStackUsage();
+ }
+
+ vTaskDelay(TRC_CFG_CTRL_TASK_DELAY);
+ }
+}
+
+#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/
+
+
+#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)
+
+/* Internal flag to tell the context of tracePEND_FUNC_CALL_FROM_ISR */
+int uiInEventGroupSetBitsFromISR = 0;
+
+/******************************************************************************
+ * TraceQueueClassTable
+ * Translates a FreeRTOS QueueType into trace objects classes (TRACE_CLASS_).
+ * Has one entry for each QueueType, gives TRACE_CLASS ID.
+ ******************************************************************************/
+traceObjectClass TraceQueueClassTable[5] = {
+ TRACE_CLASS_QUEUE,
+ TRACE_CLASS_MUTEX,
+ TRACE_CLASS_SEMAPHORE,
+ TRACE_CLASS_SEMAPHORE,
+ TRACE_CLASS_MUTEX
+};
+
+#if (TRC_CFG_SCHEDULING_ONLY == 0)
+/*******************************************************************************
+ * vTraceSetQueueName(void* object, const char* name)
+ *
+ * Parameter object: pointer to the Queue that shall be named
+ * Parameter name: the name to set (const string literal)
+ *
+ * Sets a name for Queue objects for display in Tracealyzer.
+ ******************************************************************************/
+void vTraceSetQueueName(void* object, const char* name)
+{
+ prvTraceSetObjectName(TRACE_CLASS_QUEUE, TRACE_GET_OBJECT_NUMBER(QUEUE, object), name);
+}
+
+/*******************************************************************************
+ * vTraceSetSemaphoreName(void* object, const char* name)
+ *
+ * Parameter object: pointer to the Semaphore that shall be named
+ * Parameter name: the name to set (const string literal)
+ *
+ * Sets a name for Semaphore objects for display in Tracealyzer.
+ ******************************************************************************/
+void vTraceSetSemaphoreName(void* object, const char* name)
+{
+ prvTraceSetObjectName(TRACE_CLASS_SEMAPHORE, TRACE_GET_OBJECT_NUMBER(QUEUE, object), name);
+}
+
+/*******************************************************************************
+ * vTraceSetMutexName(void* object, const char* name)
+ *
+ * Parameter object: pointer to the Mutex that shall be named
+ * Parameter name: the name to set (const string literal)
+ *
+ * Sets a name for Semaphore objects for display in Tracealyzer.
+ ******************************************************************************/
+void vTraceSetMutexName(void* object, const char* name)
+{
+ prvTraceSetObjectName(TRACE_CLASS_MUTEX, TRACE_GET_OBJECT_NUMBER(QUEUE, object), name);
+}
+
+#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X)
+/*******************************************************************************
+* vTraceSetEventGroupName(void* object, const char* name)
+*
+* Parameter object: pointer to the EventGroup that shall be named
+* Parameter name: the name to set (const string literal)
+*
+* Sets a name for EventGroup objects for display in Tracealyzer.
+******************************************************************************/
+void vTraceSetEventGroupName(void* object, const char* name)
+{
+ prvTraceSetObjectName(TRACE_CLASS_EVENTGROUP, TRACE_GET_OBJECT_NUMBER(EVENTGROUP, object), name);
+}
+#endif /* (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X) */
+
+#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
+/*******************************************************************************
+* vTraceSetStreamBufferName(void* object, const char* name)
+*
+* Parameter object: pointer to the StreamBuffer that shall be named
+* Parameter name: the name to set (const string literal)
+*
+* Sets a name for StreamBuffer objects for display in Tracealyzer.
+******************************************************************************/
+void vTraceSetStreamBufferName(void* object, const char* name)
+{
+ prvTraceSetObjectName(TRACE_CLASS_STREAMBUFFER, TRACE_GET_OBJECT_NUMBER(STREAMBUFFER, object), name);
+}
+
+/*******************************************************************************
+* vTraceSetMessageBufferName(void* object, const char* name)
+*
+* Parameter object: pointer to the MessageBuffer that shall be named
+* Parameter name: the name to set (const string literal)
+*
+* Sets a name for MessageBuffer objects for display in Tracealyzer.
+******************************************************************************/
+void vTraceSetMessageBufferName(void* object, const char* name)
+{
+ prvTraceSetObjectName(TRACE_CLASS_MESSAGEBUFFER, TRACE_GET_OBJECT_NUMBER(STREAMBUFFER, object), name);
+}
+#endif /* (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
+
+#endif /* (TRC_CFG_SCHEDULING_ONLY == 0) */
+
+void* prvTraceGetCurrentTaskHandle()
+{
+ return xTaskGetCurrentTaskHandle();
+}
+
+/******************************************************************************
+* vTraceEnable(int startOption) - snapshot mode
+*
+* 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_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, in snapshot mode:
+*
+* 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
+*
+*
+* Note: See other implementation of vTraceEnable in trcStreamingRecorder.c
+******************************************************************************/
+void vTraceEnable(int startOption)
+{
+ prvTraceInitTraceData();
+
+ if (startOption == TRC_START)
+ {
+ vTraceStart();
+ }
+ else if (startOption == TRC_START_AWAIT_HOST)
+ {
+ prvTraceError("vTraceEnable(TRC_START_AWAIT_HOST) not allowed in Snapshot mode");
+ }
+ else if (startOption != TRC_INIT)
+ {
+ prvTraceError("Unexpected argument to vTraceEnable (snapshot mode)");
+ }
+
+#if defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0)
+ /* Creates the TzCtrl task - reports unsed stack */
+ if (HandleTzCtrl == NULL)
+ {
+#if defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION == 1)
+ HandleTzCtrl = xTaskCreateStatic(TzCtrl, STRING_CAST("TzCtrl"), TRC_CFG_CTRL_TASK_STACK_SIZE, NULL, TRC_CFG_CTRL_TASK_PRIORITY, stackTzCtrl, &tcbTzCtrl);
+#else /* defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION == 1) */
+ xTaskCreate(TzCtrl, STRING_CAST("TzCtrl"), TRC_CFG_CTRL_TASK_STACK_SIZE, NULL, TRC_CFG_CTRL_TASK_PRIORITY, &HandleTzCtrl);
+#endif /* defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION == 1) */
+ }
+
+#endif /* defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0) */
+}
+
+/*******************************************************************************
+* TzCtrl
+*
+* Task for sending the trace data from the internal buffer to the stream
+* interface (assuming TRC_STREAM_PORT_USE_INTERNAL_BUFFER == 1) and for
+* receiving commands from Tracealyzer. Also does some diagnostics.
+******************************************************************************/
+#if defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0)
+static portTASK_FUNCTION(TzCtrl, pvParameters)
+{
+ (void)pvParameters;
+
+ while (1)
+ {
+ if (xTraceIsRecordingEnabled())
+ {
+ prvReportStackUsage();
+ }
+
+ vTaskDelay(TRC_CFG_CTRL_TASK_DELAY);
+ }
+}
+#endif
+
+/* Initialization of the object property table */
+void vTraceInitObjectPropertyTable()
+{
+ RecorderDataPtr->ObjectPropertyTable.NumberOfObjectClasses = TRACE_NCLASSES;
+ RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[0] = TRC_CFG_NQUEUE;
+ RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[1] = TRC_CFG_NSEMAPHORE;
+ RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[2] = TRC_CFG_NMUTEX;
+ RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[3] = TRC_CFG_NTASK;
+ RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[4] = TRC_CFG_NISR;
+ RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[5] = TRC_CFG_NTIMER;
+ RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[6] = TRC_CFG_NEVENTGROUP;
+ RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[7] = TRC_CFG_NSTREAMBUFFER;
+ RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[8] = TRC_CFG_NMESSAGEBUFFER;
+ RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[0] = TRC_CFG_NAME_LEN_QUEUE;
+ RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[1] = TRC_CFG_NAME_LEN_SEMAPHORE;
+ RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[2] = TRC_CFG_NAME_LEN_MUTEX;
+ RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[3] = TRC_CFG_NAME_LEN_TASK;
+ RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[4] = TRC_CFG_NAME_LEN_ISR;
+ RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[5] = TRC_CFG_NAME_LEN_TIMER;
+ RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[6] = TRC_CFG_NAME_LEN_EVENTGROUP;
+ RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[7] = TRC_CFG_NAME_LEN_STREAMBUFFER;
+ RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[8] = TRC_CFG_NAME_LEN_MESSAGEBUFFER;
+ RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[0] = PropertyTableSizeQueue;
+ RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[1] = PropertyTableSizeSemaphore;
+ RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[2] = PropertyTableSizeMutex;
+ RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[3] = PropertyTableSizeTask;
+ RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[4] = PropertyTableSizeISR;
+ RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[5] = PropertyTableSizeTimer;
+ RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[6] = PropertyTableSizeEventGroup;
+ RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[7] = PropertyTableSizeStreamBuffer;
+ RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[8] = PropertyTableSizeMessageBuffer;
+ RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[0] = StartIndexQueue;
+ RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[1] = StartIndexSemaphore;
+ RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[2] = StartIndexMutex;
+ RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[3] = StartIndexTask;
+ RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[4] = StartIndexISR;
+ RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[5] = StartIndexTimer;
+ RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[6] = StartIndexEventGroup;
+ RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[7] = StartIndexStreamBuffer;
+ RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[8] = StartIndexMessageBuffer;
+ RecorderDataPtr->ObjectPropertyTable.ObjectPropertyTableSizeInBytes = TRACE_OBJECT_TABLE_SIZE;
+}
+
+/* Initialization of the handle mechanism, see e.g, prvTraceGetObjectHandle */
+void vTraceInitObjectHandleStack()
+{
+ objectHandleStacks.indexOfNextAvailableHandle[0] = objectHandleStacks.lowestIndexOfClass[0] = 0;
+ objectHandleStacks.indexOfNextAvailableHandle[1] = objectHandleStacks.lowestIndexOfClass[1] = (TRC_CFG_NQUEUE);
+ objectHandleStacks.indexOfNextAvailableHandle[2] = objectHandleStacks.lowestIndexOfClass[2] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE);
+ objectHandleStacks.indexOfNextAvailableHandle[3] = objectHandleStacks.lowestIndexOfClass[3] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX);
+ objectHandleStacks.indexOfNextAvailableHandle[4] = objectHandleStacks.lowestIndexOfClass[4] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK);
+ objectHandleStacks.indexOfNextAvailableHandle[5] = objectHandleStacks.lowestIndexOfClass[5] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR);
+ objectHandleStacks.indexOfNextAvailableHandle[6] = objectHandleStacks.lowestIndexOfClass[6] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER);
+ objectHandleStacks.indexOfNextAvailableHandle[7] = objectHandleStacks.lowestIndexOfClass[7] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER) + (TRC_CFG_NEVENTGROUP);
+ objectHandleStacks.indexOfNextAvailableHandle[8] = objectHandleStacks.lowestIndexOfClass[8] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER) + (TRC_CFG_NEVENTGROUP) + (TRC_CFG_NSTREAMBUFFER);
+
+ objectHandleStacks.highestIndexOfClass[0] = (TRC_CFG_NQUEUE) - 1;
+ objectHandleStacks.highestIndexOfClass[1] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) - 1;
+ objectHandleStacks.highestIndexOfClass[2] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) - 1;
+ objectHandleStacks.highestIndexOfClass[3] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) - 1;
+ objectHandleStacks.highestIndexOfClass[4] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) - 1;
+ objectHandleStacks.highestIndexOfClass[5] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER) - 1;
+ objectHandleStacks.highestIndexOfClass[6] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER) + (TRC_CFG_NEVENTGROUP) - 1;
+ objectHandleStacks.highestIndexOfClass[7] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER) + (TRC_CFG_NEVENTGROUP) + (TRC_CFG_NSTREAMBUFFER) - 1;
+ objectHandleStacks.highestIndexOfClass[8] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER) + (TRC_CFG_NEVENTGROUP) + (TRC_CFG_NSTREAMBUFFER) + (TRC_CFG_NMESSAGEBUFFER) - 1;
+}
+
+/* Returns the "Not enough handles" error message for this object class */
+const char* pszTraceGetErrorNotEnoughHandles(traceObjectClass objectclass)
+{
+ switch(objectclass)
+ {
+ case TRACE_CLASS_TASK:
+ return "Not enough TASK handles - increase TRC_CFG_NTASK in trcSnapshotConfig.h";
+ case TRACE_CLASS_ISR:
+ return "Not enough ISR handles - increase TRC_CFG_NISR in trcSnapshotConfig.h";
+ case TRACE_CLASS_SEMAPHORE:
+ return "Not enough SEMAPHORE handles - increase TRC_CFG_NSEMAPHORE in trcSnapshotConfig.h";
+ case TRACE_CLASS_MUTEX:
+ return "Not enough MUTEX handles - increase TRC_CFG_NMUTEX in trcSnapshotConfig.h";
+ case TRACE_CLASS_QUEUE:
+ return "Not enough QUEUE handles - increase TRC_CFG_NQUEUE in trcSnapshotConfig.h";
+ case TRACE_CLASS_TIMER:
+ return "Not enough TIMER handles - increase TRC_CFG_NTIMER in trcSnapshotConfig.h";
+ case TRACE_CLASS_EVENTGROUP:
+ return "Not enough EVENTGROUP handles - increase TRC_CFG_NEVENTGROUP in trcSnapshotConfig.h";
+ case TRACE_CLASS_STREAMBUFFER:
+ return "Not enough STREAMBUFFER handles - increase TRC_CFG_NSTREAMBUFFER in trcSnapshotConfig.h";
+ case TRACE_CLASS_MESSAGEBUFFER:
+ return "Not enough MESSAGEBUFFER handles - increase TRC_CFG_NMESSAGEBUFFER in trcSnapshotConfig.h";
+ default:
+ return "pszTraceGetErrorHandles: Invalid objectclass!";
+ }
+}
+
+/*******************************************************************************
+ * prvTraceIsSchedulerSuspended
+ *
+ * Returns true if the RTOS scheduler currently is disabled, thus preventing any
+ * task-switches from occurring. Only called from vTraceStoreISREnd.
+ ******************************************************************************/
+#if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
+unsigned char prvTraceIsSchedulerSuspended(void)
+{
+ /* Assumed to be available in FreeRTOS. According to the FreeRTOS docs,
+ INCLUDE_xTaskGetSchedulerState or configUSE_TIMERS must be set to 1 in
+ FreeRTOSConfig.h for this function to be available. */
+
+ return xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED;
+}
+#endif
+
+#endif /* Snapshot mode */
+
+#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcSnapshotRecorder.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcSnapshotRecorder.c
index 9eec9d2ed..a2513b08a 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcSnapshotRecorder.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcSnapshotRecorder.c
@@ -1,3105 +1,3074 @@
-/*******************************************************************************
- * Trace Recorder Library for Tracealyzer v4.1.5
- * Percepio AB, www.percepio.com
- *
- * trcSnapshotRecorder.c
- *
- * The generic core of the trace recorder's snapshot mode.
- *
- * 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
- ******************************************************************************/
-
-#include "trcRecorder.h"
-
-#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)
-
-#if (TRC_USE_TRACEALYZER_RECORDER == 1)
-
-#include <string.h>
-#include <stdarg.h>
-#include <stdint.h>
-
-#if ((TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_INCR) || (TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_DECR))
- #error "CUSTOM timestamping mode is not (yet) supported in snapshot mode!"
-#endif
-
-/* DO NOT CHANGE */
-#define TRACE_MINOR_VERSION 5
-#if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
-static traceHandle isrstack[TRC_CFG_MAX_ISR_NESTING];
-int32_t isPendingContextSwitch = 0;
-#endif /* (TRC_CFG_INCLUDE_ISR_TRACING == 1) */
-
-#if !defined TRC_CFG_INCLUDE_READY_EVENTS || TRC_CFG_INCLUDE_READY_EVENTS == 1
-static int readyEventsEnabled = 1;
-#endif /*!defined TRC_CFG_INCLUDE_READY_EVENTS || TRC_CFG_INCLUDE_READY_EVENTS == 1*/
-
-/*******************************************************************************
- * uiTraceTickCount
- *
- * This variable is should be updated by the Kernel tick interrupt. This does
- * not need to be modified when developing a new timer port. It is preferred to
- * keep any timer port changes in the HWTC macro definitions, which typically
- * give sufficient flexibility.
- ******************************************************************************/
-uint32_t uiTraceTickCount = 0;
-
-uint32_t trace_disable_timestamp = 0;
-
-static uint32_t last_timestamp = 0;
-
-/* Flag that shows if inside a critical section of the recorder */
-volatile int recorder_busy = 0;
-
-/* Holds the value set by vTraceSetFrequency */
-uint32_t timestampFrequency = 0;
-
-/* The last error message of the recorder. NULL if no error message. */
-const char* traceErrorMessage = NULL;
-
-int8_t nISRactive = 0;
-
-traceHandle handle_of_last_logged_task = 0;
-
-/* Called when the recorder is stopped, set by vTraceSetStopHook. */
-TRACE_STOP_HOOK vTraceStopHookPtr = (TRACE_STOP_HOOK)0;
-
-uint16_t CurrentFilterMask = 0xFFFF;
-
-uint16_t CurrentFilterGroup = FilterGroup0;
-
-extern int8_t nISRactive;
-
-extern traceHandle handle_of_last_logged_task;
-
-/*************** Private Functions *******************************************/
-static void prvStrncpy(char* dst, const char* src, uint32_t maxLength);
-static uint8_t prvTraceGetObjectState(uint8_t objectclass, traceHandle id);
-static void prvTraceGetChecksum(const char *pname, uint8_t* pcrc, uint8_t* plength);
-static void* prvTraceNextFreeEventBufferSlot(void);
-static uint16_t prvTraceGetDTS(uint16_t param_maxDTS);
-static traceString prvTraceOpenSymbol(const char* name, traceString userEventChannel);
-static void prvTraceUpdateCounters(void);
-
-void vTraceStoreMemMangEvent(uint32_t ecode, uint32_t address, int32_t signed_size);
-
-#if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER)
-static void prvCheckDataToBeOverwrittenForMultiEntryEvents(uint8_t nEntries);
-#endif
-
-static traceString prvTraceCreateSymbolTableEntry(const char* name,
- uint8_t crc6,
- uint8_t len,
- traceString channel);
-
-static traceString prvTraceLookupSymbolTableEntry(const char* name,
- uint8_t crc6,
- uint8_t len,
- traceString channel);
-
-
-#if (TRC_CFG_INCLUDE_ISR_TRACING == 0)
-/* ISR tracing is turned off */
-void prvTraceIncreaseISRActive(void);
-void prvTraceDecreaseISRActive(void);
-#endif /*(TRC_CFG_INCLUDE_ISR_TRACING == 0)*/
-
-#if (TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1)
-static uint8_t prvTraceGet8BitHandle(traceHandle handle);
-#else
-#define prvTraceGet8BitHandle(x) ((uint8_t)x)
-#endif
-
-
-#if (TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1) && (TRC_CFG_SCHEDULING_ONLY == 0)
-static uint32_t heapMemUsage = 0;
-#endif
-
-#if (TRC_CFG_SCHEDULING_ONLY == 0)
-static uint32_t prvTraceGetParam(uint32_t, uint32_t);
-#endif
-
-/*******************************************************************************
- * prvTraceInitTraceData
- *
- * Allocates and initializes the recorder data structure, based on the constants
- * in trcConfig.h. This allows for allocating the data on the heap, instead of
- * using a static declaration.
- ******************************************************************************/
-static void prvTraceInitTraceData(void);
-
-/*******************************************************************************
- * 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);
-
-static void prvTraceTaskInstanceFinish(int8_t direct);
-
-#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1))
-static void vTracePrintF_Helper(traceString eventLabel, const char* formatStr, va_list vl);
-
-#if (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)
-static void vTraceUBData_Helper(traceUBChannel channelPair, va_list vl);
-static void prvTraceUBHelper1(traceUBChannel channel, traceString eventLabel, traceString formatLabel, va_list vl);
-static void prvTraceUBHelper2(traceUBChannel channel, uint32_t* data, uint32_t noOfSlots);
-#endif /*(TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)*/
-#endif /* ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)) */
-
-/********* Public Functions **************************************************/
-
-uint16_t uiIndexOfObject(traceHandle objecthandle, uint8_t objectclass);
-
-/*******************************************************************************
- * prvTraceError
- *
- * Called by various parts in the recorder. Stops the recorder and stores a
- * pointer to an error message, which is printed by the monitor task.
- ******************************************************************************/
-void prvTraceError(const char* msg);
-
-/******************************************************************************
-* vTraceEnable(int startOption) - snapshot mode
-*
-* 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_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, in snapshot mode:
-*
-* 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
-*
-*
-* Note: See other implementation of vTraceEnable in trcStreamingRecorder.c
-******************************************************************************/
-void vTraceEnable(int startOption)
-{
- prvTraceInitTraceData();
-
- if (startOption == TRC_START)
- {
- vTraceStart();
- }
- else if (startOption == TRC_START_AWAIT_HOST)
- {
- prvTraceError("vTraceEnable(TRC_START_AWAIT_HOST) not allowed in Snapshot mode");
- }
- else if (startOption != TRC_INIT)
- {
- prvTraceError("Unexpected argument to vTraceEnable (snapshot mode)");
- }
-}
-
-/*******************************************************************************
- * vTraceSetRecorderDataBuffer
- *
- * If custom allocation is used, this function must be called so the recorder
- * library knows where to save the trace data.
- ******************************************************************************/
-#if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM)
-void vTraceSetRecorderDataBuffer(void* pRecorderData)
-{
- TRACE_ASSERT(pRecorderData != NULL, "vTraceSetRecorderDataBuffer, pRecorderData == NULL", TRC_UNUSED);
- RecorderDataPtr = pRecorderData;
-}
-#endif
-
-/*******************************************************************************
- * vTraceSetStopHook
- *
- * Sets a function to be called when the recorder is stopped. This can be used
- * to save the trace to a file system, if available. This is only implemented
- * for snapshot mode.
- ******************************************************************************/
-void vTraceSetStopHook(TRACE_STOP_HOOK stopHookFunction)
-{
- vTraceStopHookPtr = stopHookFunction;
-}
-
-/*******************************************************************************
- * vTraceClear
- *
- * Resets the recorder. Only necessary if a restart is desired - this is not
- * needed in the startup initialization.
- ******************************************************************************/
-void vTraceClear(void)
-{
- TRACE_ALLOC_CRITICAL_SECTION();
- trcCRITICAL_SECTION_BEGIN();
- RecorderDataPtr->absTimeLastEventSecond = 0;
- RecorderDataPtr->absTimeLastEvent = 0;
- RecorderDataPtr->nextFreeIndex = 0;
- RecorderDataPtr->numEvents = 0;
- RecorderDataPtr->bufferIsFull = 0;
- traceErrorMessage = NULL;
- RecorderDataPtr->internalErrorOccured = 0;
- (void)memset(RecorderDataPtr->eventData, 0, RecorderDataPtr->maxEvents * 4);
- handle_of_last_logged_task = 0;
- trcCRITICAL_SECTION_END();
-}
-
-/*******************************************************************************
- * uiTraceStart
- *
- * 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 trcConfig.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.
- *
- * This function is obsolete, but has been saved for backwards compatibility.
- * We recommend using vTraceEnable instead.
- ******************************************************************************/
-uint32_t uiTraceStart(void)
-{
- traceHandle handle;
- TRACE_ALLOC_CRITICAL_SECTION();
-
- handle = 0;
-
- if (RecorderDataPtr == NULL)
- {
- TRACE_ASSERT(RecorderDataPtr != NULL, "Recorder not initialized. Use vTraceEnable() instead!", 0);
- return 0;
- }
-
- if (RecorderDataPtr->recorderActive == 1)
- return 1; /* Already running */
-
- if (traceErrorMessage == NULL)
- {
- trcCRITICAL_SECTION_BEGIN();
- RecorderDataPtr->recorderActive = 1;
-
- handle = TRACE_GET_TASK_NUMBER(TRACE_GET_CURRENT_TASK());
- if (handle == 0)
- {
- /* This occurs if the scheduler is not yet started.
- This creates a dummy "(startup)" task entry internally in the
- recorder */
- handle = prvTraceGetObjectHandle(TRACE_CLASS_TASK);
- prvTraceSetObjectName(TRACE_CLASS_TASK, handle, "(startup)");
-
- prvTraceSetPriorityProperty(TRACE_CLASS_TASK, handle, 0);
- }
-
- prvTraceStoreTaskswitch(handle); /* Register the currently running task */
- trcCRITICAL_SECTION_END();
- }
-
- return RecorderDataPtr->recorderActive;
-}
-
-/*******************************************************************************
- * vTraceStart
- *
- * 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 trcConfig.h
- * has a too small value (TRC_CFG_NTASK, TRC_CFG_NQUEUE, etc).
- *
- * This function is obsolete, but has been saved for backwards compatibility.
- * We recommend using vTraceEnable instead.
- ******************************************************************************/
-void vTraceStart(void)
-{
- (void)uiTraceStart();
-}
-
-/*******************************************************************************
- * vTraceStop
- *
- * Stops the recorder. The recording can be resumed by calling vTraceStart.
- * This does not reset the recorder. Use vTraceClear if that is desired.
- ******************************************************************************/
-void vTraceStop(void)
-{
- if (RecorderDataPtr != NULL)
- {
- RecorderDataPtr->recorderActive = 0;
- }
-
- if (vTraceStopHookPtr != (TRACE_STOP_HOOK)0)
- {
- (*vTraceStopHookPtr)(); /* An application call-back function. */
- }
-}
-
-/*******************************************************************************
-* xTraceIsRecordingEnabled
-* Returns true (1) if the recorder is enabled (i.e. is recording), otherwise 0.
-******************************************************************************/
-int xTraceIsRecordingEnabled(void)
-{
- if (RecorderDataPtr != NULL)
- {
- return (int)RecorderDataPtr->recorderActive;
- }
- else
- {
- return 0;
- }
-}
-
-/*******************************************************************************
- * xTraceGetLastError
- *
- * Gives the last error message, if any. NULL if no error message is stored.
- * Any error message is also presented when opening a trace file.
- ******************************************************************************/
-const char* xTraceGetLastError(void)
-{
- return traceErrorMessage;
-}
-
-/*******************************************************************************
-* vTraceClearError
-*
-* Removes any previous error message generated by recorder calling prvTraceError.
-* By calling this function, it may be possible to start/restart the trace
-* despite errors in the recorder, but there is no guarantee that the trace
-* recorder will work correctly in that case, depending on the type of error.
-******************************************************************************/
-void vTraceClearError(void)
-{
- traceErrorMessage = NULL;
- if (RecorderDataPtr != NULL)
- {
- RecorderDataPtr->internalErrorOccured = 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)
-{
- return RecorderDataPtr;
-}
-
-/*******************************************************************************
- * 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)
-{
- return sizeof(RecorderDataType);
-}
-
-/******************************************************************************
- * prvTraceTaskInstanceFinish
- *
- * Private common function for the vTraceTaskInstanceFinishXXX functions.
- *****************************************************************************/
-static void prvTraceTaskInstanceFinish(int8_t direct)
-{
- TaskInstanceStatusEvent* tis;
- uint8_t dts45;
-
- TRACE_ALLOC_CRITICAL_SECTION();
-
- trcCRITICAL_SECTION_BEGIN();
- if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)
- {
- dts45 = (uint8_t)prvTraceGetDTS(0xFF);
- tis = (TaskInstanceStatusEvent*) prvTraceNextFreeEventBufferSlot();
- if (tis != NULL)
- {
- if (direct == 0)
- tis->type = TASK_INSTANCE_FINISHED_NEXT_KSE;
- else
- tis->type = TASK_INSTANCE_FINISHED_DIRECT;
-
- tis->dts = dts45;
- prvTraceUpdateCounters();
- }
- }
- trcCRITICAL_SECTION_END();
-}
-
-/******************************************************************************
- * vTraceInstanceFinishedNext(void)
- *
- * 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.
- *
- * See also TRC_CFG_USE_IMPLICIT_IFE_RULES in trcConfig.h
- *
- * Example:
- *
- * while(1)
- * {
- * xQueueReceive(CommandQueue, &command, timeoutDuration);
- * processCommand(command);
- * vTraceInstanceFinishedNext();
- * }
- *****************************************************************************/
-void vTraceInstanceFinishedNext(void)
-{
- prvTraceTaskInstanceFinish(0);
-}
-
-/******************************************************************************
- * vTraceInstanceFinishedNow(void)
- *
- * Marks the current task instance as finished at this very instant.
- * This makes the viewer to splits the current fragment at this point and begin
- * a new actor instance.
- *
- * See also TRC_CFG_USE_IMPLICIT_IFE_RULES in trcConfig.h
- *
- * Example:
- *
- * This example will generate two instances for each loop iteration.
- * The first instance ends at vTraceInstanceFinishedNow(), while the second
- * instance ends at the next xQueueReceive call.
- *
- * while (1)
- * {
- * xQueueReceive(CommandQueue, &command, timeoutDuration);
- * ProcessCommand(command);
- * vTraceInstanceFinishedNow();
- * DoSometingElse();
- * vTraceInstanceFinishedNext();
- * }
- *****************************************************************************/
-void vTraceInstanceFinishedNow(void)
-{
- prvTraceTaskInstanceFinish(1);
-}
-
-/*******************************************************************************
- * Interrupt recording functions
- ******************************************************************************/
-
-#if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
-
-/*******************************************************************************
- * 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)
-{
- static traceHandle handle = 0;
- TRACE_ASSERT(RecorderDataPtr != NULL, "Recorder not initialized, call vTraceEnable() first!", (traceHandle)0);
- TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[TRACE_CLASS_ISR], "xTraceSetISRProperties: Invalid value for handle", 0);
- TRACE_ASSERT(name != NULL, "xTraceSetISRProperties: name == NULL", 0);
-
- handle++;
-
- prvTraceSetObjectName(TRACE_CLASS_ISR, handle, name);
- prvTraceSetPriorityProperty(TRACE_CLASS_ISR, handle, priority);
-
- return handle;
-}
-
-/*******************************************************************************
- * 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)
-{
- TRACE_ALLOC_CRITICAL_SECTION();
-
- if (recorder_busy)
- {
- /*************************************************************************
- * This occurs if an ISR calls a trace function, preempting a previous
- * trace call that is being processed in a different ISR or task.
- * If this occurs, there is probably a problem in the definition of the
- * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and
- * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt
- * and any other ISRs that calls the trace recorder directly or via
- * traced kernel functions. The ARM port disables all interrupts using the
- * PRIMASK register to avoid this issue.
- *************************************************************************/
- prvTraceError("vTraceStoreISRBegin - recorder busy! See code comment.");
- return;
- }
- trcCRITICAL_SECTION_BEGIN();
-
- if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)
- {
- uint16_t dts4;
-
- TRACE_ASSERT(handle != 0, "vTraceStoreISRBegin: Invalid ISR handle (NULL)", TRC_UNUSED);
- TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[TRACE_CLASS_ISR], "vTraceStoreISRBegin: Invalid ISR handle (> NISR)", TRC_UNUSED);
-
- dts4 = (uint16_t)prvTraceGetDTS(0xFFFF);
-
- if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */
- {
- if (nISRactive < TRC_CFG_MAX_ISR_NESTING)
- {
- TSEvent* ts;
- uint8_t hnd8 = prvTraceGet8BitHandle(handle);
- isrstack[nISRactive] = handle;
- nISRactive++;
- ts = (TSEvent*)prvTraceNextFreeEventBufferSlot();
- if (ts != NULL)
- {
- ts->type = TS_ISR_BEGIN;
- ts->dts = dts4;
- ts->objHandle = hnd8;
- prvTraceUpdateCounters();
- }
- }
- else
- {
- /* This should not occur unless something is very wrong */
- prvTraceError("Too many nested interrupts!");
- }
- }
- }
- trcCRITICAL_SECTION_END();
-}
-
-/*******************************************************************************
- * 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 pendingISR)
-{
- TSEvent* ts;
- uint16_t dts5;
- uint8_t hnd8 = 0, type = 0;
-
- TRACE_ALLOC_CRITICAL_SECTION();
-
- if (! RecorderDataPtr->recorderActive || ! handle_of_last_logged_task)
- {
- return;
- }
-
- if (recorder_busy)
- {
- /*************************************************************************
- * This occurs if an ISR calls a trace function, preempting a previous
- * trace call that is being processed in a different ISR or task.
- * If this occurs, there is probably a problem in the definition of the
- * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and
- * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt
- * and any other ISRs that calls the trace recorder directly or via
- * traced kernel functions. The ARM port disables all interrupts using the
- * PRIMASK register to avoid this issue.
- *************************************************************************/
- prvTraceError("vTraceStoreISREnd - recorder busy! See code comment.");
- return;
- }
-
- if (nISRactive == 0)
- {
- prvTraceError("Unmatched call to vTraceStoreISREnd (nISRactive == 0, expected > 0)");
- return;
- }
-
- trcCRITICAL_SECTION_BEGIN();
- isPendingContextSwitch |= pendingISR; /* Is there a pending context switch right now? */
- nISRactive--;
- if (nISRactive > 0)
- {
- /* Return to another ISR */
- type = TS_ISR_RESUME;
- hnd8 = prvTraceGet8BitHandle(isrstack[nISRactive - 1]); /* isrstack[nISRactive] is the handle of the ISR we're currently exiting. isrstack[nISRactive - 1] is the handle of the ISR that was executing previously. */
- }
- else if ((isPendingContextSwitch == 0) || (prvTraceIsSchedulerSuspended()))
- {
- /* Return to interrupted task, if no context switch will occur in between. */
- type = TS_TASK_RESUME;
- hnd8 = prvTraceGet8BitHandle(handle_of_last_logged_task);
- }
-
- if (type != 0)
- {
- dts5 = (uint16_t)prvTraceGetDTS(0xFFFF);
- ts = (TSEvent*)prvTraceNextFreeEventBufferSlot();
- if (ts != NULL)
- {
- ts->type = type;
- ts->objHandle = hnd8;
- ts->dts = dts5;
- prvTraceUpdateCounters();
- }
- }
-
- trcCRITICAL_SECTION_END();
-}
-
-#else
-
-/* ISR tracing is turned off */
-void prvTraceIncreaseISRActive(void)
-{
- if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)
- nISRactive++;
-}
-
-void prvTraceDecreaseISRActive(void)
-{
- if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)
- nISRactive--;
-}
-#endif /* (TRC_CFG_INCLUDE_ISR_TRACING == 1)*/
-
-
-/********************************************************************************/
-/* User Event functions */
-/********************************************************************************/
-
-#define MAX_ARG_SIZE (4+32)
-
-#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1))
-static uint8_t writeInt8(void * buffer, uint8_t i, uint8_t value)
-{
- TRACE_ASSERT(buffer != NULL, "writeInt8: buffer == NULL", 0);
-
- if (i >= MAX_ARG_SIZE)
- {
- return 255;
- }
-
- ((uint8_t*)buffer)[i] = value;
-
- if (i + 1 > MAX_ARG_SIZE)
- {
- return 255;
- }
-
- return ((uint8_t) (i + 1));
-}
-#endif
-
-#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1))
-static uint8_t writeInt16(void * buffer, uint8_t i, uint16_t value)
-{
- TRACE_ASSERT(buffer != NULL, "writeInt16: buffer == NULL", 0);
-
- /* Align to multiple of 2 */
- while ((i % 2) != 0)
- {
- if (i >= MAX_ARG_SIZE)
- {
- return 255;
- }
-
- ((uint8_t*)buffer)[i] = 0;
- i++;
- }
-
- if (i + 2 > MAX_ARG_SIZE)
- {
- return 255;
- }
-
- ((uint16_t*)buffer)[i/2] = value;
-
- return ((uint8_t) (i + 2));
-}
-#endif
-
-#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1))
-static uint8_t writeInt32(void * buffer, uint8_t i, uint32_t value)
-{
- TRACE_ASSERT(buffer != NULL, "writeInt32: buffer == NULL", 0);
-
- /* A 32 bit value should begin at an even 4-byte address */
- while ((i % 4) != 0)
- {
- if (i >= MAX_ARG_SIZE)
- {
- return 255;
- }
-
- ((uint8_t*)buffer)[i] = 0;
- i++;
- }
-
- if (i + 4 > MAX_ARG_SIZE)
- {
- return 255;
- }
-
- ((uint32_t*)buffer)[i/4] = value;
-
- return ((uint8_t) (i + 4));
-}
-#endif
-
-#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_INCLUDE_FLOAT_SUPPORT))
-static uint8_t writeFloat(void * buffer, uint8_t i, float value)
-{
- TRACE_ASSERT(buffer != NULL, "writeFloat: buffer == NULL", 0);
-
- /* A 32 bit value should begin at an even 4-byte address */
- while ((i % 4) != 0)
- {
- if (i >= MAX_ARG_SIZE)
- {
- return 255;
- }
-
- ((uint8_t*)buffer)[i] = 0;
- i++;
- }
-
- if (i + 4 > MAX_ARG_SIZE)
- {
- return 255;
- }
-
- ((float*)buffer)[i/4] = value;
-
- return i + 4;
-}
-#endif
-
-#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_INCLUDE_FLOAT_SUPPORT))
-static uint8_t writeDouble(void * buffer, uint8_t i, double value)
-{
- uint32_t * dest;
- uint32_t * src = (uint32_t*)&value;
-
- TRACE_ASSERT(buffer != NULL, "writeDouble: buffer == NULL", 0);
-
- /* The double is written as two 32 bit values, and should begin at an even
- 4-byte address (to avoid having to align with 8 byte) */
- while (i % 4 != 0)
- {
- if (i >= MAX_ARG_SIZE)
- {
- return 255;
- }
-
- ((uint8_t*)buffer)[i] = 0;
- i++;
- }
-
- if (i + 8 > MAX_ARG_SIZE)
- {
- return 255;
- }
-
- dest = &(((uint32_t *)buffer)[i/4]);
-
- dest[0] = src[0];
- dest[1] = src[1];
-
- return i + 8;
-}
-#endif
-
-/*******************************************************************************
- * prvTraceUserEventFormat
- *
- * Parses the format string and stores the arguments in the buffer.
- ******************************************************************************/
-#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1))
-static uint8_t prvTraceUserEventFormat(const char* formatStr, va_list vl, uint8_t* buffer, uint8_t byteOffset)
-{
- uint16_t formatStrIndex = 0;
- uint8_t argCounter = 0;
- uint8_t i = byteOffset;
-
- while (formatStr[formatStrIndex] != '\0')
- {
- if (formatStr[formatStrIndex] == '%')
- {
- argCounter++;
-
- if (argCounter > 15)
- {
- prvTraceError("vTracePrintF - Too many arguments, max 15 allowed!");
- return 0;
- }
-
- formatStrIndex++;
-
- while ((formatStr[formatStrIndex] >= '0' && formatStr[formatStrIndex] <= '9') || formatStr[formatStrIndex] == '#' || formatStr[formatStrIndex] == '.')
- formatStrIndex++;
-
- if (formatStr[formatStrIndex] != '\0')
- {
- switch (formatStr[formatStrIndex])
- {
- case 'd': i = writeInt32( buffer,
- i,
- (uint32_t)va_arg(vl, uint32_t));
- break;
- case 'x':
- case 'X':
- case 'u': i = writeInt32( buffer,
- i,
- (uint32_t)va_arg(vl, uint32_t));
- break;
- case 's': i = writeInt16( buffer,
- i,
- xTraceRegisterString((char*)va_arg(vl, char*)));
- break;
-
-#if (TRC_CFG_INCLUDE_FLOAT_SUPPORT)
- /* Yes, "double" as type also in the float
- case. This since "float" is promoted into "double"
- by the va_arg stuff. */
- case 'f': i = writeFloat( buffer,
- i,
- (float)va_arg(vl, double));
- break;
-#else
- /* No support for floats, but attempt to store a float user event
- avoid a possible crash due to float reference. Instead store the
- data on uint_32 format (will not be displayed anyway). This is just
- to keep va_arg and i consistent. */
-
- case 'f': i = writeInt32( buffer,
- i,
- (uint32_t)va_arg(vl, double));
- break;
-#endif
- case 'l':
- formatStrIndex++;
- switch (formatStr[formatStrIndex])
- {
-#if (TRC_CFG_INCLUDE_FLOAT_SUPPORT)
- case 'f': i = writeDouble(buffer,
- i,
- (double)va_arg(vl, double));
- break;
-#else
- /* No support for floats, but attempt to store a float user event
- avoid a possible crash due to float reference. Instead store the
- data on uint_32 format (will not be displayed anyway). This is just
- to keep va_arg and i consistent. */
- case 'f': i = writeInt32( buffer, /* In this case, the value will not be shown anyway */
- i,
- (uint32_t)va_arg(vl, double));
-
- i = writeInt32( buffer, /* Do it twice, to write in total 8 bytes */
- i,
- (uint32_t)va_arg(vl, double));
- break;
-#endif
-
- }
- break;
- case 'h':
- formatStrIndex++;
- switch (formatStr[formatStrIndex])
- {
- case 'd': i = writeInt16( buffer,
- i,
- (uint16_t)va_arg(vl, uint32_t));
- break;
- case 'u': i = writeInt16( buffer,
- i,
- (uint16_t)va_arg(vl, uint32_t));
- break;
- }
- break;
- case 'b':
- formatStrIndex++;
- switch (formatStr[formatStrIndex])
- {
- case 'd': i = writeInt8( buffer,
- i,
- (uint8_t)va_arg(vl, uint32_t));
- break;
-
- case 'u': i = writeInt8( buffer,
- i,
- (uint8_t)va_arg(vl, uint32_t));
- break;
- }
- break;
- }
- }
- else
- break;
- }
- formatStrIndex++;
- if (i == 255)
- {
- prvTraceError("vTracePrintF - Too large arguments, max 32 byte allowed!");
- return 0;
- }
- }
- return (uint8_t)(i+3)/4;
-}
-#endif
-
-/*******************************************************************************
- * prvTraceClearChannelBuffer
- *
- * Clears a number of items in the channel buffer, starting from nextSlotToWrite.
- ******************************************************************************/
-#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1))
-static void prvTraceClearChannelBuffer(uint32_t count)
-{
- uint32_t slots;
-
- TRACE_ASSERT((TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE) >= count,
- "prvTraceClearChannelBuffer: TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE is too small to handle this event.", TRC_UNUSED);
-
- /* Check if we're close to the end of the buffer */
- if (RecorderDataPtr->userEventBuffer.nextSlotToWrite + count > (TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE))
- {
- slots = (TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE) - RecorderDataPtr->userEventBuffer.nextSlotToWrite; /* Number of slots before end of buffer */
- (void)memset(&RecorderDataPtr->userEventBuffer.channelBuffer[RecorderDataPtr->userEventBuffer.nextSlotToWrite], 0, slots);
- (void)memset(&RecorderDataPtr->userEventBuffer.channelBuffer[0], 0, (count - slots));
- }
- else
- (void)memset(&RecorderDataPtr->userEventBuffer.channelBuffer[RecorderDataPtr->userEventBuffer.nextSlotToWrite], 0, count);
-}
-#endif
-
-/*******************************************************************************
- * prvTraceCopyToDataBuffer
- *
- * Copies a number of items to the data buffer, starting from nextSlotToWrite.
- ******************************************************************************/
-#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1))
-static void prvTraceCopyToDataBuffer(uint32_t* data, uint32_t count)
-{
- uint32_t slots;
-
- TRACE_ASSERT(data != NULL,
- "prvTraceCopyToDataBuffer: data == NULL.", TRC_UNUSED);
- TRACE_ASSERT(count <= (TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE),
- "prvTraceCopyToDataBuffer: TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE is too small to handle this event.", TRC_UNUSED);
- /* Check if we're close to the end of the buffer */
- if (RecorderDataPtr->userEventBuffer.nextSlotToWrite + count > (TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE))
- {
- slots = (TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE) - RecorderDataPtr->userEventBuffer.nextSlotToWrite; /* Number of slots before end of buffer */
- (void)memcpy(&RecorderDataPtr->userEventBuffer.dataBuffer[RecorderDataPtr->userEventBuffer.nextSlotToWrite * 4], data, slots * 4);
- (void)memcpy(&RecorderDataPtr->userEventBuffer.dataBuffer[0], data + slots, (count - slots) * 4);
- }
- else
- {
- (void)memcpy(&RecorderDataPtr->userEventBuffer.dataBuffer[RecorderDataPtr->userEventBuffer.nextSlotToWrite * 4], data, count * 4);
- }
-}
-#endif
-
-/*******************************************************************************
- * prvTraceUBHelper1
- *
- * Calls on prvTraceUserEventFormat() to do the actual formatting, then goes on
- * to the next helper function.
- ******************************************************************************/
-#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1))
-static void prvTraceUBHelper1(traceUBChannel channel, traceString eventLabel, traceString formatLabel, va_list vl)
-{
- uint32_t data[(3 + MAX_ARG_SIZE) / 4];
- uint8_t byteOffset = 4; /* Need room for timestamp */
- uint8_t noOfSlots;
-
- if (channel == 0)
- {
- /* We are dealing with an unknown channel format pair */
- byteOffset = (uint8_t)(byteOffset + 4); /* Also need room for channel and format */
- ((uint16_t*)data)[2] = eventLabel;
- ((uint16_t*)data)[3] = formatLabel;
- }
-
- noOfSlots = prvTraceUserEventFormat((char*)&(RecorderDataPtr->SymbolTable.symbytes[formatLabel+4]), vl, (uint8_t*)data, byteOffset);
-
- prvTraceUBHelper2(channel, data, noOfSlots);
-}
-#endif
-
-/*******************************************************************************
- * prvTraceUBHelper2
- *
- * This function simply copies the data buffer to the actual user event buffer.
- ******************************************************************************/
-#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1))
-static void prvTraceUBHelper2(traceUBChannel channel, uint32_t* data, uint32_t noOfSlots)
-{
- static uint32_t old_timestamp = 0;
- uint32_t old_nextSlotToWrite = 0;
-
- TRACE_ALLOC_CRITICAL_SECTION();
-
- TRACE_ASSERT((TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE) >= noOfSlots, "prvTraceUBHelper2: TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE is too small to handle this event.", TRC_UNUSED);
-
- trcCRITICAL_SECTION_BEGIN();
- /* Store the timestamp */
- prvTracePortGetTimeStamp(data);
-
- if (*data < old_timestamp)
- {
- RecorderDataPtr->userEventBuffer.wraparoundCounter++;
- }
-
- old_timestamp = *data;
-
- /* Start by erasing any information in the channel buffer */
- prvTraceClearChannelBuffer(noOfSlots);
-
- prvTraceCopyToDataBuffer(data, noOfSlots); /* Will wrap around the data if necessary */
-
- old_nextSlotToWrite = RecorderDataPtr->userEventBuffer.nextSlotToWrite; /* Save the index that we want to write the channel data at when we're done */
- RecorderDataPtr->userEventBuffer.nextSlotToWrite = (RecorderDataPtr->userEventBuffer.nextSlotToWrite + noOfSlots) % (TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE); /* Make sure we never end up outside the buffer */
-
- /* Write to the channel buffer to indicate that this user event is ready to be used */
- if (channel != 0)
- {
- RecorderDataPtr->userEventBuffer.channelBuffer[old_nextSlotToWrite] = channel;
- }
- else
- {
- /* 0xFF indicates that this is not a normal channel id */
- RecorderDataPtr->userEventBuffer.channelBuffer[old_nextSlotToWrite] = (traceUBChannel)0xFF;
- }
- trcCRITICAL_SECTION_END();
-}
-#endif
-
-/*******************************************************************************
- * xTraceRegisterUBChannel
- *
- * Registers a channel for Separated User Events, i.e., those stored in the
- * separate user event buffer.
- *
- * Note: Only available if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is enabled in
- * trcSnapshotConfig.h
- ******************************************************************************/
-#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1))
-traceUBChannel xTraceRegisterUBChannel(traceString channel, traceString formatStr)
-{
- uint8_t i;
- traceUBChannel retVal = 0;
-
- TRACE_ALLOC_CRITICAL_SECTION();
-
- TRACE_ASSERT(formatStr != 0, "xTraceRegisterChannelFormat: formatStr == 0", (traceUBChannel)0);
-
- trcCRITICAL_SECTION_BEGIN();
- for (i = 1; i <= (TRC_CFG_UB_CHANNELS); i++) /* Size of the channels buffer is TRC_CFG_UB_CHANNELS + 1. Index 0 is unused. */
- {
- if(RecorderDataPtr->userEventBuffer.channels[i].name == 0 && RecorderDataPtr->userEventBuffer.channels[i].defaultFormat == 0)
- {
- /* Found empty slot */
- RecorderDataPtr->userEventBuffer.channels[i].name = channel;
- RecorderDataPtr->userEventBuffer.channels[i].defaultFormat = formatStr;
- retVal = (traceUBChannel)i;
- break;
- }
-
- if (RecorderDataPtr->userEventBuffer.channels[i].name == channel && RecorderDataPtr->userEventBuffer.channels[i].defaultFormat == formatStr)
- {
- /* Found a match */
- retVal = (traceUBChannel)i;
- break;
- }
- }
- trcCRITICAL_SECTION_END();
-
- return retVal;
-}
-#endif
-
-/******************************************************************************
- * vTraceUBData
- *
- * Slightly faster version of vTracePrintF() due to no lookups.
- *
- * Note: This is only available if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is
- * enabled in trcSnapshotConfig.h
- ******************************************************************************/
-#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1))
-void vTraceUBData(traceUBChannel channelPair, ...)
-{
- va_list vl;
-
- TRACE_ASSERT(channelPair != 0, "vTraceUBData: Not a valid traceUBChannel!", TRC_UNUSED);
-
- va_start(vl, channelPair);
- vTraceUBData_Helper(channelPair, vl);
- va_end(vl);
-}
-#endif
-
-/* Extracts the channel name and format string from the traceUBChannel, then calls prvTraceUBHelper1. */
-#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1))
-void vTraceUBData_Helper(traceUBChannel channelPair, va_list vl)
-{
- traceString channel;
- traceString formatStr;
-
- TRACE_ASSERT(channelPair != 0, "vTraceUBData_Helper: channelPair == 0", TRC_UNUSED);
- TRACE_ASSERT(channelPair <= (TRC_CFG_UB_CHANNELS), "vTraceUBData_Helper: ", TRC_UNUSED);
-
- channel = RecorderDataPtr->userEventBuffer.channels[channelPair].name;
- formatStr = RecorderDataPtr->userEventBuffer.channels[channelPair].defaultFormat;
-
- prvTraceUBHelper1(channelPair, channel, formatStr, vl);
-}
-#endif
-
-/******************************************************************************
- * vTraceUBEvent
- *
- * Slightly faster version of ... due to no lookups.
- ******************************************************************************/
-#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1))
-void vTraceUBEvent(traceUBChannel channelPair)
-{
- uint32_t data[(3 + MAX_ARG_SIZE) / 4];
-
- TRACE_ASSERT(channelPair != 0, "vTraceUBEvent: channelPair == 0", TRC_UNUSED);
- TRACE_ASSERT(channelPair <= (TRC_CFG_UB_CHANNELS), "vTraceUBEvent: ", TRC_UNUSED);
-
- prvTraceUBHelper2(channelPair, data, 1); /* Only need one slot for timestamp */
-}
-#endif
-
-/******************************************************************************
- * vTracePrintF
- *
- * Generates User Event with formatted text and data, similar to a "printf".
- * It is very fast compared to a normal "printf" since this function only
- * stores the arguments. The actual formatting is done
- * on the host PC when the trace is displayed in the viewer tool.
- *
- * User Event labels are created using xTraceRegisterString.
- * Example:
- *
- * traceString adc_uechannel = xTraceRegisterString("ADC User Events");
- * ...
- * vTracePrintF(adc_uechannel,
- * "ADC channel %d: %lf volts",
- * ch, (double)adc_reading/(double)scale);
- *
- * This can be combined into one line, if desired, but this is slower:
- *
- * vTracePrintF(xTraceRegisterString("ADC User Events"),
- * "ADC channel %d: %lf volts",
- * ch, (double)adc_reading/(double)scale);
- *
- * Calling xTraceRegisterString multiple times will not create duplicate entries, but
- * it is of course faster to just do it once, and then keep the handle for later
- * use. If you don't have any data arguments, only a text label/string, it is
- * better to use vTracePrint - it is faster.
- *
- * Format specifiers supported:
- * %d - 32 bit signed integer
- * %u - 32 bit unsigned integer
- * %f - 32 bit float
- * %s - string (is copied to the recorder symbol table)
- * %hd - 16 bit signed integer
- * %hu - 16 bit unsigned integer
- * %bd - 8 bit signed integer
- * %bu - 8 bit unsigned integer
- * %lf - double-precision float (Note! See below...)
- *
- * Up to 15 data arguments are allowed, with a total size of maximum 32 byte.
- * In case this is exceeded, the user event is changed into an error message.
- *
- * The data is stored in trace buffer, and is packed to allow storing multiple
- * smaller data entries in the same 4-byte record, e.g., four 8-bit values.
- * A string requires two bytes, as the symbol table is limited to 64K. Storing
- * a double (%lf) uses two records, so this is quite costly. Use float (%f)
- * unless the higher precision is really necessary.
- *
- * Note that the double-precision float (%lf) assumes a 64 bit double
- * representation. This does not seem to be the case on e.g. PIC24 and PIC32.
- * Before using a %lf argument on a 16-bit MCU, please verify that
- * "sizeof(double)" actually gives 8 as expected. If not, use %f instead.
- ******************************************************************************/
-#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1))
-void vTracePrintF(traceString eventLabel, const char* formatStr, ...)
-{
- va_list vl;
-
- va_start(vl, formatStr);
- vTracePrintF_Helper(eventLabel, formatStr, vl);
- va_end(vl);
-}
-#endif
-
-#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1))
-void vTracePrintF_Helper(traceString eventLabel, const char* formatStr, va_list vl)
-{
-#if (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 0)
- uint32_t noOfSlots;
- UserEvent* ue1;
- uint32_t tempDataBuffer[(3 + MAX_ARG_SIZE) / 4];
- TRACE_ALLOC_CRITICAL_SECTION();
-
- TRACE_ASSERT(formatStr != NULL, "vTracePrintF_Helper: formatStr == NULL", TRC_UNUSED);
-
- trcCRITICAL_SECTION_BEGIN();
-
- if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)
- {
- /* First, write the "primary" user event entry in the local buffer, but
- let the event type be "EVENT_BEING_WRITTEN" for now...*/
-
- ue1 = (UserEvent*)(&tempDataBuffer[0]);
-
- ue1->type = EVENT_BEING_WRITTEN; /* Update this as the last step */
-
- noOfSlots = prvTraceUserEventFormat(formatStr, vl, (uint8_t*)tempDataBuffer, 4);
-
- /* Store the format string, with a reference to the channel symbol */
- ue1->payload = prvTraceOpenSymbol(formatStr, eventLabel);
-
- ue1->dts = (uint8_t)prvTraceGetDTS(0xFF);
-
- /* prvTraceGetDTS might stop the recorder in some cases... */
- if (RecorderDataPtr->recorderActive)
- {
-
- /* If the data does not fit in the remaining main buffer, wrap around to
- 0 if allowed, otherwise stop the recorder and quit). */
- if (RecorderDataPtr->nextFreeIndex + noOfSlots > RecorderDataPtr->maxEvents)
- {
- #if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER)
- (void)memset(& RecorderDataPtr->eventData[RecorderDataPtr->nextFreeIndex * 4],
- 0,
- (RecorderDataPtr->maxEvents - RecorderDataPtr->nextFreeIndex)*4);
- RecorderDataPtr->nextFreeIndex = 0;
- RecorderDataPtr->bufferIsFull = 1;
- #else
-
- /* Stop recorder, since the event data will not fit in the
- buffer and not circular buffer in this case... */
- vTraceStop();
- #endif
- }
-
- /* Check if recorder has been stopped (i.e., vTraceStop above) */
- if (RecorderDataPtr->recorderActive)
- {
- /* Check that the buffer to be overwritten does not contain any user
- events that would be partially overwritten. If so, they must be "killed"
- by replacing the user event and following data with NULL events (i.e.,
- using a memset to zero).*/
- #if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER)
- prvCheckDataToBeOverwrittenForMultiEntryEvents((uint8_t)noOfSlots);
- #endif
- /* Copy the local buffer to the main buffer */
- (void)memcpy(& RecorderDataPtr->eventData[RecorderDataPtr->nextFreeIndex * 4],
- tempDataBuffer,
- noOfSlots * 4);
-
- /* Update the event type, i.e., number of data entries following the
- main USER_EVENT entry (Note: important that this is after the memcpy,
- but within the critical section!)*/
- RecorderDataPtr->eventData[RecorderDataPtr->nextFreeIndex * 4] =
- (uint8_t) ( USER_EVENT + noOfSlots - 1 );
-
- /* Update the main buffer event index (already checked that it fits in
- the buffer, so no need to check for wrapping)*/
-
- RecorderDataPtr->nextFreeIndex += noOfSlots;
- RecorderDataPtr->numEvents += noOfSlots;
-
- if (RecorderDataPtr->nextFreeIndex >= (TRC_CFG_EVENT_BUFFER_SIZE))
- {
- #if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER)
- /* We have reached the end, but this is a ring buffer. Start from the beginning again. */
- RecorderDataPtr->bufferIsFull = 1;
- RecorderDataPtr->nextFreeIndex = 0;
- #else
- /* We have reached the end so we stop. */
- vTraceStop();
- #endif
- }
- }
-
- #if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER)
- /* Make sure the next entry is cleared correctly */
- prvCheckDataToBeOverwrittenForMultiEntryEvents(1);
- #endif
-
- }
- }
- trcCRITICAL_SECTION_END();
-
-#elif (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)
- /* Use the separate user event buffer */
- traceString formatLabel;
- traceUBChannel channel;
-
- if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)
- {
- formatLabel = xTraceRegisterString(formatStr);
-
- channel = xTraceRegisterUBChannel(eventLabel, formatLabel);
-
- prvTraceUBHelper1(channel, eventLabel, formatLabel, vl);
- }
-#endif
-}
-#endif
-
-/******************************************************************************
- * vTracePrint
- *
- * Basic user event
- *
- * Generates a User Event with a text label. The label is created/looked up
- * in the symbol table using xTraceRegisterString.
- ******************************************************************************/
-#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1))
-void vTracePrint(traceString chn, const char* str)
-{
-#if (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 0)
- UserEvent* ue;
- uint8_t dts1;
- TRACE_ALLOC_CRITICAL_SECTION();
-
- trcCRITICAL_SECTION_BEGIN();
- if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)
- {
- dts1 = (uint8_t)prvTraceGetDTS(0xFF);
- ue = (UserEvent*) prvTraceNextFreeEventBufferSlot();
- if (ue != NULL)
- {
- ue->dts = dts1;
- ue->type = USER_EVENT;
- ue->payload = prvTraceOpenSymbol(str, chn);
- prvTraceUpdateCounters();
- }
- }
- trcCRITICAL_SECTION_END();
-
-#elif (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)
- traceUBChannel channel;
- uint32_t noOfSlots = 1;
- uint32_t tempDataBuffer[(3 + MAX_ARG_SIZE) / 4];
- if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)
- {
- traceString trcStr = prvTraceOpenSymbol(str, chn);
- channel = xTraceRegisterUBChannel(chn, trcStr);
-
- if (channel == 0)
- {
- /* We are dealing with an unknown channel format pair */
- noOfSlots++; /* Also need room for channel and format */
- ((uint16_t*)tempDataBuffer)[2] = chn;
- ((uint16_t*)tempDataBuffer)[3] = trcStr;
- }
-
- prvTraceUBHelper2(channel, tempDataBuffer, noOfSlots);
- }
-#endif
-}
-#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* label)
-{
- TRACE_ASSERT(label != NULL, "xTraceRegisterString: label == NULL", (traceString)0);
- TRACE_ASSERT(RecorderDataPtr != NULL, "Recorder not initialized, call vTraceEnable() first!", (traceHandle)0);
- return prvTraceOpenSymbol(label, 0);
-}
-#endif
-
-
-#if ((!defined TRC_CFG_INCLUDE_READY_EVENTS) || (TRC_CFG_INCLUDE_READY_EVENTS == 1))
-
-void prvTraceSetReadyEventsEnabled(int status)
-{
- readyEventsEnabled = status;
-}
-
-/*******************************************************************************
- * prvTraceStoreTaskReady
- *
- * This function stores a ready state for the task handle sent in as parameter.
- ******************************************************************************/
-void prvTraceStoreTaskReady(traceHandle handle)
-{
- uint16_t dts3;
- TREvent* tr;
- uint8_t hnd8;
-
- TRACE_ALLOC_CRITICAL_SECTION();
-
- if (handle == 0)
- {
- /* On FreeRTOS v7.3.0, this occurs when creating tasks due to a bad
- placement of the trace macro. In that case, the events are ignored. */
- return;
- }
-
- if (! readyEventsEnabled)
- {
- /* When creating tasks, ready events are also created. If creating
- a "hidden" (not traced) task, we must therefore disable recording
- of ready events to avoid an undesired ready event... */
- return;
- }
-
- TRACE_ASSERT(handle <= (TRC_CFG_NTASK), "prvTraceStoreTaskReady: Invalid value for handle", TRC_UNUSED);
-
- if (recorder_busy)
- {
- /*************************************************************************
- * This occurs if an ISR calls a trace function, preempting a previous
- * trace call that is being processed in a different ISR or task.
- * If this occurs, there is probably a problem in the definition of the
- * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and
- * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt
- * and any other ISRs that calls the trace recorder directly or via
- * traced kernel functions. The ARM port disables all interrupts using the
- * PRIMASK register to avoid this issue.
- *************************************************************************/
- prvTraceError("Recorder busy - high priority ISR using syscall? (1)");
- return;
- }
-
- trcCRITICAL_SECTION_BEGIN();
- if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */
- {
- dts3 = (uint16_t)prvTraceGetDTS(0xFFFF);
- hnd8 = prvTraceGet8BitHandle(handle);
- tr = (TREvent*)prvTraceNextFreeEventBufferSlot();
- if (tr != NULL)
- {
- tr->type = DIV_TASK_READY;
- tr->dts = dts3;
- tr->objHandle = hnd8;
- prvTraceUpdateCounters();
- }
- }
- trcCRITICAL_SECTION_END();
-}
-#endif
-
-/*******************************************************************************
- * prvTraceStoreLowPower
- *
- * This function stores a low power state.
- ******************************************************************************/
-void prvTraceStoreLowPower(uint32_t flag)
-{
- uint16_t dts;
- LPEvent* lp;
- TRACE_ALLOC_CRITICAL_SECTION();
-
- TRACE_ASSERT(flag <= 1, "prvTraceStoreLowPower: Invalid flag value", TRC_UNUSED);
-
- if (recorder_busy)
- {
- /*************************************************************************
- * This occurs if an ISR calls a trace function, preempting a previous
- * trace call that is being processed in a different ISR or task.
- * If this occurs, there is probably a problem in the definition of the
- * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and
- * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt
- * and any other ISRs that calls the trace recorder directly or via
- * traced kernel functions. The ARM port disables all interrupts using the
- * PRIMASK register to avoid this issue.
- *************************************************************************/
- prvTraceError("Recorder busy - high priority ISR using syscall? (1)");
- return;
- }
-
- trcCRITICAL_SECTION_BEGIN();
- if (RecorderDataPtr->recorderActive)
- {
- dts = (uint16_t)prvTraceGetDTS(0xFFFF);
- lp = (LPEvent*)prvTraceNextFreeEventBufferSlot();
- if (lp != NULL)
- {
- lp->type = (uint8_t) (LOW_POWER_BEGIN + ( uint8_t ) flag); /* BEGIN or END depending on flag */
- lp->dts = dts;
- prvTraceUpdateCounters();
- }
- }
- trcCRITICAL_SECTION_END();
-}
-
-/*******************************************************************************
- * vTraceStoreMemMangEvent
- *
- * This function stores malloc and free events. Each call requires two records,
- * for size and address respectively. The event code parameter (ecode) is applied
- * to the first record (size) and the following address record gets event
- * code "ecode + 1", so make sure this is respected in the event code table.
- * Note: On "free" calls, the signed_size parameter should be negative.
- ******************************************************************************/
-#if (TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1)
-#if (TRC_CFG_SCHEDULING_ONLY == 0)
-void vTraceStoreMemMangEvent(uint32_t ecode, uint32_t address, int32_t signed_size)
-{
- uint8_t dts1;
- MemEventSize * ms;
- MemEventAddr * ma;
- uint16_t size_low;
- uint16_t addr_low;
- uint8_t addr_high;
- uint32_t size;
- TRACE_ALLOC_CRITICAL_SECTION();
-
- if (RecorderDataPtr == NULL)
- {
- /* Occurs in vTraceInitTraceData, if using dynamic allocation. */
- return;
- }
-
- if (signed_size < 0)
- size = (uint32_t)(- signed_size);
- else
- size = (uint32_t)(signed_size);
-
- trcCRITICAL_SECTION_BEGIN();
-
- heapMemUsage = heapMemUsage + (uint32_t)signed_size;
-
- if (RecorderDataPtr->recorderActive)
- {
- dts1 = (uint8_t)prvTraceGetDTS(0xFF);
- size_low = (uint16_t)prvTraceGetParam(0xFFFF, size);
- ms = (MemEventSize *)prvTraceNextFreeEventBufferSlot();
-
- if (ms != NULL)
- {
- ms->dts = dts1;
- ms->type = NULL_EVENT; /* Updated when all events are written */
- ms->size = size_low;
- prvTraceUpdateCounters();
-
- /* Storing a second record with address (signals "failed" if null) */
- #if (TRC_CFG_HEAP_SIZE_BELOW_16M)
- /* If the heap address range is within 16 MB, i.e., the upper 8 bits
- of addresses are constant, this optimization avoids storing an extra
- event record by ignoring the upper 8 bit of the address */
- addr_low = address & 0xFFFF;
- addr_high = (address >> 16) & 0xFF;
- #else
- /* The whole 32 bit address is stored using a second event record
- for the upper 16 bit */
- addr_low = (uint16_t)prvTraceGetParam(0xFFFF, address);
- addr_high = 0;
- #endif
-
- ma = (MemEventAddr *) prvTraceNextFreeEventBufferSlot();
- if (ma != NULL)
- {
- ma->addr_low = addr_low;
- ma->addr_high = addr_high;
- ma->type = (uint8_t) (ecode + 1); /* Note this! */
- ms->type = (uint8_t) ecode;
- prvTraceUpdateCounters();
- RecorderDataPtr->heapMemUsage = heapMemUsage;
- }
- }
- }
- trcCRITICAL_SECTION_END();
-}
-#endif /* TRC_CFG_SCHEDULING_ONLY */
-#endif
-
-/*******************************************************************************
- * prvTraceStoreKernelCall
- *
- * This is the main integration point for storing kernel calls, and
- * is called by the hooks in trcKernelHooks.h (see trcKernelPort.h for event codes).
- ******************************************************************************/
-#if (TRC_CFG_SCHEDULING_ONLY == 0)
-void prvTraceStoreKernelCall(uint32_t ecode, traceObjectClass objectClass, uint32_t objectNumber)
-{
- KernelCall * kse;
- uint16_t dts1;
- uint8_t hnd8;
- TRACE_ALLOC_CRITICAL_SECTION();
-
- TRACE_ASSERT(ecode < 0xFF, "prvTraceStoreKernelCall: ecode >= 0xFF", TRC_UNUSED);
- TRACE_ASSERT(objectClass < TRACE_NCLASSES, "prvTraceStoreKernelCall: objectClass >= TRACE_NCLASSES", TRC_UNUSED);
- TRACE_ASSERT(objectNumber <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectClass], "prvTraceStoreKernelCall: Invalid value for objectNumber", TRC_UNUSED);
-
- if (recorder_busy)
- {
- /*************************************************************************
- * This occurs if an ISR calls a trace function, preempting a previous
- * trace call that is being processed in a different ISR or task.
- * If this occurs, there is probably a problem in the definition of the
- * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and
- * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt
- * and any other ISRs that calls the trace recorder directly or via
- * traced kernel functions. The ARM port disables all interrupts using the
- * PRIMASK register to avoid this issue.
- *************************************************************************/
- prvTraceError("Recorder busy - high priority ISR using syscall? (2)");
- return;
- }
-
- if (handle_of_last_logged_task == 0)
- {
- return;
- }
-
- trcCRITICAL_SECTION_BEGIN();
- if (RecorderDataPtr->recorderActive)
- {
- dts1 = (uint16_t)prvTraceGetDTS(0xFFFF);
- hnd8 = prvTraceGet8BitHandle((traceHandle)objectNumber);
- kse = (KernelCall*) prvTraceNextFreeEventBufferSlot();
- if (kse != NULL)
- {
- kse->dts = dts1;
- kse->type = (uint8_t)ecode;
- kse->objHandle = hnd8;
- prvTraceUpdateCounters();
- }
- }
- trcCRITICAL_SECTION_END();
-}
-#endif /* TRC_CFG_SCHEDULING_ONLY */
-
-/*******************************************************************************
- * prvTraceStoreKernelCallWithParam
- *
- * Used for storing kernel calls with a handle and a numeric parameter. If the
- * numeric parameter does not fit in one byte, and extra XPS event is inserted
- * before the kernel call event containing the three upper bytes.
- ******************************************************************************/
-#if (TRC_CFG_SCHEDULING_ONLY == 0)
-void prvTraceStoreKernelCallWithParam(uint32_t evtcode,
- traceObjectClass objectClass,
- uint32_t objectNumber,
- uint32_t param)
-{
- KernelCallWithParamAndHandle * kse;
- uint8_t dts2;
- uint8_t hnd8;
- uint8_t p8;
- TRACE_ALLOC_CRITICAL_SECTION();
-
- TRACE_ASSERT(evtcode < 0xFF, "prvTraceStoreKernelCallWithParam: evtcode >= 0xFF", TRC_UNUSED);
- TRACE_ASSERT(objectClass < TRACE_NCLASSES, "prvTraceStoreKernelCallWithParam: objectClass >= TRACE_NCLASSES", TRC_UNUSED);
- TRACE_ASSERT(objectNumber <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectClass], "prvTraceStoreKernelCallWithParam: Invalid value for objectNumber", TRC_UNUSED);
-
- if (recorder_busy)
- {
- /*************************************************************************
- * This occurs if an ISR calls a trace function, preempting a previous
- * trace call that is being processed in a different ISR or task.
- * If this occurs, there is probably a problem in the definition of the
- * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and
- * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt
- * and any other ISRs that calls the trace recorder directly or via
- * traced kernel functions. The ARM port disables all interrupts using the
- * PRIMASK register to avoid this issue.
- *************************************************************************/
- prvTraceError("Recorder busy - high priority ISR using syscall? (3)");
- return;
- }
-
- trcCRITICAL_SECTION_BEGIN();
- if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)
- {
- dts2 = (uint8_t)prvTraceGetDTS(0xFF);
- p8 = (uint8_t) prvTraceGetParam(0xFF, param);
- hnd8 = prvTraceGet8BitHandle((traceHandle)objectNumber);
- kse = (KernelCallWithParamAndHandle*) prvTraceNextFreeEventBufferSlot();
- if (kse != NULL)
- {
- kse->dts = dts2;
- kse->type = (uint8_t)evtcode;
- kse->objHandle = hnd8;
- kse->param = p8;
- prvTraceUpdateCounters();
- }
- }
- trcCRITICAL_SECTION_END();
-}
-#endif /* TRC_CFG_SCHEDULING_ONLY */
-
-
-/*******************************************************************************
- * prvTraceGetParam
- *
- * Used for storing extra bytes for kernel calls with numeric parameters.
- *
- * May only be called within a critical section!
- ******************************************************************************/
-#if (TRC_CFG_SCHEDULING_ONLY == 0)
-static uint32_t prvTraceGetParam(uint32_t param_max, uint32_t param)
-{
- XPSEvent* xps;
-
- TRACE_ASSERT(param_max == 0xFF || param_max == 0xFFFF,
- "prvTraceGetParam: Invalid value for param_max", param);
-
- if (param <= param_max)
- {
- return param;
- }
- else
- {
- xps = (XPSEvent*) prvTraceNextFreeEventBufferSlot();
- if (xps != NULL)
- {
- xps->type = DIV_XPS;
- xps->xps_8 = (uint8_t)((param & (0xFF00 & ~param_max)) >> 8);
- xps->xps_16 = (uint16_t)((param & (0xFFFF0000 & ~param_max)) >> 16);
- prvTraceUpdateCounters();
- }
-
- return param & param_max;
- }
-}
-#endif
-
-/*******************************************************************************
- * prvTraceStoreKernelCallWithNumericParamOnly
- *
- * Used for storing kernel calls with numeric parameters only. This is
- * only used for traceTASK_DELAY and traceDELAY_UNTIL at the moment.
- ******************************************************************************/
-#if (TRC_CFG_SCHEDULING_ONLY == 0)
-void prvTraceStoreKernelCallWithNumericParamOnly(uint32_t evtcode, uint32_t param)
-{
- KernelCallWithParam16 * kse;
- uint8_t dts6;
- uint16_t restParam;
- TRACE_ALLOC_CRITICAL_SECTION();
-
- restParam = 0;
-
- TRACE_ASSERT(evtcode < 0xFF, "prvTraceStoreKernelCallWithNumericParamOnly: Invalid value for evtcode", TRC_UNUSED);
-
- if (recorder_busy)
- {
- /*************************************************************************
- * This occurs if an ISR calls a trace function, preempting a previous
- * trace call that is being processed in a different ISR or task.
- * If this occurs, there is probably a problem in the definition of the
- * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and
- * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt
- * and any other ISRs that calls the trace recorder directly or via
- * traced kernel functions. The ARM port disables all interrupts using the
- * PRIMASK register to avoid this issue.
- *************************************************************************/
- prvTraceError("Recorder busy - high priority ISR using syscall? (4)");
- return;
- }
-
- trcCRITICAL_SECTION_BEGIN();
- if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)
- {
- dts6 = (uint8_t)prvTraceGetDTS(0xFF);
- restParam = (uint16_t)prvTraceGetParam(0xFFFF, param);
- kse = (KernelCallWithParam16*) prvTraceNextFreeEventBufferSlot();
- if (kse != NULL)
- {
- kse->dts = dts6;
- kse->type = (uint8_t)evtcode;
- kse->param = restParam;
- prvTraceUpdateCounters();
- }
- }
- trcCRITICAL_SECTION_END();
-}
-#endif /* TRC_CFG_SCHEDULING_ONLY */
-
-/*******************************************************************************
- * prvTraceStoreTaskswitch
- * Called by the scheduler from the SWITCHED_OUT hook, and by uiTraceStart.
- * At this point interrupts are assumed to be disabled!
- ******************************************************************************/
-void prvTraceStoreTaskswitch(traceHandle task_handle)
-{
- uint16_t dts3;
- TSEvent* ts;
- uint8_t hnd8;
-#if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
- extern int32_t isPendingContextSwitch;
-#endif
- trcSR_ALLOC_CRITICAL_SECTION_ON_CORTEX_M_ONLY();
-
- TRACE_ASSERT(task_handle <= (TRC_CFG_NTASK),
- "prvTraceStoreTaskswitch: Invalid value for task_handle", TRC_UNUSED);
-
- trcCRITICAL_SECTION_BEGIN_ON_CORTEX_M_ONLY();
-
- if ((task_handle != handle_of_last_logged_task) && (RecorderDataPtr->recorderActive))
- {
-#if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
- isPendingContextSwitch = 0;
-#endif
-
- dts3 = (uint16_t)prvTraceGetDTS(0xFFFF);
- handle_of_last_logged_task = task_handle;
- hnd8 = prvTraceGet8BitHandle(handle_of_last_logged_task);
- ts = (TSEvent*)prvTraceNextFreeEventBufferSlot();
-
- if (ts != NULL)
- {
- if (prvTraceGetObjectState(TRACE_CLASS_TASK,
- handle_of_last_logged_task) == TASK_STATE_INSTANCE_ACTIVE)
- {
- ts->type = TS_TASK_RESUME;
- }
- else
- {
- ts->type = TS_TASK_BEGIN;
- }
-
- ts->dts = dts3;
- ts->objHandle = hnd8;
-
- prvTraceSetObjectState(TRACE_CLASS_TASK,
- handle_of_last_logged_task,
- TASK_STATE_INSTANCE_ACTIVE);
-
- prvTraceUpdateCounters();
- }
- }
-
- trcCRITICAL_SECTION_END_ON_CORTEX_M_ONLY();
-}
-
-/*******************************************************************************
- * prvTraceStoreObjectNameOnCloseEvent
- *
- * Updates the symbol table with the name of this object from the dynamic
- * objects table and stores a "close" event, holding the mapping between handle
- * and name (a symbol table handle). The stored name-handle mapping is thus the
- * "old" one, valid up until this point.
- ******************************************************************************/
-void prvTraceStoreObjectNameOnCloseEvent(uint8_t evtcode, traceHandle handle,
- traceObjectClass objectclass)
-{
- ObjCloseNameEvent * ce;
- const char * name;
- traceString idx;
-
- TRACE_ASSERT(objectclass < TRACE_NCLASSES,
- "prvTraceStoreObjectNameOnCloseEvent: objectclass >= TRACE_NCLASSES", TRC_UNUSED);
- TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
- "prvTraceStoreObjectNameOnCloseEvent: Invalid value for handle", TRC_UNUSED);
-
- if (RecorderDataPtr->recorderActive)
- {
- uint8_t hnd8 = prvTraceGet8BitHandle(handle);
- name = TRACE_PROPERTY_NAME_GET(objectclass, handle);
- idx = prvTraceOpenSymbol(name, 0);
-
- // Interrupt disable not necessary, already done in trcHooks.h macro
- ce = (ObjCloseNameEvent*) prvTraceNextFreeEventBufferSlot();
- if (ce != NULL)
- {
- ce->type = (uint8_t) evtcode;
- ce->objHandle = hnd8;
- ce->symbolIndex = idx;
- prvTraceUpdateCounters();
- }
- }
-}
-
-void prvTraceStoreObjectPropertiesOnCloseEvent(uint8_t evtcode, traceHandle handle,
- traceObjectClass objectclass)
-{
- ObjClosePropEvent * pe;
-
- TRACE_ASSERT(objectclass < TRACE_NCLASSES,
- "prvTraceStoreObjectPropertiesOnCloseEvent: objectclass >= TRACE_NCLASSES", TRC_UNUSED);
- TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
- "prvTraceStoreObjectPropertiesOnCloseEvent: Invalid value for handle", TRC_UNUSED);
-
- if (RecorderDataPtr->recorderActive)
- {
- // Interrupt disable not necessary, already done in trcHooks.h macro
- pe = (ObjClosePropEvent*) prvTraceNextFreeEventBufferSlot();
- if (pe != NULL)
- {
- if (objectclass == TRACE_CLASS_TASK)
- {
- pe->arg1 = TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, handle);
- }
- else
- {
- pe->arg1 = TRACE_PROPERTY_OBJECT_STATE(objectclass, handle);
- }
- pe->type = evtcode;
- prvTraceUpdateCounters();
- }
- }
-}
-
-void prvTraceSetPriorityProperty(uint8_t objectclass, traceHandle id, uint8_t value)
-{
- TRACE_ASSERT(objectclass < TRACE_NCLASSES,
- "prvTraceSetPriorityProperty: objectclass >= TRACE_NCLASSES", TRC_UNUSED);
- TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
- "prvTraceSetPriorityProperty: Invalid value for id", TRC_UNUSED);
-
- TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, id) = value;
-}
-
-uint8_t prvTraceGetPriorityProperty(uint8_t objectclass, traceHandle id)
-{
- TRACE_ASSERT(objectclass < TRACE_NCLASSES,
- "prvTraceGetPriorityProperty: objectclass >= TRACE_NCLASSES", 0);
- TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
- "prvTraceGetPriorityProperty: Invalid value for id", 0);
-
- return TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, id);
-}
-
-void prvTraceSetObjectState(uint8_t objectclass, traceHandle id, uint8_t value)
-{
- TRACE_ASSERT(objectclass < TRACE_NCLASSES,
- "prvTraceSetObjectState: objectclass >= TRACE_NCLASSES", TRC_UNUSED);
- TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
- "prvTraceSetObjectState: Invalid value for id", TRC_UNUSED);
-
- TRACE_PROPERTY_OBJECT_STATE(objectclass, id) = value;
-}
-
-uint8_t prvTraceGetObjectState(uint8_t objectclass, traceHandle id)
-{
- TRACE_ASSERT(objectclass < TRACE_NCLASSES,
- "prvTraceGetObjectState: objectclass >= TRACE_NCLASSES", 0);
- TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
- "prvTraceGetObjectState: Invalid value for id", 0);
-
- return TRACE_PROPERTY_OBJECT_STATE(objectclass, id);
-}
-
-void prvTraceSetTaskInstanceFinished(traceHandle handle)
-{
- TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[TRACE_CLASS_TASK],
- "prvTraceSetTaskInstanceFinished: Invalid value for handle", TRC_UNUSED);
-
-#if (TRC_CFG_USE_IMPLICIT_IFE_RULES == 1)
- TRACE_PROPERTY_OBJECT_STATE(TRACE_CLASS_TASK, handle) = 0;
-#endif
-}
-
-/*******************************************************************************
- * Static data initializations
- ******************************************************************************/
-
-/* A set of stacks that keeps track of available object handles for each class.
-The stacks are empty initially, meaning that allocation of new handles will be
-based on a counter (for each object class). Any delete operation will
-return the handle to the corresponding stack, for reuse on the next allocate.*/
-objectHandleStackType objectHandleStacks = { { 0 }, { 0 }, { 0 }, { 0 }, { 0 } };
-
-/* Initial TRC_HWTC_COUNT value, for detecting if the time-stamping source is
-enabled. If using the OS periodic timer for time-stamping, this might not
-have been configured on the earliest events during the startup. */
-uint32_t init_hwtc_count;
-
-/*******************************************************************************
- * RecorderData
- *
- * The main data structure in snapshot mode, when using the default static memory
- * allocation (TRC_RECORDER_BUFFER_ALLOCATION_STATIC). The recorder uses a pointer
- * RecorderDataPtr to access the data, to also allow for dynamic or custom data
- * allocation (see TRC_CFG_RECORDER_BUFFER_ALLOCATION).
- ******************************************************************************/
-#if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_STATIC)
-RecorderDataType RecorderData;
-#endif
-
-/*******************************************************************************
- * RecorderDataPtr
- *
- * Pointer to the main data structure, when in snapshot mode.
- ******************************************************************************/
-RecorderDataType* RecorderDataPtr = NULL;
-
-/* This version of the function dynamically allocates the trace data */
-void prvTraceInitTraceData()
-{
-
- if (RecorderDataPtr == NULL)
- {
-#if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_STATIC)
- RecorderDataPtr = &RecorderData;
-#elif (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC)
- RecorderDataPtr = (RecorderDataType*)TRACE_MALLOC(sizeof(RecorderDataType));
- if (! RecorderDataPtr)
- {
- prvTraceError("Failed allocating recorder buffer!");
- return;
- }
-#elif (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM)
- if (! RecorderDataPtr)
- {
- prvTraceError("Recorder data pointer not set! Use vTraceSetRecorderDataBuffer().");
- return;
- }
-#endif
- }
- else
- {
- if (RecorderDataPtr->startmarker0 == 1)
- {
- /* Already initialized */
- return;
- }
- }
-
- init_hwtc_count = TRC_HWTC_COUNT;
-
- (void)memset(RecorderDataPtr, 0, sizeof(RecorderDataType));
-
- RecorderDataPtr->version = TRACE_KERNEL_VERSION;
- RecorderDataPtr->minor_version = TRACE_MINOR_VERSION;
- RecorderDataPtr->irq_priority_order = TRC_IRQ_PRIORITY_ORDER;
- RecorderDataPtr->filesize = sizeof(RecorderDataType);
- RecorderDataPtr->maxEvents = (TRC_CFG_EVENT_BUFFER_SIZE);
- RecorderDataPtr->debugMarker0 = (int32_t) 0xF0F0F0F0;
- RecorderDataPtr->isUsing16bitHandles = TRC_CFG_USE_16BIT_OBJECT_HANDLES;
- RecorderDataPtr->isrTailchainingThreshold = TRC_CFG_ISR_TAILCHAINING_THRESHOLD;
-
- /* This function is kernel specific */
- vTraceInitObjectPropertyTable();
-
- RecorderDataPtr->debugMarker1 = (int32_t)0xF1F1F1F1;
- RecorderDataPtr->SymbolTable.symTableSize = (TRC_CFG_SYMBOL_TABLE_SIZE);
- RecorderDataPtr->SymbolTable.nextFreeSymbolIndex = 1;
-#if (TRC_CFG_INCLUDE_FLOAT_SUPPORT == 1)
- RecorderDataPtr->exampleFloatEncoding = 1.0f; /* otherwise already zero */
-#endif
- RecorderDataPtr->debugMarker2 = (int32_t)0xF2F2F2F2;
- prvStrncpy(RecorderDataPtr->systemInfo, "Trace Recorder Demo", 80);
- RecorderDataPtr->debugMarker3 = (int32_t)0xF3F3F3F3;
- RecorderDataPtr->endmarker0 = 0x0A;
- RecorderDataPtr->endmarker1 = 0x0B;
- RecorderDataPtr->endmarker2 = 0x0C;
- RecorderDataPtr->endmarker3 = 0x0D;
- RecorderDataPtr->endmarker4 = 0x71;
- RecorderDataPtr->endmarker5 = 0x72;
- RecorderDataPtr->endmarker6 = 0x73;
- RecorderDataPtr->endmarker7 = 0x74;
- RecorderDataPtr->endmarker8 = 0xF1;
- RecorderDataPtr->endmarker9 = 0xF2;
- RecorderDataPtr->endmarker10 = 0xF3;
- RecorderDataPtr->endmarker11 = 0xF4;
-
-#if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER
- RecorderDataPtr->userEventBuffer.bufferID = 1;
- RecorderDataPtr->userEventBuffer.version = 0;
- RecorderDataPtr->userEventBuffer.numberOfSlots = (TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE);
- RecorderDataPtr->userEventBuffer.numberOfChannels = (TRC_CFG_UB_CHANNELS) + 1;
-#endif
-
- /* Kernel specific initialization of the objectHandleStacks variable */
- vTraceInitObjectHandleStack();
-
-
- /* Finally, the 12-byte "start markers" are initialized, allowing for
- Tracealyzer to find the trace data in a larger RAM dump.
-
- The start and end markers must be unique, but without proper precautions there
- might be a risk of accidental duplicates of the start/end markers, e.g., due to
- compiler optimizations.
-
- The below initialization of the start marker is therefore made in reverse order
- and the fields are volatile to ensure this assignment order. This to avoid any
- chance of accidental duplicates of this elsewhere in memory.
-
- Moreover, the fields are set byte-by-byte to avoid endian issues.*/
-
- RecorderDataPtr->startmarker11 = 0xF4;
- RecorderDataPtr->startmarker10 = 0xF3;
- RecorderDataPtr->startmarker9 = 0xF2;
- RecorderDataPtr->startmarker8 = 0xF1;
- RecorderDataPtr->startmarker7 = 0x74;
- RecorderDataPtr->startmarker6 = 0x73;
- RecorderDataPtr->startmarker5 = 0x72;
- RecorderDataPtr->startmarker4 = 0x71;
- RecorderDataPtr->startmarker3 = 0x04;
- RecorderDataPtr->startmarker2 = 0x03;
- RecorderDataPtr->startmarker1 = 0x02;
- RecorderDataPtr->startmarker0 = 0x01;
-
- if (traceErrorMessage != NULL)
- {
- // An error was detected before vTraceEnable was called, make sure this is stored in the trace data.
- prvStrncpy(RecorderDataPtr->systemInfo, traceErrorMessage, 80);
- RecorderDataPtr->internalErrorOccured = 1;
- vTraceStop();
- }
-
-
-
-#ifdef TRC_PORT_SPECIFIC_INIT
- TRC_PORT_SPECIFIC_INIT();
-#endif
-}
-
-
-void* prvTraceNextFreeEventBufferSlot(void)
-{
- if (! RecorderDataPtr->recorderActive)
- {
- /* If an XTS or XPS event prior to the main event has filled the buffer
- before saving the main event, and store mode is "stop when full". */
- return NULL;
- }
-
- if (RecorderDataPtr->nextFreeIndex >= (TRC_CFG_EVENT_BUFFER_SIZE))
- {
- prvTraceError("Attempt to index outside event buffer!");
- return NULL;
- }
- return (void*)(&RecorderDataPtr->eventData[RecorderDataPtr->nextFreeIndex*4]);
-}
-
-uint16_t uiIndexOfObject(traceHandle objecthandle, uint8_t objectclass)
-{
- TRACE_ASSERT(objectclass < TRACE_NCLASSES,
- "uiIndexOfObject: Invalid value for objectclass", 0);
- TRACE_ASSERT(objecthandle > 0 && objecthandle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
- "uiIndexOfObject: Invalid value for objecthandle", 0);
-
- if ((objectclass < TRACE_NCLASSES) && (objecthandle > 0) &&
- (objecthandle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass]))
- {
- return (uint16_t)(RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[objectclass] +
- (RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[objectclass] * (objecthandle-1)));
- }
-
- prvTraceError("Object table lookup with invalid object handle or object class!");
- return 0;
-}
-
-traceHandle prvTraceGetObjectHandle(traceObjectClass objectclass)
-{
- traceHandle handle;
- static int indexOfHandle;
-
- TRACE_ALLOC_CRITICAL_SECTION();
-
- TRACE_ASSERT(RecorderDataPtr != NULL, "Recorder not initialized, call vTraceEnable() first!", (traceHandle)0);
-
- TRACE_ASSERT(objectclass < TRACE_NCLASSES,
- "prvTraceGetObjectHandle: Invalid value for objectclass", (traceHandle)0);
-
- trcCRITICAL_SECTION_BEGIN();
- indexOfHandle = objectHandleStacks.indexOfNextAvailableHandle[objectclass];
- if (objectHandleStacks.objectHandles[indexOfHandle] == 0)
- {
- /* Zero is used to indicate a never before used handle, i.e.,
- new slots in the handle stack. The handle slot needs to
- be initialized here (starts at 1). */
- objectHandleStacks.objectHandles[indexOfHandle] =
- (traceHandle)(1 + indexOfHandle -
- objectHandleStacks.lowestIndexOfClass[objectclass]);
- }
-
- handle = objectHandleStacks.objectHandles[indexOfHandle];
-
- if (objectHandleStacks.indexOfNextAvailableHandle[objectclass]
- > objectHandleStacks.highestIndexOfClass[objectclass])
- {
- prvTraceError(pszTraceGetErrorNotEnoughHandles(objectclass));
- handle = 0;
- }
- else
- {
- int hndCount;
- objectHandleStacks.indexOfNextAvailableHandle[objectclass]++;
-
- hndCount = objectHandleStacks.indexOfNextAvailableHandle[objectclass] -
- objectHandleStacks.lowestIndexOfClass[objectclass];
-
- if (hndCount >
- objectHandleStacks.handleCountWaterMarksOfClass[objectclass])
- {
- objectHandleStacks.handleCountWaterMarksOfClass[objectclass] =
- (traceHandle)hndCount;
- }
- }
- trcCRITICAL_SECTION_END();
-
- return handle;
-}
-
-void prvTraceFreeObjectHandle(traceObjectClass objectclass, traceHandle handle)
-{
- int indexOfHandle;
-
- TRACE_ASSERT(objectclass < TRACE_NCLASSES,
- "prvTraceFreeObjectHandle: Invalid value for objectclass", TRC_UNUSED);
- TRACE_ASSERT(handle > 0 && handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
- "prvTraceFreeObjectHandle: Invalid value for handle", TRC_UNUSED);
-
- /* Check that there is room to push the handle on the stack */
- if ((objectHandleStacks.indexOfNextAvailableHandle[objectclass] - 1) <
- objectHandleStacks.lowestIndexOfClass[objectclass])
- {
- /* Error */
- prvTraceError("Attempt to free more handles than allocated!");
- }
- else
- {
- objectHandleStacks.indexOfNextAvailableHandle[objectclass]--;
- indexOfHandle = objectHandleStacks.indexOfNextAvailableHandle[objectclass];
- objectHandleStacks.objectHandles[indexOfHandle] = handle;
- }
-}
-
-/*******************************************************************************
- * prvMarkObjectAsUsed
- *
- * Sets an "is used flag" on object creation, using the first byte of the name
- * field. This allows for counting the number of used Object Table slots, even
- * if no names have been set.
- ******************************************************************************/
-void prvMarkObjectAsUsed(traceObjectClass objectclass, traceHandle handle)
-{
- uint16_t idx = uiIndexOfObject(handle, objectclass);
- RecorderDataPtr->ObjectPropertyTable.objbytes[idx] = 1;
-}
-
-/*******************************************************************************
- * prvStrncpy
- *
- * Private string copy function, to improve portability between compilers.
- ******************************************************************************/
-static void prvStrncpy(char* dst, const char* src, uint32_t maxLength)
-{
- uint32_t i;
- for (i = 0; i < maxLength; i++)
- {
- dst[i] = src[i];
- if (src[i] == 0)
- break;
- }
-}
-
-/*******************************************************************************
- * prvTraceSetObjectName
- *
- * Registers the names of queues, semaphores and other kernel objects in the
- * recorder's Object Property Table, at the given handle and object class.
- ******************************************************************************/
-void prvTraceSetObjectName(traceObjectClass objectclass,
- traceHandle handle,
- const char* name)
-{
- static uint16_t idx;
-
- TRACE_ASSERT(name != NULL, "prvTraceSetObjectName: name == NULL", TRC_UNUSED);
-
- if (objectclass >= TRACE_NCLASSES)
- {
- prvTraceError("Illegal object class in prvTraceSetObjectName");
- return;
- }
-
- if (handle == 0)
- {
- prvTraceError("Illegal handle (0) in prvTraceSetObjectName.");
- return;
- }
-
- if (handle > RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass])
- {
- /* ERROR */
- prvTraceError(pszTraceGetErrorNotEnoughHandles(objectclass));
- }
- else
- {
- idx = uiIndexOfObject(handle, objectclass);
-
- if (traceErrorMessage == NULL)
- {
- prvStrncpy((char*)&(RecorderDataPtr->ObjectPropertyTable.objbytes[idx]),
- name,
- RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[ objectclass ]);
- }
- }
-}
-
-traceString prvTraceOpenSymbol(const char* name, traceString userEventChannel)
-{
- uint16_t result;
- uint8_t len;
- uint8_t crc;
- TRACE_ALLOC_CRITICAL_SECTION();
-
- len = 0;
- crc = 0;
-
- TRACE_ASSERT(name != NULL, "prvTraceOpenSymbol: name == NULL", (traceString)0);
-
- prvTraceGetChecksum(name, &crc, &len);
-
- trcCRITICAL_SECTION_BEGIN();
- result = prvTraceLookupSymbolTableEntry(name, crc, len, userEventChannel);
- if (!result)
- {
- result = prvTraceCreateSymbolTableEntry(name, crc, len, userEventChannel);
- }
- trcCRITICAL_SECTION_END();
-
- return result;
-}
-
-
-/******************************************************************************
-* 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)
-{
- timestampFrequency = frequency;
-}
-
-/*******************************************************************************
- * Supporting functions
- ******************************************************************************/
-
-/*******************************************************************************
- * prvTraceError
- *
- * Called by various parts in the recorder. Stops the recorder and stores a
- * pointer to an error message, which is printed by the monitor task.
- * If you are not using the monitor task, you may use xTraceGetLastError()
- * from your application to check if the recorder is OK.
- *
- * Note: If a recorder error is registered before vTraceStart is called, the
- * trace start will be aborted. This can occur if any of the Nxxxx constants
- * (e.g., TRC_CFG_NTASK) in trcConfig.h is too small.
- ******************************************************************************/
-void prvTraceError(const char* msg)
-{
- /* Stop the recorder */
- if (RecorderDataPtr != NULL)
- {
- vTraceStop();
- }
-
- /* If first error only... */
- if (traceErrorMessage == NULL)
- {
- traceErrorMessage = (char*)(intptr_t) msg;
- if (RecorderDataPtr != NULL)
- {
- prvStrncpy(RecorderDataPtr->systemInfo, traceErrorMessage, 80);
- RecorderDataPtr->internalErrorOccured = 1;
- }
- }
-}
-
-void vTraceSetFilterMask(uint16_t filterMask)
-{
- CurrentFilterMask = filterMask;
-}
-
-void vTraceSetFilterGroup(uint16_t filterGroup)
-{
- CurrentFilterGroup = filterGroup;
-}
-
-/******************************************************************************
- * prvCheckDataToBeOverwrittenForMultiEntryEvents
- *
- * This checks if the next event to be overwritten is a multi-entry user event,
- * i.e., a USER_EVENT followed by data entries.
- * Such data entries do not have an event code at byte 0, as other events.
- * All 4 bytes are user data, so the first byte of such data events must
- * not be interpreted as type field. The number of data entries following
- * a USER_EVENT is given in the event code of the USER_EVENT.
- * Therefore, when overwriting a USER_EVENT (when using in ring-buffer mode)
- * any data entries following must be replaced with NULL events (code 0).
- *
- * This is assumed to execute within a critical section...
- *****************************************************************************/
-
-#if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER)
-void prvCheckDataToBeOverwrittenForMultiEntryEvents(uint8_t nofEntriesToCheck)
-{
- /* Generic "int" type is desired - should be 16 bit variable on 16 bit HW */
- unsigned int i = 0;
- unsigned int e = 0;
-
- TRACE_ASSERT(nofEntriesToCheck != 0,
- "prvCheckDataToBeOverwrittenForMultiEntryEvents: nofEntriesToCheck == 0", TRC_UNUSED);
-
- while (i < nofEntriesToCheck)
- {
- e = RecorderDataPtr->nextFreeIndex + i;
- if ((RecorderDataPtr->eventData[e*4] > USER_EVENT) &&
- (RecorderDataPtr->eventData[e*4] < USER_EVENT + 16))
- {
- uint8_t nDataEvents = (uint8_t)(RecorderDataPtr->eventData[e*4] - USER_EVENT);
- if ((e + nDataEvents) < RecorderDataPtr->maxEvents)
- {
- (void)memset(& RecorderDataPtr->eventData[e*4], 0, (size_t) (4 + 4 * nDataEvents));
- }
- }
- else if (RecorderDataPtr->eventData[e*4] == DIV_XPS)
- {
- if ((e + 1) < RecorderDataPtr->maxEvents)
- {
- /* Clear 8 bytes */
- (void)memset(& RecorderDataPtr->eventData[e*4], 0, 4 + 4);
- }
- else
- {
- /* Clear 8 bytes, 4 first and 4 last */
- (void)memset(& RecorderDataPtr->eventData[0], 0, 4);
- (void)memset(& RecorderDataPtr->eventData[e*4], 0, 4);
- }
- }
- i++;
- }
-}
-#endif
-
-/*******************************************************************************
- * prvTraceUpdateCounters
- *
- * Updates the index of the event buffer.
- ******************************************************************************/
-void prvTraceUpdateCounters(void)
-{
- if (RecorderDataPtr->recorderActive == 0)
- {
- return;
- }
-
- RecorderDataPtr->numEvents++;
-
- RecorderDataPtr->nextFreeIndex++;
-
- if (RecorderDataPtr->nextFreeIndex >= (TRC_CFG_EVENT_BUFFER_SIZE))
- {
-#if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER)
- RecorderDataPtr->bufferIsFull = 1;
- RecorderDataPtr->nextFreeIndex = 0;
-#else
- vTraceStop();
-#endif
- }
-
-#if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER)
- prvCheckDataToBeOverwrittenForMultiEntryEvents(1);
-#endif
-}
-
-/******************************************************************************
- * prvTraceGetDTS
- *
- * Returns a differential timestamp (DTS), i.e., the time since
- * last event, and creates an XTS event if the DTS does not fit in the
- * number of bits given. The XTS event holds the MSB bytes of the DTS.
- *
- * The parameter param_maxDTS should be 0xFF for 8-bit dts or 0xFFFF for
- * events with 16-bit dts fields.
- *****************************************************************************/
-uint16_t prvTraceGetDTS(uint16_t param_maxDTS)
-{
- static uint32_t old_timestamp = 0;
- XTSEvent* xts = 0;
- uint32_t dts = 0;
- uint32_t timestamp = 0;
-
- TRACE_ASSERT(param_maxDTS == 0xFF || param_maxDTS == 0xFFFF, "prvTraceGetDTS: Invalid value for param_maxDTS", 0);
-
-
- if (RecorderDataPtr->frequency == 0)
- {
- if (timestampFrequency != 0)
- {
- /* If to override default TRC_HWTC_FREQ_HZ value with value set by vTraceSetFrequency */
- RecorderDataPtr->frequency = timestampFrequency / (TRC_HWTC_DIVISOR);
- }
- else if (init_hwtc_count != (TRC_HWTC_COUNT))
- {
- /* If using default value and timer has been started.
- Note: If the default frequency value set here would be incorrect, e.g.,
- if the timer has actually not been configured yet, override this
- with vTraceSetFrequency.
- */
- RecorderDataPtr->frequency = (TRC_HWTC_FREQ_HZ) / (TRC_HWTC_DIVISOR);
- }
- /* If no override (vTraceSetFrequency) and timer inactive -> no action */
- }
-
- /**************************************************************************
- * The below statements read the timestamp from the timer port module.
- * If necessary, whole seconds are extracted using division while the rest
- * comes from the modulo operation.
- **************************************************************************/
-
- prvTracePortGetTimeStamp(&timestamp);
-
- /***************************************************************************
- * Since dts is unsigned the result will be correct even if timestamp has
- * wrapped around.
- ***************************************************************************/
- dts = timestamp - old_timestamp;
- old_timestamp = timestamp;
-
- if (RecorderDataPtr->frequency > 0)
- {
- /* Check if dts > 1 second */
- if (dts > RecorderDataPtr->frequency)
- {
- /* More than 1 second has passed */
- RecorderDataPtr->absTimeLastEventSecond += dts / RecorderDataPtr->frequency;
- /* The part that is not an entire second is added to absTimeLastEvent */
- RecorderDataPtr->absTimeLastEvent += dts % RecorderDataPtr->frequency;
- }
- else
- {
- RecorderDataPtr->absTimeLastEvent += dts;
- }
-
- /* Check if absTimeLastEvent >= 1 second */
- if (RecorderDataPtr->absTimeLastEvent >= RecorderDataPtr->frequency)
- {
- /* RecorderDataPtr->absTimeLastEvent is more than or equal to 1 second, but always less than 2 seconds */
- RecorderDataPtr->absTimeLastEventSecond++;
- RecorderDataPtr->absTimeLastEvent -= RecorderDataPtr->frequency;
- /* RecorderDataPtr->absTimeLastEvent is now less than 1 second */
- }
- }
- else
- {
- /* Special case if the recorder has not yet started (frequency may be uninitialized, i.e., zero) */
- RecorderDataPtr->absTimeLastEvent = timestamp;
- }
-
- /* If the dts (time since last event) does not fit in event->dts (only 8 or 16 bits) */
- if (dts > param_maxDTS)
- {
- /* Create an XTS event (eXtended TimeStamp) containing the higher dts bits*/
- xts = (XTSEvent*) prvTraceNextFreeEventBufferSlot();
-
- if (xts != NULL)
- {
- if (param_maxDTS == 0xFFFF)
- {
- xts->type = XTS16;
- xts->xts_16 = (uint16_t)((dts / 0x10000) & 0xFFFF);
- xts->xts_8 = 0;
- }
- else if (param_maxDTS == 0xFF)
- {
- xts->type = XTS8;
- xts->xts_16 = (uint16_t)((dts / 0x100) & 0xFFFF);
- xts->xts_8 = (uint8_t)((dts / 0x1000000) & 0xFF);
- }
- else
- {
- prvTraceError("Bad param_maxDTS in prvTraceGetDTS");
- }
- prvTraceUpdateCounters();
- }
- }
-
- return (uint16_t)dts & param_maxDTS;
-}
-
-/*******************************************************************************
- * prvTraceLookupSymbolTableEntry
- *
- * Find an entry in the symbol table, return 0 if not present.
- *
- * The strings are stored in a byte pool, with four bytes of "meta-data" for
- * every string.
- * byte 0-1: index of next entry with same checksum (for fast lookup).
- * byte 2-3: reference to a symbol table entry, a label for vTracePrintF
- * format strings only (the handle of the destination channel).
- * byte 4..(4 + length): the string (object name or user event label), with
- * zero-termination
- ******************************************************************************/
-traceString prvTraceLookupSymbolTableEntry(const char* name,
- uint8_t crc6,
- uint8_t len,
- traceString chn)
-{
- uint16_t i = RecorderDataPtr->SymbolTable.latestEntryOfChecksum[ crc6 ];
-
- TRACE_ASSERT(name != NULL, "prvTraceLookupSymbolTableEntry: name == NULL", (traceString)0);
- TRACE_ASSERT(len != 0, "prvTraceLookupSymbolTableEntry: len == 0", (traceString)0);
-
- while (i != 0)
- {
- if (RecorderDataPtr->SymbolTable.symbytes[i + 2] == (chn & 0x00FF))
- {
- if (RecorderDataPtr->SymbolTable.symbytes[i + 3] == (chn / 0x100))
- {
- if (RecorderDataPtr->SymbolTable.symbytes[i + 4 + len] == '\0')
- {
- if (strncmp((char*)(& RecorderDataPtr->SymbolTable.symbytes[i + 4]), name, len) == 0)
- {
- break; /* found */
- }
- }
- }
- }
- i = (uint16_t)(RecorderDataPtr->SymbolTable.symbytes[i] + (RecorderDataPtr->SymbolTable.symbytes[i + 1] * 0x100));
- }
- return i;
-}
-
-/*******************************************************************************
- * prvTraceCreateSymbolTableEntry
- *
- * Creates an entry in the symbol table, independent if it exists already.
- *
- * The strings are stored in a byte pool, with four bytes of "meta-data" for
- * every string.
- * byte 0-1: index of next entry with same checksum (for fast lookup).
- * byte 2-3: reference to a symbol table entry, a label for vTracePrintF
- * format strings only (the handle of the destination channel).
- * byte 4..(4 + length): the string (object name or user event label), with
- * zero-termination
- ******************************************************************************/
-uint16_t prvTraceCreateSymbolTableEntry(const char* name,
- uint8_t crc6,
- uint8_t len,
- traceString channel)
-{
- uint16_t ret = 0;
-
- TRACE_ASSERT(name != NULL, "prvTraceCreateSymbolTableEntry: name == NULL", 0);
- TRACE_ASSERT(len != 0, "prvTraceCreateSymbolTableEntry: len == 0", 0);
-
- if (RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + len + 4 >= (TRC_CFG_SYMBOL_TABLE_SIZE))
- {
- prvTraceError("Symbol table full. Increase TRC_CFG_SYMBOL_TABLE_SIZE in trcConfig.h");
- ret = 0;
- }
- else
- {
-
- RecorderDataPtr->SymbolTable.symbytes
- [ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex] =
- (uint8_t)(RecorderDataPtr->SymbolTable.latestEntryOfChecksum[ crc6 ] & 0x00FF);
-
- RecorderDataPtr->SymbolTable.symbytes
- [ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 1] =
- (uint8_t)(RecorderDataPtr->SymbolTable.latestEntryOfChecksum[ crc6 ] / 0x100);
-
- RecorderDataPtr->SymbolTable.symbytes
- [ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 2] =
- (uint8_t)(channel & 0x00FF);
-
- RecorderDataPtr->SymbolTable.symbytes
- [ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 3] =
- (uint8_t)(channel / 0x100);
-
- /* set name (bytes 4...4+len-1) */
- prvStrncpy((char*)&(RecorderDataPtr->SymbolTable.symbytes
- [ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 4]), name, len);
-
- /* Set zero termination (at offset 4+len) */
- RecorderDataPtr->SymbolTable.symbytes
- [RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 4 + len] = '\0';
-
- /* store index of entry (for return value, and as head of LL[crc6]) */
- RecorderDataPtr->SymbolTable.latestEntryOfChecksum
- [ crc6 ] = (uint16_t)RecorderDataPtr->SymbolTable.nextFreeSymbolIndex;
-
- RecorderDataPtr->SymbolTable.nextFreeSymbolIndex += (uint32_t) (len + 5);
-
- ret = (uint16_t)(RecorderDataPtr->SymbolTable.nextFreeSymbolIndex - (uint8_t)(len + 5));
- }
-
- return ret;
-}
-
-
-/*******************************************************************************
- * prvTraceGetChecksum
- *
- * Calculates a simple 6-bit checksum from a string, used to index the string
- * for fast symbol table lookup.
- ******************************************************************************/
-void prvTraceGetChecksum(const char *pname, uint8_t* pcrc, uint8_t* plength)
-{
- unsigned char c;
- int length = 1; /* Should be 1 to account for '\0' */
- int crc = 0;
-
- TRACE_ASSERT(pname != NULL, "prvTraceGetChecksum: pname == NULL", TRC_UNUSED);
- TRACE_ASSERT(pcrc != NULL, "prvTraceGetChecksum: pcrc == NULL", TRC_UNUSED);
- TRACE_ASSERT(plength != NULL, "prvTraceGetChecksum: plength == NULL", TRC_UNUSED);
-
- if (pname != (const char *) 0)
- {
- for (; (c = (unsigned char) *pname++) != '\0';)
- {
- crc += c;
- length++;
- }
- }
- *pcrc = (uint8_t)(crc & 0x3F);
- *plength = (uint8_t)length;
-}
-
-#if (TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1)
-
-static void prvTraceStoreXID(traceHandle handle);
-
-/******************************************************************************
- * prvTraceStoreXID
- *
- * Stores an XID (eXtended IDentifier) event.
- * This is used if an object/task handle is larger than 255.
- * The parameter "handle" is the full (16 bit) handle, assumed to be 256 or
- * larger. Handles below 256 should not use this function.
- *
- * NOTE: this function MUST be called from within a critical section.
- *****************************************************************************/
-static void prvTraceStoreXID(traceHandle handle)
-{
- XPSEvent* xid;
-
- TRACE_ASSERT(handle >= 256, "prvTraceStoreXID: Handle < 256", TRC_UNUSED);
-
- xid = (XPSEvent*)prvTraceNextFreeEventBufferSlot();
-
- if (xid != NULL)
- {
- xid->type = XID;
-
- /* This function is (only) used when traceHandle is 16 bit... */
- xid->xps_16 = handle;
-
- prvTraceUpdateCounters();
- }
-}
-
-static uint8_t prvTraceGet8BitHandle(traceHandle handle)
-{
- if (handle > 255)
- {
- prvTraceStoreXID(handle);
- /* The full handle (16 bit) is stored in the XID event.
- This code (255) is used instead of zero (which is an error code).*/
- return 255;
- }
- return (uint8_t)(handle & 0xFF);
-}
-#endif /*(TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1)*/
-
-
-/* If using DWT timestamping (default on ARM Cortex-M3, M4 and M7), make sure the DWT unit is initialized. */
-#ifndef TRC_CFG_ARM_CM_USE_SYSTICK
-#if ((TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_Cortex_M) && (defined (__CORTEX_M) && (__CORTEX_M >= 0x03)))
-void prvTraceInitCortexM()
-{
- /* Ensure that the DWT registers are unlocked and can be modified. */
- TRC_REG_ITM_LOCKACCESS = TRC_ITM_LOCKACCESS_UNLOCK;
-
- /* Make sure DWT is enabled, if supported */
- TRC_REG_DEMCR |= TRC_DEMCR_TRCENA;
-
- do{
- /* Verify that DWT is supported */
- if (TRC_REG_DEMCR == 0)
- {
- /* This function is called on Cortex-M3, M4 and M7 devices to initialize
- the DWT unit, assumed present. The DWT cycle counter is used for timestamping.
-
- If the below error is produced, the DWT unit does not seem to be available.
-
- In that case, define the macro TRC_CFG_ARM_CM_USE_SYSTICK in your build
- to use SysTick timestamping instead, or define your own timestamping by
- setting TRC_CFG_HARDWARE_PORT to TRC_HARDWARE_PORT_APPLICATION_DEFINED
- and make the necessary definitions, as explained in trcHardwarePort.h.*/
-
- prvTraceError("DWT unit not available, see code comment.");
- break;
- }
-
- /* Verify that DWT_CYCCNT is supported */
- if (TRC_REG_DWT_CTRL & TRC_DWT_CTRL_NOCYCCNT)
- {
- /* This function is called on Cortex-M3, M4 and M7 devices to initialize
- the DWT unit, assumed present. The DWT cycle counter is used for timestamping.
-
- If the below error is produced, the cycle counter does not seem to be available.
-
- In that case, define the macro TRC_CFG_ARM_CM_USE_SYSTICK in your build
- to use SysTick timestamping instead, or define your own timestamping by
- setting TRC_CFG_HARDWARE_PORT to TRC_HARDWARE_PORT_APPLICATION_DEFINED
- and make the necessary definitions, as explained in trcHardwarePort.h.*/
-
- prvTraceError("DWT_CYCCNT not available, see code comment.");
- break;
- }
-
- /* Reset the cycle counter */
- TRC_REG_DWT_CYCCNT = 0;
-
- /* Enable the cycle counter */
- TRC_REG_DWT_CTRL |= TRC_DWT_CTRL_CYCCNTENA;
-
- }while(0); /* breaks above jump here */
-}
-#endif
-#endif
-
-/******************************************************************************
- * 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 *pTimestamp)
-{
- static uint32_t last_hwtc_count = 0;
- uint32_t hwtc_count = 0;
-
-#if TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR
- /* systick based timer */
- static uint32_t last_traceTickCount = 0;
- uint32_t traceTickCount = 0;
-#else /*TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR*/
- /* Free running timer */
- static uint32_t last_hwtc_rest = 0;
- uint32_t diff = 0;
- uint32_t diff_scaled = 0;
-#endif /*TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR*/
-
- if (trace_disable_timestamp == 1)
- {
- if (pTimestamp)
- *pTimestamp = last_timestamp;
- return;
- }
-
- /* Retrieve TRC_HWTC_COUNT only once since the same value should be used all throughout this function. */
-#if (TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_INCR)
- /* Get the increasing tick count */
- hwtc_count = (TRC_HWTC_COUNT);
-#elif (TRC_HWTC_TYPE == TRC_OS_TIMER_DECR || TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_DECR)
- /* Convert decreasing tick count into increasing tick count */
- hwtc_count = (TRC_HWTC_PERIOD) - (TRC_HWTC_COUNT);
-#else
- #error "TRC_HWTC_TYPE has unexpected value"
-#endif
-
-#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Win32)
- /* The Win32 port uses ulGetRunTimeCounterValue for timestamping, which in turn
- uses QueryPerformanceCounter. That function is not always reliable when used over
- multiple threads. We must therefore handle rare cases where the timestamp is less
- than the previous. In practice, this should "never" roll over since the
- performance counter is 64 bit wide. */
-
- if (last_hwtc_count > hwtc_count)
- {
- hwtc_count = last_hwtc_count;
- }
-#endif
-
-#if (TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR)
- /* Timestamping is based on a timer that wraps at TRC_HWTC_PERIOD */
- if (last_traceTickCount - uiTraceTickCount - 1 < 0x80000000)
- {
- /* This means last_traceTickCount is higher than uiTraceTickCount,
- so we have previously compensated for a missed tick.
- Therefore we use the last stored value because that is more accurate. */
- traceTickCount = last_traceTickCount;
- }
- else
- {
- /* Business as usual */
- traceTickCount = uiTraceTickCount;
- }
-
- /* Check for overflow. May occur if the update of uiTraceTickCount has been
- delayed due to disabled interrupts. */
- if (traceTickCount == last_traceTickCount && hwtc_count < last_hwtc_count)
- {
- /* A trace tick has occurred but not been executed by the kernel, so we compensate manually. */
- traceTickCount++;
- }
-
- /* Check if the return address is OK, then we perform the calculation. */
- if (pTimestamp)
- {
- /* Get timestamp from trace ticks. Scale down the period to avoid unwanted overflows. */
- last_timestamp = traceTickCount * ((TRC_HWTC_PERIOD) / (TRC_HWTC_DIVISOR));
- /* Increase timestamp by (hwtc_count + "lost hardware ticks from scaling down period") / TRC_HWTC_DIVISOR. */
- last_timestamp += (hwtc_count + traceTickCount * ((TRC_HWTC_PERIOD) % (TRC_HWTC_DIVISOR))) / (TRC_HWTC_DIVISOR);
- }
- /* Store the previous value */
- last_traceTickCount = traceTickCount;
-
-#else /*(TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR)*/
-
- /* Timestamping is based on a free running timer */
- /* This part handles free running clocks that can be scaled down to avoid too large DTS values.
- Without this, the scaled timestamp will incorrectly wrap at (2^32 / TRC_HWTC_DIVISOR) ticks.
- The scaled timestamp returned from this function is supposed to go from 0 -> 2^32, which in real time would represent (0 -> 2^32 * TRC_HWTC_DIVISOR) ticks. */
-
- /* First we see how long time has passed since the last timestamp call, and we also add the ticks that was lost when we scaled down the last time. */
- diff = (hwtc_count - last_hwtc_count) + last_hwtc_rest;
-
- /* Scale down the diff */
- diff_scaled = diff / (TRC_HWTC_DIVISOR);
-
- /* Find out how many ticks were lost when scaling down, so we can add them the next time */
- last_hwtc_rest = diff % (TRC_HWTC_DIVISOR);
-
- /* We increase the scaled timestamp by the scaled amount */
- last_timestamp += diff_scaled;
-#endif /*(TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR)*/
-
- /* Is anyone interested in the results? */
- if (pTimestamp)
- *pTimestamp = last_timestamp;
-
- /* Store the previous value */
- last_hwtc_count = hwtc_count;
-}
-
-#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/
-
-#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)*/
+/*******************************************************************************
+ * Trace Recorder Library for Tracealyzer v4.3.11
+ * Percepio AB, www.percepio.com
+ *
+ * trcSnapshotRecorder.c
+ *
+ * The generic core of the trace recorder's snapshot mode.
+ *
+ * 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
+ ******************************************************************************/
+
+#include "trcRecorder.h"
+
+#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)
+
+#if (TRC_USE_TRACEALYZER_RECORDER == 1)
+
+#include <string.h>
+#include <stdarg.h>
+#include <stdint.h>
+
+#if ((TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_INCR) || (TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_DECR))
+ #error "CUSTOM timestamping mode is not (yet) supported in snapshot mode!"
+#endif
+
+/* DO NOT CHANGE */
+#define TRACE_MINOR_VERSION 5
+#if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
+static traceHandle isrstack[TRC_CFG_MAX_ISR_NESTING];
+int32_t isPendingContextSwitch = 0;
+#endif /* (TRC_CFG_INCLUDE_ISR_TRACING == 1) */
+
+#if !defined TRC_CFG_INCLUDE_READY_EVENTS || TRC_CFG_INCLUDE_READY_EVENTS == 1
+static int readyEventsEnabled = 1;
+#endif /*!defined TRC_CFG_INCLUDE_READY_EVENTS || TRC_CFG_INCLUDE_READY_EVENTS == 1*/
+
+/*******************************************************************************
+ * uiTraceTickCount
+ *
+ * This variable is should be updated by the Kernel tick interrupt. This does
+ * not need to be modified when developing a new timer port. It is preferred to
+ * keep any timer port changes in the HWTC macro definitions, which typically
+ * give sufficient flexibility.
+ ******************************************************************************/
+uint32_t uiTraceTickCount = 0;
+
+uint32_t trace_disable_timestamp = 0;
+
+static uint32_t last_timestamp = 0;
+
+/* Indicates if we are currently performing a context switch or just running application code */
+volatile uint32_t uiTraceSystemState = TRC_STATE_IN_STARTUP;
+
+/* Flag that shows if inside a critical section of the recorder */
+volatile int recorder_busy = 0;
+
+/* Holds the value set by vTraceSetFrequency */
+uint32_t timestampFrequency = 0;
+
+/* The last error message of the recorder. NULL if no error message. */
+const char* traceErrorMessage = NULL;
+
+int8_t nISRactive = 0;
+
+traceHandle handle_of_last_logged_task = 0;
+
+/* Called when the recorder is stopped, set by vTraceSetStopHook. */
+TRACE_STOP_HOOK vTraceStopHookPtr = (TRACE_STOP_HOOK)0;
+
+uint16_t CurrentFilterMask = 0xFFFF;
+
+uint16_t CurrentFilterGroup = FilterGroup0;
+
+extern int8_t nISRactive;
+
+extern traceHandle handle_of_last_logged_task;
+
+/*************** Private Functions *******************************************/
+static void prvStrncpy(char* dst, const char* src, uint32_t maxLength);
+static uint8_t prvTraceGetObjectState(uint8_t objectclass, traceHandle id);
+static void prvTraceGetChecksum(const char *pname, uint8_t* pcrc, uint8_t* plength);
+static void* prvTraceNextFreeEventBufferSlot(void);
+static uint16_t prvTraceGetDTS(uint16_t param_maxDTS);
+static traceString prvTraceOpenSymbol(const char* name, traceString userEventChannel);
+static void prvTraceUpdateCounters(void);
+
+void vTraceStoreMemMangEvent(uint32_t ecode, uint32_t address, int32_t signed_size);
+
+#if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER)
+static void prvCheckDataToBeOverwrittenForMultiEntryEvents(uint8_t nEntries);
+#endif
+
+static traceString prvTraceCreateSymbolTableEntry(const char* name,
+ uint8_t crc6,
+ uint8_t len,
+ traceString channel);
+
+static traceString prvTraceLookupSymbolTableEntry(const char* name,
+ uint8_t crc6,
+ uint8_t len,
+ traceString channel);
+
+
+#if (TRC_CFG_INCLUDE_ISR_TRACING == 0)
+/* ISR tracing is turned off */
+void prvTraceIncreaseISRActive(void);
+void prvTraceDecreaseISRActive(void);
+#endif /*(TRC_CFG_INCLUDE_ISR_TRACING == 0)*/
+
+#if (TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1)
+static uint8_t prvTraceGet8BitHandle(traceHandle handle);
+#else
+#define prvTraceGet8BitHandle(x) ((uint8_t)x)
+#endif
+
+
+#if (TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1) && (TRC_CFG_SCHEDULING_ONLY == 0)
+static uint32_t heapMemUsage = 0;
+#endif
+
+#if (TRC_CFG_SCHEDULING_ONLY == 0)
+static uint32_t prvTraceGetParam(uint32_t, uint32_t);
+#endif
+
+/*******************************************************************************
+ * 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);
+
+static void prvTraceTaskInstanceFinish(int8_t direct);
+
+#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1))
+#if (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)
+static void vTraceUBData_Helper(traceUBChannel channelPair, va_list vl);
+static void prvTraceUBHelper1(traceUBChannel channel, traceString eventLabel, traceString formatLabel, va_list vl);
+static void prvTraceUBHelper2(traceUBChannel channel, uint32_t* data, uint32_t noOfSlots);
+#endif /* (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1) */
+#endif /* ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)) */
+
+/********* Public Functions **************************************************/
+
+uint16_t uiIndexOfObject(traceHandle objecthandle, uint8_t objectclass);
+
+/*******************************************************************************
+ * prvTraceError
+ *
+ * Called by various parts in the recorder. Stops the recorder and stores a
+ * pointer to an error message, which is printed by the monitor task.
+ ******************************************************************************/
+void prvTraceError(const char* msg);
+
+/*******************************************************************************
+ * vTraceSetRecorderDataBuffer
+ *
+ * If custom allocation is used, this function must be called so the recorder
+ * library knows where to save the trace data.
+ ******************************************************************************/
+#if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM)
+void vTraceSetRecorderDataBuffer(void* pRecorderData)
+{
+ TRACE_ASSERT(pRecorderData != NULL, "vTraceSetRecorderDataBuffer, pRecorderData == NULL", TRC_UNUSED);
+ RecorderDataPtr = pRecorderData;
+}
+#endif
+
+/*******************************************************************************
+ * vTraceSetStopHook
+ *
+ * Sets a function to be called when the recorder is stopped. This can be used
+ * to save the trace to a file system, if available. This is only implemented
+ * for snapshot mode.
+ ******************************************************************************/
+void vTraceSetStopHook(TRACE_STOP_HOOK stopHookFunction)
+{
+ vTraceStopHookPtr = stopHookFunction;
+}
+
+/*******************************************************************************
+ * vTraceClear
+ *
+ * Resets the recorder. Only necessary if a restart is desired - this is not
+ * needed in the startup initialization.
+ ******************************************************************************/
+void vTraceClear(void)
+{
+ TRACE_ALLOC_CRITICAL_SECTION();
+ trcCRITICAL_SECTION_BEGIN();
+ RecorderDataPtr->absTimeLastEventSecond = 0;
+ RecorderDataPtr->absTimeLastEvent = 0;
+ RecorderDataPtr->nextFreeIndex = 0;
+ RecorderDataPtr->numEvents = 0;
+ RecorderDataPtr->bufferIsFull = 0;
+ traceErrorMessage = NULL;
+ RecorderDataPtr->internalErrorOccured = 0;
+ (void)memset(RecorderDataPtr->eventData, 0, RecorderDataPtr->maxEvents * 4);
+ handle_of_last_logged_task = 0;
+ trcCRITICAL_SECTION_END();
+}
+
+/*******************************************************************************
+ * uiTraceStart
+ *
+ * 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 trcConfig.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.
+ *
+ * This function is obsolete, but has been saved for backwards compatibility.
+ * We recommend using vTraceEnable instead.
+ ******************************************************************************/
+uint32_t uiTraceStart(void)
+{
+ traceHandle handle;
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ handle = 0;
+
+ if (RecorderDataPtr == NULL)
+ {
+ TRACE_ASSERT(RecorderDataPtr != NULL, "Recorder not initialized. Use vTraceEnable() instead!", 0);
+ return 0;
+ }
+
+ if (RecorderDataPtr->recorderActive == 1)
+ return 1; /* Already running */
+
+ if (traceErrorMessage == NULL)
+ {
+ trcCRITICAL_SECTION_BEGIN();
+ RecorderDataPtr->recorderActive = 1;
+
+ handle = TRACE_GET_TASK_NUMBER(TRACE_GET_CURRENT_TASK());
+ if (handle == 0)
+ {
+ /* This occurs if the scheduler is not yet started.
+ This creates a dummy "(startup)" task entry internally in the
+ recorder */
+ handle = prvTraceGetObjectHandle(TRACE_CLASS_TASK);
+ prvTraceSetObjectName(TRACE_CLASS_TASK, handle, "(startup)");
+
+ prvTraceSetPriorityProperty(TRACE_CLASS_TASK, handle, 0);
+ }
+
+ prvTraceStoreTaskswitch(handle); /* Register the currently running task */
+ trcCRITICAL_SECTION_END();
+ }
+
+ return RecorderDataPtr->recorderActive;
+}
+
+/*******************************************************************************
+ * vTraceStart
+ *
+ * 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 trcConfig.h
+ * has a too small value (TRC_CFG_NTASK, TRC_CFG_NQUEUE, etc).
+ *
+ * This function is obsolete, but has been saved for backwards compatibility.
+ * We recommend using vTraceEnable instead.
+ ******************************************************************************/
+void vTraceStart(void)
+{
+ (void)uiTraceStart();
+}
+
+/*******************************************************************************
+ * vTraceStop
+ *
+ * Stops the recorder. The recording can be resumed by calling vTraceStart.
+ * This does not reset the recorder. Use vTraceClear if that is desired.
+ ******************************************************************************/
+void vTraceStop(void)
+{
+ if (RecorderDataPtr != NULL)
+ {
+ RecorderDataPtr->recorderActive = 0;
+ }
+
+ if (vTraceStopHookPtr != (TRACE_STOP_HOOK)0)
+ {
+ (*vTraceStopHookPtr)(); /* An application call-back function. */
+ }
+}
+
+/*******************************************************************************
+* xTraceIsRecordingEnabled
+* Returns true (1) if the recorder is enabled (i.e. is recording), otherwise 0.
+******************************************************************************/
+int xTraceIsRecordingEnabled(void)
+{
+ if (RecorderDataPtr != NULL)
+ {
+ return (int)RecorderDataPtr->recorderActive;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+/*******************************************************************************
+ * xTraceGetLastError
+ *
+ * Gives the last error message, if any. NULL if no error message is stored.
+ * Any error message is also presented when opening a trace file.
+ ******************************************************************************/
+const char* xTraceGetLastError(void)
+{
+ return traceErrorMessage;
+}
+
+/*******************************************************************************
+* vTraceClearError
+*
+* Removes any previous error message generated by recorder calling prvTraceError.
+* By calling this function, it may be possible to start/restart the trace
+* despite errors in the recorder, but there is no guarantee that the trace
+* recorder will work correctly in that case, depending on the type of error.
+******************************************************************************/
+void vTraceClearError(void)
+{
+ traceErrorMessage = NULL;
+ if (RecorderDataPtr != NULL)
+ {
+ RecorderDataPtr->internalErrorOccured = 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)
+{
+ return RecorderDataPtr;
+}
+
+/*******************************************************************************
+ * 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)
+{
+ return sizeof(RecorderDataType);
+}
+
+/******************************************************************************
+ * prvTraceTaskInstanceFinish
+ *
+ * Private common function for the vTraceTaskInstanceFinishXXX functions.
+ *****************************************************************************/
+static void prvTraceTaskInstanceFinish(int8_t direct)
+{
+ TaskInstanceStatusEvent* tis;
+ uint8_t dts45;
+
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ trcCRITICAL_SECTION_BEGIN();
+ if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)
+ {
+ dts45 = (uint8_t)prvTraceGetDTS(0xFF);
+ tis = (TaskInstanceStatusEvent*) prvTraceNextFreeEventBufferSlot();
+ if (tis != NULL)
+ {
+ if (direct == 0)
+ tis->type = TASK_INSTANCE_FINISHED_NEXT_KSE;
+ else
+ tis->type = TASK_INSTANCE_FINISHED_DIRECT;
+
+ tis->dts = dts45;
+ prvTraceUpdateCounters();
+ }
+ }
+ trcCRITICAL_SECTION_END();
+}
+
+/******************************************************************************
+ * vTraceInstanceFinishedNext(void)
+ *
+ * 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.
+ *
+ * See also TRC_CFG_USE_IMPLICIT_IFE_RULES in trcConfig.h
+ *
+ * Example:
+ *
+ * while(1)
+ * {
+ * xQueueReceive(CommandQueue, &command, timeoutDuration);
+ * processCommand(command);
+ * vTraceInstanceFinishedNext();
+ * }
+ *****************************************************************************/
+void vTraceInstanceFinishedNext(void)
+{
+ prvTraceTaskInstanceFinish(0);
+}
+
+/******************************************************************************
+ * vTraceInstanceFinishedNow(void)
+ *
+ * Marks the current task instance as finished at this very instant.
+ * This makes the viewer to splits the current fragment at this point and begin
+ * a new actor instance.
+ *
+ * See also TRC_CFG_USE_IMPLICIT_IFE_RULES in trcConfig.h
+ *
+ * Example:
+ *
+ * This example will generate two instances for each loop iteration.
+ * The first instance ends at vTraceInstanceFinishedNow(), while the second
+ * instance ends at the next xQueueReceive call.
+ *
+ * while (1)
+ * {
+ * xQueueReceive(CommandQueue, &command, timeoutDuration);
+ * ProcessCommand(command);
+ * vTraceInstanceFinishedNow();
+ * DoSometingElse();
+ * vTraceInstanceFinishedNext();
+ * }
+ *****************************************************************************/
+void vTraceInstanceFinishedNow(void)
+{
+ prvTraceTaskInstanceFinish(1);
+}
+
+/*******************************************************************************
+ * Interrupt recording functions
+ ******************************************************************************/
+
+#if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
+
+/*******************************************************************************
+ * 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)
+{
+ static traceHandle handle = 0;
+ TRACE_ASSERT(RecorderDataPtr != NULL, "Recorder not initialized, call vTraceEnable() first!", (traceHandle)0);
+ TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[TRACE_CLASS_ISR], "xTraceSetISRProperties: Invalid value for handle", 0);
+ TRACE_ASSERT(name != NULL, "xTraceSetISRProperties: name == NULL", 0);
+
+ handle++;
+
+ prvTraceSetObjectName(TRACE_CLASS_ISR, handle, name);
+ prvTraceSetPriorityProperty(TRACE_CLASS_ISR, handle, priority);
+
+ return handle;
+}
+
+/*******************************************************************************
+ * 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)
+{
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ if (recorder_busy)
+ {
+ /*************************************************************************
+ * This occurs if an ISR calls a trace function, preempting a previous
+ * trace call that is being processed in a different ISR or task.
+ * If this occurs, there is probably a problem in the definition of the
+ * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and
+ * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt
+ * and any other ISRs that calls the trace recorder directly or via
+ * traced kernel functions. The ARM port disables all interrupts using the
+ * PRIMASK register to avoid this issue.
+ *************************************************************************/
+ prvTraceError("vTraceStoreISRBegin - recorder busy! See code comment.");
+ return;
+ }
+ trcCRITICAL_SECTION_BEGIN();
+
+ if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)
+ {
+ uint16_t dts4;
+
+ TRACE_ASSERT(handle != 0, "vTraceStoreISRBegin: Invalid ISR handle (NULL)", TRC_UNUSED);
+ TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[TRACE_CLASS_ISR], "vTraceStoreISRBegin: Invalid ISR handle (> NISR)", TRC_UNUSED);
+
+ dts4 = (uint16_t)prvTraceGetDTS(0xFFFF);
+
+ if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */
+ {
+ if (nISRactive < TRC_CFG_MAX_ISR_NESTING)
+ {
+ TSEvent* ts;
+ uint8_t hnd8 = prvTraceGet8BitHandle(handle);
+ isrstack[nISRactive] = handle;
+ nISRactive++;
+ ts = (TSEvent*)prvTraceNextFreeEventBufferSlot();
+ if (ts != NULL)
+ {
+ ts->type = TS_ISR_BEGIN;
+ ts->dts = dts4;
+ ts->objHandle = hnd8;
+ prvTraceUpdateCounters();
+ }
+ }
+ else
+ {
+ /* This should not occur unless something is very wrong */
+ prvTraceError("Too many nested interrupts!");
+ }
+ }
+ }
+ trcCRITICAL_SECTION_END();
+}
+
+/*******************************************************************************
+ * 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 pendingISR)
+{
+ TSEvent* ts;
+ uint16_t dts5;
+ uint8_t hnd8 = 0, type = 0;
+
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ if (! RecorderDataPtr->recorderActive || ! handle_of_last_logged_task)
+ {
+ return;
+ }
+
+ if (recorder_busy)
+ {
+ /*************************************************************************
+ * This occurs if an ISR calls a trace function, preempting a previous
+ * trace call that is being processed in a different ISR or task.
+ * If this occurs, there is probably a problem in the definition of the
+ * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and
+ * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt
+ * and any other ISRs that calls the trace recorder directly or via
+ * traced kernel functions. The ARM port disables all interrupts using the
+ * PRIMASK register to avoid this issue.
+ *************************************************************************/
+ prvTraceError("vTraceStoreISREnd - recorder busy! See code comment.");
+ return;
+ }
+
+ if (nISRactive == 0)
+ {
+ prvTraceError("Unmatched call to vTraceStoreISREnd (nISRactive == 0, expected > 0)");
+ return;
+ }
+
+ trcCRITICAL_SECTION_BEGIN();
+ isPendingContextSwitch |= pendingISR; /* Is there a pending context switch right now? */
+ nISRactive--;
+ if (nISRactive > 0)
+ {
+ /* Return to another ISR */
+ type = TS_ISR_RESUME;
+ hnd8 = prvTraceGet8BitHandle(isrstack[nISRactive - 1]); /* isrstack[nISRactive] is the handle of the ISR we're currently exiting. isrstack[nISRactive - 1] is the handle of the ISR that was executing previously. */
+ }
+ else if ((isPendingContextSwitch == 0) || (prvTraceIsSchedulerSuspended()))
+ {
+ /* Return to interrupted task, if no context switch will occur in between. */
+ type = TS_TASK_RESUME;
+ hnd8 = prvTraceGet8BitHandle(handle_of_last_logged_task);
+ }
+
+ if (type != 0)
+ {
+ dts5 = (uint16_t)prvTraceGetDTS(0xFFFF);
+ ts = (TSEvent*)prvTraceNextFreeEventBufferSlot();
+ if (ts != NULL)
+ {
+ ts->type = type;
+ ts->objHandle = hnd8;
+ ts->dts = dts5;
+ prvTraceUpdateCounters();
+ }
+ }
+
+ trcCRITICAL_SECTION_END();
+}
+
+#else
+
+/* ISR tracing is turned off */
+void prvTraceIncreaseISRActive(void)
+{
+ if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)
+ nISRactive++;
+}
+
+void prvTraceDecreaseISRActive(void)
+{
+ if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)
+ nISRactive--;
+}
+#endif /* (TRC_CFG_INCLUDE_ISR_TRACING == 1)*/
+
+
+/********************************************************************************/
+/* User Event functions */
+/********************************************************************************/
+
+#define MAX_ARG_SIZE (4+32)
+
+#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1))
+static uint8_t writeInt8(void * buffer, uint8_t i, uint8_t value)
+{
+ TRACE_ASSERT(buffer != NULL, "writeInt8: buffer == NULL", 0);
+
+ if (i >= MAX_ARG_SIZE)
+ {
+ return 255;
+ }
+
+ ((uint8_t*)buffer)[i] = value;
+
+ if (i + 1 > MAX_ARG_SIZE)
+ {
+ return 255;
+ }
+
+ return ((uint8_t) (i + 1));
+}
+#endif
+
+#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1))
+static uint8_t writeInt16(void * buffer, uint8_t i, uint16_t value)
+{
+ TRACE_ASSERT(buffer != NULL, "writeInt16: buffer == NULL", 0);
+
+ /* Align to multiple of 2 */
+ while ((i % 2) != 0)
+ {
+ if (i >= MAX_ARG_SIZE)
+ {
+ return 255;
+ }
+
+ ((uint8_t*)buffer)[i] = 0;
+ i++;
+ }
+
+ if (i + 2 > MAX_ARG_SIZE)
+ {
+ return 255;
+ }
+
+ ((uint16_t*)buffer)[i/2] = value;
+
+ return ((uint8_t) (i + 2));
+}
+#endif
+
+#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1))
+static uint8_t writeInt32(void * buffer, uint8_t i, uint32_t value)
+{
+ TRACE_ASSERT(buffer != NULL, "writeInt32: buffer == NULL", 0);
+
+ /* A 32 bit value should begin at an even 4-byte address */
+ while ((i % 4) != 0)
+ {
+ if (i >= MAX_ARG_SIZE)
+ {
+ return 255;
+ }
+
+ ((uint8_t*)buffer)[i] = 0;
+ i++;
+ }
+
+ if (i + 4 > MAX_ARG_SIZE)
+ {
+ return 255;
+ }
+
+ ((uint32_t*)buffer)[i/4] = value;
+
+ return ((uint8_t) (i + 4));
+}
+#endif
+
+#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_INCLUDE_FLOAT_SUPPORT))
+static uint8_t writeFloat(void * buffer, uint8_t i, float value)
+{
+ TRACE_ASSERT(buffer != NULL, "writeFloat: buffer == NULL", 0);
+
+ /* A 32 bit value should begin at an even 4-byte address */
+ while ((i % 4) != 0)
+ {
+ if (i >= MAX_ARG_SIZE)
+ {
+ return 255;
+ }
+
+ ((uint8_t*)buffer)[i] = 0;
+ i++;
+ }
+
+ if (i + 4 > MAX_ARG_SIZE)
+ {
+ return 255;
+ }
+
+ ((float*)buffer)[i/4] = value;
+
+ return i + 4;
+}
+#endif
+
+#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_INCLUDE_FLOAT_SUPPORT))
+static uint8_t writeDouble(void * buffer, uint8_t i, double value)
+{
+ uint32_t * dest;
+ uint32_t * src = (uint32_t*)&value;
+
+ TRACE_ASSERT(buffer != NULL, "writeDouble: buffer == NULL", 0);
+
+ /* The double is written as two 32 bit values, and should begin at an even
+ 4-byte address (to avoid having to align with 8 byte) */
+ while (i % 4 != 0)
+ {
+ if (i >= MAX_ARG_SIZE)
+ {
+ return 255;
+ }
+
+ ((uint8_t*)buffer)[i] = 0;
+ i++;
+ }
+
+ if (i + 8 > MAX_ARG_SIZE)
+ {
+ return 255;
+ }
+
+ dest = &(((uint32_t *)buffer)[i/4]);
+
+ dest[0] = src[0];
+ dest[1] = src[1];
+
+ return i + 8;
+}
+#endif
+
+/*******************************************************************************
+ * prvTraceUserEventFormat
+ *
+ * Parses the format string and stores the arguments in the buffer.
+ ******************************************************************************/
+#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1))
+static uint8_t prvTraceUserEventFormat(const char* formatStr, va_list vl, uint8_t* buffer, uint8_t byteOffset)
+{
+ uint16_t formatStrIndex = 0;
+ uint8_t argCounter = 0;
+ uint8_t i = byteOffset;
+
+ while (formatStr[formatStrIndex] != '\0')
+ {
+ if (formatStr[formatStrIndex] == '%')
+ {
+ if (formatStr[formatStrIndex + 1] == '%')
+ {
+ formatStrIndex += 2;
+ continue;
+ }
+
+ /* We found a possible argument */
+ argCounter++;
+
+ formatStrIndex++;
+
+ while ((formatStr[formatStrIndex] >= '0' && formatStr[formatStrIndex] <= '9') || formatStr[formatStrIndex] == '#' || formatStr[formatStrIndex] == '.')
+ formatStrIndex++;
+
+ /* This check is necessary to avoid moving past end of string. */
+ if (formatStr[formatStrIndex] != '\0')
+ {
+ switch (formatStr[formatStrIndex])
+ {
+ case 'd':
+ i = writeInt32( buffer,
+ i,
+ (uint32_t)va_arg(vl, uint32_t));
+ break;
+ case 'x':
+ case 'X':
+ case 'u':
+ i = writeInt32( buffer,
+ i,
+ (uint32_t)va_arg(vl, uint32_t));
+ break;
+ case 's':
+ i = writeInt16( buffer,
+ i,
+ xTraceRegisterString((char*)va_arg(vl, char*)));
+ break;
+
+#if (TRC_CFG_INCLUDE_FLOAT_SUPPORT)
+ /* Yes, "double" as type also in the float
+ case. This since "float" is promoted into "double"
+ by the va_arg stuff. */
+ case 'f':
+ i = writeFloat( buffer,
+ i,
+ (float)va_arg(vl, double));
+ break;
+#else
+ /* No support for floats, but attempt to store a float user event
+ avoid a possible crash due to float reference. Instead store the
+ data on uint_32 format (will not be displayed anyway). This is just
+ to keep va_arg and i consistent. */
+
+ case 'f':
+ i = writeInt32( buffer,
+ i,
+ (uint32_t)va_arg(vl, double));
+ break;
+#endif
+ case 'l':
+ formatStrIndex++;
+ switch (formatStr[formatStrIndex])
+ {
+#if (TRC_CFG_INCLUDE_FLOAT_SUPPORT)
+ case 'f': i = writeDouble(buffer,
+ i,
+ (double)va_arg(vl, double));
+ break;
+#else
+ /* No support for floats, but attempt to store a float user event
+ avoid a possible crash due to float reference. Instead store the
+ data on uint_32 format (will not be displayed anyway). This is just
+ to keep va_arg and i consistent. */
+ case 'f':
+ i = writeInt32( buffer, /* In this case, the value will not be shown anyway */
+ i,
+ (uint32_t)va_arg(vl, double));
+
+ i = writeInt32( buffer, /* Do it twice, to write in total 8 bytes */
+ i,
+ (uint32_t)va_arg(vl, double));
+ break;
+#endif
+ }
+ break;
+ case 'h':
+ formatStrIndex++;
+ switch (formatStr[formatStrIndex])
+ {
+ case 'd':
+ i = writeInt16( buffer,
+ i,
+ (uint16_t)va_arg(vl, uint32_t));
+ break;
+ case 'u':
+ i = writeInt16( buffer,
+ i,
+ (uint16_t)va_arg(vl, uint32_t));
+ break;
+ }
+ break;
+ case 'b':
+ formatStrIndex++;
+ switch (formatStr[formatStrIndex])
+ {
+ case 'd':
+ i = writeInt8( buffer,
+ i,
+ (uint8_t)va_arg(vl, uint32_t));
+ break;
+ case 'u':
+ i = writeInt8( buffer,
+ i,
+ (uint8_t)va_arg(vl, uint32_t));
+ break;
+ }
+ break;
+ default:
+ /* False alarm: this wasn't a valid format specifier */
+ argCounter--;
+ break;
+ }
+
+ if (argCounter > 15)
+ {
+ prvTraceError("vTracePrintF - Too many arguments, max 15 allowed!");
+ return 0;
+ }
+ }
+ else
+ break;
+ }
+ formatStrIndex++;
+ if (i == 255)
+ {
+ prvTraceError("vTracePrintF - Too large arguments, max 32 byte allowed!");
+ return 0;
+ }
+ }
+ return (uint8_t)(i+3)/4;
+}
+#endif
+
+/*******************************************************************************
+ * prvTraceClearChannelBuffer
+ *
+ * Clears a number of items in the channel buffer, starting from nextSlotToWrite.
+ ******************************************************************************/
+#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1))
+static void prvTraceClearChannelBuffer(uint32_t count)
+{
+ uint32_t slots;
+
+ TRACE_ASSERT((TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE) >= count,
+ "prvTraceClearChannelBuffer: TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE is too small to handle this event.", TRC_UNUSED);
+
+ /* Check if we're close to the end of the buffer */
+ if (RecorderDataPtr->userEventBuffer.nextSlotToWrite + count > (TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE))
+ {
+ slots = (TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE) - RecorderDataPtr->userEventBuffer.nextSlotToWrite; /* Number of slots before end of buffer */
+ (void)memset(&RecorderDataPtr->userEventBuffer.channelBuffer[RecorderDataPtr->userEventBuffer.nextSlotToWrite], 0, slots);
+ (void)memset(&RecorderDataPtr->userEventBuffer.channelBuffer[0], 0, (count - slots));
+ }
+ else
+ (void)memset(&RecorderDataPtr->userEventBuffer.channelBuffer[RecorderDataPtr->userEventBuffer.nextSlotToWrite], 0, count);
+}
+#endif
+
+/*******************************************************************************
+ * prvTraceCopyToDataBuffer
+ *
+ * Copies a number of items to the data buffer, starting from nextSlotToWrite.
+ ******************************************************************************/
+#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1))
+static void prvTraceCopyToDataBuffer(uint32_t* data, uint32_t count)
+{
+ uint32_t slots;
+
+ TRACE_ASSERT(data != NULL,
+ "prvTraceCopyToDataBuffer: data == NULL.", TRC_UNUSED);
+ TRACE_ASSERT(count <= (TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE),
+ "prvTraceCopyToDataBuffer: TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE is too small to handle this event.", TRC_UNUSED);
+ /* Check if we're close to the end of the buffer */
+ if (RecorderDataPtr->userEventBuffer.nextSlotToWrite + count > (TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE))
+ {
+ slots = (TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE) - RecorderDataPtr->userEventBuffer.nextSlotToWrite; /* Number of slots before end of buffer */
+ (void)memcpy(&RecorderDataPtr->userEventBuffer.dataBuffer[RecorderDataPtr->userEventBuffer.nextSlotToWrite * 4], data, slots * 4);
+ (void)memcpy(&RecorderDataPtr->userEventBuffer.dataBuffer[0], data + slots, (count - slots) * 4);
+ }
+ else
+ {
+ (void)memcpy(&RecorderDataPtr->userEventBuffer.dataBuffer[RecorderDataPtr->userEventBuffer.nextSlotToWrite * 4], data, count * 4);
+ }
+}
+#endif
+
+/*******************************************************************************
+ * prvTraceUBHelper1
+ *
+ * Calls on prvTraceUserEventFormat() to do the actual formatting, then goes on
+ * to the next helper function.
+ ******************************************************************************/
+#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1))
+static void prvTraceUBHelper1(traceUBChannel channel, traceString eventLabel, traceString formatLabel, va_list vl)
+{
+ uint32_t data[(3 + MAX_ARG_SIZE) / 4];
+ uint8_t byteOffset = 4; /* Need room for timestamp */
+ uint8_t noOfSlots;
+
+ if (channel == 0)
+ {
+ /* We are dealing with an unknown channel format pair */
+ byteOffset = (uint8_t)(byteOffset + 4); /* Also need room for channel and format */
+ ((uint16_t*)data)[2] = eventLabel;
+ ((uint16_t*)data)[3] = formatLabel;
+ }
+
+ noOfSlots = prvTraceUserEventFormat((char*)&(RecorderDataPtr->SymbolTable.symbytes[formatLabel+4]), vl, (uint8_t*)data, byteOffset);
+
+ prvTraceUBHelper2(channel, data, noOfSlots);
+}
+#endif
+
+/*******************************************************************************
+ * prvTraceUBHelper2
+ *
+ * This function simply copies the data buffer to the actual user event buffer.
+ ******************************************************************************/
+#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1))
+static void prvTraceUBHelper2(traceUBChannel channel, uint32_t* data, uint32_t noOfSlots)
+{
+ static uint32_t old_timestamp = 0;
+ uint32_t old_nextSlotToWrite = 0;
+
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ TRACE_ASSERT((TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE) >= noOfSlots, "prvTraceUBHelper2: TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE is too small to handle this event.", TRC_UNUSED);
+
+ trcCRITICAL_SECTION_BEGIN();
+ /* Store the timestamp */
+ prvTracePortGetTimeStamp(data);
+
+ if (*data < old_timestamp)
+ {
+ RecorderDataPtr->userEventBuffer.wraparoundCounter++;
+ }
+
+ old_timestamp = *data;
+
+ /* Start by erasing any information in the channel buffer */
+ prvTraceClearChannelBuffer(noOfSlots);
+
+ prvTraceCopyToDataBuffer(data, noOfSlots); /* Will wrap around the data if necessary */
+
+ old_nextSlotToWrite = RecorderDataPtr->userEventBuffer.nextSlotToWrite; /* Save the index that we want to write the channel data at when we're done */
+ RecorderDataPtr->userEventBuffer.nextSlotToWrite = (RecorderDataPtr->userEventBuffer.nextSlotToWrite + noOfSlots) % (TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE); /* Make sure we never end up outside the buffer */
+
+ /* Write to the channel buffer to indicate that this user event is ready to be used */
+ if (channel != 0)
+ {
+ RecorderDataPtr->userEventBuffer.channelBuffer[old_nextSlotToWrite] = channel;
+ }
+ else
+ {
+ /* 0xFF indicates that this is not a normal channel id */
+ RecorderDataPtr->userEventBuffer.channelBuffer[old_nextSlotToWrite] = (traceUBChannel)0xFF;
+ }
+ trcCRITICAL_SECTION_END();
+}
+#endif
+
+/*******************************************************************************
+ * xTraceRegisterUBChannel
+ *
+ * Registers a channel for Separated User Events, i.e., those stored in the
+ * separate user event buffer.
+ *
+ * Note: Only available if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is enabled in
+ * trcSnapshotConfig.h
+ ******************************************************************************/
+#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1))
+traceUBChannel xTraceRegisterUBChannel(traceString channel, traceString formatStr)
+{
+ uint8_t i;
+ traceUBChannel retVal = 0;
+
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ TRACE_ASSERT(formatStr != 0, "xTraceRegisterChannelFormat: formatStr == 0", (traceUBChannel)0);
+
+ trcCRITICAL_SECTION_BEGIN();
+ for (i = 1; i <= (TRC_CFG_UB_CHANNELS); i++) /* Size of the channels buffer is TRC_CFG_UB_CHANNELS + 1. Index 0 is unused. */
+ {
+ if(RecorderDataPtr->userEventBuffer.channels[i].name == 0 && RecorderDataPtr->userEventBuffer.channels[i].defaultFormat == 0)
+ {
+ /* Found empty slot */
+ RecorderDataPtr->userEventBuffer.channels[i].name = channel;
+ RecorderDataPtr->userEventBuffer.channels[i].defaultFormat = formatStr;
+ retVal = (traceUBChannel)i;
+ break;
+ }
+
+ if (RecorderDataPtr->userEventBuffer.channels[i].name == channel && RecorderDataPtr->userEventBuffer.channels[i].defaultFormat == formatStr)
+ {
+ /* Found a match */
+ retVal = (traceUBChannel)i;
+ break;
+ }
+ }
+ trcCRITICAL_SECTION_END();
+
+ return retVal;
+}
+#endif
+
+/******************************************************************************
+ * vTraceUBData
+ *
+ * Slightly faster version of vTracePrintF() due to no lookups.
+ *
+ * Note: This is only available if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is
+ * enabled in trcSnapshotConfig.h
+ ******************************************************************************/
+#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1))
+void vTraceUBData(traceUBChannel channelPair, ...)
+{
+ va_list vl;
+
+ TRACE_ASSERT(channelPair != 0, "vTraceUBData: Not a valid traceUBChannel!", TRC_UNUSED);
+
+ va_start(vl, channelPair);
+ vTraceUBData_Helper(channelPair, vl);
+ va_end(vl);
+}
+#endif
+
+/* Extracts the channel name and format string from the traceUBChannel, then calls prvTraceUBHelper1. */
+#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1))
+void vTraceUBData_Helper(traceUBChannel channelPair, va_list vl)
+{
+ traceString channel;
+ traceString formatStr;
+
+ TRACE_ASSERT(channelPair != 0, "vTraceUBData_Helper: channelPair == 0", TRC_UNUSED);
+ TRACE_ASSERT(channelPair <= (TRC_CFG_UB_CHANNELS), "vTraceUBData_Helper: ", TRC_UNUSED);
+
+ channel = RecorderDataPtr->userEventBuffer.channels[channelPair].name;
+ formatStr = RecorderDataPtr->userEventBuffer.channels[channelPair].defaultFormat;
+
+ prvTraceUBHelper1(channelPair, channel, formatStr, vl);
+}
+#endif
+
+/******************************************************************************
+ * vTraceUBEvent
+ *
+ * Slightly faster version of ... due to no lookups.
+ ******************************************************************************/
+#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1))
+void vTraceUBEvent(traceUBChannel channelPair)
+{
+ uint32_t data[(3 + MAX_ARG_SIZE) / 4];
+
+ TRACE_ASSERT(channelPair != 0, "vTraceUBEvent: channelPair == 0", TRC_UNUSED);
+ TRACE_ASSERT(channelPair <= (TRC_CFG_UB_CHANNELS), "vTraceUBEvent: ", TRC_UNUSED);
+
+ prvTraceUBHelper2(channelPair, data, 1); /* Only need one slot for timestamp */
+}
+#endif
+
+/******************************************************************************
+ * vTracePrintF
+ *
+ * Generates User Event with formatted text and data, similar to a "printf".
+ * It is very fast compared to a normal "printf" since this function only
+ * stores the arguments. The actual formatting is done
+ * on the host PC when the trace is displayed in the viewer tool.
+ *
+ * User Event labels are created using xTraceRegisterString.
+ * Example:
+ *
+ * traceString adc_uechannel = xTraceRegisterString("ADC User Events");
+ * ...
+ * vTracePrintF(adc_uechannel,
+ * "ADC channel %d: %lf volts",
+ * ch, (double)adc_reading/(double)scale);
+ *
+ * This can be combined into one line, if desired, but this is slower:
+ *
+ * vTracePrintF(xTraceRegisterString("ADC User Events"),
+ * "ADC channel %d: %lf volts",
+ * ch, (double)adc_reading/(double)scale);
+ *
+ * Calling xTraceRegisterString multiple times will not create duplicate entries, but
+ * it is of course faster to just do it once, and then keep the handle for later
+ * use. If you don't have any data arguments, only a text label/string, it is
+ * better to use vTracePrint - it is faster.
+ *
+ * Format specifiers supported:
+ * %d - 32 bit signed integer
+ * %u - 32 bit unsigned integer
+ * %f - 32 bit float
+ * %s - string (is copied to the recorder symbol table)
+ * %hd - 16 bit signed integer
+ * %hu - 16 bit unsigned integer
+ * %bd - 8 bit signed integer
+ * %bu - 8 bit unsigned integer
+ * %lf - double-precision float (Note! See below...)
+ *
+ * Up to 15 data arguments are allowed, with a total size of maximum 32 byte.
+ * In case this is exceeded, the user event is changed into an error message.
+ *
+ * The data is stored in trace buffer, and is packed to allow storing multiple
+ * smaller data entries in the same 4-byte record, e.g., four 8-bit values.
+ * A string requires two bytes, as the symbol table is limited to 64K. Storing
+ * a double (%lf) uses two records, so this is quite costly. Use float (%f)
+ * unless the higher precision is really necessary.
+ *
+ * Note that the double-precision float (%lf) assumes a 64 bit double
+ * representation. This does not seem to be the case on e.g. PIC24 and PIC32.
+ * Before using a %lf argument on a 16-bit MCU, please verify that
+ * "sizeof(double)" actually gives 8 as expected. If not, use %f instead.
+ ******************************************************************************/
+#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1))
+void vTracePrintF(traceString eventLabel, const char* formatStr, ...)
+{
+ va_list vl;
+
+ va_start(vl, formatStr);
+ vTraceVPrintF(eventLabel, formatStr, vl);
+ va_end(vl);
+}
+#endif
+
+/******************************************************************************
+ * vTraceVPrintF
+ *
+ * vTracePrintF variant that accepts a va_list.
+ * See vTracePrintF documentation for further details.
+ *
+ ******************************************************************************/
+#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1))
+void vTraceVPrintF(traceString eventLabel, const char* formatStr, va_list vl)
+{
+#if (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 0)
+ uint32_t noOfSlots;
+ UserEvent* ue1;
+ uint32_t tempDataBuffer[(3 + MAX_ARG_SIZE) / 4];
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ TRACE_ASSERT(formatStr != NULL, "vTraceVPrintF: formatStr == NULL", TRC_UNUSED);
+
+ trcCRITICAL_SECTION_BEGIN();
+
+ if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)
+ {
+ /* First, write the "primary" user event entry in the local buffer, but
+ let the event type be "EVENT_BEING_WRITTEN" for now...*/
+
+ ue1 = (UserEvent*)(&tempDataBuffer[0]);
+
+ ue1->type = EVENT_BEING_WRITTEN; /* Update this as the last step */
+
+ noOfSlots = prvTraceUserEventFormat(formatStr, vl, (uint8_t*)tempDataBuffer, 4);
+
+ /* Store the format string, with a reference to the channel symbol */
+ ue1->payload = prvTraceOpenSymbol(formatStr, eventLabel);
+
+ ue1->dts = (uint8_t)prvTraceGetDTS(0xFF);
+
+ /* prvTraceGetDTS might stop the recorder in some cases... */
+ if (RecorderDataPtr->recorderActive)
+ {
+
+ /* If the data does not fit in the remaining main buffer, wrap around to
+ 0 if allowed, otherwise stop the recorder and quit). */
+ if (RecorderDataPtr->nextFreeIndex + noOfSlots > RecorderDataPtr->maxEvents)
+ {
+ #if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER)
+ (void)memset(& RecorderDataPtr->eventData[RecorderDataPtr->nextFreeIndex * 4],
+ 0,
+ (RecorderDataPtr->maxEvents - RecorderDataPtr->nextFreeIndex)*4);
+ RecorderDataPtr->nextFreeIndex = 0;
+ RecorderDataPtr->bufferIsFull = 1;
+ #else
+
+ /* Stop recorder, since the event data will not fit in the
+ buffer and not circular buffer in this case... */
+ vTraceStop();
+ #endif
+ }
+
+ /* Check if recorder has been stopped (i.e., vTraceStop above) */
+ if (RecorderDataPtr->recorderActive)
+ {
+ /* Check that the buffer to be overwritten does not contain any user
+ events that would be partially overwritten. If so, they must be "killed"
+ by replacing the user event and following data with NULL events (i.e.,
+ using a memset to zero).*/
+ #if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER)
+ prvCheckDataToBeOverwrittenForMultiEntryEvents((uint8_t)noOfSlots);
+ #endif
+ /* Copy the local buffer to the main buffer */
+ (void)memcpy(& RecorderDataPtr->eventData[RecorderDataPtr->nextFreeIndex * 4],
+ tempDataBuffer,
+ noOfSlots * 4);
+
+ /* Update the event type, i.e., number of data entries following the
+ main USER_EVENT entry (Note: important that this is after the memcpy,
+ but within the critical section!)*/
+ RecorderDataPtr->eventData[RecorderDataPtr->nextFreeIndex * 4] =
+ (uint8_t) ( USER_EVENT + noOfSlots - 1 );
+
+ /* Update the main buffer event index (already checked that it fits in
+ the buffer, so no need to check for wrapping)*/
+
+ RecorderDataPtr->nextFreeIndex += noOfSlots;
+ RecorderDataPtr->numEvents += noOfSlots;
+
+ if (RecorderDataPtr->nextFreeIndex >= (TRC_CFG_EVENT_BUFFER_SIZE))
+ {
+ #if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER)
+ /* We have reached the end, but this is a ring buffer. Start from the beginning again. */
+ RecorderDataPtr->bufferIsFull = 1;
+ RecorderDataPtr->nextFreeIndex = 0;
+ #else
+ /* We have reached the end so we stop. */
+ vTraceStop();
+ #endif
+ }
+ }
+
+ #if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER)
+ /* Make sure the next entry is cleared correctly */
+ prvCheckDataToBeOverwrittenForMultiEntryEvents(1);
+ #endif
+
+ }
+ }
+ trcCRITICAL_SECTION_END();
+
+#elif (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)
+ /* Use the separate user event buffer */
+ traceString formatLabel;
+ traceUBChannel channel;
+
+ if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)
+ {
+ formatLabel = xTraceRegisterString(formatStr);
+
+ channel = xTraceRegisterUBChannel(eventLabel, formatLabel);
+
+ prvTraceUBHelper1(channel, eventLabel, formatLabel, vl);
+ }
+#endif
+}
+#endif
+
+/******************************************************************************
+ * vTracePrint
+ *
+ * Basic user event
+ *
+ * Generates a User Event with a text label. The label is created/looked up
+ * in the symbol table using xTraceRegisterString.
+ ******************************************************************************/
+#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1))
+void vTracePrint(traceString chn, const char* str)
+{
+#if (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 0)
+ UserEvent* ue;
+ uint8_t dts1;
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ trcCRITICAL_SECTION_BEGIN();
+ if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)
+ {
+ dts1 = (uint8_t)prvTraceGetDTS(0xFF);
+ ue = (UserEvent*) prvTraceNextFreeEventBufferSlot();
+ if (ue != NULL)
+ {
+ ue->dts = dts1;
+ ue->type = USER_EVENT;
+ ue->payload = prvTraceOpenSymbol(str, chn);
+ prvTraceUpdateCounters();
+ }
+ }
+ trcCRITICAL_SECTION_END();
+
+#elif (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)
+ traceUBChannel channel;
+ uint32_t noOfSlots = 1;
+ uint32_t tempDataBuffer[(3 + MAX_ARG_SIZE) / 4];
+ if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)
+ {
+ traceString trcStr = prvTraceOpenSymbol(str, chn);
+ channel = xTraceRegisterUBChannel(chn, trcStr);
+
+ if (channel == 0)
+ {
+ /* We are dealing with an unknown channel format pair */
+ noOfSlots++; /* Also need room for channel and format */
+ ((uint16_t*)tempDataBuffer)[2] = chn;
+ ((uint16_t*)tempDataBuffer)[3] = trcStr;
+ }
+
+ prvTraceUBHelper2(channel, tempDataBuffer, noOfSlots);
+ }
+#endif
+}
+#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* label)
+{
+ TRACE_ASSERT(label != NULL, "xTraceRegisterString: label == NULL", (traceString)0);
+ TRACE_ASSERT(RecorderDataPtr != NULL, "Recorder not initialized, call vTraceEnable() first!", (traceHandle)0);
+ return prvTraceOpenSymbol(label, 0);
+}
+#endif
+
+
+#if ((!defined TRC_CFG_INCLUDE_READY_EVENTS) || (TRC_CFG_INCLUDE_READY_EVENTS == 1))
+
+void prvTraceSetReadyEventsEnabled(int status)
+{
+ readyEventsEnabled = status;
+}
+
+/*******************************************************************************
+ * prvTraceStoreTaskReady
+ *
+ * This function stores a ready state for the task handle sent in as parameter.
+ ******************************************************************************/
+void prvTraceStoreTaskReady(traceHandle handle)
+{
+ uint16_t dts3;
+ TREvent* tr;
+ uint8_t hnd8;
+
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ if (handle == 0)
+ {
+ /* On FreeRTOS v7.3.0, this occurs when creating tasks due to a bad
+ placement of the trace macro. In that case, the events are ignored. */
+ return;
+ }
+
+ if (! readyEventsEnabled)
+ {
+ /* When creating tasks, ready events are also created. If creating
+ a "hidden" (not traced) task, we must therefore disable recording
+ of ready events to avoid an undesired ready event... */
+ return;
+ }
+
+ TRACE_ASSERT(handle <= (TRC_CFG_NTASK), "prvTraceStoreTaskReady: Invalid value for handle", TRC_UNUSED);
+
+ if (recorder_busy)
+ {
+ /*************************************************************************
+ * This occurs if an ISR calls a trace function, preempting a previous
+ * trace call that is being processed in a different ISR or task.
+ * If this occurs, there is probably a problem in the definition of the
+ * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and
+ * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt
+ * and any other ISRs that calls the trace recorder directly or via
+ * traced kernel functions. The ARM port disables all interrupts using the
+ * PRIMASK register to avoid this issue.
+ *************************************************************************/
+ prvTraceError("Recorder busy - high priority ISR using syscall? (1)");
+ return;
+ }
+
+ trcCRITICAL_SECTION_BEGIN();
+ if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */
+ {
+ dts3 = (uint16_t)prvTraceGetDTS(0xFFFF);
+ hnd8 = prvTraceGet8BitHandle(handle);
+ tr = (TREvent*)prvTraceNextFreeEventBufferSlot();
+ if (tr != NULL)
+ {
+ tr->type = DIV_TASK_READY;
+ tr->dts = dts3;
+ tr->objHandle = hnd8;
+ prvTraceUpdateCounters();
+ }
+ }
+ trcCRITICAL_SECTION_END();
+}
+#endif
+
+/*******************************************************************************
+ * prvTraceStoreLowPower
+ *
+ * This function stores a low power state.
+ ******************************************************************************/
+void prvTraceStoreLowPower(uint32_t flag)
+{
+ uint16_t dts;
+ LPEvent* lp;
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ TRACE_ASSERT(flag <= 1, "prvTraceStoreLowPower: Invalid flag value", TRC_UNUSED);
+
+ if (recorder_busy)
+ {
+ /*************************************************************************
+ * This occurs if an ISR calls a trace function, preempting a previous
+ * trace call that is being processed in a different ISR or task.
+ * If this occurs, there is probably a problem in the definition of the
+ * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and
+ * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt
+ * and any other ISRs that calls the trace recorder directly or via
+ * traced kernel functions. The ARM port disables all interrupts using the
+ * PRIMASK register to avoid this issue.
+ *************************************************************************/
+ prvTraceError("Recorder busy - high priority ISR using syscall? (1)");
+ return;
+ }
+
+ trcCRITICAL_SECTION_BEGIN();
+ if (RecorderDataPtr->recorderActive)
+ {
+ dts = (uint16_t)prvTraceGetDTS(0xFFFF);
+ lp = (LPEvent*)prvTraceNextFreeEventBufferSlot();
+ if (lp != NULL)
+ {
+ lp->type = (uint8_t) (LOW_POWER_BEGIN + ( uint8_t ) flag); /* BEGIN or END depending on flag */
+ lp->dts = dts;
+ prvTraceUpdateCounters();
+ }
+ }
+ trcCRITICAL_SECTION_END();
+}
+
+/*******************************************************************************
+ * vTraceStoreMemMangEvent
+ *
+ * This function stores malloc and free events. Each call requires two records,
+ * for size and address respectively. The event code parameter (ecode) is applied
+ * to the first record (size) and the following address record gets event
+ * code "ecode + 1", so make sure this is respected in the event code table.
+ * Note: On "free" calls, the signed_size parameter should be negative.
+ ******************************************************************************/
+#if (TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1)
+#if (TRC_CFG_SCHEDULING_ONLY == 0)
+void vTraceStoreMemMangEvent(uint32_t ecode, uint32_t address, int32_t signed_size)
+{
+ uint8_t dts1;
+ MemEventSize * ms;
+ MemEventAddr * ma;
+ uint16_t size_low;
+ uint16_t addr_low;
+ uint8_t addr_high;
+ uint32_t size;
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ if (RecorderDataPtr == NULL)
+ {
+ /* Occurs in vTraceInitTraceData, if using dynamic allocation. */
+ return;
+ }
+
+ if (signed_size < 0)
+ size = (uint32_t)(- signed_size);
+ else
+ size = (uint32_t)(signed_size);
+
+ trcCRITICAL_SECTION_BEGIN();
+
+ /* Only update heapMemUsage if we have a valid address */
+ if (address != 0)
+ heapMemUsage += (uint32_t)signed_size;
+
+ if (RecorderDataPtr->recorderActive)
+ {
+ dts1 = (uint8_t)prvTraceGetDTS(0xFF);
+ size_low = (uint16_t)prvTraceGetParam(0xFFFF, size);
+ ms = (MemEventSize *)prvTraceNextFreeEventBufferSlot();
+
+ if (ms != NULL)
+ {
+ ms->dts = dts1;
+ ms->type = NULL_EVENT; /* Updated when all events are written */
+ ms->size = size_low;
+ prvTraceUpdateCounters();
+
+ /* Storing a second record with address (signals "failed" if null) */
+ #if (TRC_CFG_HEAP_SIZE_BELOW_16M)
+ /* If the heap address range is within 16 MB, i.e., the upper 8 bits
+ of addresses are constant, this optimization avoids storing an extra
+ event record by ignoring the upper 8 bit of the address */
+ addr_low = address & 0xFFFF;
+ addr_high = (address >> 16) & 0xFF;
+ #else
+ /* The whole 32 bit address is stored using a second event record
+ for the upper 16 bit */
+ addr_low = (uint16_t)prvTraceGetParam(0xFFFF, address);
+ addr_high = 0;
+ #endif
+
+ ma = (MemEventAddr *) prvTraceNextFreeEventBufferSlot();
+ if (ma != NULL)
+ {
+ ma->addr_low = addr_low;
+ ma->addr_high = addr_high;
+ ma->type = (uint8_t) (ecode + 1); /* Note this! */
+ ms->type = (uint8_t) ecode;
+ prvTraceUpdateCounters();
+ RecorderDataPtr->heapMemUsage = heapMemUsage;
+ }
+ }
+ }
+ trcCRITICAL_SECTION_END();
+}
+#endif /* TRC_CFG_SCHEDULING_ONLY */
+#endif
+
+/*******************************************************************************
+ * prvTraceStoreKernelCall
+ *
+ * This is the main integration point for storing kernel calls, and
+ * is called by the hooks in trcKernelHooks.h (see trcKernelPort.h for event codes).
+ ******************************************************************************/
+#if (TRC_CFG_SCHEDULING_ONLY == 0)
+void prvTraceStoreKernelCall(uint32_t ecode, traceObjectClass objectClass, uint32_t objectNumber)
+{
+ KernelCall * kse;
+ uint16_t dts1;
+ uint8_t hnd8;
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ TRACE_ASSERT(ecode < 0xFF, "prvTraceStoreKernelCall: ecode >= 0xFF", TRC_UNUSED);
+ TRACE_ASSERT(objectClass < TRACE_NCLASSES, "prvTraceStoreKernelCall: objectClass >= TRACE_NCLASSES", TRC_UNUSED);
+ TRACE_ASSERT(objectNumber <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectClass], "prvTraceStoreKernelCall: Invalid value for objectNumber", TRC_UNUSED);
+
+ if (recorder_busy)
+ {
+ /*************************************************************************
+ * This occurs if an ISR calls a trace function, preempting a previous
+ * trace call that is being processed in a different ISR or task.
+ * If this occurs, there is probably a problem in the definition of the
+ * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and
+ * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt
+ * and any other ISRs that calls the trace recorder directly or via
+ * traced kernel functions. The ARM port disables all interrupts using the
+ * PRIMASK register to avoid this issue.
+ *************************************************************************/
+ prvTraceError("Recorder busy - high priority ISR using syscall? (2)");
+ return;
+ }
+
+ if (handle_of_last_logged_task == 0)
+ {
+ return;
+ }
+
+ trcCRITICAL_SECTION_BEGIN();
+ if (RecorderDataPtr->recorderActive)
+ {
+ dts1 = (uint16_t)prvTraceGetDTS(0xFFFF);
+ hnd8 = prvTraceGet8BitHandle((traceHandle)objectNumber);
+ kse = (KernelCall*) prvTraceNextFreeEventBufferSlot();
+ if (kse != NULL)
+ {
+ kse->dts = dts1;
+ kse->type = (uint8_t)ecode;
+ kse->objHandle = hnd8;
+ prvTraceUpdateCounters();
+ }
+ }
+ trcCRITICAL_SECTION_END();
+}
+#endif /* TRC_CFG_SCHEDULING_ONLY */
+
+/*******************************************************************************
+ * prvTraceStoreKernelCallWithParam
+ *
+ * Used for storing kernel calls with a handle and a numeric parameter. If the
+ * numeric parameter does not fit in one byte, and extra XPS event is inserted
+ * before the kernel call event containing the three upper bytes.
+ ******************************************************************************/
+#if (TRC_CFG_SCHEDULING_ONLY == 0)
+void prvTraceStoreKernelCallWithParam(uint32_t evtcode,
+ traceObjectClass objectClass,
+ uint32_t objectNumber,
+ uint32_t param)
+{
+ KernelCallWithParamAndHandle * kse;
+ uint8_t dts2;
+ uint8_t hnd8;
+ uint8_t p8;
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ TRACE_ASSERT(evtcode < 0xFF, "prvTraceStoreKernelCallWithParam: evtcode >= 0xFF", TRC_UNUSED);
+ TRACE_ASSERT(objectClass < TRACE_NCLASSES, "prvTraceStoreKernelCallWithParam: objectClass >= TRACE_NCLASSES", TRC_UNUSED);
+ TRACE_ASSERT(objectNumber <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectClass], "prvTraceStoreKernelCallWithParam: Invalid value for objectNumber", TRC_UNUSED);
+
+ if (recorder_busy)
+ {
+ /*************************************************************************
+ * This occurs if an ISR calls a trace function, preempting a previous
+ * trace call that is being processed in a different ISR or task.
+ * If this occurs, there is probably a problem in the definition of the
+ * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and
+ * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt
+ * and any other ISRs that calls the trace recorder directly or via
+ * traced kernel functions. The ARM port disables all interrupts using the
+ * PRIMASK register to avoid this issue.
+ *************************************************************************/
+ prvTraceError("Recorder busy - high priority ISR using syscall? (3)");
+ return;
+ }
+
+ trcCRITICAL_SECTION_BEGIN();
+ if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)
+ {
+ dts2 = (uint8_t)prvTraceGetDTS(0xFF);
+ p8 = (uint8_t) prvTraceGetParam(0xFF, param);
+ hnd8 = prvTraceGet8BitHandle((traceHandle)objectNumber);
+ kse = (KernelCallWithParamAndHandle*) prvTraceNextFreeEventBufferSlot();
+ if (kse != NULL)
+ {
+ kse->dts = dts2;
+ kse->type = (uint8_t)evtcode;
+ kse->objHandle = hnd8;
+ kse->param = p8;
+ prvTraceUpdateCounters();
+ }
+ }
+ trcCRITICAL_SECTION_END();
+}
+#endif /* TRC_CFG_SCHEDULING_ONLY */
+
+
+/*******************************************************************************
+ * prvTraceGetParam
+ *
+ * Used for storing extra bytes for kernel calls with numeric parameters.
+ *
+ * May only be called within a critical section!
+ ******************************************************************************/
+#if (TRC_CFG_SCHEDULING_ONLY == 0)
+static uint32_t prvTraceGetParam(uint32_t param_max, uint32_t param)
+{
+ XPSEvent* xps;
+
+ TRACE_ASSERT(param_max == 0xFF || param_max == 0xFFFF,
+ "prvTraceGetParam: Invalid value for param_max", param);
+
+ if (param <= param_max)
+ {
+ return param;
+ }
+ else
+ {
+ xps = (XPSEvent*) prvTraceNextFreeEventBufferSlot();
+ if (xps != NULL)
+ {
+ xps->type = DIV_XPS;
+ xps->xps_8 = (uint8_t)((param & (0xFF00 & ~param_max)) >> 8);
+ xps->xps_16 = (uint16_t)((param & (0xFFFF0000 & ~param_max)) >> 16);
+ prvTraceUpdateCounters();
+ }
+
+ return param & param_max;
+ }
+}
+#endif
+
+/*******************************************************************************
+ * prvTraceStoreKernelCallWithNumericParamOnly
+ *
+ * Used for storing kernel calls with numeric parameters only. This is
+ * only used for traceTASK_DELAY and traceDELAY_UNTIL at the moment.
+ ******************************************************************************/
+#if (TRC_CFG_SCHEDULING_ONLY == 0)
+void prvTraceStoreKernelCallWithNumericParamOnly(uint32_t evtcode, uint32_t param)
+{
+ KernelCallWithParam16 * kse;
+ uint8_t dts6;
+ uint16_t restParam;
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ restParam = 0;
+
+ TRACE_ASSERT(evtcode < 0xFF, "prvTraceStoreKernelCallWithNumericParamOnly: Invalid value for evtcode", TRC_UNUSED);
+
+ if (recorder_busy)
+ {
+ /*************************************************************************
+ * This occurs if an ISR calls a trace function, preempting a previous
+ * trace call that is being processed in a different ISR or task.
+ * If this occurs, there is probably a problem in the definition of the
+ * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and
+ * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt
+ * and any other ISRs that calls the trace recorder directly or via
+ * traced kernel functions. The ARM port disables all interrupts using the
+ * PRIMASK register to avoid this issue.
+ *************************************************************************/
+ prvTraceError("Recorder busy - high priority ISR using syscall? (4)");
+ return;
+ }
+
+ trcCRITICAL_SECTION_BEGIN();
+ if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)
+ {
+ dts6 = (uint8_t)prvTraceGetDTS(0xFF);
+ restParam = (uint16_t)prvTraceGetParam(0xFFFF, param);
+ kse = (KernelCallWithParam16*) prvTraceNextFreeEventBufferSlot();
+ if (kse != NULL)
+ {
+ kse->dts = dts6;
+ kse->type = (uint8_t)evtcode;
+ kse->param = restParam;
+ prvTraceUpdateCounters();
+ }
+ }
+ trcCRITICAL_SECTION_END();
+}
+#endif /* TRC_CFG_SCHEDULING_ONLY */
+
+/*******************************************************************************
+ * prvTraceStoreTaskswitch
+ * Called by the scheduler from the SWITCHED_OUT hook, and by uiTraceStart.
+ * At this point interrupts are assumed to be disabled!
+ ******************************************************************************/
+void prvTraceStoreTaskswitch(traceHandle task_handle)
+{
+ uint16_t dts3;
+ TSEvent* ts;
+ uint8_t hnd8;
+#if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
+ extern int32_t isPendingContextSwitch;
+#endif
+ trcSR_ALLOC_CRITICAL_SECTION_ON_CORTEX_M_ONLY();
+
+ TRACE_ASSERT(task_handle <= (TRC_CFG_NTASK),
+ "prvTraceStoreTaskswitch: Invalid value for task_handle", TRC_UNUSED);
+
+ trcCRITICAL_SECTION_BEGIN_ON_CORTEX_M_ONLY();
+
+ if ((task_handle != handle_of_last_logged_task) && (RecorderDataPtr->recorderActive))
+ {
+#if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
+ isPendingContextSwitch = 0;
+#endif
+
+ dts3 = (uint16_t)prvTraceGetDTS(0xFFFF);
+ handle_of_last_logged_task = task_handle;
+ hnd8 = prvTraceGet8BitHandle(handle_of_last_logged_task);
+ ts = (TSEvent*)prvTraceNextFreeEventBufferSlot();
+
+ if (ts != NULL)
+ {
+ if (prvTraceGetObjectState(TRACE_CLASS_TASK,
+ handle_of_last_logged_task) == TASK_STATE_INSTANCE_ACTIVE)
+ {
+ ts->type = TS_TASK_RESUME;
+ }
+ else
+ {
+ ts->type = TS_TASK_BEGIN;
+ }
+
+ ts->dts = dts3;
+ ts->objHandle = hnd8;
+
+ prvTraceSetObjectState(TRACE_CLASS_TASK,
+ handle_of_last_logged_task,
+ TASK_STATE_INSTANCE_ACTIVE);
+
+ prvTraceUpdateCounters();
+ }
+ }
+
+ trcCRITICAL_SECTION_END_ON_CORTEX_M_ONLY();
+}
+
+/*******************************************************************************
+ * prvTraceStoreObjectNameOnCloseEvent
+ *
+ * Updates the symbol table with the name of this object from the dynamic
+ * objects table and stores a "close" event, holding the mapping between handle
+ * and name (a symbol table handle). The stored name-handle mapping is thus the
+ * "old" one, valid up until this point.
+ ******************************************************************************/
+void prvTraceStoreObjectNameOnCloseEvent(uint8_t evtcode, traceHandle handle,
+ traceObjectClass objectclass)
+{
+ ObjCloseNameEvent * ce;
+ const char * name;
+ traceString idx;
+
+ TRACE_ASSERT(objectclass < TRACE_NCLASSES,
+ "prvTraceStoreObjectNameOnCloseEvent: objectclass >= TRACE_NCLASSES", TRC_UNUSED);
+ TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
+ "prvTraceStoreObjectNameOnCloseEvent: Invalid value for handle", TRC_UNUSED);
+
+ if (RecorderDataPtr->recorderActive)
+ {
+ uint8_t hnd8 = prvTraceGet8BitHandle(handle);
+ name = TRACE_PROPERTY_NAME_GET(objectclass, handle);
+ idx = prvTraceOpenSymbol(name, 0);
+
+ // Interrupt disable not necessary, already done in trcHooks.h macro
+ ce = (ObjCloseNameEvent*) prvTraceNextFreeEventBufferSlot();
+ if (ce != NULL)
+ {
+ ce->type = (uint8_t) evtcode;
+ ce->objHandle = hnd8;
+ ce->symbolIndex = idx;
+ prvTraceUpdateCounters();
+ }
+ }
+}
+
+void prvTraceStoreObjectPropertiesOnCloseEvent(uint8_t evtcode, traceHandle handle,
+ traceObjectClass objectclass)
+{
+ ObjClosePropEvent * pe;
+
+ TRACE_ASSERT(objectclass < TRACE_NCLASSES,
+ "prvTraceStoreObjectPropertiesOnCloseEvent: objectclass >= TRACE_NCLASSES", TRC_UNUSED);
+ TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
+ "prvTraceStoreObjectPropertiesOnCloseEvent: Invalid value for handle", TRC_UNUSED);
+
+ if (RecorderDataPtr->recorderActive)
+ {
+ // Interrupt disable not necessary, already done in trcHooks.h macro
+ pe = (ObjClosePropEvent*) prvTraceNextFreeEventBufferSlot();
+ if (pe != NULL)
+ {
+ if (objectclass == TRACE_CLASS_TASK)
+ {
+ pe->arg1 = TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, handle);
+ }
+ else
+ {
+ pe->arg1 = TRACE_PROPERTY_OBJECT_STATE(objectclass, handle);
+ }
+ pe->type = evtcode;
+ prvTraceUpdateCounters();
+ }
+ }
+}
+
+void prvTraceSetPriorityProperty(uint8_t objectclass, traceHandle id, uint8_t value)
+{
+ TRACE_ASSERT(objectclass < TRACE_NCLASSES,
+ "prvTraceSetPriorityProperty: objectclass >= TRACE_NCLASSES", TRC_UNUSED);
+ TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
+ "prvTraceSetPriorityProperty: Invalid value for id", TRC_UNUSED);
+
+ TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, id) = value;
+}
+
+uint8_t prvTraceGetPriorityProperty(uint8_t objectclass, traceHandle id)
+{
+ TRACE_ASSERT(objectclass < TRACE_NCLASSES,
+ "prvTraceGetPriorityProperty: objectclass >= TRACE_NCLASSES", 0);
+ TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
+ "prvTraceGetPriorityProperty: Invalid value for id", 0);
+
+ return TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, id);
+}
+
+void prvTraceSetObjectState(uint8_t objectclass, traceHandle id, uint8_t value)
+{
+ TRACE_ASSERT(objectclass < TRACE_NCLASSES,
+ "prvTraceSetObjectState: objectclass >= TRACE_NCLASSES", TRC_UNUSED);
+ TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
+ "prvTraceSetObjectState: Invalid value for id", TRC_UNUSED);
+
+ TRACE_PROPERTY_OBJECT_STATE(objectclass, id) = value;
+}
+
+uint8_t prvTraceGetObjectState(uint8_t objectclass, traceHandle id)
+{
+ TRACE_ASSERT(objectclass < TRACE_NCLASSES,
+ "prvTraceGetObjectState: objectclass >= TRACE_NCLASSES", 0);
+ TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
+ "prvTraceGetObjectState: Invalid value for id", 0);
+
+ return TRACE_PROPERTY_OBJECT_STATE(objectclass, id);
+}
+
+void prvTraceSetTaskInstanceFinished(traceHandle handle)
+{
+ TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[TRACE_CLASS_TASK],
+ "prvTraceSetTaskInstanceFinished: Invalid value for handle", TRC_UNUSED);
+
+#if (TRC_CFG_USE_IMPLICIT_IFE_RULES == 1)
+ TRACE_PROPERTY_OBJECT_STATE(TRACE_CLASS_TASK, handle) = 0;
+#endif
+}
+
+/*******************************************************************************
+ * Static data initializations
+ ******************************************************************************/
+
+/* A set of stacks that keeps track of available object handles for each class.
+The stacks are empty initially, meaning that allocation of new handles will be
+based on a counter (for each object class). Any delete operation will
+return the handle to the corresponding stack, for reuse on the next allocate.*/
+objectHandleStackType objectHandleStacks = { { 0 }, { 0 }, { 0 }, { 0 }, { 0 } };
+
+/* Initial TRC_HWTC_COUNT value, for detecting if the time-stamping source is
+enabled. If using the OS periodic timer for time-stamping, this might not
+have been configured on the earliest events during the startup. */
+uint32_t init_hwtc_count;
+
+/*******************************************************************************
+ * RecorderData
+ *
+ * The main data structure in snapshot mode, when using the default static memory
+ * allocation (TRC_RECORDER_BUFFER_ALLOCATION_STATIC). The recorder uses a pointer
+ * RecorderDataPtr to access the data, to also allow for dynamic or custom data
+ * allocation (see TRC_CFG_RECORDER_BUFFER_ALLOCATION).
+ ******************************************************************************/
+#if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_STATIC)
+RecorderDataType RecorderData;
+#endif
+
+/*******************************************************************************
+ * RecorderDataPtr
+ *
+ * Pointer to the main data structure, when in snapshot mode.
+ ******************************************************************************/
+RecorderDataType* RecorderDataPtr = NULL;
+
+/* This version of the function dynamically allocates the trace data */
+void prvTraceInitTraceData()
+{
+
+ if (RecorderDataPtr == NULL)
+ {
+#if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_STATIC)
+ RecorderDataPtr = &RecorderData;
+#elif (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC)
+ RecorderDataPtr = (RecorderDataType*)TRACE_MALLOC(sizeof(RecorderDataType));
+ if (! RecorderDataPtr)
+ {
+ prvTraceError("Failed allocating recorder buffer!");
+ return;
+ }
+#elif (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM)
+ if (! RecorderDataPtr)
+ {
+ prvTraceError("Recorder data pointer not set! Use vTraceSetRecorderDataBuffer().");
+ return;
+ }
+#endif
+ }
+ else
+ {
+ if (RecorderDataPtr->startmarker0 == 1)
+ {
+ /* Already initialized */
+ return;
+ }
+ }
+
+ init_hwtc_count = TRC_HWTC_COUNT;
+
+ (void)memset(RecorderDataPtr, 0, sizeof(RecorderDataType));
+
+ RecorderDataPtr->version = TRACE_KERNEL_VERSION;
+ RecorderDataPtr->minor_version = TRACE_MINOR_VERSION;
+ RecorderDataPtr->irq_priority_order = TRC_IRQ_PRIORITY_ORDER;
+ RecorderDataPtr->filesize = sizeof(RecorderDataType);
+ RecorderDataPtr->maxEvents = (TRC_CFG_EVENT_BUFFER_SIZE);
+ RecorderDataPtr->debugMarker0 = (int32_t) 0xF0F0F0F0;
+ RecorderDataPtr->isUsing16bitHandles = TRC_CFG_USE_16BIT_OBJECT_HANDLES;
+ RecorderDataPtr->isrTailchainingThreshold = TRC_CFG_ISR_TAILCHAINING_THRESHOLD;
+
+ /* This function is kernel specific */
+ vTraceInitObjectPropertyTable();
+
+ RecorderDataPtr->debugMarker1 = (int32_t)0xF1F1F1F1;
+ RecorderDataPtr->SymbolTable.symTableSize = (TRC_CFG_SYMBOL_TABLE_SIZE);
+ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex = 1;
+#if (TRC_CFG_INCLUDE_FLOAT_SUPPORT == 1)
+ RecorderDataPtr->exampleFloatEncoding = 1.0f; /* otherwise already zero */
+#endif
+ RecorderDataPtr->debugMarker2 = (int32_t)0xF2F2F2F2;
+ prvStrncpy(RecorderDataPtr->systemInfo, "Trace Recorder Demo", 80);
+ RecorderDataPtr->debugMarker3 = (int32_t)0xF3F3F3F3;
+ RecorderDataPtr->endmarker0 = 0x0A;
+ RecorderDataPtr->endmarker1 = 0x0B;
+ RecorderDataPtr->endmarker2 = 0x0C;
+ RecorderDataPtr->endmarker3 = 0x0D;
+ RecorderDataPtr->endmarker4 = 0x71;
+ RecorderDataPtr->endmarker5 = 0x72;
+ RecorderDataPtr->endmarker6 = 0x73;
+ RecorderDataPtr->endmarker7 = 0x74;
+ RecorderDataPtr->endmarker8 = 0xF1;
+ RecorderDataPtr->endmarker9 = 0xF2;
+ RecorderDataPtr->endmarker10 = 0xF3;
+ RecorderDataPtr->endmarker11 = 0xF4;
+
+#if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER
+ RecorderDataPtr->userEventBuffer.bufferID = 1;
+ RecorderDataPtr->userEventBuffer.version = 0;
+ RecorderDataPtr->userEventBuffer.numberOfSlots = (TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE);
+ RecorderDataPtr->userEventBuffer.numberOfChannels = (TRC_CFG_UB_CHANNELS) + 1;
+#endif
+
+ /* Kernel specific initialization of the objectHandleStacks variable */
+ vTraceInitObjectHandleStack();
+
+
+ /* Finally, the 12-byte "start markers" are initialized, allowing for
+ Tracealyzer to find the trace data in a larger RAM dump.
+
+ The start and end markers must be unique, but without proper precautions there
+ might be a risk of accidental duplicates of the start/end markers, e.g., due to
+ compiler optimizations.
+
+ The below initialization of the start marker is therefore made in reverse order
+ and the fields are volatile to ensure this assignment order. This to avoid any
+ chance of accidental duplicates of this elsewhere in memory.
+
+ Moreover, the fields are set byte-by-byte to avoid endian issues.*/
+
+ RecorderDataPtr->startmarker11 = 0xF4;
+ RecorderDataPtr->startmarker10 = 0xF3;
+ RecorderDataPtr->startmarker9 = 0xF2;
+ RecorderDataPtr->startmarker8 = 0xF1;
+ RecorderDataPtr->startmarker7 = 0x74;
+ RecorderDataPtr->startmarker6 = 0x73;
+ RecorderDataPtr->startmarker5 = 0x72;
+ RecorderDataPtr->startmarker4 = 0x71;
+ RecorderDataPtr->startmarker3 = 0x04;
+ RecorderDataPtr->startmarker2 = 0x03;
+ RecorderDataPtr->startmarker1 = 0x02;
+ RecorderDataPtr->startmarker0 = 0x01;
+
+ if (traceErrorMessage != NULL)
+ {
+ // An error was detected before vTraceEnable was called, make sure this is stored in the trace data.
+ prvStrncpy(RecorderDataPtr->systemInfo, traceErrorMessage, 80);
+ RecorderDataPtr->internalErrorOccured = 1;
+ vTraceStop();
+ }
+
+
+
+#ifdef TRC_PORT_SPECIFIC_INIT
+ TRC_PORT_SPECIFIC_INIT();
+#endif
+}
+
+
+void* prvTraceNextFreeEventBufferSlot(void)
+{
+ if (! RecorderDataPtr->recorderActive)
+ {
+ /* If an XTS or XPS event prior to the main event has filled the buffer
+ before saving the main event, and store mode is "stop when full". */
+ return NULL;
+ }
+
+ if (RecorderDataPtr->nextFreeIndex >= (TRC_CFG_EVENT_BUFFER_SIZE))
+ {
+ prvTraceError("Attempt to index outside event buffer!");
+ return NULL;
+ }
+ return (void*)(&RecorderDataPtr->eventData[RecorderDataPtr->nextFreeIndex*4]);
+}
+
+uint16_t uiIndexOfObject(traceHandle objecthandle, uint8_t objectclass)
+{
+ TRACE_ASSERT(objectclass < TRACE_NCLASSES,
+ "uiIndexOfObject: Invalid value for objectclass", 0);
+ TRACE_ASSERT(objecthandle > 0 && objecthandle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
+ "uiIndexOfObject: Invalid value for objecthandle", 0);
+
+ if ((objectclass < TRACE_NCLASSES) && (objecthandle > 0) &&
+ (objecthandle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass]))
+ {
+ return (uint16_t)(RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[objectclass] +
+ (RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[objectclass] * (objecthandle-1)));
+ }
+
+ prvTraceError("Object table lookup with invalid object handle or object class!");
+ return 0;
+}
+
+traceHandle prvTraceGetObjectHandle(traceObjectClass objectclass)
+{
+ traceHandle handle;
+ static int indexOfHandle;
+
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ TRACE_ASSERT(RecorderDataPtr != NULL, "Recorder not initialized, call vTraceEnable() first!", (traceHandle)0);
+
+ TRACE_ASSERT(objectclass < TRACE_NCLASSES,
+ "prvTraceGetObjectHandle: Invalid value for objectclass", (traceHandle)0);
+
+ trcCRITICAL_SECTION_BEGIN();
+ indexOfHandle = objectHandleStacks.indexOfNextAvailableHandle[objectclass];
+ if (objectHandleStacks.objectHandles[indexOfHandle] == 0)
+ {
+ /* Zero is used to indicate a never before used handle, i.e.,
+ new slots in the handle stack. The handle slot needs to
+ be initialized here (starts at 1). */
+ objectHandleStacks.objectHandles[indexOfHandle] =
+ (traceHandle)(1 + indexOfHandle -
+ objectHandleStacks.lowestIndexOfClass[objectclass]);
+ }
+
+ handle = objectHandleStacks.objectHandles[indexOfHandle];
+
+ if (objectHandleStacks.indexOfNextAvailableHandle[objectclass]
+ > objectHandleStacks.highestIndexOfClass[objectclass])
+ {
+ prvTraceError(pszTraceGetErrorNotEnoughHandles(objectclass));
+ handle = 0;
+ }
+ else
+ {
+ int hndCount;
+ objectHandleStacks.indexOfNextAvailableHandle[objectclass]++;
+
+ hndCount = objectHandleStacks.indexOfNextAvailableHandle[objectclass] -
+ objectHandleStacks.lowestIndexOfClass[objectclass];
+
+ if (hndCount >
+ objectHandleStacks.handleCountWaterMarksOfClass[objectclass])
+ {
+ objectHandleStacks.handleCountWaterMarksOfClass[objectclass] =
+ (traceHandle)hndCount;
+ }
+ }
+ trcCRITICAL_SECTION_END();
+
+ return handle;
+}
+
+void prvTraceFreeObjectHandle(traceObjectClass objectclass, traceHandle handle)
+{
+ int indexOfHandle;
+
+ TRACE_ASSERT(objectclass < TRACE_NCLASSES,
+ "prvTraceFreeObjectHandle: Invalid value for objectclass", TRC_UNUSED);
+ TRACE_ASSERT(handle > 0 && handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
+ "prvTraceFreeObjectHandle: Invalid value for handle", TRC_UNUSED);
+
+ /* Check that there is room to push the handle on the stack */
+ if ((objectHandleStacks.indexOfNextAvailableHandle[objectclass] - 1) <
+ objectHandleStacks.lowestIndexOfClass[objectclass])
+ {
+ /* Error */
+ prvTraceError("Attempt to free more handles than allocated!");
+ }
+ else
+ {
+ objectHandleStacks.indexOfNextAvailableHandle[objectclass]--;
+ indexOfHandle = objectHandleStacks.indexOfNextAvailableHandle[objectclass];
+ objectHandleStacks.objectHandles[indexOfHandle] = handle;
+ }
+}
+
+/*******************************************************************************
+ * prvMarkObjectAsUsed
+ *
+ * Sets an "is used flag" on object creation, using the first byte of the name
+ * field. This allows for counting the number of used Object Table slots, even
+ * if no names have been set.
+ ******************************************************************************/
+void prvMarkObjectAsUsed(traceObjectClass objectclass, traceHandle handle)
+{
+ uint16_t idx = uiIndexOfObject(handle, objectclass);
+ RecorderDataPtr->ObjectPropertyTable.objbytes[idx] = 1;
+}
+
+/*******************************************************************************
+ * prvStrncpy
+ *
+ * Private string copy function, to improve portability between compilers.
+ ******************************************************************************/
+static void prvStrncpy(char* dst, const char* src, uint32_t maxLength)
+{
+ uint32_t i;
+ for (i = 0; i < maxLength; i++)
+ {
+ dst[i] = src[i];
+ if (src[i] == 0)
+ break;
+ }
+}
+
+/*******************************************************************************
+ * prvTraceSetObjectName
+ *
+ * Registers the names of queues, semaphores and other kernel objects in the
+ * recorder's Object Property Table, at the given handle and object class.
+ ******************************************************************************/
+void prvTraceSetObjectName(traceObjectClass objectclass,
+ traceHandle handle,
+ const char* name)
+{
+ static uint16_t idx;
+
+ TRACE_ASSERT(name != NULL, "prvTraceSetObjectName: name == NULL", TRC_UNUSED);
+
+ if (objectclass >= TRACE_NCLASSES)
+ {
+ prvTraceError("Illegal object class in prvTraceSetObjectName");
+ return;
+ }
+
+ if (handle == 0)
+ {
+ prvTraceError("Illegal handle (0) in prvTraceSetObjectName.");
+ return;
+ }
+
+ if (handle > RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass])
+ {
+ /* ERROR */
+ prvTraceError(pszTraceGetErrorNotEnoughHandles(objectclass));
+ }
+ else
+ {
+ idx = uiIndexOfObject(handle, objectclass);
+
+ if (traceErrorMessage == NULL)
+ {
+ prvStrncpy((char*)&(RecorderDataPtr->ObjectPropertyTable.objbytes[idx]),
+ name,
+ RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[ objectclass ]);
+ }
+ }
+}
+
+traceString prvTraceOpenSymbol(const char* name, traceString userEventChannel)
+{
+ uint16_t result;
+ uint8_t len;
+ uint8_t crc;
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ len = 0;
+ crc = 0;
+
+ TRACE_ASSERT(name != NULL, "prvTraceOpenSymbol: name == NULL", (traceString)0);
+
+ prvTraceGetChecksum(name, &crc, &len);
+
+ trcCRITICAL_SECTION_BEGIN();
+ result = prvTraceLookupSymbolTableEntry(name, crc, len, userEventChannel);
+ if (!result)
+ {
+ result = prvTraceCreateSymbolTableEntry(name, crc, len, userEventChannel);
+ }
+ trcCRITICAL_SECTION_END();
+
+ return result;
+}
+
+
+/******************************************************************************
+* 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)
+{
+ timestampFrequency = frequency;
+}
+
+/*******************************************************************************
+ * Supporting functions
+ ******************************************************************************/
+
+/*******************************************************************************
+ * prvTraceError
+ *
+ * Called by various parts in the recorder. Stops the recorder and stores a
+ * pointer to an error message, which is printed by the monitor task.
+ * If you are not using the monitor task, you may use xTraceGetLastError()
+ * from your application to check if the recorder is OK.
+ *
+ * Note: If a recorder error is registered before vTraceStart is called, the
+ * trace start will be aborted. This can occur if any of the Nxxxx constants
+ * (e.g., TRC_CFG_NTASK) in trcConfig.h is too small.
+ ******************************************************************************/
+void prvTraceError(const char* msg)
+{
+ /* Stop the recorder */
+ if (RecorderDataPtr != NULL)
+ {
+ vTraceStop();
+ }
+
+ /* If first error only... */
+ if (traceErrorMessage == NULL)
+ {
+ traceErrorMessage = (char*)(intptr_t) msg;
+ if (RecorderDataPtr != NULL)
+ {
+ prvStrncpy(RecorderDataPtr->systemInfo, traceErrorMessage, 80);
+ RecorderDataPtr->internalErrorOccured = 1;
+ }
+ }
+}
+
+void vTraceSetFilterMask(uint16_t filterMask)
+{
+ CurrentFilterMask = filterMask;
+}
+
+void vTraceSetFilterGroup(uint16_t filterGroup)
+{
+ CurrentFilterGroup = filterGroup;
+}
+
+/******************************************************************************
+ * prvCheckDataToBeOverwrittenForMultiEntryEvents
+ *
+ * This checks if the next event to be overwritten is a multi-entry user event,
+ * i.e., a USER_EVENT followed by data entries.
+ * Such data entries do not have an event code at byte 0, as other events.
+ * All 4 bytes are user data, so the first byte of such data events must
+ * not be interpreted as type field. The number of data entries following
+ * a USER_EVENT is given in the event code of the USER_EVENT.
+ * Therefore, when overwriting a USER_EVENT (when using in ring-buffer mode)
+ * any data entries following must be replaced with NULL events (code 0).
+ *
+ * This is assumed to execute within a critical section...
+ *****************************************************************************/
+
+#if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER)
+void prvCheckDataToBeOverwrittenForMultiEntryEvents(uint8_t nofEntriesToCheck)
+{
+ /* Generic "int" type is desired - should be 16 bit variable on 16 bit HW */
+ unsigned int i = 0;
+ unsigned int e = 0;
+
+ TRACE_ASSERT(nofEntriesToCheck != 0,
+ "prvCheckDataToBeOverwrittenForMultiEntryEvents: nofEntriesToCheck == 0", TRC_UNUSED);
+
+ while (i < nofEntriesToCheck)
+ {
+ e = RecorderDataPtr->nextFreeIndex + i;
+ if ((RecorderDataPtr->eventData[e*4] > USER_EVENT) &&
+ (RecorderDataPtr->eventData[e*4] < USER_EVENT + 16))
+ {
+ uint8_t nDataEvents = (uint8_t)(RecorderDataPtr->eventData[e*4] - USER_EVENT);
+ if ((e + nDataEvents) < RecorderDataPtr->maxEvents)
+ {
+ (void)memset(& RecorderDataPtr->eventData[e*4], 0, (size_t) (4 + 4 * nDataEvents));
+ }
+ }
+ else if (RecorderDataPtr->eventData[e*4] == DIV_XPS)
+ {
+ if ((e + 1) < RecorderDataPtr->maxEvents)
+ {
+ /* Clear 8 bytes */
+ (void)memset(& RecorderDataPtr->eventData[e*4], 0, 4 + 4);
+ }
+ else
+ {
+ /* Clear 8 bytes, 4 first and 4 last */
+ (void)memset(& RecorderDataPtr->eventData[0], 0, 4);
+ (void)memset(& RecorderDataPtr->eventData[e*4], 0, 4);
+ }
+ }
+ i++;
+ }
+}
+#endif
+
+/*******************************************************************************
+ * prvTraceUpdateCounters
+ *
+ * Updates the index of the event buffer.
+ ******************************************************************************/
+void prvTraceUpdateCounters(void)
+{
+ if (RecorderDataPtr->recorderActive == 0)
+ {
+ return;
+ }
+
+ RecorderDataPtr->numEvents++;
+
+ RecorderDataPtr->nextFreeIndex++;
+
+ if (RecorderDataPtr->nextFreeIndex >= (TRC_CFG_EVENT_BUFFER_SIZE))
+ {
+#if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER)
+ RecorderDataPtr->bufferIsFull = 1;
+ RecorderDataPtr->nextFreeIndex = 0;
+#else
+ vTraceStop();
+#endif
+ }
+
+#if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER)
+ prvCheckDataToBeOverwrittenForMultiEntryEvents(1);
+#endif
+}
+
+/******************************************************************************
+ * prvTraceGetDTS
+ *
+ * Returns a differential timestamp (DTS), i.e., the time since
+ * last event, and creates an XTS event if the DTS does not fit in the
+ * number of bits given. The XTS event holds the MSB bytes of the DTS.
+ *
+ * The parameter param_maxDTS should be 0xFF for 8-bit dts or 0xFFFF for
+ * events with 16-bit dts fields.
+ *****************************************************************************/
+uint16_t prvTraceGetDTS(uint16_t param_maxDTS)
+{
+ static uint32_t old_timestamp = 0;
+ XTSEvent* xts = 0;
+ uint32_t dts = 0;
+ uint32_t timestamp = 0;
+
+ TRACE_ASSERT(param_maxDTS == 0xFF || param_maxDTS == 0xFFFF, "prvTraceGetDTS: Invalid value for param_maxDTS", 0);
+
+
+ if (RecorderDataPtr->frequency == 0)
+ {
+ if (timestampFrequency != 0)
+ {
+ /* If to override default TRC_HWTC_FREQ_HZ value with value set by vTraceSetFrequency */
+ RecorderDataPtr->frequency = timestampFrequency / (TRC_HWTC_DIVISOR);
+ }
+ else if (init_hwtc_count != (TRC_HWTC_COUNT))
+ {
+ /* If using default value and timer has been started.
+ Note: If the default frequency value set here would be incorrect, e.g.,
+ if the timer has actually not been configured yet, override this
+ with vTraceSetFrequency.
+ */
+ RecorderDataPtr->frequency = (TRC_HWTC_FREQ_HZ) / (TRC_HWTC_DIVISOR);
+ }
+ /* If no override (vTraceSetFrequency) and timer inactive -> no action */
+ }
+
+ /**************************************************************************
+ * The below statements read the timestamp from the timer port module.
+ * If necessary, whole seconds are extracted using division while the rest
+ * comes from the modulo operation.
+ **************************************************************************/
+
+ prvTracePortGetTimeStamp(&timestamp);
+
+ /***************************************************************************
+ * Since dts is unsigned the result will be correct even if timestamp has
+ * wrapped around.
+ ***************************************************************************/
+ dts = timestamp - old_timestamp;
+ old_timestamp = timestamp;
+
+ if (RecorderDataPtr->frequency > 0)
+ {
+ /* Check if dts > 1 second */
+ if (dts > RecorderDataPtr->frequency)
+ {
+ /* More than 1 second has passed */
+ RecorderDataPtr->absTimeLastEventSecond += dts / RecorderDataPtr->frequency;
+ /* The part that is not an entire second is added to absTimeLastEvent */
+ RecorderDataPtr->absTimeLastEvent += dts % RecorderDataPtr->frequency;
+ }
+ else
+ {
+ RecorderDataPtr->absTimeLastEvent += dts;
+ }
+
+ /* Check if absTimeLastEvent >= 1 second */
+ if (RecorderDataPtr->absTimeLastEvent >= RecorderDataPtr->frequency)
+ {
+ /* RecorderDataPtr->absTimeLastEvent is more than or equal to 1 second, but always less than 2 seconds */
+ RecorderDataPtr->absTimeLastEventSecond++;
+ RecorderDataPtr->absTimeLastEvent -= RecorderDataPtr->frequency;
+ /* RecorderDataPtr->absTimeLastEvent is now less than 1 second */
+ }
+ }
+ else
+ {
+ /* Special case if the recorder has not yet started (frequency may be uninitialized, i.e., zero) */
+ RecorderDataPtr->absTimeLastEvent = timestamp;
+ }
+
+ /* If the dts (time since last event) does not fit in event->dts (only 8 or 16 bits) */
+ if (dts > param_maxDTS)
+ {
+ /* Create an XTS event (eXtended TimeStamp) containing the higher dts bits*/
+ xts = (XTSEvent*) prvTraceNextFreeEventBufferSlot();
+
+ if (xts != NULL)
+ {
+ if (param_maxDTS == 0xFFFF)
+ {
+ xts->type = XTS16;
+ xts->xts_16 = (uint16_t)((dts / 0x10000) & 0xFFFF);
+ xts->xts_8 = 0;
+ }
+ else if (param_maxDTS == 0xFF)
+ {
+ xts->type = XTS8;
+ xts->xts_16 = (uint16_t)((dts / 0x100) & 0xFFFF);
+ xts->xts_8 = (uint8_t)((dts / 0x1000000) & 0xFF);
+ }
+ else
+ {
+ prvTraceError("Bad param_maxDTS in prvTraceGetDTS");
+ }
+ prvTraceUpdateCounters();
+ }
+ }
+
+ return (uint16_t)dts & param_maxDTS;
+}
+
+/*******************************************************************************
+ * prvTraceLookupSymbolTableEntry
+ *
+ * Find an entry in the symbol table, return 0 if not present.
+ *
+ * The strings are stored in a byte pool, with four bytes of "meta-data" for
+ * every string.
+ * byte 0-1: index of next entry with same checksum (for fast lookup).
+ * byte 2-3: reference to a symbol table entry, a label for vTracePrintF
+ * format strings only (the handle of the destination channel).
+ * byte 4..(4 + length): the string (object name or user event label), with
+ * zero-termination
+ ******************************************************************************/
+traceString prvTraceLookupSymbolTableEntry(const char* name,
+ uint8_t crc6,
+ uint8_t len,
+ traceString chn)
+{
+ uint16_t i = RecorderDataPtr->SymbolTable.latestEntryOfChecksum[ crc6 ];
+
+ TRACE_ASSERT(name != NULL, "prvTraceLookupSymbolTableEntry: name == NULL", (traceString)0);
+ TRACE_ASSERT(len != 0, "prvTraceLookupSymbolTableEntry: len == 0", (traceString)0);
+
+ while (i != 0)
+ {
+ if (RecorderDataPtr->SymbolTable.symbytes[i + 2] == (chn & 0x00FF))
+ {
+ if (RecorderDataPtr->SymbolTable.symbytes[i + 3] == (chn / 0x100))
+ {
+ if (RecorderDataPtr->SymbolTable.symbytes[i + 4 + len] == '\0')
+ {
+ if (strncmp((char*)(& RecorderDataPtr->SymbolTable.symbytes[i + 4]), name, len) == 0)
+ {
+ break; /* found */
+ }
+ }
+ }
+ }
+ i = (uint16_t)(RecorderDataPtr->SymbolTable.symbytes[i] + (RecorderDataPtr->SymbolTable.symbytes[i + 1] * 0x100));
+ }
+ return i;
+}
+
+/*******************************************************************************
+ * prvTraceCreateSymbolTableEntry
+ *
+ * Creates an entry in the symbol table, independent if it exists already.
+ *
+ * The strings are stored in a byte pool, with four bytes of "meta-data" for
+ * every string.
+ * byte 0-1: index of next entry with same checksum (for fast lookup).
+ * byte 2-3: reference to a symbol table entry, a label for vTracePrintF
+ * format strings only (the handle of the destination channel).
+ * byte 4..(4 + length): the string (object name or user event label), with
+ * zero-termination
+ ******************************************************************************/
+uint16_t prvTraceCreateSymbolTableEntry(const char* name,
+ uint8_t crc6,
+ uint8_t len,
+ traceString channel)
+{
+ uint16_t ret = 0;
+
+ TRACE_ASSERT(name != NULL, "prvTraceCreateSymbolTableEntry: name == NULL", 0);
+ TRACE_ASSERT(len != 0, "prvTraceCreateSymbolTableEntry: len == 0", 0);
+
+ if (RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + len + 4 >= (TRC_CFG_SYMBOL_TABLE_SIZE))
+ {
+ prvTraceError("Symbol table full. Increase TRC_CFG_SYMBOL_TABLE_SIZE in trcConfig.h");
+ ret = 0;
+ }
+ else
+ {
+
+ RecorderDataPtr->SymbolTable.symbytes
+ [ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex] =
+ (uint8_t)(RecorderDataPtr->SymbolTable.latestEntryOfChecksum[ crc6 ] & 0x00FF);
+
+ RecorderDataPtr->SymbolTable.symbytes
+ [ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 1] =
+ (uint8_t)(RecorderDataPtr->SymbolTable.latestEntryOfChecksum[ crc6 ] / 0x100);
+
+ RecorderDataPtr->SymbolTable.symbytes
+ [ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 2] =
+ (uint8_t)(channel & 0x00FF);
+
+ RecorderDataPtr->SymbolTable.symbytes
+ [ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 3] =
+ (uint8_t)(channel / 0x100);
+
+ /* set name (bytes 4...4+len-1) */
+ prvStrncpy((char*)&(RecorderDataPtr->SymbolTable.symbytes
+ [ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 4]), name, len);
+
+ /* Set zero termination (at offset 4+len) */
+ RecorderDataPtr->SymbolTable.symbytes
+ [RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 4 + len] = '\0';
+
+ /* store index of entry (for return value, and as head of LL[crc6]) */
+ RecorderDataPtr->SymbolTable.latestEntryOfChecksum
+ [ crc6 ] = (uint16_t)RecorderDataPtr->SymbolTable.nextFreeSymbolIndex;
+
+ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex += (uint32_t) (len + 5);
+
+ ret = (uint16_t)(RecorderDataPtr->SymbolTable.nextFreeSymbolIndex - (uint8_t)(len + 5));
+ }
+
+ return ret;
+}
+
+
+/*******************************************************************************
+ * prvTraceGetChecksum
+ *
+ * Calculates a simple 6-bit checksum from a string, used to index the string
+ * for fast symbol table lookup.
+ ******************************************************************************/
+void prvTraceGetChecksum(const char *pname, uint8_t* pcrc, uint8_t* plength)
+{
+ unsigned char c;
+ int length = 1; /* Should be 1 to account for '\0' */
+ int crc = 0;
+
+ TRACE_ASSERT(pname != NULL, "prvTraceGetChecksum: pname == NULL", TRC_UNUSED);
+ TRACE_ASSERT(pcrc != NULL, "prvTraceGetChecksum: pcrc == NULL", TRC_UNUSED);
+ TRACE_ASSERT(plength != NULL, "prvTraceGetChecksum: plength == NULL", TRC_UNUSED);
+
+ if (pname != (const char *) 0)
+ {
+ for (; (c = (unsigned char) *pname++) != '\0';)
+ {
+ crc += c;
+ length++;
+ }
+ }
+ *pcrc = (uint8_t)(crc & 0x3F);
+ *plength = (uint8_t)length;
+}
+
+#if (TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1)
+
+static void prvTraceStoreXID(traceHandle handle);
+
+/******************************************************************************
+ * prvTraceStoreXID
+ *
+ * Stores an XID (eXtended IDentifier) event.
+ * This is used if an object/task handle is larger than 255.
+ * The parameter "handle" is the full (16 bit) handle, assumed to be 256 or
+ * larger. Handles below 256 should not use this function.
+ *
+ * NOTE: this function MUST be called from within a critical section.
+ *****************************************************************************/
+static void prvTraceStoreXID(traceHandle handle)
+{
+ XPSEvent* xid;
+
+ TRACE_ASSERT(handle >= 256, "prvTraceStoreXID: Handle < 256", TRC_UNUSED);
+
+ xid = (XPSEvent*)prvTraceNextFreeEventBufferSlot();
+
+ if (xid != NULL)
+ {
+ xid->type = XID;
+
+ /* This function is (only) used when traceHandle is 16 bit... */
+ xid->xps_16 = handle;
+
+ prvTraceUpdateCounters();
+ }
+}
+
+static uint8_t prvTraceGet8BitHandle(traceHandle handle)
+{
+ if (handle > 255)
+ {
+ prvTraceStoreXID(handle);
+ /* The full handle (16 bit) is stored in the XID event.
+ This code (255) is used instead of zero (which is an error code).*/
+ return 255;
+ }
+ return (uint8_t)(handle & 0xFF);
+}
+#endif /*(TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1)*/
+
+
+/* If using DWT timestamping (default on ARM Cortex-M3, M4 and M7), make sure the DWT unit is initialized. */
+#ifndef TRC_CFG_ARM_CM_USE_SYSTICK
+#if ((TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_Cortex_M) && (defined (__CORTEX_M) && (__CORTEX_M >= 0x03)))
+void prvTraceInitCortexM()
+{
+ /* Ensure that the DWT registers are unlocked and can be modified. */
+ TRC_REG_ITM_LOCKACCESS = TRC_ITM_LOCKACCESS_UNLOCK;
+
+ /* Make sure DWT is enabled, if supported */
+ TRC_REG_DEMCR |= TRC_DEMCR_TRCENA;
+
+ do{
+ /* Verify that DWT is supported */
+ if (TRC_REG_DEMCR == 0)
+ {
+ /* This function is called on Cortex-M3, M4 and M7 devices to initialize
+ the DWT unit, assumed present. The DWT cycle counter is used for timestamping.
+
+ If the below error is produced, the DWT unit does not seem to be available.
+
+ In that case, define the macro TRC_CFG_ARM_CM_USE_SYSTICK in your build
+ to use SysTick timestamping instead, or define your own timestamping by
+ setting TRC_CFG_HARDWARE_PORT to TRC_HARDWARE_PORT_APPLICATION_DEFINED
+ and make the necessary definitions, as explained in trcHardwarePort.h.*/
+
+ prvTraceError("DWT unit not available, see code comment.");
+ break;
+ }
+
+ /* Verify that DWT_CYCCNT is supported */
+ if (TRC_REG_DWT_CTRL & TRC_DWT_CTRL_NOCYCCNT)
+ {
+ /* This function is called on Cortex-M3, M4 and M7 devices to initialize
+ the DWT unit, assumed present. The DWT cycle counter is used for timestamping.
+
+ If the below error is produced, the cycle counter does not seem to be available.
+
+ In that case, define the macro TRC_CFG_ARM_CM_USE_SYSTICK in your build
+ to use SysTick timestamping instead, or define your own timestamping by
+ setting TRC_CFG_HARDWARE_PORT to TRC_HARDWARE_PORT_APPLICATION_DEFINED
+ and make the necessary definitions, as explained in trcHardwarePort.h.*/
+
+ prvTraceError("DWT_CYCCNT not available, see code comment.");
+ break;
+ }
+
+ /* Reset the cycle counter */
+ TRC_REG_DWT_CYCCNT = 0;
+
+ /* Enable the cycle counter */
+ TRC_REG_DWT_CTRL |= TRC_DWT_CTRL_CYCCNTENA;
+
+ }while(0); /* breaks above jump here */
+}
+#endif
+#endif
+
+/******************************************************************************
+ * 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 *pTimestamp)
+{
+ static uint32_t last_hwtc_count = 0;
+ uint32_t hwtc_count = 0;
+
+#if TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR
+ /* systick based timer */
+ static uint32_t last_traceTickCount = 0;
+ uint32_t traceTickCount = 0;
+#else /*TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR*/
+ /* Free running timer */
+ static uint32_t last_hwtc_rest = 0;
+ uint32_t diff = 0;
+ uint32_t diff_scaled = 0;
+#endif /*TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR*/
+
+ if (trace_disable_timestamp == 1)
+ {
+ if (pTimestamp)
+ *pTimestamp = last_timestamp;
+ return;
+ }
+
+ /* Retrieve TRC_HWTC_COUNT only once since the same value should be used all throughout this function. */
+#if (TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_INCR)
+ /* Get the increasing tick count */
+ hwtc_count = (TRC_HWTC_COUNT);
+#elif (TRC_HWTC_TYPE == TRC_OS_TIMER_DECR || TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_DECR)
+ /* Convert decreasing tick count into increasing tick count */
+ hwtc_count = (TRC_HWTC_PERIOD) - (TRC_HWTC_COUNT);
+#else
+ #error "TRC_HWTC_TYPE has unexpected value"
+#endif
+
+#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Win32)
+ /* The Win32 port uses ulGetRunTimeCounterValue for timestamping, which in turn
+ uses QueryPerformanceCounter. That function is not always reliable when used over
+ multiple threads. We must therefore handle rare cases where the timestamp is less
+ than the previous. In practice, this should "never" roll over since the
+ performance counter is 64 bit wide. */
+
+ if (last_hwtc_count > hwtc_count)
+ {
+ hwtc_count = last_hwtc_count;
+ }
+#endif
+
+#if (TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR)
+ /* Timestamping is based on a timer that wraps at TRC_HWTC_PERIOD */
+ if (last_traceTickCount - uiTraceTickCount - 1 < 0x80000000)
+ {
+ /* This means last_traceTickCount is higher than uiTraceTickCount,
+ so we have previously compensated for a missed tick.
+ Therefore we use the last stored value because that is more accurate. */
+ traceTickCount = last_traceTickCount;
+ }
+ else
+ {
+ /* Business as usual */
+ traceTickCount = uiTraceTickCount;
+ }
+
+ /* Check for overflow. May occur if the update of uiTraceTickCount has been
+ delayed due to disabled interrupts. */
+ if (traceTickCount == last_traceTickCount && hwtc_count < last_hwtc_count)
+ {
+ /* A trace tick has occurred but not been executed by the kernel, so we compensate manually. */
+ traceTickCount++;
+ }
+
+ /* Check if the return address is OK, then we perform the calculation. */
+ if (pTimestamp)
+ {
+ /* Get timestamp from trace ticks. Scale down the period to avoid unwanted overflows. */
+ last_timestamp = traceTickCount * ((TRC_HWTC_PERIOD) / (TRC_HWTC_DIVISOR));
+ /* Increase timestamp by (hwtc_count + "lost hardware ticks from scaling down period") / TRC_HWTC_DIVISOR. */
+ last_timestamp += (hwtc_count + traceTickCount * ((TRC_HWTC_PERIOD) % (TRC_HWTC_DIVISOR))) / (TRC_HWTC_DIVISOR);
+ }
+ /* Store the previous value */
+ last_traceTickCount = traceTickCount;
+
+#else /*(TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR)*/
+
+ /* Timestamping is based on a free running timer */
+ /* This part handles free running clocks that can be scaled down to avoid too large DTS values.
+ Without this, the scaled timestamp will incorrectly wrap at (2^32 / TRC_HWTC_DIVISOR) ticks.
+ The scaled timestamp returned from this function is supposed to go from 0 -> 2^32, which in real time would represent (0 -> 2^32 * TRC_HWTC_DIVISOR) ticks. */
+
+ /* First we see how long time has passed since the last timestamp call, and we also add the ticks that was lost when we scaled down the last time. */
+ diff = (hwtc_count - last_hwtc_count) + last_hwtc_rest;
+
+ /* Scale down the diff */
+ diff_scaled = diff / (TRC_HWTC_DIVISOR);
+
+ /* Find out how many ticks were lost when scaling down, so we can add them the next time */
+ last_hwtc_rest = diff % (TRC_HWTC_DIVISOR);
+
+ /* We increase the scaled timestamp by the scaled amount */
+ last_timestamp += diff_scaled;
+#endif /*(TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR)*/
+
+ /* Is anyone interested in the results? */
+ if (pTimestamp)
+ *pTimestamp = last_timestamp;
+
+ /* Store the previous value */
+ last_hwtc_count = hwtc_count;
+}
+
+#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/
+
+#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)*/
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcStreamingRecorder.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcStreamingRecorder.c
index dc1b87865..0ca034b84 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcStreamingRecorder.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcStreamingRecorder.c
@@ -1,1896 +1,2035 @@
-/*******************************************************************************
- * Trace Recorder Library for Tracealyzer v4.1.5
- * Percepio AB, www.percepio.com
- *
- * trcStreamingRecorder.c
- *
- * The generic core of the trace recorder's streaming mode.
- *
- * 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
- ******************************************************************************/
-
-#include "trcRecorder.h"
-
-#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
-
-#if (TRC_USE_TRACEALYZER_RECORDER == 1)
-
-#include <stdio.h>
-#include <stdarg.h>
-
-typedef struct{
- uint16_t EventID;
- uint16_t EventCount;
- uint32_t TS;
-} BaseEvent;
-
-typedef struct{
- BaseEvent base;
- uint32_t param1;
-} EventWithParam_1;
-
-typedef struct{
- BaseEvent base;
- uint32_t param1;
- uint32_t param2;
-} EventWithParam_2;
-
-typedef struct{
- BaseEvent base;
- uint32_t param1;
- uint32_t param2;
- uint32_t param3;
-} EventWithParam_3;
-
-/* Used in event functions with variable number of parameters. */
-typedef struct
-{
- BaseEvent base;
- uint32_t data[15]; /* maximum payload size */
-} largestEventType;
-
-typedef struct{
- uint32_t psf;
- uint16_t version;
- uint16_t platform;
- uint32_t options;
- uint16_t symbolSize;
- uint16_t symbolCount;
- uint16_t objectDataSize;
- uint16_t objectDataCount;
-} PSFHeaderInfo;
-
-
-/* The size of each slot in the Symbol Table */
-#define SYMBOL_TABLE_SLOT_SIZE (sizeof(uint32_t) + (((TRC_CFG_SYMBOL_MAX_LENGTH)+(sizeof(uint32_t)-1))/sizeof(uint32_t))*sizeof(uint32_t))
-
-#define OBJECT_DATA_SLOT_SIZE (sizeof(uint32_t) + sizeof(uint32_t))
-
-/* The total size of the Symbol Table */
-#define SYMBOL_TABLE_BUFFER_SIZE ((TRC_CFG_SYMBOL_TABLE_SLOTS) * SYMBOL_TABLE_SLOT_SIZE)
-
-/* The total size of the Object Data Table */
-#define OBJECT_DATA_TABLE_BUFFER_SIZE ((TRC_CFG_OBJECT_DATA_SLOTS) * OBJECT_DATA_SLOT_SIZE)
-
-/* The Symbol Table type - just a byte array */
-typedef struct{
- union
- {
- uint32_t pSymbolTableBufferUINT32[SYMBOL_TABLE_BUFFER_SIZE / sizeof(uint32_t)];
- uint8_t pSymbolTableBufferUINT8[SYMBOL_TABLE_BUFFER_SIZE];
- } SymbolTableBuffer;
-} SymbolTable;
-
-/* The Object Data Table type - just a byte array */
-typedef struct{
- union
- {
- uint32_t pObjectDataTableBufferUINT32[OBJECT_DATA_TABLE_BUFFER_SIZE / sizeof(uint32_t)];
- uint8_t pObjectDataTableBufferUINT8[OBJECT_DATA_TABLE_BUFFER_SIZE];
- } ObjectDataTableBuffer;
-} ObjectDataTable;
-
-typedef struct{
- uint16_t Status; /* 16 bit to avoid implicit padding (warnings) */
- uint16_t BytesRemaining;
- char* WritePointer;
-} PageType;
-
-/* Code used for "task address" when no task has started. (NULL = idle task) */
-#define HANDLE_NO_TASK 2
-
-#define PAGE_STATUS_FREE 0
-#define PAGE_STATUS_WRITE 1
-#define PAGE_STATUS_READ 2
-
-#define PSF_ASSERT(_assert, _err) if (! (_assert)){ prvTraceError(_err); return; }
-
-/* Part of the PSF format - encodes the number of 32-bit params in an event */
-#define PARAM_COUNT(n) ((n & 0xF) << 12)
-
-/* The Symbol Table instance - keeps names of tasks and other named objects. */
-static SymbolTable symbolTable = { { { 0 } } };
-
-/* This points to the first unused entry in the symbol table. */
-static uint32_t firstFreeSymbolTableIndex = 0;
-
-/* The Object Data Table instance - keeps initial priorities of tasks. */
-static ObjectDataTable objectDataTable = { { { 0 } } };
-
-/* This points to the first unused entry in the object data table. */
-static uint32_t firstFreeObjectDataTableIndex = 0;
-
-/* Keeps track of ISR nesting */
-static uint32_t ISR_stack[TRC_CFG_MAX_ISR_NESTING];
-
-/* Keeps track of ISR nesting */
-static int8_t ISR_stack_index = -1;
-
-/* Any error that occurred in the recorder (also creates User Event) */
-static int errorCode = 0;
-
-/* Counts the number of trace sessions (not yet used) */
-static uint32_t SessionCounter = 0u;
-
-/* Master switch for recording (0 => Disabled, 1 => Enabled) */
-uint32_t RecorderEnabled = 0u;
-
-/* Used to determine endian of data (big/little) */
-static uint32_t PSFEndianessIdentifier = 0x50534600;
-
-/* Used to interpret the data format */
-static uint16_t FormatVersion = 0x0004;
-
-/* The number of events stored. Used as event sequence number. */
-static uint32_t eventCounter = 0;
-
-/* Remembers if an earlier ISR in a sequence of adjacent ISRs has triggered a task switch.
-In that case, vTraceStoreISREnd does not store a return to the previously executing task. */
-int32_t isPendingContextSwitch = 0;
-
-uint32_t uiTraceTickCount = 0;
-uint32_t timestampFrequency = 0;
-uint32_t DroppedEventCounter = 0;
-uint32_t TotalBytesRemaining_LowWaterMark = (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT) * (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE);
-uint32_t TotalBytesRemaining = (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT) * (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE);
-
-PageType PageInfo[TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT];
-
-char* EventBuffer = NULL;
-
-/*******************************************************************************
- * NoRoomForSymbol
- *
- * Incremented on prvTraceSaveSymbol if no room for saving the symbol name. This
- * is used for storing the names of:
- * - Tasks
- * - Named ISRs (xTraceSetISRProperties)
- * - Named kernel objects (vTraceStoreKernelObjectName)
- * - User event channels (xTraceRegisterString)
- *
- * This variable should be zero. If not, it shows the number of missing slots so
- * far. In that case, increment SYMBOL_TABLE_SLOTS with (at least) this value.
- ******************************************************************************/
-volatile uint32_t NoRoomForSymbol = 0;
-
-/*******************************************************************************
- * NoRoomForObjectData
- *
- * Incremented on prvTraceSaveObjectData if no room for saving the object data,
- * i.e., the base priorities of tasks. There must be one slot for each task.
- * If not, this variable will show the difference.
- *
- * This variable should be zero. If not, it shows the number of missing slots so
- * far. In that case, increment OBJECT_DATA_SLOTS with (at least) this value.
- ******************************************************************************/
-volatile uint32_t NoRoomForObjectData = 0;
-
-/*******************************************************************************
- * LongestSymbolName
- *
- * Updated in prvTraceSaveSymbol. Should not exceed TRC_CFG_SYMBOL_MAX_LENGTH,
- * otherwise symbol names will be truncated. In that case, set
- * TRC_CFG_SYMBOL_MAX_LENGTH to (at least) this value.
- ******************************************************************************/
-volatile uint32_t LongestSymbolName = 0;
-
-/*******************************************************************************
- * MaxBytesTruncated
- *
- * Set in prvTraceStoreStringEvent if the total data payload exceeds 60 bytes,
- * including data arguments and the string. For user events, that is 52 bytes
- * for string and data arguments. In that is exceeded, the event is truncated
- * (usually only the string, unless more than 15 parameters) and this variable
- * holds the maximum number of truncated bytes, from any event.
- ******************************************************************************/
-volatile uint32_t MaxBytesTruncated = 0;
-
-uint16_t CurrentFilterMask = 0xFFFF;
-
-uint16_t CurrentFilterGroup = FilterGroup0;
-
-/* Internal common function for storing string events */
-static void prvTraceStoreStringEventHelper( int nArgs,
- uint16_t eventID,
- traceString userEvtChannel,
- int len,
- const char* str,
- va_list* vl);
-
-/* Not static to avoid warnings from SysGCC/PPC */
-void prvTraceStoreSimpleStringEventHelper(traceString userEvtChannel,
- const char* str);
-
-
-/* Stores the header information on Start */
-static void prvTraceStoreHeader(void);
-
-/* Stores the symbol table on Start */
-static void prvTraceStoreSymbolTable(void);
-
-/* Stores the object table on Start */
-static void prvTraceStoreObjectDataTable(void);
-
-/* Store the Timestamp Config on Start */
-static void prvTraceStoreTSConfig(void);
-
-/* Store the current warnings */
-static void prvTraceStoreWarnings(void);
-
-/* Internal function for starting/stopping the recorder. */
-static void prvSetRecorderEnabled(uint32_t isEnabled);
-
-/* Mark the page read as complete. */
-static void prvPageReadComplete(int pageIndex);
-
-/* Retrieve a buffer page to write to. */
-static int prvAllocateBufferPage(int prevPage);
-
-/* Get the current buffer page index (return value) and the number
-of valid bytes in the buffer page (bytesUsed). */
-static int prvGetBufferPage(int32_t* bytesUsed);
-
-/* Performs timestamping using definitions in trcHardwarePort.h */
-static uint32_t prvGetTimestamp32(void);
-
-/* Signal an error. */
-void prvTraceError(int errCode);
-
-/* Signal an warning (does not stop the recorder). */
-void prvTraceWarning(int errCode);
-
-/******************************************************************************
- * vTraceInstanceFinishedNow
- *
- * 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)
-{
- prvTraceStoreEvent0(PSF_EVENT_IFE_DIRECT);
-}
-
-/******************************************************************************
- * 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)
-{
- prvTraceStoreEvent0(PSF_EVENT_IFE_NEXT);
-}
-
-/*******************************************************************************
- * vTraceStoreKernelObjectName
- *
- * Parameter object: pointer to the Event Group that shall be named
- * Parameter name: the name to set (const string literal)
- *
- * Sets a name for a kernel object for display in Tracealyzer.
- ******************************************************************************/
-void vTraceStoreKernelObjectName(void* object, const char* name)
-{
- /* Always save in symbol table, if the recording has not yet started */
- prvTraceSaveSymbol(object, name);
-
- prvTraceStoreStringEvent(1, PSF_EVENT_OBJ_NAME, name, (uint32_t)object);
-}
-
-
-/******************************************************************************
-* 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.
-*****************************************************************************/
-void vTraceSetFrequency(uint32_t frequency)
-{
- timestampFrequency = frequency;
-}
-
-#if (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)
-
-/*******************************************************************************
-* xTraceRegisterString
-*
-* Stores a name for a user event channel, returns the handle.
-******************************************************************************/
-traceString xTraceRegisterString(const char* name)
-{
- prvTraceSaveSymbol((const void*)name, name);
-
- /* Always save in symbol table, if the recording has not yet started */
- prvTraceStoreStringEvent(1, PSF_EVENT_OBJ_NAME, (const char*)name, (uint32_t)name);
-
- return (traceString)name;
-}
-
-/******************************************************************************
- * vTracePrint
- *
- * Generates "User Events", with unformatted text.
- *
- * User Events can be used for very efficient application logging, and are shown
- * as yellow labels in the main trace view.
- *
- * You may group User Events into User Event Channels. The yellow User Event
- * labels shows the logged string, preceded by the channel name within
- * brackets. For 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 chn = xTraceRegisterString("MyChannel");
- * ...
- * vTracePrint(chn, "Hello World!");
- *
- ******************************************************************************/
-void vTracePrint(traceString chn, const char* str)
-{
- prvTraceStoreSimpleStringEventHelper(chn, str);
-}
-
-
-/*******************************************************************************
-* 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);
-******************************************************************************/
-void vTraceConsoleChannelPrintF(const char* fmt, ...)
-{
- va_list vl;
- char tempBuf[60];
- static traceString consoleChannel = NULL;
-
- if (consoleChannel == NULL)
- consoleChannel = xTraceRegisterString("Debug Console");
-
- va_start(vl, fmt);
- vsnprintf(tempBuf, 60, fmt, vl);
- vTracePrint(consoleChannel, tempBuf);
- va_end(vl);
-}
-
-/******************************************************************************
- * vTracePrintF
- *
- * Generates "User Events", with formatted text and data, similar to a "printf".
- * It is very fast since the actual formatting is done on the host side when the
- * trace is displayed.
- *
- * User Events can be used for very efficient application logging, and are shown
- * as yellow labels in the main trace view.
- * 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);
- *
- * All data arguments are assumed to be 32 bit wide. The following formats are
- * supported:
- * %d - signed integer. The following width and padding format is supported: "%05d" -> "-0042" and "%5d" -> " -42"
- * %u - unsigned integer. The following width and padding format is supported: "%05u" -> "00042" and "%5u" -> " 42"
- * %X - hexadecimal (uppercase). The following width and padding format is supported: "%04X" -> "002A" and "%4X" -> " 2A"
- * %x - hexadecimal (lowercase). The following width and padding format is supported: "%04x" -> "002a" and "%4x" -> " 2a"
- * %s - string (currently, this must be an earlier stored symbol name)
- *
- * Up to 15 data arguments are allowed, with a total size of maximum 60 byte
- * including 8 byte for the base event fields and the format string. So with
- * one data argument, the maximum string length is 48 chars. If this is exceeded
- * the string is truncated (4 bytes at a time).
- *
- ******************************************************************************/
-void vTracePrintF(traceString chn, const char* fmt, ...)
-{
- va_list vl;
- int i = 0;
-
- int nArgs = 0;
-
- /* Count the number of arguments in the format string (e.g., %d) */
- for (i = 0; (fmt[i] != 0) && (i < 52); i++)
- {
- if (fmt[i] == '%')
- {
- if (fmt[i + 1] != 0 && fmt[i + 1] != '%')
- {
- nArgs++; /* Found an argument */
- }
-
- i++; /* Move past format specifier or non-argument '%' */
- }
- }
-
- va_start(vl, fmt);
-
- if (chn != NULL)
- {
- prvTraceStoreStringEventHelper(nArgs, (uint16_t)(PSF_EVENT_USER_EVENT + nArgs + 1), chn, i, fmt, &vl);
- }
- else
- {
- prvTraceStoreStringEventHelper(nArgs, (uint16_t)(PSF_EVENT_USER_EVENT + nArgs), chn, i, fmt, &vl);
- }
- va_end(vl);
-}
-#endif /* (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) */
-
-/*******************************************************************************
- * 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)
-{
- /* Save object data in object data table */
- prvTraceSaveObjectData((const void*)name, priority);
-
- /* Note: "name" is used both as a string argument, and the address as ID */
- prvTraceStoreStringEvent(2, PSF_EVENT_DEFINE_ISR, name, name, priority);
-
- /* Always save in symbol table, if the recording has not yet started */
- prvTraceSaveSymbol((const void*)name, name);
-
- return (traceHandle)name;
-}
-
-/*******************************************************************************
- * 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)
-{
- TRACE_ALLOC_CRITICAL_SECTION();
-
- TRACE_ENTER_CRITICAL_SECTION();
-
- /* We are at the start of a possible ISR chain.
- No context switches should have been triggered now. */
- if (ISR_stack_index == -1)
- isPendingContextSwitch = 0;
-
- if (ISR_stack_index < (TRC_CFG_MAX_ISR_NESTING) - 1)
- {
- ISR_stack_index++;
- ISR_stack[ISR_stack_index] = (uint32_t)handle;
-#if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
- prvTraceStoreEvent1(PSF_EVENT_ISR_BEGIN, (uint32_t)handle);
-#endif
- TRACE_EXIT_CRITICAL_SECTION();
- }
- else
- {
- TRACE_EXIT_CRITICAL_SECTION();
- prvTraceError(PSF_ERROR_ISR_NESTING_OVERFLOW);
- }
-}
-
-/*******************************************************************************
- * 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)
-{
- TRACE_ALLOC_CRITICAL_SECTION();
-
- TRACE_ENTER_CRITICAL_SECTION();
-
- (void)ISR_stack;
-
- /* Is there a pending task-switch? (perhaps from an earlier ISR) */
- isPendingContextSwitch |= isTaskSwitchRequired;
-
- if (ISR_stack_index > 0)
- {
- ISR_stack_index--;
-
-#if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
- /* Store return to interrupted ISR (if nested ISRs)*/
- prvTraceStoreEvent1(PSF_EVENT_ISR_RESUME, (uint32_t)ISR_stack[ISR_stack_index]);
-#endif
- }
- else
- {
- ISR_stack_index--;
-
- /* Store return to interrupted task, if no context switch will occur in between. */
- if ((isPendingContextSwitch == 0) || (prvTraceIsSchedulerSuspended()))
- {
-#if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
- prvTraceStoreEvent1(PSF_EVENT_TS_RESUME, (uint32_t)TRACE_GET_CURRENT_TASK());
-#endif
- }
- }
-
- TRACE_EXIT_CRITICAL_SECTION();
-}
-
-
-/*******************************************************************************
- * xTraceGetLastError
- *
- * Returns the last error or warning, as a string, or NULL if none.
- *****************************************************************************/
-const char* xTraceGetLastError(void)
-{
- /* Note: the error messages are short, in order to fit in a User Event.
- Instead, the users can read more in the below comments.*/
-
- switch (errorCode)
- {
-
- case PSF_WARNING_SYMBOL_TABLE_SLOTS:
- /* There was not enough symbol table slots for storing symbol names.
- The number of missing slots is counted by NoRoomForSymbol. Inspect this
- variable and increase TRC_CFG_SYMBOL_TABLE_SLOTS by at least that value. */
-
- return "Exceeded SYMBOL_TABLE_SLOTS (see xTraceGetLastError)";
-
- case PSF_WARNING_SYMBOL_MAX_LENGTH:
- /* A symbol name exceeded TRC_CFG_SYMBOL_MAX_LENGTH in length.
- Make sure the symbol names are at most TRC_CFG_SYMBOL_MAX_LENGTH,
- or inspect LongestSymbolName and increase TRC_CFG_SYMBOL_MAX_LENGTH
- to at least this value. */
-
- return "Exceeded SYMBOL_MAX_LENGTH (see xTraceGetLastError)";
-
- case PSF_WARNING_OBJECT_DATA_SLOTS:
- /* There was not enough symbol object table slots for storing object
- properties, such as task priorites. The number of missing slots is
- counted by NoRoomForObjectData. Inspect this variable and increase
- TRC_CFG_OBJECT_DATA_SLOTS by at least that value. */
-
- return "Exceeded OBJECT_DATA_SLOTS (see xTraceGetLastError)";
-
- case PSF_WARNING_STRING_TOO_LONG:
- /* Some string argument was longer than the maximum payload size
- and has been truncated by "MaxBytesTruncated" bytes.
-
- This may happen for the following functions:
- - vTracePrint
- - vTracePrintF
- - vTraceStoreKernelObjectName
- - xTraceRegisterString
- - vTraceSetISRProperties
-
- A PSF event may store maximum 60 bytes payload, including data
- arguments and string characters. For User Events, also the User
- Event Channel (4 bytes) must be squeezed in, if a channel is
- specified (can be NULL). */
-
- return "String too long (see xTraceGetLastError)";
-
- case PSF_WARNING_STREAM_PORT_READ:
- /* TRC_STREAM_PORT_READ_DATA is expected to return 0 when completed successfully.
- This means there is an error in the communication with host/Tracealyzer. */
-
- return "TRC_STREAM_PORT_READ_DATA returned error (!= 0).";
-
- case PSF_WARNING_STREAM_PORT_WRITE:
- /* TRC_STREAM_PORT_WRITE_DATA is expected to return 0 when completed successfully.
- This means there is an error in the communication with host/Tracealyzer. */
-
- return "TRC_STREAM_PORT_WRITE_DATA returned error (!= 0).";
-
- case PSF_ERROR_EVENT_CODE_TOO_LARGE:
- /* The highest allowed event code is 4095, anything higher is an unexpected error.
- Please contact support@percepio.com for assistance.*/
-
- return "Invalid event code (see xTraceGetLastError)";
-
- case PSF_ERROR_ISR_NESTING_OVERFLOW:
- /* Nesting of ISR trace calls exceeded the limit (TRC_CFG_MAX_ISR_NESTING).
- If this is unlikely, make sure that you call vTraceStoreISRExit in the end
- of all ISR handlers. Or increase TRC_CFG_MAX_ISR_NESTING. */
-
- return "Exceeded ISR nesting (see xTraceGetLastError)";
-
- case PSF_ERROR_DWT_NOT_SUPPORTED:
- /* On ARM Cortex-M only - failed to initialize DWT Cycle Counter since not supported by this chip.
- DWT timestamping is selected automatically for ART Cortex-M3, M4 and higher, based on the __CORTEX_M
- macro normally set by ARM's CMSIS library, since typically available. You can however select
- SysTick timestamping instead by defining adding "#define TRC_CFG_ARM_CM_USE_SYSTICK".*/
-
- return "DWT not supported (see xTraceGetLastError)";
-
- case PSF_ERROR_DWT_CYCCNT_NOT_SUPPORTED:
- /* On ARM Cortex-M only - failed to initialize DWT Cycle Counter since not supported by this chip.
- DWT timestamping is selected automatically for ART Cortex-M3, M4 and higher, based on the __CORTEX_M
- macro normally set by ARM's CMSIS library, since typically available. You can however select
- SysTick timestamping instead by defining adding "#define TRC_CFG_ARM_CM_USE_SYSTICK".*/
-
- return "DWT_CYCCNT not supported (see xTraceGetLastError)";
-
- case PSF_ERROR_TZCTRLTASK_NOT_CREATED:
- /* vTraceEnable failed creating the trace control task (TzCtrl) - incorrect parameters (priority?)
- or insufficient heap size? */
- return "Could not create TzCtrl (see xTraceGetLastError)";
-
- }
-
- return NULL;
-}
-
-/*******************************************************************************
- * vTraceClearError
- *
- * Clears any errors.
- *****************************************************************************/
-void vTraceClearError(void)
-{
- NoRoomForSymbol = 0;
- LongestSymbolName = 0;
- NoRoomForObjectData = 0;
- MaxBytesTruncated = 0;
- errorCode = PSF_ERROR_NONE;
-}
-
-/*******************************************************************************
- * vTraceStop
- *
- * Stops the tracing.
- *****************************************************************************/
-void vTraceStop(void)
-{
- prvSetRecorderEnabled(0);
-}
-
-/*******************************************************************************
- * vTraceSetRecorderDataBuffer
- *
- * If custom allocation is used, this function must be called so the recorder
- * library knows where to save the trace data.
- ******************************************************************************/
-#if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM)
-
-extern char* _TzTraceData;
-
-void vTraceSetRecorderDataBuffer(void* pRecorderData)
-{
- _TzTraceData = pRecorderData;
-}
-#endif
-
-
-/*******************************************************************************
-* xTraceIsRecordingEnabled
-* Returns true (1) if the recorder is enabled (i.e. is recording), otherwise 0.
-******************************************************************************/
-int xTraceIsRecordingEnabled(void)
-{
- return (int)RecorderEnabled;
-}
-
-void vTraceSetFilterMask(uint16_t filterMask)
-{
- CurrentFilterMask = filterMask;
-}
-
-void vTraceSetFilterGroup(uint16_t filterGroup)
-{
- CurrentFilterGroup = filterGroup;
-}
-
-
-/******************************************************************************/
-/*** INTERNAL FUNCTIONS *******************************************************/
-/******************************************************************************/
-
-/* Internal function for starting/stopping the recorder. */
-static void prvSetRecorderEnabled(uint32_t isEnabled)
-{
- void* currentTask;
-
- TRACE_ALLOC_CRITICAL_SECTION();
-
- if (RecorderEnabled == isEnabled)
- {
- return;
- }
-
- currentTask = TRACE_GET_CURRENT_TASK();
-
- TRACE_ENTER_CRITICAL_SECTION();
-
- RecorderEnabled = isEnabled;
-
- if (currentTask == NULL)
- {
- currentTask = (void*)HANDLE_NO_TASK;
- }
-
- if (RecorderEnabled)
- {
- TRC_STREAM_PORT_ON_TRACE_BEGIN();
-
- #if (TRC_STREAM_PORT_USE_INTERNAL_BUFFER == 1)
- prvPagedEventBufferInit(_TzTraceData);
- #endif
-
- eventCounter = 0;
- ISR_stack_index = -1;
- prvTraceStoreHeader();
- prvTraceStoreSymbolTable();
- prvTraceStoreObjectDataTable();
- prvTraceStoreEvent3( PSF_EVENT_TRACE_START,
- (uint32_t)TRACE_GET_OS_TICKS(),
- (uint32_t)currentTask,
- SessionCounter++);
- prvTraceStoreTSConfig();
- prvTraceStoreWarnings();
- }
- else
- {
- TRC_STREAM_PORT_ON_TRACE_END();
- }
-
- TRACE_EXIT_CRITICAL_SECTION();
-}
-
-/* Stores the symbol table on Start */
-static void prvTraceStoreSymbolTable(void)
-{
- uint32_t i = 0;
- uint32_t j = 0;
- TRACE_ALLOC_CRITICAL_SECTION();
-
- TRACE_ENTER_CRITICAL_SECTION();
-
- if (RecorderEnabled)
- {
- for (i = 0; i < (sizeof(SymbolTable) / sizeof(uint32_t)); i += (SYMBOL_TABLE_SLOT_SIZE / sizeof(uint32_t)))
- {
- TRC_STREAM_PORT_ALLOCATE_EVENT(uint32_t, data, SYMBOL_TABLE_SLOT_SIZE);
- if (data != NULL)
- {
- for (j = 0; j < (SYMBOL_TABLE_SLOT_SIZE / sizeof(uint32_t)); j++)
- {
- data[j] = symbolTable.SymbolTableBuffer.pSymbolTableBufferUINT32[i+j];
- }
- TRC_STREAM_PORT_COMMIT_EVENT(data, SYMBOL_TABLE_SLOT_SIZE);
- }
- }
- }
- TRACE_EXIT_CRITICAL_SECTION();
-}
-
-/* Stores the object table on Start */
-static void prvTraceStoreObjectDataTable(void)
-{
- uint32_t i = 0;
- uint32_t j = 0;
- TRACE_ALLOC_CRITICAL_SECTION();
-
- TRACE_ENTER_CRITICAL_SECTION();
-
- if (RecorderEnabled)
- {
- for (i = 0; i < (sizeof(ObjectDataTable) / sizeof(uint32_t)); i += (OBJECT_DATA_SLOT_SIZE / sizeof(uint32_t)))
- {
- TRC_STREAM_PORT_ALLOCATE_EVENT(uint32_t, data, OBJECT_DATA_SLOT_SIZE);
- if (data != NULL)
- {
- for (j = 0; j < (OBJECT_DATA_SLOT_SIZE / sizeof(uint32_t)); j++)
- {
- data[j] = objectDataTable.ObjectDataTableBuffer.pObjectDataTableBufferUINT32[i+j];
- }
- TRC_STREAM_PORT_COMMIT_EVENT(data, OBJECT_DATA_SLOT_SIZE);
- }
- }
- }
- TRACE_EXIT_CRITICAL_SECTION();
-}
-
-/* Stores the header information on Start */
-static void prvTraceStoreHeader(void)
-{
- TRACE_ALLOC_CRITICAL_SECTION();
-
- TRACE_ENTER_CRITICAL_SECTION();
-
- if (RecorderEnabled)
- {
- TRC_STREAM_PORT_ALLOCATE_EVENT(PSFHeaderInfo, header, sizeof(PSFHeaderInfo));
- if (header != NULL)
- {
- header->psf = PSFEndianessIdentifier;
- header->version = FormatVersion;
- header->platform = TRACE_KERNEL_VERSION;
- header->options = 0;
- /* Lowest bit used for TRC_IRQ_PRIORITY_ORDER */
- header->options = header->options | (TRC_IRQ_PRIORITY_ORDER << 0);
- header->symbolSize = SYMBOL_TABLE_SLOT_SIZE;
- header->symbolCount = (TRC_CFG_SYMBOL_TABLE_SLOTS);
- header->objectDataSize = 8;
- header->objectDataCount = (TRC_CFG_OBJECT_DATA_SLOTS);
- TRC_STREAM_PORT_COMMIT_EVENT(header, sizeof(PSFHeaderInfo));
- }
- }
- TRACE_EXIT_CRITICAL_SECTION();
-}
-
-/* Store the current warnings */
-static void prvTraceStoreWarnings(void)
-{
- if (RecorderEnabled)
- {
- const char* errStr = xTraceGetLastError();
-
- if (errStr != NULL)
- {
- vTracePrint(trcWarningChannel, errStr);
- }
- }
-}
-
-/* Store an event with zero parameters (event ID only) */
-void prvTraceStoreEvent0(uint16_t eventID)
-{
- TRACE_ALLOC_CRITICAL_SECTION();
-
- PSF_ASSERT(eventID < 4096, PSF_ERROR_EVENT_CODE_TOO_LARGE);
-
- TRACE_ENTER_CRITICAL_SECTION();
-
- if (RecorderEnabled)
- {
- eventCounter++;
-
- {
- TRC_STREAM_PORT_ALLOCATE_EVENT(BaseEvent, event, sizeof(BaseEvent));
- if (event != NULL)
- {
- event->EventID = eventID | PARAM_COUNT(0);
- event->EventCount = (uint16_t)eventCounter;
- event->TS = prvGetTimestamp32();
- TRC_STREAM_PORT_COMMIT_EVENT(event, sizeof(BaseEvent));
- }
- }
- }
- TRACE_EXIT_CRITICAL_SECTION();
-}
-
-/* Store an event with one 32-bit parameter (pointer address or an int) */
-void prvTraceStoreEvent1(uint16_t eventID, uint32_t param1)
-{
- TRACE_ALLOC_CRITICAL_SECTION();
-
- PSF_ASSERT(eventID < 4096, PSF_ERROR_EVENT_CODE_TOO_LARGE);
-
- TRACE_ENTER_CRITICAL_SECTION();
-
- if (RecorderEnabled)
- {
- eventCounter++;
-
- {
- TRC_STREAM_PORT_ALLOCATE_EVENT(EventWithParam_1, event, sizeof(EventWithParam_1));
- if (event != NULL)
- {
- event->base.EventID = eventID | PARAM_COUNT(1);
- event->base.EventCount = (uint16_t)eventCounter;
- event->base.TS = prvGetTimestamp32();
- event->param1 = (uint32_t)param1;
- TRC_STREAM_PORT_COMMIT_EVENT(event, sizeof(EventWithParam_1));
- }
- }
- }
- TRACE_EXIT_CRITICAL_SECTION();
-}
-
-/* Store an event with two 32-bit parameters */
-void prvTraceStoreEvent2(uint16_t eventID, uint32_t param1, uint32_t param2)
-{
- TRACE_ALLOC_CRITICAL_SECTION();
-
- PSF_ASSERT(eventID < 4096, PSF_ERROR_EVENT_CODE_TOO_LARGE);
-
- TRACE_ENTER_CRITICAL_SECTION();
-
- if (RecorderEnabled)
- {
- eventCounter++;
-
- {
- TRC_STREAM_PORT_ALLOCATE_EVENT(EventWithParam_2, event, sizeof(EventWithParam_2));
- if (event != NULL)
- {
- event->base.EventID = eventID | PARAM_COUNT(2);
- event->base.EventCount = (uint16_t)eventCounter;
- event->base.TS = prvGetTimestamp32();
- event->param1 = (uint32_t)param1;
- event->param2 = param2;
- TRC_STREAM_PORT_COMMIT_EVENT(event, sizeof(EventWithParam_2));
- }
- }
- }
- TRACE_EXIT_CRITICAL_SECTION();
-}
-
-/* Store an event with three 32-bit parameters */
-void prvTraceStoreEvent3( uint16_t eventID,
- uint32_t param1,
- uint32_t param2,
- uint32_t param3)
-{
- TRACE_ALLOC_CRITICAL_SECTION();
-
- PSF_ASSERT(eventID < 4096, PSF_ERROR_EVENT_CODE_TOO_LARGE);
-
- TRACE_ENTER_CRITICAL_SECTION();
-
- if (RecorderEnabled)
- {
- eventCounter++;
-
- {
- TRC_STREAM_PORT_ALLOCATE_EVENT(EventWithParam_3, event, sizeof(EventWithParam_3));
- if (event != NULL)
- {
- event->base.EventID = eventID | PARAM_COUNT(3);
- event->base.EventCount = (uint16_t)eventCounter;
- event->base.TS = prvGetTimestamp32();
- event->param1 = (uint32_t)param1;
- event->param2 = param2;
- event->param3 = param3;
- TRC_STREAM_PORT_COMMIT_EVENT(event, sizeof(EventWithParam_3));
- }
- }
- }
- TRACE_EXIT_CRITICAL_SECTION();
-}
-
-/* Stores an event with <nParam> 32-bit integer parameters */
-void prvTraceStoreEvent(int nParam, uint16_t eventID, ...)
-{
- va_list vl;
- int i;
- TRACE_ALLOC_CRITICAL_SECTION();
-
- PSF_ASSERT(eventID < 4096, PSF_ERROR_EVENT_CODE_TOO_LARGE);
-
- TRACE_ENTER_CRITICAL_SECTION();
-
- if (RecorderEnabled)
- {
- int eventSize = (int)sizeof(BaseEvent) + nParam * (int)sizeof(uint32_t);
-
- eventCounter++;
-
- {
- TRC_STREAM_PORT_ALLOCATE_DYNAMIC_EVENT(largestEventType, event, eventSize);
- if (event != NULL)
- {
- event->base.EventID = eventID | (uint16_t)PARAM_COUNT(nParam);
- event->base.EventCount = (uint16_t)eventCounter;
- event->base.TS = prvGetTimestamp32();
-
- va_start(vl, eventID);
- for (i = 0; i < nParam; i++)
- {
- uint32_t* tmp = (uint32_t*) &(event->data[i]);
- *tmp = va_arg(vl, uint32_t);
- }
- va_end(vl);
-
- TRC_STREAM_PORT_COMMIT_EVENT(event, (uint32_t)eventSize);
- }
- }
- }
- TRACE_EXIT_CRITICAL_SECTION();
-}
-
-/* Stories an event with a string and <nParam> 32-bit integer parameters */
-void prvTraceStoreStringEvent(int nArgs, uint16_t eventID, const char* str, ...)
-{
- int len;
- va_list vl;
-
- for (len = 0; (str[len] != 0) && (len < 52); len++); /* empty loop */
-
- va_start(vl, str);
- prvTraceStoreStringEventHelper(nArgs, eventID, NULL, len, str, &vl);
- va_end(vl);
-}
-
-/* Internal common function for storing string events */
-static void prvTraceStoreStringEventHelper(int nArgs,
- uint16_t eventID,
- traceString userEvtChannel,
- int len,
- const char* str,
- va_list* vl)
-{
- int nWords;
- int nStrWords;
- int i;
- int offset = 0;
- TRACE_ALLOC_CRITICAL_SECTION();
-
- PSF_ASSERT(eventID < 4096, PSF_ERROR_EVENT_CODE_TOO_LARGE);
-
- /* The string length in multiples of 32 bit words (+1 for null character) */
- nStrWords = (len+1+3)/4;
-
- /* If a user event channel is specified, add in the list */
- if (userEvtChannel)
- nArgs++;
-
- offset = nArgs * 4;
-
- /* The total number of 32-bit words needed for the whole payload */
- nWords = nStrWords + nArgs;
-
- if (nWords > 15) /* if attempting to store more than 60 byte (= max) */
- {
- /* Truncate event if too large. The string characters are stored
- last, so usually only the string is truncated, unless there a lot
- of parameters... */
-
- /* Diagnostics ... */
- uint32_t bytesTruncated = (uint32_t)(nWords - 15) * 4;
-
- if (bytesTruncated > MaxBytesTruncated)
- {
- MaxBytesTruncated = bytesTruncated;
- }
-
- nWords = 15;
- len = 15 * 4 - offset;
- }
-
- TRACE_ENTER_CRITICAL_SECTION();
-
- if (RecorderEnabled)
- {
- int eventSize = (int)sizeof(BaseEvent) + nWords * (int)sizeof(uint32_t);
-
- eventCounter++;
-
- {
- TRC_STREAM_PORT_ALLOCATE_DYNAMIC_EVENT(largestEventType, event, eventSize);
- if (event != NULL)
- {
- uint32_t* data32;
- uint8_t* data8;
- event->base.EventID = (eventID) | (uint16_t)PARAM_COUNT(nWords);
- event->base.EventCount = (uint16_t)eventCounter;
- event->base.TS = prvGetTimestamp32();
-
- /* 32-bit write-pointer for the data argument */
- data32 = (uint32_t*) &(event->data[0]);
-
- for (i = 0; i < nArgs; i++)
- {
- if ((userEvtChannel != NULL) && (i == 0))
- {
- /* First, add the User Event Channel if not NULL */
- data32[i] = (uint32_t)userEvtChannel;
- }
- else
- {
- /* Add data arguments... */
- data32[i] = va_arg(*vl, uint32_t);
- }
- }
- data8 = (uint8_t*)&(event->data[0]);
- for (i = 0; i < len; i++)
- {
- data8[offset + i] = str[i];
- }
-
- if (len < (15 * 4 - offset))
- data8[offset + len] = 0; /* Only truncate if we don't fill up the buffer completely */
- TRC_STREAM_PORT_COMMIT_EVENT(event, (uint32_t)eventSize);
- }
- }
- }
-
- TRACE_EXIT_CRITICAL_SECTION();
-}
-
-/* Internal common function for storing string events without additional arguments */
-void prvTraceStoreSimpleStringEventHelper(traceString userEvtChannel,
- const char* str)
-{
- int len;
- int nWords;
- int nStrWords;
- int i;
- int nArgs = 0;
- int offset = 0;
- uint16_t eventID = PSF_EVENT_USER_EVENT;
- TRACE_ALLOC_CRITICAL_SECTION();
-
- PSF_ASSERT(eventID < 4096, PSF_ERROR_EVENT_CODE_TOO_LARGE);
-
- for (len = 0; (str[len] != 0) && (len < 52); len++); /* empty loop */
-
- /* The string length in multiples of 32 bit words (+1 for null character) */
- nStrWords = (len+1+3)/4;
-
- /* If a user event channel is specified, add in the list */
- if (userEvtChannel)
- {
- nArgs++;
- eventID++;
- }
-
- offset = nArgs * 4;
-
- /* The total number of 32-bit words needed for the whole payload */
- nWords = nStrWords + nArgs;
-
- if (nWords > 15) /* if attempting to store more than 60 byte (= max) */
- {
- /* Truncate event if too large. The string characters are stored
- last, so usually only the string is truncated, unless there a lot
- of parameters... */
-
- /* Diagnostics ... */
- uint32_t bytesTruncated = (uint32_t)(nWords - 15) * 4;
-
- if (bytesTruncated > MaxBytesTruncated)
- {
- MaxBytesTruncated = bytesTruncated;
- }
-
- nWords = 15;
- len = 15 * 4 - offset;
- }
-
- TRACE_ENTER_CRITICAL_SECTION();
-
- if (RecorderEnabled)
- {
- int eventSize = (int)sizeof(BaseEvent) + nWords * (int)sizeof(uint32_t);
-
- eventCounter++;
-
- {
- TRC_STREAM_PORT_ALLOCATE_DYNAMIC_EVENT(largestEventType, event, eventSize);
- if (event != NULL)
- {
- uint32_t* data32;
- uint8_t* data8;
- event->base.EventID = (eventID) | (uint16_t)PARAM_COUNT(nWords);
- event->base.EventCount = (uint16_t)eventCounter;
- event->base.TS = prvGetTimestamp32();
-
- /* 32-bit write-pointer for the data argument */
- data32 = (uint32_t*) &(event->data[0]);
-
- if (userEvtChannel != NULL)
- {
- /* First, add the User Event Channel if not NULL */
- data32[0] = (uint32_t)userEvtChannel;
- }
-
- data8 = (uint8_t*) &(event->data[0]);
- for (i = 0; i < len; i++)
- {
- data8[offset + i] = str[i];
- }
-
- if (len < (15 * 4 - offset))
- data8[offset + len] = 0; /* Only truncate if we don't fill up the buffer completely */
- TRC_STREAM_PORT_COMMIT_EVENT(event, (uint32_t)eventSize);
- }
- }
- }
-
- TRACE_EXIT_CRITICAL_SECTION();
-}
-
-/* Saves a symbol name (task name etc.) in symbol table */
-void prvTraceSaveSymbol(const void *address, const char *name)
-{
- uint32_t i;
- uint32_t foundSlot;
- uint32_t *ptrAddress;
- uint8_t *ptrSymbol;
- TRACE_ALLOC_CRITICAL_SECTION();
-
- TRACE_ENTER_CRITICAL_SECTION();
-
- foundSlot = firstFreeSymbolTableIndex;
-
- /* First look for previous entries using this address */
- for (i = 0; i < firstFreeSymbolTableIndex; i += SYMBOL_TABLE_SLOT_SIZE)
- {
- /* We access the symbol table via the union member pSymbolTableBufferUINT32 to avoid strict-aliasing issues */
- ptrAddress = &symbolTable.SymbolTableBuffer.pSymbolTableBufferUINT32[i / sizeof(uint32_t)];
- if (*ptrAddress == (uint32_t)address)
- {
- foundSlot = i;
- break;
- }
- }
-
- if (foundSlot < SYMBOL_TABLE_BUFFER_SIZE)
- {
- /* We access the symbol table via the union member pSymbolTableBufferUINT32 to avoid strict-aliasing issues */
- symbolTable.SymbolTableBuffer.pSymbolTableBufferUINT32[foundSlot / sizeof(uint32_t)] = (uint32_t)address;
-
- /* We access the symbol table via the union member pSymbolTableBufferUINT8 to avoid strict-aliasing issues */
- ptrSymbol = &symbolTable.SymbolTableBuffer.pSymbolTableBufferUINT8[foundSlot + sizeof(uint32_t)];
- for (i = 0; i < (TRC_CFG_SYMBOL_MAX_LENGTH); i++)
- {
- ptrSymbol[i] = (uint8_t)name[i]; /* We do this first to ensure we also get the 0 termination, if there is one */
-
- if (name[i] == 0)
- break;
- }
-
- /* Check the length of "name", if longer than SYMBOL_MAX_LENGTH */
- while ((name[i] != 0) && i < 128)
- {
- i++;
- }
-
- /* Remember the longest symbol name, for diagnostic purposes */
- if (i > LongestSymbolName)
- {
- LongestSymbolName = i;
- }
-
- /* Is this the last entry in the symbol table? */
- if (foundSlot == firstFreeSymbolTableIndex)
- {
- firstFreeSymbolTableIndex += SYMBOL_TABLE_SLOT_SIZE;
- }
- }
- else
- {
- NoRoomForSymbol++;
- }
-
- TRACE_EXIT_CRITICAL_SECTION();
-}
-
-/* Deletes a symbol name (task name etc.) from symbol table */
-void prvTraceDeleteSymbol(void *address)
-{
- uint32_t i, j;
- uint32_t *ptr, *lastEntryPtr;
- TRACE_ALLOC_CRITICAL_SECTION();
-
- TRACE_ENTER_CRITICAL_SECTION();
-
- for (i = 0; i < firstFreeSymbolTableIndex; i += SYMBOL_TABLE_SLOT_SIZE)
- {
- /* We access the symbol table via the union member pSymbolTableBufferUINT32 to avoid strict-aliasing issues */
- ptr = &symbolTable.SymbolTableBuffer.pSymbolTableBufferUINT32[i / sizeof(uint32_t)];
- if (*ptr == (uint32_t)address)
- {
- /* See if we have another entry in the table, and that this isn't already the last entry */
- if (firstFreeSymbolTableIndex > SYMBOL_TABLE_SLOT_SIZE && i != (firstFreeSymbolTableIndex - SYMBOL_TABLE_SLOT_SIZE))
- {
- /* Another entry is available, get pointer to the last one */
- /* We access the symbol table via the union member pSymbolTableBufferUINT32 to avoid strict-aliasing issues */
- lastEntryPtr = &symbolTable.SymbolTableBuffer.pSymbolTableBufferUINT32[(firstFreeSymbolTableIndex - SYMBOL_TABLE_SLOT_SIZE) / sizeof(uint32_t)];
-
- /* Copy last entry to this position */
- for (j = 0; j < (SYMBOL_TABLE_SLOT_SIZE) / sizeof(uint32_t); j++)
- {
- ptr[j] = lastEntryPtr[j];
- }
-
- /* For good measure we also zero out the original position */
- *lastEntryPtr = 0;
- }
- else
- *ptr = 0; /* No other entry found, or this is the last entry */
-
- /* Lower index */
- firstFreeSymbolTableIndex -= SYMBOL_TABLE_SLOT_SIZE;
-
- break;
- }
- }
-
- TRACE_EXIT_CRITICAL_SECTION();
-}
-
-/* Saves an object data entry (current task priority) in object data table */
-void prvTraceSaveObjectData(const void *address, uint32_t data)
-{
- uint32_t i;
- uint32_t foundSlot;
- uint32_t *ptr;
- TRACE_ALLOC_CRITICAL_SECTION();
-
- TRACE_ENTER_CRITICAL_SECTION();
-
- foundSlot = firstFreeObjectDataTableIndex;
-
- /* First look for previous entries using this address */
- for (i = 0; i < firstFreeObjectDataTableIndex; i += OBJECT_DATA_SLOT_SIZE)
- {
- /* We access the data table via the union member pObjectDataTableBufferUINT32 to avoid strict-aliasing issues */
- ptr = &objectDataTable.ObjectDataTableBuffer.pObjectDataTableBufferUINT32[i / sizeof(uint32_t)];
- if (*ptr == (uint32_t)address)
- {
- foundSlot = i;
- break;
- }
- }
-
- if (foundSlot < OBJECT_DATA_TABLE_BUFFER_SIZE)
- {
- /* We access the data table via the union member pObjectDataTableBufferUINT32 to avoid strict-aliasing issues */
- objectDataTable.ObjectDataTableBuffer.pObjectDataTableBufferUINT32[foundSlot / sizeof(uint32_t)] = (uint32_t)address;
- objectDataTable.ObjectDataTableBuffer.pObjectDataTableBufferUINT32[foundSlot / sizeof(uint32_t) + 1] = data;
-
- /* Is this the last entry in the object data table? */
- if (foundSlot == firstFreeObjectDataTableIndex)
- {
- firstFreeObjectDataTableIndex += OBJECT_DATA_SLOT_SIZE;
- }
- }
- else
- {
- NoRoomForObjectData++;
- }
-
- TRACE_EXIT_CRITICAL_SECTION();
-}
-
-/* Removes an object data entry (task base priority) from object data table */
-void prvTraceDeleteObjectData(void *address)
-{
- uint32_t i, j;
- uint32_t *ptr, *lastEntryPtr;
- TRACE_ALLOC_CRITICAL_SECTION();
-
- TRACE_ENTER_CRITICAL_SECTION();
-
- for (i = 0; i < firstFreeObjectDataTableIndex; i += OBJECT_DATA_SLOT_SIZE)
- {
- /* We access the data table via the union member pObjectDataTableBufferUINT32 to avoid strict-aliasing issues */
- ptr = &objectDataTable.ObjectDataTableBuffer.pObjectDataTableBufferUINT32[i / sizeof(uint32_t)];
- if (*ptr == (uint32_t)address)
- {
- /* See if we have another entry in the table, and that this isn't already the last entry */
- if (firstFreeObjectDataTableIndex > OBJECT_DATA_SLOT_SIZE && i != (firstFreeObjectDataTableIndex - OBJECT_DATA_SLOT_SIZE))
- {
- /* Another entry is available, get pointer to the last one */
- /* We access the data table via the union member pObjectDataTableBufferUINT32 to avoid strict-aliasing issues */
- lastEntryPtr = &objectDataTable.ObjectDataTableBuffer.pObjectDataTableBufferUINT32[(firstFreeObjectDataTableIndex - OBJECT_DATA_SLOT_SIZE) / sizeof(uint32_t)];
-
- /* Copy last entry to this position */
- for (j = 0; j < (OBJECT_DATA_SLOT_SIZE) / sizeof(uint32_t); j++)
- {
- ptr[j] = lastEntryPtr[j];
- }
-
- /* For good measure we also zero out the original position */
- *lastEntryPtr = 0;
- }
- else
- *ptr = 0; /* No other entry found, or this is the last entry */
-
- /* Lower index */
- firstFreeObjectDataTableIndex -= OBJECT_DATA_SLOT_SIZE;
-
- break;
- }
- }
-
- TRACE_EXIT_CRITICAL_SECTION();
-}
-
-/* Checks if the provided command is a valid command */
-int prvIsValidCommand(TracealyzerCommandType* cmd)
-{
- uint16_t checksum = (uint16_t)(0xFFFF - ( cmd->cmdCode +
- cmd->param1 +
- cmd->param2 +
- cmd->param3 +
- cmd->param4 +
- cmd->param5));
-
- if (cmd->checksumMSB != (unsigned char)(checksum >> 8))
- return 0;
-
- if (cmd->checksumLSB != (unsigned char)(checksum & 0xFF))
- return 0;
-
- if (cmd->cmdCode > CMD_LAST_COMMAND)
- return 0;
-
- return 1;
-}
-
-/* Executed the received command (Start or Stop) */
-void prvProcessCommand(TracealyzerCommandType* cmd)
-{
- switch(cmd->cmdCode)
- {
- case CMD_SET_ACTIVE:
- prvSetRecorderEnabled(cmd->param1);
- break;
- default:
- break;
- }
-}
-
-/* Called on warnings, when the recording can continue. */
-void prvTraceWarning(int errCode)
-{
- if (!errorCode)
- {
- errorCode = errCode;
- prvTraceStoreWarnings();
- }
-}
-
-/* Called on critical errors in the recorder. Stops the recorder! */
-void prvTraceError(int errCode)
-{
- if (! errorCode)
- {
- errorCode = errCode;
- prvTraceStoreWarnings();
- vTracePrintF(trcWarningChannel, "Recorder stopped in prvTraceError()");
-
- prvSetRecorderEnabled(0);
- }
-}
-
-/* If using DWT timestamping (default on ARM Cortex-M3, M4 and M7), make sure the DWT unit is initialized. */
-#ifndef TRC_CFG_ARM_CM_USE_SYSTICK
-#if ((TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_Cortex_M) && (defined (__CORTEX_M) && (__CORTEX_M >= 0x03)))
-
-void prvTraceInitCortexM()
-{
- /* Make sure the DWT registers are unlocked, in case the debugger doesn't do this. */
- TRC_REG_ITM_LOCKACCESS = TRC_ITM_LOCKACCESS_UNLOCK;
-
- /* Make sure DWT is enabled is enabled, if supported */
- TRC_REG_DEMCR |= TRC_DEMCR_TRCENA;
-
- do
- {
- /* Verify that DWT is supported */
- if (TRC_REG_DEMCR == 0)
- {
- /* This function is called on Cortex-M3, M4 and M7 devices to initialize
- the DWT unit, assumed present. The DWT cycle counter is used for timestamping.
-
- If the below error is produced, the DWT unit does not seem to be available.
-
- In that case, define the macro TRC_CFG_ARM_CM_USE_SYSTICK in your build
- to use SysTick timestamping instead, or define your own timestamping by
- setting TRC_CFG_HARDWARE_PORT to TRC_HARDWARE_PORT_APPLICATION_DEFINED
- and make the necessary definitions, as explained in trcHardwarePort.h.*/
-
- prvTraceError(PSF_ERROR_DWT_NOT_SUPPORTED);
- break;
- }
-
- /* Verify that DWT_CYCCNT is supported */
- if (TRC_REG_DWT_CTRL & TRC_DWT_CTRL_NOCYCCNT)
- {
- /* This function is called on Cortex-M3, M4 and M7 devices to initialize
- the DWT unit, assumed present. The DWT cycle counter is used for timestamping.
-
- If the below error is produced, the cycle counter does not seem to be available.
-
- In that case, define the macro TRC_CFG_ARM_CM_USE_SYSTICK in your build
- to use SysTick timestamping instead, or define your own timestamping by
- setting TRC_CFG_HARDWARE_PORT to TRC_HARDWARE_PORT_APPLICATION_DEFINED
- and make the necessary definitions, as explained in trcHardwarePort.h.*/
-
- prvTraceError(PSF_ERROR_DWT_CYCCNT_NOT_SUPPORTED);
- break;
- }
-
- /* Reset the cycle counter */
- TRC_REG_DWT_CYCCNT = 0;
-
- /* Enable the cycle counter */
- TRC_REG_DWT_CTRL |= TRC_DWT_CTRL_CYCCNTENA;
-
- } while(0); /* breaks above jump here */
-}
-#endif
-#endif
-
-/* Performs timestamping using definitions in trcHardwarePort.h */
-static uint32_t prvGetTimestamp32(void)
-{
-#if ((TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_INCR) || (TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_DECR))
- return TRC_HWTC_COUNT;
-#endif
-
-#if ((TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_INCR) || (TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_DECR))
- return TRC_HWTC_COUNT;
-#endif
-
-#if ((TRC_HWTC_TYPE == TRC_OS_TIMER_INCR) || (TRC_HWTC_TYPE == TRC_OS_TIMER_DECR))
- uint32_t ticks = TRACE_GET_OS_TICKS();
- return ((TRC_HWTC_COUNT) & 0x00FFFFFFU) + ((ticks & 0x000000FFU) << 24);
-#endif
-}
-
-/* Store the Timestamp Config event */
-static void prvTraceStoreTSConfig(void)
-{
- /* If not overridden using vTraceSetFrequency, use default value */
- if (timestampFrequency == 0)
- {
- timestampFrequency = TRC_HWTC_FREQ_HZ;
- }
-
- #if (TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_INCR || TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_DECR)
-
- prvTraceStoreEvent(5,
- PSF_EVENT_TS_CONFIG,
- (uint32_t)timestampFrequency,
- (uint32_t)(TRACE_TICK_RATE_HZ),
- (uint32_t)(TRC_HWTC_TYPE),
- (uint32_t)(TRC_CFG_ISR_TAILCHAINING_THRESHOLD),
- (uint32_t)(TRC_HWTC_PERIOD));
-
- #else
-
- prvTraceStoreEvent(4,
- PSF_EVENT_TS_CONFIG,
- (uint32_t)timestampFrequency,
- (uint32_t)(TRACE_TICK_RATE_HZ),
- (uint32_t)(TRC_HWTC_TYPE),
- (uint32_t)(TRC_CFG_ISR_TAILCHAINING_THRESHOLD));
- #endif
-}
-
-/* Retrieve a buffer page to write to. */
-static int prvAllocateBufferPage(int prevPage)
-{
- int index;
- int count = 0;
-
- index = (prevPage + 1) % (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT);
-
- while((PageInfo[index].Status != PAGE_STATUS_FREE) && (count ++ < (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT)))
- {
- index = (index + 1) % (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT);
- }
-
- if (PageInfo[index].Status == PAGE_STATUS_FREE)
- {
- return index;
- }
-
- return -1;
-}
-
-/* Mark the page read as complete. */
-static void prvPageReadComplete(int pageIndex)
-{
- TRACE_ALLOC_CRITICAL_SECTION();
-
- TRACE_ENTER_CRITICAL_SECTION();
- PageInfo[pageIndex].BytesRemaining = (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE);
- PageInfo[pageIndex].WritePointer = &EventBuffer[pageIndex * (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE)];
- PageInfo[pageIndex].Status = PAGE_STATUS_FREE;
-
- TotalBytesRemaining += (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE);
-
- TRACE_EXIT_CRITICAL_SECTION();
-}
-
-/* Get the current buffer page index and remaining number of bytes. */
-static int prvGetBufferPage(int32_t* bytesUsed)
-{
- static int8_t lastPage = -1;
- int count = 0;
- int8_t index = (int8_t) ((lastPage + 1) % (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT));
-
- while((PageInfo[index].Status != PAGE_STATUS_READ) && (count++ < (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT)))
- {
- index = (int8_t)((index + 1) % (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT));
- }
-
- if (PageInfo[index].Status == PAGE_STATUS_READ)
- {
- *bytesUsed = (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE) - PageInfo[index].BytesRemaining;
- lastPage = index;
- return index;
- }
-
- *bytesUsed = 0;
-
- return -1;
-}
-
-/*******************************************************************************
- * uint32_t prvPagedEventBufferTransfer(void)
- *
- * Transfers one buffer page of trace data, if a full page is available, using
- * the macro TRC_STREAM_PORT_WRITE_DATA as defined in trcStreamingPort.h.
- *
- * This function is intended to be called the periodic TzCtrl task with a suitable
- * delay (e.g. 10-100 ms).
- *
- * Returns the number of bytes sent. If non-zero, it is good to call this
- * again, in order to send any additional data waiting in the buffer.
- * If zero, wait a while before calling again.
- *
- * In case of errors from the streaming interface, it registers a warning
- * (PSF_WARNING_STREAM_PORT_WRITE) provided by xTraceGetLastError().
- *
- *******************************************************************************/
-uint32_t prvPagedEventBufferTransfer(void)
-{
- int8_t pageToTransfer = -1;
- int32_t bytesTransferredTotal = 0;
- int32_t bytesTransferredNow = 0;
- int32_t bytesToTransfer;
-
- pageToTransfer = (int8_t)prvGetBufferPage(&bytesToTransfer);
-
- /* bytesToTransfer now contains the number of "valid" bytes in the buffer page, that should be transmitted.
- There might be some unused junk bytes in the end, that must be ignored. */
-
- if (pageToTransfer > -1)
- {
- while (1) /* Keep going until we have transferred all that we intended to */
- {
- if (TRC_STREAM_PORT_WRITE_DATA(
- &EventBuffer[pageToTransfer * (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE) + bytesTransferredTotal],
- (uint32_t)(bytesToTransfer - bytesTransferredTotal),
- &bytesTransferredNow) == 0)
- {
- /* Write was successful. Update the number of transferred bytes. */
- bytesTransferredTotal += bytesTransferredNow;
-
- if (bytesTransferredTotal == bytesToTransfer)
- {
- /* All bytes have been transferred. Mark the buffer page as "Read Complete" (so it can be written to) and return OK. */
- prvPageReadComplete(pageToTransfer);
- return (uint32_t)bytesTransferredTotal;
- }
- }
- else
- {
- /* Some error from the streaming interface... */
- prvTraceWarning(PSF_WARNING_STREAM_PORT_WRITE);
- return 0;
- }
- }
- }
- return 0;
-}
-
-/*******************************************************************************
- * void* prvPagedEventBufferGetWritePointer(int sizeOfEvent)
- *
- * Returns a pointer to an available location in the buffer able to store the
- * requested size.
- *
- * Return value: The pointer.
- *
- * Parameters:
- * - sizeOfEvent: The size of the event that is to be placed in the buffer.
- *
-*******************************************************************************/
-void* prvPagedEventBufferGetWritePointer(int sizeOfEvent)
-{
- void* ret;
- static int currentWritePage = -1;
-
- if (currentWritePage == -1)
- {
- currentWritePage = prvAllocateBufferPage(currentWritePage);
- if (currentWritePage == -1)
- {
- DroppedEventCounter++;
- return NULL;
- }
- }
-
- if (PageInfo[currentWritePage].BytesRemaining - sizeOfEvent < 0)
- {
- PageInfo[currentWritePage].Status = PAGE_STATUS_READ;
-
- TotalBytesRemaining -= PageInfo[currentWritePage].BytesRemaining; // Last trailing bytes
-
- if (TotalBytesRemaining < TotalBytesRemaining_LowWaterMark)
- TotalBytesRemaining_LowWaterMark = TotalBytesRemaining;
-
- currentWritePage = prvAllocateBufferPage(currentWritePage);
- if (currentWritePage == -1)
- {
- DroppedEventCounter++;
- return NULL;
- }
- }
- ret = PageInfo[currentWritePage].WritePointer;
- PageInfo[currentWritePage].WritePointer += sizeOfEvent;
- PageInfo[currentWritePage].BytesRemaining = (uint16_t)(PageInfo[currentWritePage].BytesRemaining -sizeOfEvent);
-
- TotalBytesRemaining = (TotalBytesRemaining-(uint16_t)sizeOfEvent);
-
- if (TotalBytesRemaining < TotalBytesRemaining_LowWaterMark)
- TotalBytesRemaining_LowWaterMark = TotalBytesRemaining;
-
- return ret;
-}
-
-/*******************************************************************************
- * void prvPagedEventBufferInit(char* buffer)
- *
- * Assigns the buffer to use and initializes the PageInfo structure.
- *
- * Return value: void
- *
- * Parameters:
- * - char* buffer: pointer to the trace data buffer, allocated by the caller.
- *
-*******************************************************************************/
-void prvPagedEventBufferInit(char* buffer)
-{
- int i;
- TRACE_ALLOC_CRITICAL_SECTION();
-
- EventBuffer = buffer;
-
- TRACE_ENTER_CRITICAL_SECTION();
- for (i = 0; i < (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT); i++)
- {
- PageInfo[i].BytesRemaining = (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE);
- PageInfo[i].WritePointer = &EventBuffer[i * (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE)];
- PageInfo[i].Status = PAGE_STATUS_FREE;
- }
- TRACE_EXIT_CRITICAL_SECTION();
-
-}
-
-#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/
-
-#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/
+/*******************************************************************************
+ * Trace Recorder Library for Tracealyzer v4.3.11
+ * Percepio AB, www.percepio.com
+ *
+ * trcStreamingRecorder.c
+ *
+ * The generic core of the trace recorder's streaming mode.
+ *
+ * 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
+ ******************************************************************************/
+
+#include "trcRecorder.h"
+
+#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
+
+#if (TRC_USE_TRACEALYZER_RECORDER == 1)
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+
+#include "trcExtensions.h"
+
+uint32_t trcHeapCounter = 0;
+
+typedef struct{
+ uint16_t EventID;
+ uint16_t EventCount;
+ uint32_t TS;
+} BaseEvent;
+
+typedef struct{
+ BaseEvent base;
+ uint32_t param1;
+} EventWithParam_1;
+
+typedef struct{
+ BaseEvent base;
+ uint32_t param1;
+ uint32_t param2;
+} EventWithParam_2;
+
+typedef struct{
+ BaseEvent base;
+ uint32_t param1;
+ uint32_t param2;
+ uint32_t param3;
+} EventWithParam_3;
+
+typedef struct{
+ BaseEvent base;
+ uint32_t param1;
+ uint32_t param2;
+ uint32_t param3;
+ uint32_t param4;
+} EventWithParam_4;
+
+typedef struct{
+ BaseEvent base;
+ uint32_t param1;
+ uint32_t param2;
+ uint32_t param3;
+ uint32_t param4;
+ uint32_t param5;
+} EventWithParam_5;
+
+/* Used in event functions with variable number of parameters. */
+typedef struct
+{
+ BaseEvent base;
+ uint32_t data[15]; /* maximum payload size */
+} largestEventType;
+
+typedef struct{
+ uint32_t psf;
+ uint16_t version;
+ uint16_t platform;
+ uint32_t options;
+ uint32_t heapCounter;
+ uint16_t symbolSize;
+ uint16_t symbolCount;
+ uint16_t objectDataSize;
+ uint16_t objectDataCount;
+} PSFHeaderInfo;
+
+
+/* The size of each slot in the Symbol Table */
+#define SYMBOL_TABLE_SLOT_SIZE (sizeof(uint32_t) + (((TRC_CFG_SYMBOL_MAX_LENGTH)+(sizeof(uint32_t)-1))/sizeof(uint32_t))*sizeof(uint32_t))
+
+#define OBJECT_DATA_SLOT_SIZE (sizeof(uint32_t) + sizeof(uint32_t))
+
+/* The total size of the Symbol Table */
+#define SYMBOL_TABLE_BUFFER_SIZE ((TRC_CFG_SYMBOL_TABLE_SLOTS) * SYMBOL_TABLE_SLOT_SIZE)
+
+/* The total size of the Object Data Table */
+#define OBJECT_DATA_TABLE_BUFFER_SIZE ((TRC_CFG_OBJECT_DATA_SLOTS) * OBJECT_DATA_SLOT_SIZE)
+
+#if (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT > 128)
+#error "TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT cannot be larger than 128"
+#endif /* (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT > 128) */
+
+/* The Symbol Table type - just a byte array */
+typedef struct{
+ union
+ {
+ uint32_t pSymbolTableBufferUINT32[SYMBOL_TABLE_BUFFER_SIZE / sizeof(uint32_t)];
+ uint8_t pSymbolTableBufferUINT8[SYMBOL_TABLE_BUFFER_SIZE];
+ } SymbolTableBuffer;
+} SymbolTable;
+
+/* The Object Data Table type - just a byte array */
+typedef struct{
+ union
+ {
+ uint32_t pObjectDataTableBufferUINT32[OBJECT_DATA_TABLE_BUFFER_SIZE / sizeof(uint32_t)];
+ uint8_t pObjectDataTableBufferUINT8[OBJECT_DATA_TABLE_BUFFER_SIZE];
+ } ObjectDataTableBuffer;
+} ObjectDataTable;
+
+typedef struct{
+ uint16_t Status; /* 16 bit to avoid implicit padding (warnings) */
+ uint16_t BytesRemaining;
+ char* WritePointer;
+} PageType;
+
+/* Code used for "task address" when no task has started, to indicate "(startup)".
+ * This value was used since NULL/0 was already reserved for the idle task. */
+#define HANDLE_NO_TASK 2
+
+/* The status codes for the pages of the internal trace buffer. */
+#define PAGE_STATUS_FREE 0
+#define PAGE_STATUS_WRITE 1
+#define PAGE_STATUS_READ 2
+
+/* Calls prvTraceError if the _assert condition is false. For void functions,
+where no return value is to be provided. */
+#define PSF_ASSERT_VOID(_assert, _err) if (! (_assert)){ prvTraceError(_err); return; }
+
+/* Calls prvTraceError if the _assert condition is false. For non-void functions,
+where a return value is to be provided. */
+#define PSF_ASSERT_RET(_assert, _err, _return) if (! (_assert)){ prvTraceError(_err); return _return; }
+
+/* Part of the PSF format - encodes the number of 32-bit params in an event */
+#define PARAM_COUNT(n) ((n & 0xF) << 12)
+
+/* We skip the slot for PSF_ERROR_NONE so error code 1 is the first bit */
+#define GET_ERROR_WARNING_FLAG(errCode) (ErrorAndWarningFlags & (1 << ((errCode) - 1)))
+#define SET_ERROR_WARNING_FLAG(errCode) (ErrorAndWarningFlags |= (1 << ((errCode) - 1)))
+
+/* Used for flags indicating if a certain error or warning has occurred */
+static uint32_t ErrorAndWarningFlags = 0;
+
+/* The Symbol Table instance - keeps names of tasks and other named objects. */
+static SymbolTable symbolTable = { { { 0 } } };
+
+/* This points to the first unused entry in the symbol table. */
+static uint32_t firstFreeSymbolTableIndex = 0;
+
+/* The Object Data Table instance - keeps initial priorities of tasks. */
+static ObjectDataTable objectDataTable = { { { 0 } } };
+
+/* This points to the first unused entry in the object data table. */
+static uint32_t firstFreeObjectDataTableIndex = 0;
+
+/* Keeps track of ISR nesting */
+static uint32_t ISR_stack[TRC_CFG_MAX_ISR_NESTING];
+
+/* Keeps track of ISR nesting */
+static int8_t ISR_stack_index = -1;
+
+/* Any error that occurred in the recorder (also creates User Event) */
+static int errorCode = PSF_ERROR_NONE;
+
+/* Counts the number of trace sessions (not yet used) */
+static uint32_t SessionCounter = 0u;
+
+/* Master switch for recording (0 => Disabled, 1 => Enabled) */
+uint32_t RecorderEnabled = 0u;
+
+/* Used to determine endian of data (big/little) */
+static uint32_t PSFEndianessIdentifier = 0x50534600;
+
+/* Used to interpret the data format */
+static uint16_t FormatVersion = 0x0006;
+
+/* The number of events stored. Used as event sequence number. */
+static uint32_t eventCounter = 0;
+
+/* Remembers if an earlier ISR in a sequence of adjacent ISRs has triggered a task switch.
+In that case, vTraceStoreISREnd does not store a return to the previously executing task. */
+int32_t isPendingContextSwitch = 0;
+
+uint32_t uiTraceTickCount = 0;
+uint32_t timestampFrequency = 0;
+uint32_t DroppedEventCounter = 0;
+uint32_t TotalBytesRemaining_LowWaterMark = (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT) * (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE);
+uint32_t TotalBytesRemaining = (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT) * (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE);
+
+PageType PageInfo[TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT];
+
+char* EventBuffer = NULL;
+
+PSFExtensionInfoType PSFExtensionInfo = TRC_EXTENSION_INFO;
+
+/*******************************************************************************
+ * NoRoomForSymbol
+ *
+ * Incremented on prvTraceSaveSymbol if no room for saving the symbol name. This
+ * is used for storing the names of:
+ * - Tasks
+ * - Named ISRs (xTraceSetISRProperties)
+ * - Named kernel objects (vTraceStoreKernelObjectName)
+ * - User event channels (xTraceRegisterString)
+ *
+ * This variable should be zero. If not, it shows the number of missing slots so
+ * far. In that case, increment SYMBOL_TABLE_SLOTS with (at least) this value.
+ ******************************************************************************/
+volatile uint32_t NoRoomForSymbol = 0;
+
+/*******************************************************************************
+ * NoRoomForObjectData
+ *
+ * Incremented on prvTraceSaveObjectData if no room for saving the object data,
+ * i.e., the base priorities of tasks. There must be one slot for each task.
+ * If not, this variable will show the difference.
+ *
+ * This variable should be zero. If not, it shows the number of missing slots so
+ * far. In that case, increment OBJECT_DATA_SLOTS with (at least) this value.
+ ******************************************************************************/
+volatile uint32_t NoRoomForObjectData = 0;
+
+/*******************************************************************************
+ * LongestSymbolName
+ *
+ * Updated in prvTraceSaveSymbol. Should not exceed TRC_CFG_SYMBOL_MAX_LENGTH,
+ * otherwise symbol names will be truncated. In that case, set
+ * TRC_CFG_SYMBOL_MAX_LENGTH to (at least) this value.
+ ******************************************************************************/
+volatile uint32_t LongestSymbolName = 0;
+
+/*******************************************************************************
+ * MaxBytesTruncated
+ *
+ * Set in prvTraceStoreStringEvent if the total data payload exceeds 60 bytes,
+ * including data arguments and the string. For user events, that is 52 bytes
+ * for string and data arguments. In that is exceeded, the event is truncated
+ * (usually only the string, unless more than 15 parameters) and this variable
+ * holds the maximum number of truncated bytes, from any event.
+ ******************************************************************************/
+volatile uint32_t MaxBytesTruncated = 0;
+
+uint16_t CurrentFilterMask = 0xFFFF;
+
+uint16_t CurrentFilterGroup = FilterGroup0;
+
+volatile uint32_t uiTraceSystemState = TRC_STATE_IN_STARTUP;
+
+/* Internal common function for storing string events */
+static void prvTraceStoreStringEventHelper( int nArgs,
+ uint16_t eventID,
+ traceString userEvtChannel,
+ int len,
+ const char* str,
+ va_list vl);
+
+/* Not static to avoid warnings from SysGCC/PPC */
+void prvTraceStoreSimpleStringEventHelper(uint16_t eventID,
+ traceString userEvtChannel,
+ const char* str);
+
+/* Stores the header information on Start */
+static void prvTraceStoreHeader(void);
+
+/* Stores the Start Event */
+static void prvTraceStoreStartEvent(void);
+
+/* Stores the symbol table on Start */
+static void prvTraceStoreSymbolTable(void);
+
+/* Stores the object table on Start */
+static void prvTraceStoreObjectDataTable(void);
+
+/* Store the Timestamp Config on Start */
+static void prvTraceStoreTSConfig(void);
+
+/* Store information about trace library extensions. */
+static void prvTraceStoreExtensionInfo(void);
+
+/* Internal function for starting/stopping the recorder. */
+static void prvSetRecorderEnabled(uint32_t isEnabled);
+
+/* Mark the page read as complete. */
+static void prvPageReadComplete(int pageIndex);
+
+/* Retrieve a buffer page to write to. */
+static int prvAllocateBufferPage(int prevPage);
+
+/* Get the current buffer page index (return value) and the number
+of valid bytes in the buffer page (bytesUsed). */
+static int prvGetBufferPage(int32_t* bytesUsed);
+
+/* Performs timestamping using definitions in trcHardwarePort.h */
+static uint32_t prvGetTimestamp32(void);
+
+/* Returns the string associated with the error code */
+static const char* prvTraceGetError(int errCode);
+
+/* Signal an error. */
+void prvTraceError(int errCode);
+
+/* Signal a warning (does not stop the recorder). */
+void prvTraceWarning(int errCode);
+
+/******************************************************************************
+ * vTraceInstanceFinishedNow
+ *
+ * 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)
+{
+ prvTraceStoreEvent0(PSF_EVENT_IFE_DIRECT);
+}
+
+/******************************************************************************
+ * 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)
+{
+ prvTraceStoreEvent0(PSF_EVENT_IFE_NEXT);
+}
+
+/*******************************************************************************
+ * vTraceStoreKernelObjectName
+ *
+ * Parameter object: pointer to the Event Group that shall be named
+ * Parameter name: the name to set (const string literal)
+ *
+ * Sets a name for a kernel object for display in Tracealyzer.
+ ******************************************************************************/
+void vTraceStoreKernelObjectName(void* object, const char* name)
+{
+ uint16_t eventID = PSF_EVENT_OBJ_NAME;
+
+ PSF_ASSERT_VOID(eventID < 4096, PSF_ERROR_EVENT_CODE_TOO_LARGE);
+
+ /* Always save in symbol table, in case the recording has not yet started */
+ prvTraceSaveObjectSymbol(object, name);
+
+ prvTraceStoreStringEvent(1, eventID, name, object);
+}
+
+
+/******************************************************************************
+* 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.
+*****************************************************************************/
+void vTraceSetFrequency(uint32_t frequency)
+{
+ timestampFrequency = frequency;
+}
+
+#if (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)
+
+/*******************************************************************************
+* xTraceRegisterString
+*
+* Stores a name for a user event channel, returns the handle.
+******************************************************************************/
+traceString xTraceRegisterString(const char* name)
+{
+ traceString str;
+ uint16_t eventID = PSF_EVENT_OBJ_NAME;
+
+ str = prvTraceSaveSymbol(name);
+
+ PSF_ASSERT_RET(eventID < 4096, PSF_ERROR_EVENT_CODE_TOO_LARGE, str);
+
+ /* Always save in symbol table, if the recording has not yet started */
+ prvTraceStoreStringEvent(1, eventID, (const char*)name, str);
+
+ return str;
+}
+
+/******************************************************************************
+ * vTracePrint
+ *
+ * Generates "User Events", with unformatted text.
+ *
+ * User Events can be used for very efficient application logging, and are shown
+ * as yellow labels in the main trace view.
+ *
+ * You may group User Events into User Event Channels. The yellow User Event
+ * labels shows the logged string, preceded by the channel name within
+ * brackets. For 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 chn = xTraceRegisterString("MyChannel");
+ * ...
+ * vTracePrint(chn, "Hello World!");
+ *
+ ******************************************************************************/
+void vTracePrint(traceString chn, const char* str)
+{
+ uint16_t eventID = PSF_EVENT_USER_EVENT;
+ PSF_ASSERT_VOID(eventID < 4096, PSF_ERROR_EVENT_CODE_TOO_LARGE);
+
+ prvTraceStoreSimpleStringEventHelper(eventID, chn, str);
+}
+
+/*******************************************************************************
+* 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);
+******************************************************************************/
+void vTraceConsoleChannelPrintF(const char* fmt, ...)
+{
+ va_list vl;
+ char tempBuf[60];
+ static traceString consoleChannel = NULL;
+
+ if (consoleChannel == NULL)
+ consoleChannel = xTraceRegisterString("Debug Console");
+
+ va_start(vl, fmt);
+ vsnprintf(tempBuf, 60, fmt, vl);
+ vTracePrint(consoleChannel, tempBuf);
+ va_end(vl);
+}
+
+/******************************************************************************
+ * vTracePrintF
+ *
+ * Generates "User Events", with formatted text and data, similar to a "printf".
+ * It is very fast since the actual formatting is done on the host side when the
+ * trace is displayed.
+ *
+ * User Events can be used for very efficient application logging, and are shown
+ * as yellow labels in the main trace view.
+ * 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);
+ *
+ * All data arguments are assumed to be 32 bit wide. The following formats are
+ * supported:
+ * %d - signed integer. The following width and padding format is supported: "%05d" -> "-0042" and "%5d" -> " -42"
+ * %u - unsigned integer. The following width and padding format is supported: "%05u" -> "00042" and "%5u" -> " 42"
+ * %X - hexadecimal (uppercase). The following width and padding format is supported: "%04X" -> "002A" and "%4X" -> " 2A"
+ * %x - hexadecimal (lowercase). The following width and padding format is supported: "%04x" -> "002a" and "%4x" -> " 2a"
+ * %s - string (currently, this must be an earlier stored symbol name)
+ *
+ * Up to 15 data arguments are allowed, with a total size of maximum 60 byte
+ * including 8 byte for the base event fields and the format string. So with
+ * one data argument, the maximum string length is 48 chars. If this is exceeded
+ * the string is truncated (4 bytes at a time).
+ *
+ ******************************************************************************/
+void vTracePrintF(traceString chn, const char* fmt, ...)
+{
+ va_list vl;
+
+ va_start(vl, fmt);
+ vTraceVPrintF(chn, fmt, vl);
+ va_end(vl);
+}
+
+/******************************************************************************
+ * vTraceVPrintF
+ *
+ * vTracePrintF variant that accepts a va_list.
+ * See vTracePrintF documentation for further details.
+ *
+ ******************************************************************************/
+void vTraceVPrintF(traceString chn, const char* fmt, va_list vl)
+{
+ int i = 0;
+ int nArgs = 0;
+ int eventID = PSF_EVENT_USER_EVENT;
+
+ /* Count the number of arguments in the format string (e.g., %d) */
+ for (i = 0; (fmt[i] != 0) && (i < 52); i++)
+ {
+ if (fmt[i] == '%')
+ {
+ if (fmt[i + 1] == 0)
+ {
+ /* Found end of string, let for loop detect it */
+ continue;
+ }
+
+ if (fmt[i + 1] != '%')
+ {
+ nArgs++; /* Found an argument */
+ }
+
+ i++; /* Move past format specifier or non-argument '%' */
+ }
+ }
+
+ if (chn != NULL)
+ {
+ /* Make room for the channel */
+ nArgs++;
+ }
+ eventID += nArgs;
+
+ PSF_ASSERT_VOID(eventID < 4096, PSF_ERROR_EVENT_CODE_TOO_LARGE);
+
+ prvTraceStoreStringEventHelper(nArgs, (uint16_t)eventID, chn, i, fmt, vl);
+}
+#endif /* (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) */
+
+/*******************************************************************************
+ * 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)
+{
+ traceHandle isrHandle;
+ uint16_t eventID = PSF_EVENT_DEFINE_ISR;
+
+ /* Always save in symbol table, in case the recording has not yet started */
+ isrHandle = prvTraceSaveSymbol(name);
+
+ /* Save object data in object data table */
+ prvTraceSaveObjectData((void*)isrHandle, priority);
+
+ PSF_ASSERT_RET(eventID < 4096, PSF_ERROR_EVENT_CODE_TOO_LARGE, isrHandle);
+
+ prvTraceStoreStringEvent(2, eventID, name, isrHandle, priority);
+
+ return isrHandle;
+}
+
+/*******************************************************************************
+ * 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)
+{
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ TRACE_ENTER_CRITICAL_SECTION();
+
+ /* We are at the start of a possible ISR chain.
+ No context switches should have been triggered now. */
+ if (ISR_stack_index == -1)
+ isPendingContextSwitch = 0;
+
+ if (ISR_stack_index < (TRC_CFG_MAX_ISR_NESTING) - 1)
+ {
+ ISR_stack_index++;
+ ISR_stack[ISR_stack_index] = (uint32_t)handle;
+#if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
+ prvTraceStoreEvent1(PSF_EVENT_ISR_BEGIN, (uint32_t)handle);
+#endif
+ TRACE_EXIT_CRITICAL_SECTION();
+ }
+ else
+ {
+ TRACE_EXIT_CRITICAL_SECTION();
+ prvTraceError(PSF_ERROR_ISR_NESTING_OVERFLOW);
+ }
+}
+
+/*******************************************************************************
+ * 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)
+{
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ TRACE_ENTER_CRITICAL_SECTION();
+
+ (void)ISR_stack;
+
+ /* Is there a pending task-switch? (perhaps from an earlier ISR) */
+ isPendingContextSwitch |= isTaskSwitchRequired;
+
+ if (ISR_stack_index > 0)
+ {
+ ISR_stack_index--;
+
+#if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
+ /* Store return to interrupted ISR (if nested ISRs)*/
+ prvTraceStoreEvent1(PSF_EVENT_ISR_RESUME, (uint32_t)ISR_stack[ISR_stack_index]);
+#endif
+ }
+ else
+ {
+ ISR_stack_index--;
+
+ /* Store return to interrupted task, if no context switch will occur in between. */
+ if ((isPendingContextSwitch == 0) || (prvTraceIsSchedulerSuspended()))
+ {
+#if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
+ prvTraceStoreEvent1(PSF_EVENT_TS_RESUME, (uint32_t)TRACE_GET_CURRENT_TASK());
+#endif
+ }
+ }
+
+ TRACE_EXIT_CRITICAL_SECTION();
+}
+
+/*******************************************************************************
+ * xTraceGetLastError
+ *
+ * Returns the last error or warning, as a string, or NULL if none.
+ *****************************************************************************/
+const char* xTraceGetLastError(void)
+{
+ return prvTraceGetError(errorCode);
+}
+
+/*******************************************************************************
+ * vTraceClearError
+ *
+ * Clears any errors.
+ *****************************************************************************/
+void vTraceClearError(void)
+{
+ NoRoomForSymbol = 0;
+ LongestSymbolName = 0;
+ NoRoomForObjectData = 0;
+ MaxBytesTruncated = 0;
+ errorCode = PSF_ERROR_NONE;
+}
+
+/*******************************************************************************
+ * vTraceStop
+ *
+ * Stops the tracing.
+ *****************************************************************************/
+void vTraceStop(void)
+{
+ prvSetRecorderEnabled(0);
+}
+
+/*******************************************************************************
+ * vTraceSetRecorderDataBuffer
+ *
+ * If custom allocation is used, this function must be called so the recorder
+ * library knows where to save the trace data.
+ ******************************************************************************/
+#if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM)
+
+extern char* _TzTraceData;
+
+void vTraceSetRecorderDataBuffer(void* pRecorderData)
+{
+ _TzTraceData = pRecorderData;
+}
+#endif
+
+
+/*******************************************************************************
+* xTraceIsRecordingEnabled
+* Returns true (1) if the recorder is enabled (i.e. is recording), otherwise 0.
+******************************************************************************/
+int xTraceIsRecordingEnabled(void)
+{
+ return (int)RecorderEnabled;
+}
+
+void vTraceSetFilterMask(uint16_t filterMask)
+{
+ CurrentFilterMask = filterMask;
+}
+
+void vTraceSetFilterGroup(uint16_t filterGroup)
+{
+ CurrentFilterGroup = filterGroup;
+}
+
+
+/******************************************************************************/
+/*** INTERNAL FUNCTIONS *******************************************************/
+/******************************************************************************/
+
+/* Internal function for starting/stopping the recorder. */
+static void prvSetRecorderEnabled(uint32_t isEnabled)
+{
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ if (RecorderEnabled == isEnabled)
+ {
+ return;
+ }
+
+ TRACE_ENTER_CRITICAL_SECTION();
+
+ if (isEnabled)
+ {
+ TRC_STREAM_PORT_ON_TRACE_BEGIN();
+
+ #if (TRC_STREAM_PORT_USE_INTERNAL_BUFFER == 1)
+ prvPagedEventBufferInit(_TzTraceData);
+ #endif
+
+ eventCounter = 0;
+ ISR_stack_index = -1;
+ prvTraceStoreHeader();
+ prvTraceStoreSymbolTable();
+ prvTraceStoreObjectDataTable();
+ prvTraceStoreExtensionInfo();
+ prvTraceStoreStartEvent();
+ prvTraceStoreTSConfig();
+ }
+ else
+ {
+ TRC_STREAM_PORT_ON_TRACE_END();
+ }
+
+ RecorderEnabled = isEnabled;
+
+ TRACE_EXIT_CRITICAL_SECTION();
+}
+
+static void prvTraceStoreStartEvent()
+{
+ void* currentTask;
+
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ TRACE_ENTER_CRITICAL_SECTION();
+
+ if (uiTraceSystemState == TRC_STATE_IN_STARTUP)
+ {
+ currentTask = (void*)HANDLE_NO_TASK;
+ }
+ else
+ {
+ currentTask = TRACE_GET_CURRENT_TASK();
+ }
+
+ eventCounter++;
+
+ {
+ TRC_STREAM_PORT_ALLOCATE_EVENT_BLOCKING(EventWithParam_3, pxEvent, sizeof(EventWithParam_3));
+ if (pxEvent != NULL)
+ {
+ pxEvent->base.EventID = PSF_EVENT_TRACE_START | PARAM_COUNT(3);
+ pxEvent->base.EventCount = (uint16_t)eventCounter;
+ pxEvent->base.TS = prvGetTimestamp32();
+ pxEvent->param1 = (uint32_t)TRACE_GET_OS_TICKS();
+ pxEvent->param2 = (uint32_t)currentTask;
+ pxEvent->param3 = SessionCounter++;
+ TRC_STREAM_PORT_COMMIT_EVENT_BLOCKING(pxEvent, sizeof(EventWithParam_3));
+ }
+ }
+
+ TRACE_EXIT_CRITICAL_SECTION();
+}
+
+/* Store the Timestamp Config event */
+static void prvTraceStoreTSConfig(void)
+{
+ /* If not overridden using vTraceSetFrequency, use default value */
+ if (timestampFrequency == 0)
+ {
+ timestampFrequency = TRC_HWTC_FREQ_HZ;
+ }
+
+ eventCounter++;
+
+
+ {
+#if (TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_INCR || TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_DECR)
+
+ TRC_STREAM_PORT_ALLOCATE_EVENT_BLOCKING(EventWithParam_5, event, sizeof(EventWithParam_5));
+ if (event != NULL)
+ {
+ event->base.EventID = PSF_EVENT_TS_CONFIG | (uint16_t)PARAM_COUNT(5);
+ event->base.EventCount = (uint16_t)eventCounter;
+ event->base.TS = prvGetTimestamp32();
+
+ event->param1 = (uint32_t)timestampFrequency;
+ event->param2 = (uint32_t)(TRACE_TICK_RATE_HZ);
+ event->param3 = (uint32_t)(TRC_HWTC_TYPE);
+ event->param4 = (uint32_t)(TRC_CFG_ISR_TAILCHAINING_THRESHOLD);
+ event->param5 = (uint32_t)(TRC_HWTC_PERIOD);
+ TRC_STREAM_PORT_COMMIT_EVENT_BLOCKING(event, (uint32_t)sizeof(EventWithParam_5));
+ }
+#else
+ TRC_STREAM_PORT_ALLOCATE_EVENT_BLOCKING(EventWithParam_4, event, sizeof(EventWithParam_4));
+ if (event != NULL)
+ {
+ event->base.EventID = PSF_EVENT_TS_CONFIG | (uint16_t)PARAM_COUNT(4);
+ event->base.EventCount = (uint16_t)eventCounter;
+ event->base.TS = prvGetTimestamp32();
+
+ event->param1 = (uint32_t)timestampFrequency;
+ event->param2 = (uint32_t)(TRACE_TICK_RATE_HZ);
+ event->param3 = (uint32_t)(TRC_HWTC_TYPE);
+ event->param4 = (uint32_t)(TRC_CFG_ISR_TAILCHAINING_THRESHOLD);
+ TRC_STREAM_PORT_COMMIT_EVENT_BLOCKING(event, (uint32_t)sizeof(EventWithParam_4));
+ }
+#endif
+
+ }
+}
+
+/* Stores the symbol table on Start */
+static void prvTraceStoreSymbolTable(void)
+{
+ uint32_t i = 0;
+ uint32_t j = 0;
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ TRACE_ENTER_CRITICAL_SECTION();
+
+ {
+ for (i = 0; i < (sizeof(SymbolTable) / sizeof(uint32_t)); i += (SYMBOL_TABLE_SLOT_SIZE / sizeof(uint32_t)))
+ {
+ TRC_STREAM_PORT_ALLOCATE_EVENT_BLOCKING(uint32_t, data, SYMBOL_TABLE_SLOT_SIZE);
+
+ for (j = 0; j < (SYMBOL_TABLE_SLOT_SIZE / sizeof(uint32_t)); j++)
+ {
+ data[j] = symbolTable.SymbolTableBuffer.pSymbolTableBufferUINT32[i+j];
+ }
+
+ TRC_STREAM_PORT_COMMIT_EVENT_BLOCKING(data, SYMBOL_TABLE_SLOT_SIZE);
+ }
+ }
+ TRACE_EXIT_CRITICAL_SECTION();
+}
+
+/* Stores the object table on Start */
+static void prvTraceStoreObjectDataTable(void)
+{
+ uint32_t i = 0;
+ uint32_t j = 0;
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ TRACE_ENTER_CRITICAL_SECTION();
+
+ {
+ for (i = 0; i < (sizeof(ObjectDataTable) / sizeof(uint32_t)); i += (OBJECT_DATA_SLOT_SIZE / sizeof(uint32_t)))
+ {
+ TRC_STREAM_PORT_ALLOCATE_EVENT_BLOCKING(uint32_t, data, OBJECT_DATA_SLOT_SIZE);
+
+ for (j = 0; j < (OBJECT_DATA_SLOT_SIZE / sizeof(uint32_t)); j++)
+ {
+ data[j] = objectDataTable.ObjectDataTableBuffer.pObjectDataTableBufferUINT32[i+j];
+ }
+
+ TRC_STREAM_PORT_COMMIT_EVENT_BLOCKING(data, OBJECT_DATA_SLOT_SIZE);
+ }
+ }
+ TRACE_EXIT_CRITICAL_SECTION();
+}
+
+/* Stores the header information on Start */
+static void prvTraceStoreHeader(void)
+{
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ TRACE_ENTER_CRITICAL_SECTION();
+
+ {
+ TRC_STREAM_PORT_ALLOCATE_EVENT_BLOCKING(PSFHeaderInfo, header, sizeof(PSFHeaderInfo));
+ header->psf = PSFEndianessIdentifier;
+ header->version = FormatVersion;
+ header->platform = TRACE_KERNEL_VERSION;
+ header->options = 0;
+ header->heapCounter = trcHeapCounter;
+ /* Lowest bit used for TRC_IRQ_PRIORITY_ORDER */
+ header->options = header->options | (TRC_IRQ_PRIORITY_ORDER << 0);
+ header->symbolSize = SYMBOL_TABLE_SLOT_SIZE;
+ header->symbolCount = (TRC_CFG_SYMBOL_TABLE_SLOTS);
+ header->objectDataSize = 8;
+ header->objectDataCount = (TRC_CFG_OBJECT_DATA_SLOTS);
+ TRC_STREAM_PORT_COMMIT_EVENT_BLOCKING(header, sizeof(PSFHeaderInfo));
+ }
+ TRACE_EXIT_CRITICAL_SECTION();
+}
+
+/* Stores the header information on Start */
+static void prvTraceStoreExtensionInfo(void)
+{
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ TRACE_ENTER_CRITICAL_SECTION();
+
+ {
+ TRC_STREAM_PORT_ALLOCATE_EVENT_BLOCKING(PSFExtensionInfoType, extinfo, sizeof(PSFExtensionInfoType));
+ memcpy(extinfo, &PSFExtensionInfo, sizeof(PSFExtensionInfoType));
+ TRC_STREAM_PORT_COMMIT_EVENT_BLOCKING(extinfo, sizeof(PSFExtensionInfoType));
+ }
+ TRACE_EXIT_CRITICAL_SECTION();
+}
+
+/* Returns the error or warning, as a string, or NULL if none. */
+static const char* prvTraceGetError(int errCode)
+{
+ /* Note: the error messages are short, in order to fit in a User Event.
+ Instead, the users can read more in the below comments.*/
+
+ switch (errCode)
+ {
+
+ case PSF_WARNING_SYMBOL_TABLE_SLOTS:
+ /* There was not enough symbol table slots for storing symbol names.
+ The number of missing slots is counted by NoRoomForSymbol. Inspect this
+ variable and increase TRC_CFG_SYMBOL_TABLE_SLOTS by at least that value. */
+
+ return "Exceeded SYMBOL_TABLE_SLOTS (see prvTraceGetError)";
+
+ case PSF_WARNING_SYMBOL_MAX_LENGTH:
+ /* A symbol name exceeded TRC_CFG_SYMBOL_MAX_LENGTH in length.
+ Make sure the symbol names are at most TRC_CFG_SYMBOL_MAX_LENGTH,
+ or inspect LongestSymbolName and increase TRC_CFG_SYMBOL_MAX_LENGTH
+ to at least this value. */
+
+ return "Exceeded SYMBOL_MAX_LENGTH (see prvTraceGetError)";
+
+ case PSF_WARNING_OBJECT_DATA_SLOTS:
+ /* There was not enough symbol object table slots for storing object
+ properties, such as task priorites. The number of missing slots is
+ counted by NoRoomForObjectData. Inspect this variable and increase
+ TRC_CFG_OBJECT_DATA_SLOTS by at least that value. */
+
+ return "Exceeded OBJECT_DATA_SLOTS (see prvTraceGetError)";
+
+ case PSF_WARNING_STRING_TOO_LONG:
+ /* Some string argument was longer than the maximum payload size
+ and has been truncated by "MaxBytesTruncated" bytes.
+
+ This may happen for the following functions:
+ - vTracePrint
+ - vTracePrintF
+ - vTraceStoreKernelObjectName
+ - xTraceRegisterString
+ - vTraceSetISRProperties
+
+ A PSF event may store maximum 60 bytes payload, including data
+ arguments and string characters. For User Events, also the User
+ Event Channel (4 bytes) must be squeezed in, if a channel is
+ specified (can be NULL). */
+
+ return "String too long (see prvTraceGetError)";
+
+ case PSF_WARNING_STREAM_PORT_READ:
+ /* TRC_STREAM_PORT_READ_DATA is expected to return 0 when completed successfully.
+ This means there is an error in the communication with host/Tracealyzer. */
+
+ return "TRC_STREAM_PORT_READ_DATA returned error (!= 0).";
+
+ case PSF_WARNING_STREAM_PORT_WRITE:
+ /* TRC_STREAM_PORT_WRITE_DATA is expected to return 0 when completed successfully.
+ This means there is an error in the communication with host/Tracealyzer. */
+
+ return "TRC_STREAM_PORT_WRITE_DATA returned error (!= 0).";
+
+ case PSF_WARNING_STACKMON_NO_SLOTS:
+ /* TRC_CFG_STACK_MONITOR_MAX_TASKS is too small to monitor all tasks. */
+
+ return "TRC_CFG_STACK_MONITOR_MAX_TASKS too small!";
+
+ case PSF_WARNING_STREAM_PORT_INITIAL_BLOCKING:
+ /* Blocking occurred during vTraceEnable. This happens if the trace buffer is
+ smaller than the initial transmission (trace header, object table, and symbol table). */
+
+ return "Blocking in vTraceEnable (see xTraceGetLastError)";
+
+ case PSF_ERROR_EVENT_CODE_TOO_LARGE:
+ /* The highest allowed event code is 4095, anything higher is an unexpected error.
+ Please contact support@percepio.com for assistance.*/
+
+ return "Invalid event code (see prvTraceGetError)";
+
+ case PSF_ERROR_ISR_NESTING_OVERFLOW:
+ /* Nesting of ISR trace calls exceeded the limit (TRC_CFG_MAX_ISR_NESTING).
+ If this is unlikely, make sure that you call vTraceStoreISRExit in the end
+ of all ISR handlers. Or increase TRC_CFG_MAX_ISR_NESTING. */
+
+ return "Exceeded ISR nesting (see prvTraceGetError)";
+
+ case PSF_ERROR_DWT_NOT_SUPPORTED:
+ /* On ARM Cortex-M only - failed to initialize DWT Cycle Counter since not supported by this chip.
+ DWT timestamping is selected automatically for ART Cortex-M3, M4 and higher, based on the __CORTEX_M
+ macro normally set by ARM's CMSIS library, since typically available. You can however select
+ SysTick timestamping instead by defining adding "#define TRC_CFG_ARM_CM_USE_SYSTICK".*/
+
+ return "DWT not supported (see prvTraceGetError)";
+
+ case PSF_ERROR_DWT_CYCCNT_NOT_SUPPORTED:
+ /* On ARM Cortex-M only - failed to initialize DWT Cycle Counter since not supported by this chip.
+ DWT timestamping is selected automatically for ART Cortex-M3, M4 and higher, based on the __CORTEX_M
+ macro normally set by ARM's CMSIS library, since typically available. You can however select
+ SysTick timestamping instead by defining adding "#define TRC_CFG_ARM_CM_USE_SYSTICK".*/
+
+ return "DWT_CYCCNT not supported (see prvTraceGetError)";
+
+ case PSF_ERROR_TZCTRLTASK_NOT_CREATED:
+ /* vTraceEnable failed creating the trace control task (TzCtrl) - incorrect parameters (priority?)
+ or insufficient heap size? */
+ return "Could not create TzCtrl (see prvTraceGetError)";
+
+ case PSF_ERROR_STREAM_PORT_WRITE:
+ /* TRC_STREAM_PORT_WRITE_DATA is expected to return 0 when completed successfully.
+ This means there is an error in the communication with host/Tracealyzer. */
+ return "TRC_STREAM_PORT_WRITE_DATA returned error (!= 0).";
+ }
+
+ return NULL;
+}
+
+/* Store an event with zero parameters (event ID only) */
+void prvTraceStoreEvent0(uint16_t eventID)
+{
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ PSF_ASSERT_VOID(eventID < 4096, PSF_ERROR_EVENT_CODE_TOO_LARGE);
+
+ TRACE_ENTER_CRITICAL_SECTION();
+
+ if (RecorderEnabled)
+ {
+ eventCounter++;
+
+ {
+ TRC_STREAM_PORT_ALLOCATE_EVENT(BaseEvent, event, sizeof(BaseEvent));
+ if (event != NULL)
+ {
+ event->EventID = eventID | PARAM_COUNT(0);
+ event->EventCount = (uint16_t)eventCounter;
+ event->TS = prvGetTimestamp32();
+ TRC_STREAM_PORT_COMMIT_EVENT(event, sizeof(BaseEvent));
+ }
+ }
+ }
+ TRACE_EXIT_CRITICAL_SECTION();
+}
+
+/* Store an event with one 32-bit parameter (pointer address or an int) */
+void prvTraceStoreEvent1(uint16_t eventID, uint32_t param1)
+{
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ PSF_ASSERT_VOID(eventID < 4096, PSF_ERROR_EVENT_CODE_TOO_LARGE);
+
+ TRACE_ENTER_CRITICAL_SECTION();
+
+ if (RecorderEnabled)
+ {
+ eventCounter++;
+
+ {
+ TRC_STREAM_PORT_ALLOCATE_EVENT(EventWithParam_1, event, sizeof(EventWithParam_1));
+ if (event != NULL)
+ {
+ event->base.EventID = eventID | PARAM_COUNT(1);
+ event->base.EventCount = (uint16_t)eventCounter;
+ event->base.TS = prvGetTimestamp32();
+ event->param1 = (uint32_t)param1;
+ TRC_STREAM_PORT_COMMIT_EVENT(event, sizeof(EventWithParam_1));
+ }
+ }
+ }
+ TRACE_EXIT_CRITICAL_SECTION();
+}
+
+/* Store an event with two 32-bit parameters */
+void prvTraceStoreEvent2(uint16_t eventID, uint32_t param1, uint32_t param2)
+{
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ PSF_ASSERT_VOID(eventID < 4096, PSF_ERROR_EVENT_CODE_TOO_LARGE);
+
+ TRACE_ENTER_CRITICAL_SECTION();
+
+ if (RecorderEnabled)
+ {
+ eventCounter++;
+
+ {
+ TRC_STREAM_PORT_ALLOCATE_EVENT(EventWithParam_2, event, sizeof(EventWithParam_2));
+ if (event != NULL)
+ {
+ event->base.EventID = eventID | PARAM_COUNT(2);
+ event->base.EventCount = (uint16_t)eventCounter;
+ event->base.TS = prvGetTimestamp32();
+ event->param1 = (uint32_t)param1;
+ event->param2 = param2;
+ TRC_STREAM_PORT_COMMIT_EVENT(event, sizeof(EventWithParam_2));
+ }
+ }
+ }
+ TRACE_EXIT_CRITICAL_SECTION();
+}
+
+/* Store an event with three 32-bit parameters */
+void prvTraceStoreEvent3( uint16_t eventID,
+ uint32_t param1,
+ uint32_t param2,
+ uint32_t param3)
+{
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ PSF_ASSERT_VOID(eventID < 4096, PSF_ERROR_EVENT_CODE_TOO_LARGE);
+
+ TRACE_ENTER_CRITICAL_SECTION();
+
+ if (RecorderEnabled)
+ {
+ eventCounter++;
+
+ {
+ TRC_STREAM_PORT_ALLOCATE_EVENT(EventWithParam_3, event, sizeof(EventWithParam_3));
+ if (event != NULL)
+ {
+ event->base.EventID = eventID | PARAM_COUNT(3);
+ event->base.EventCount = (uint16_t)eventCounter;
+ event->base.TS = prvGetTimestamp32();
+ event->param1 = (uint32_t)param1;
+ event->param2 = param2;
+ event->param3 = param3;
+ TRC_STREAM_PORT_COMMIT_EVENT(event, sizeof(EventWithParam_3));
+ }
+ }
+ }
+ TRACE_EXIT_CRITICAL_SECTION();
+}
+
+/* Stores an event with <nParam> 32-bit integer parameters */
+void prvTraceStoreEvent(int nParam, uint16_t eventID, ...)
+{
+ va_list vl;
+ int i;
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ PSF_ASSERT_VOID(eventID < 4096, PSF_ERROR_EVENT_CODE_TOO_LARGE);
+
+ TRACE_ENTER_CRITICAL_SECTION();
+
+ if (RecorderEnabled)
+ {
+ int eventSize = (int)sizeof(BaseEvent) + nParam * (int)sizeof(uint32_t);
+
+ eventCounter++;
+
+ {
+ TRC_STREAM_PORT_ALLOCATE_DYNAMIC_EVENT(largestEventType, event, eventSize);
+ if (event != NULL)
+ {
+ event->base.EventID = eventID | (uint16_t)PARAM_COUNT(nParam);
+ event->base.EventCount = (uint16_t)eventCounter;
+ event->base.TS = prvGetTimestamp32();
+
+ va_start(vl, eventID);
+ for (i = 0; i < nParam; i++)
+ {
+ uint32_t* tmp = (uint32_t*) &(event->data[i]);
+ *tmp = va_arg(vl, uint32_t);
+ }
+ va_end(vl);
+
+ TRC_STREAM_PORT_COMMIT_EVENT(event, (uint32_t)eventSize);
+ }
+ }
+ }
+ TRACE_EXIT_CRITICAL_SECTION();
+}
+
+/* Stories an event with a string and <nParam> 32-bit integer parameters */
+void prvTraceStoreStringEvent(int nArgs, uint16_t eventID, const char* str, ...)
+{
+ int len;
+ va_list vl;
+
+ for (len = 0; (str[len] != 0) && (len < 52); len++); /* empty loop */
+
+ va_start(vl, str);
+ prvTraceStoreStringEventHelper(nArgs, eventID, NULL, len, str, vl);
+ va_end(vl);
+}
+
+/* Internal common function for storing string events */
+static void prvTraceStoreStringEventHelper(int nArgs,
+ uint16_t eventID,
+ traceString userEvtChannel,
+ int len,
+ const char* str,
+ va_list vl)
+{
+ int nWords;
+ int nStrWords;
+ int i;
+ int offset = 0;
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ /* The string length in multiples of 32 bit words (+1 for null character) */
+ nStrWords = (len+1+3)/4;
+
+ offset = nArgs * 4;
+
+ /* The total number of 32-bit words needed for the whole payload */
+ nWords = nStrWords + nArgs;
+
+ if (nWords > 15) /* if attempting to store more than 60 byte (= max) */
+ {
+ /* Truncate event if too large. The string characters are stored
+ last, so usually only the string is truncated, unless there a lot
+ of parameters... */
+
+ /* Diagnostics ... */
+ uint32_t bytesTruncated = (uint32_t)(nWords - 15) * 4;
+
+ if (bytesTruncated > MaxBytesTruncated)
+ {
+ MaxBytesTruncated = bytesTruncated;
+ }
+
+ nWords = 15;
+ len = 15 * 4 - offset;
+ }
+
+ TRACE_ENTER_CRITICAL_SECTION();
+
+ if (RecorderEnabled)
+ {
+ int eventSize = (int)sizeof(BaseEvent) + nWords * (int)sizeof(uint32_t);
+
+ eventCounter++;
+
+ {
+ TRC_STREAM_PORT_ALLOCATE_DYNAMIC_EVENT(largestEventType, event, eventSize);
+ if (event != NULL)
+ {
+ uint32_t* data32;
+ uint8_t* data8;
+ event->base.EventID = (eventID) | (uint16_t)PARAM_COUNT(nWords);
+ event->base.EventCount = (uint16_t)eventCounter;
+ event->base.TS = prvGetTimestamp32();
+
+ /* 32-bit write-pointer for the data argument */
+ data32 = (uint32_t*) &(event->data[0]);
+
+ for (i = 0; i < nArgs; i++)
+ {
+ if ((userEvtChannel != NULL) && (i == 0))
+ {
+ /* First, add the User Event Channel if not NULL */
+ data32[i] = (uint32_t)userEvtChannel;
+ }
+ else
+ {
+ /* Add data arguments... */
+ data32[i] = va_arg(vl, uint32_t);
+ }
+ }
+ data8 = (uint8_t*)&(event->data[0]);
+ for (i = 0; i < len; i++)
+ {
+ data8[offset + i] = str[i];
+ }
+
+ if (len < (15 * 4 - offset))
+ data8[offset + len] = 0; /* Only truncate if we don't fill up the buffer completely */
+ TRC_STREAM_PORT_COMMIT_EVENT(event, (uint32_t)eventSize);
+ }
+ }
+ }
+
+ TRACE_EXIT_CRITICAL_SECTION();
+}
+
+/* Internal common function for storing string events without additional arguments */
+void prvTraceStoreSimpleStringEventHelper(uint16_t eventID,
+ traceString userEvtChannel,
+ const char* str)
+{
+ int len;
+ int nWords;
+ int nStrWords;
+ int i;
+ int nArgs = 0;
+ int offset = 0;
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ for (len = 0; (str[len] != 0) && (len < 52); len++); /* empty loop */
+
+ /* The string length in multiples of 32 bit words (+1 for null character) */
+ nStrWords = (len+1+3)/4;
+
+ /* If a user event channel is specified, add in the list */
+ if (userEvtChannel)
+ {
+ nArgs++;
+ eventID++;
+ }
+
+ offset = nArgs * 4;
+
+ /* The total number of 32-bit words needed for the whole payload */
+ nWords = nStrWords + nArgs;
+
+ if (nWords > 15) /* if attempting to store more than 60 byte (= max) */
+ {
+ /* Truncate event if too large. The string characters are stored
+ last, so usually only the string is truncated, unless there a lot
+ of parameters... */
+
+ /* Diagnostics ... */
+ uint32_t bytesTruncated = (uint32_t)(nWords - 15) * 4;
+
+ if (bytesTruncated > MaxBytesTruncated)
+ {
+ MaxBytesTruncated = bytesTruncated;
+ }
+
+ nWords = 15;
+ len = 15 * 4 - offset;
+ }
+
+ TRACE_ENTER_CRITICAL_SECTION();
+
+ if (RecorderEnabled)
+ {
+ int eventSize = (int)sizeof(BaseEvent) + nWords * (int)sizeof(uint32_t);
+
+ eventCounter++;
+
+ {
+ TRC_STREAM_PORT_ALLOCATE_DYNAMIC_EVENT(largestEventType, event, eventSize);
+ if (event != NULL)
+ {
+ uint32_t* data32;
+ uint8_t* data8;
+ event->base.EventID = (eventID) | (uint16_t)PARAM_COUNT(nWords);
+ event->base.EventCount = (uint16_t)eventCounter;
+ event->base.TS = prvGetTimestamp32();
+
+ /* 32-bit write-pointer for the data argument */
+ data32 = (uint32_t*) &(event->data[0]);
+
+ if (userEvtChannel != NULL)
+ {
+ /* First, add the User Event Channel if not NULL */
+ data32[0] = (uint32_t)userEvtChannel;
+ }
+
+ data8 = (uint8_t*) &(event->data[0]);
+ for (i = 0; i < len; i++)
+ {
+ data8[offset + i] = str[i];
+ }
+
+ if (len < (15 * 4 - offset))
+ data8[offset + len] = 0; /* Only truncate if we don't fill up the buffer completely */
+ TRC_STREAM_PORT_COMMIT_EVENT(event, (uint32_t)eventSize);
+ }
+ }
+ }
+
+ TRACE_EXIT_CRITICAL_SECTION();
+}
+
+/* Saves a symbol name in the symbol table and returns the slot address */
+void* prvTraceSaveSymbol(const char *name)
+{
+ void* retVal = 0;
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ TRACE_ENTER_CRITICAL_SECTION();
+ if (firstFreeSymbolTableIndex < SYMBOL_TABLE_BUFFER_SIZE)
+ {
+ /* The address to the available symbol table slot is the address we use */
+ retVal = &symbolTable.SymbolTableBuffer.pSymbolTableBufferUINT8[firstFreeSymbolTableIndex];
+ prvTraceSaveObjectSymbol(retVal, name);
+ }
+ TRACE_EXIT_CRITICAL_SECTION();
+
+ return retVal;
+}
+
+/* Saves a string in the symbol table for an object (task name etc.) */
+void prvTraceSaveObjectSymbol(void* address, const char *name)
+{
+ uint32_t i;
+ uint8_t *ptrSymbol;
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ TRACE_ENTER_CRITICAL_SECTION();
+
+ /* We do not look for previous entries -> changing a registered string is no longer possible */
+ if (firstFreeSymbolTableIndex < SYMBOL_TABLE_BUFFER_SIZE)
+ {
+ /* We access the symbol table via the union member pSymbolTableBufferUINT32 to avoid strict-aliasing issues */
+ symbolTable.SymbolTableBuffer.pSymbolTableBufferUINT32[firstFreeSymbolTableIndex / sizeof(uint32_t)] = (uint32_t)address;
+
+ /* We access the symbol table via the union member pSymbolTableBufferUINT8 to avoid strict-aliasing issues */
+ ptrSymbol = &symbolTable.SymbolTableBuffer.pSymbolTableBufferUINT8[firstFreeSymbolTableIndex + sizeof(uint32_t)];
+ for (i = 0; i < (TRC_CFG_SYMBOL_MAX_LENGTH); i++)
+ {
+ ptrSymbol[i] = (uint8_t)name[i]; /* We do this first to ensure we also get the 0 termination, if there is one */
+
+ if (name[i] == 0)
+ break;
+ }
+
+ /* Check the length of "name", if longer than SYMBOL_MAX_LENGTH */
+ while ((name[i] != 0) && i < 128)
+ {
+ i++;
+ }
+
+ /* Remember the longest symbol name, for diagnostic purposes */
+ if (i > LongestSymbolName)
+ {
+ LongestSymbolName = i;
+ }
+
+ firstFreeSymbolTableIndex += SYMBOL_TABLE_SLOT_SIZE;
+ }
+ else
+ {
+ NoRoomForSymbol++;
+ }
+
+ TRACE_EXIT_CRITICAL_SECTION();
+}
+
+/* Deletes a symbol name (task name etc.) from symbol table */
+void prvTraceDeleteSymbol(void *address)
+{
+ uint32_t i, j;
+ uint32_t *ptr, *lastEntryPtr;
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ TRACE_ENTER_CRITICAL_SECTION();
+
+ for (i = 0; i < firstFreeSymbolTableIndex; i += SYMBOL_TABLE_SLOT_SIZE)
+ {
+ /* We access the symbol table via the union member pSymbolTableBufferUINT32 to avoid strict-aliasing issues */
+ ptr = &symbolTable.SymbolTableBuffer.pSymbolTableBufferUINT32[i / sizeof(uint32_t)];
+ if (*ptr == (uint32_t)address)
+ {
+ /* See if we have another entry in the table, and that this isn't already the last entry */
+ if (firstFreeSymbolTableIndex > SYMBOL_TABLE_SLOT_SIZE && i != (firstFreeSymbolTableIndex - SYMBOL_TABLE_SLOT_SIZE))
+ {
+ /* Another entry is available, get pointer to the last one */
+ /* We access the symbol table via the union member pSymbolTableBufferUINT32 to avoid strict-aliasing issues */
+ lastEntryPtr = &symbolTable.SymbolTableBuffer.pSymbolTableBufferUINT32[(firstFreeSymbolTableIndex - SYMBOL_TABLE_SLOT_SIZE) / sizeof(uint32_t)];
+
+ /* Copy last entry to this position */
+ for (j = 0; j < (SYMBOL_TABLE_SLOT_SIZE) / sizeof(uint32_t); j++)
+ {
+ ptr[j] = lastEntryPtr[j];
+ }
+
+ /* For good measure we also zero out the original position */
+ *lastEntryPtr = 0;
+ }
+ else
+ *ptr = 0; /* No other entry found, or this is the last entry */
+
+ /* Lower index */
+ firstFreeSymbolTableIndex -= SYMBOL_TABLE_SLOT_SIZE;
+
+ break;
+ }
+ }
+
+ TRACE_EXIT_CRITICAL_SECTION();
+}
+
+/* Saves an object data entry (current task priority) in object data table */
+void prvTraceSaveObjectData(const void *address, uint32_t data)
+{
+ uint32_t i;
+ uint32_t foundSlot;
+ uint32_t *ptr;
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ TRACE_ENTER_CRITICAL_SECTION();
+
+ foundSlot = firstFreeObjectDataTableIndex;
+
+ /* First look for previous entries using this address */
+ for (i = 0; i < firstFreeObjectDataTableIndex; i += OBJECT_DATA_SLOT_SIZE)
+ {
+ /* We access the data table via the union member pObjectDataTableBufferUINT32 to avoid strict-aliasing issues */
+ ptr = &objectDataTable.ObjectDataTableBuffer.pObjectDataTableBufferUINT32[i / sizeof(uint32_t)];
+ if (*ptr == (uint32_t)address)
+ {
+ foundSlot = i;
+ break;
+ }
+ }
+
+ if (foundSlot < OBJECT_DATA_TABLE_BUFFER_SIZE)
+ {
+ /* We access the data table via the union member pObjectDataTableBufferUINT32 to avoid strict-aliasing issues */
+ objectDataTable.ObjectDataTableBuffer.pObjectDataTableBufferUINT32[foundSlot / sizeof(uint32_t)] = (uint32_t)address;
+ objectDataTable.ObjectDataTableBuffer.pObjectDataTableBufferUINT32[foundSlot / sizeof(uint32_t) + 1] = data;
+
+ /* Is this the last entry in the object data table? */
+ if (foundSlot == firstFreeObjectDataTableIndex)
+ {
+ firstFreeObjectDataTableIndex += OBJECT_DATA_SLOT_SIZE;
+ }
+ }
+ else
+ {
+ NoRoomForObjectData++;
+ }
+
+ TRACE_EXIT_CRITICAL_SECTION();
+}
+
+/* Removes an object data entry (task base priority) from object data table */
+void prvTraceDeleteObjectData(void *address)
+{
+ uint32_t i, j;
+ uint32_t *ptr, *lastEntryPtr;
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ TRACE_ENTER_CRITICAL_SECTION();
+
+ for (i = 0; i < firstFreeObjectDataTableIndex; i += OBJECT_DATA_SLOT_SIZE)
+ {
+ /* We access the data table via the union member pObjectDataTableBufferUINT32 to avoid strict-aliasing issues */
+ ptr = &objectDataTable.ObjectDataTableBuffer.pObjectDataTableBufferUINT32[i / sizeof(uint32_t)];
+ if (*ptr == (uint32_t)address)
+ {
+ /* See if we have another entry in the table, and that this isn't already the last entry */
+ if (firstFreeObjectDataTableIndex > OBJECT_DATA_SLOT_SIZE && i != (firstFreeObjectDataTableIndex - OBJECT_DATA_SLOT_SIZE))
+ {
+ /* Another entry is available, get pointer to the last one */
+ /* We access the data table via the union member pObjectDataTableBufferUINT32 to avoid strict-aliasing issues */
+ lastEntryPtr = &objectDataTable.ObjectDataTableBuffer.pObjectDataTableBufferUINT32[(firstFreeObjectDataTableIndex - OBJECT_DATA_SLOT_SIZE) / sizeof(uint32_t)];
+
+ /* Copy last entry to this position */
+ for (j = 0; j < (OBJECT_DATA_SLOT_SIZE) / sizeof(uint32_t); j++)
+ {
+ ptr[j] = lastEntryPtr[j];
+ }
+
+ /* For good measure we also zero out the original position */
+ *lastEntryPtr = 0;
+ }
+ else
+ *ptr = 0; /* No other entry found, or this is the last entry */
+
+ /* Lower index */
+ firstFreeObjectDataTableIndex -= OBJECT_DATA_SLOT_SIZE;
+
+ break;
+ }
+ }
+
+ TRACE_EXIT_CRITICAL_SECTION();
+}
+
+/* Checks if the provided command is a valid command */
+int prvIsValidCommand(TracealyzerCommandType* cmd)
+{
+ uint16_t checksum = (uint16_t)(0xFFFF - ( cmd->cmdCode +
+ cmd->param1 +
+ cmd->param2 +
+ cmd->param3 +
+ cmd->param4 +
+ cmd->param5));
+
+ if (cmd->checksumMSB != (unsigned char)(checksum >> 8))
+ return 0;
+
+ if (cmd->checksumLSB != (unsigned char)(checksum & 0xFF))
+ return 0;
+
+ if (cmd->cmdCode > CMD_LAST_COMMAND)
+ return 0;
+
+ return 1;
+}
+
+/* Executed the received command (Start or Stop) */
+void prvProcessCommand(TracealyzerCommandType* cmd)
+{
+ switch(cmd->cmdCode)
+ {
+ case CMD_SET_ACTIVE:
+ prvSetRecorderEnabled(cmd->param1);
+ break;
+ default:
+ break;
+ }
+}
+
+/* Called on warnings, when the recording can continue. */
+void prvTraceWarning(int errCode)
+{
+ if (GET_ERROR_WARNING_FLAG(errCode) == 0)
+ {
+ /* Will never reach this point more than once per warning type, since we verify if ErrorAndWarningFlags[errCode] has already been set */
+ SET_ERROR_WARNING_FLAG(errCode);
+
+ prvTraceStoreSimpleStringEventHelper(PSF_EVENT_USER_EVENT, trcWarningChannel, prvTraceGetError(errCode));
+ }
+}
+
+/* Called on critical errors in the recorder. Stops the recorder! */
+void prvTraceError(int errCode)
+{
+ if (errorCode == PSF_ERROR_NONE)
+ {
+ /* Will never reach this point more than once, since we verify if errorCode has already been set */
+ errorCode = errCode;
+ SET_ERROR_WARNING_FLAG(errorCode);
+
+ prvTraceStoreSimpleStringEventHelper(PSF_EVENT_USER_EVENT, trcWarningChannel, prvTraceGetError(errorCode));
+ prvTraceStoreSimpleStringEventHelper(PSF_EVENT_USER_EVENT, trcWarningChannel, "Recorder stopped in prvTraceError()");
+
+ prvSetRecorderEnabled(0);
+ }
+}
+
+/* If using DWT timestamping (default on ARM Cortex-M3, M4 and M7), make sure the DWT unit is initialized. */
+#ifndef TRC_CFG_ARM_CM_USE_SYSTICK
+#if ((TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_Cortex_M) && (defined (__CORTEX_M) && (__CORTEX_M >= 0x03)))
+
+void prvTraceInitCortexM()
+{
+ /* Make sure the DWT registers are unlocked, in case the debugger doesn't do this. */
+ TRC_REG_ITM_LOCKACCESS = TRC_ITM_LOCKACCESS_UNLOCK;
+
+ /* Make sure DWT is enabled is enabled, if supported */
+ TRC_REG_DEMCR |= TRC_DEMCR_TRCENA;
+
+ do
+ {
+ /* Verify that DWT is supported */
+ if (TRC_REG_DEMCR == 0)
+ {
+ /* This function is called on Cortex-M3, M4 and M7 devices to initialize
+ the DWT unit, assumed present. The DWT cycle counter is used for timestamping.
+
+ If the below error is produced, the DWT unit does not seem to be available.
+
+ In that case, define the macro TRC_CFG_ARM_CM_USE_SYSTICK in your build
+ to use SysTick timestamping instead, or define your own timestamping by
+ setting TRC_CFG_HARDWARE_PORT to TRC_HARDWARE_PORT_APPLICATION_DEFINED
+ and make the necessary definitions, as explained in trcHardwarePort.h.*/
+
+ prvTraceError(PSF_ERROR_DWT_NOT_SUPPORTED);
+ break;
+ }
+
+ /* Verify that DWT_CYCCNT is supported */
+ if (TRC_REG_DWT_CTRL & TRC_DWT_CTRL_NOCYCCNT)
+ {
+ /* This function is called on Cortex-M3, M4 and M7 devices to initialize
+ the DWT unit, assumed present. The DWT cycle counter is used for timestamping.
+
+ If the below error is produced, the cycle counter does not seem to be available.
+
+ In that case, define the macro TRC_CFG_ARM_CM_USE_SYSTICK in your build
+ to use SysTick timestamping instead, or define your own timestamping by
+ setting TRC_CFG_HARDWARE_PORT to TRC_HARDWARE_PORT_APPLICATION_DEFINED
+ and make the necessary definitions, as explained in trcHardwarePort.h.*/
+
+ prvTraceError(PSF_ERROR_DWT_CYCCNT_NOT_SUPPORTED);
+ break;
+ }
+
+ /* Reset the cycle counter */
+ TRC_REG_DWT_CYCCNT = 0;
+
+ /* Enable the cycle counter */
+ TRC_REG_DWT_CTRL |= TRC_DWT_CTRL_CYCCNTENA;
+
+ } while(0); /* breaks above jump here */
+}
+#endif
+#endif
+
+/* Performs timestamping using definitions in trcHardwarePort.h */
+static uint32_t prvGetTimestamp32(void)
+{
+#if ((TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_INCR) || (TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_DECR))
+ return TRC_HWTC_COUNT;
+#endif
+
+#if ((TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_INCR) || (TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_DECR))
+ return TRC_HWTC_COUNT;
+#endif
+
+#if ((TRC_HWTC_TYPE == TRC_OS_TIMER_INCR) || (TRC_HWTC_TYPE == TRC_OS_TIMER_DECR))
+ uint32_t ticks = TRACE_GET_OS_TICKS();
+ return ((TRC_HWTC_COUNT) & 0x00FFFFFFU) + ((ticks & 0x000000FFU) << 24);
+#endif
+}
+
+/* Retrieve a buffer page to write to. */
+static int prvAllocateBufferPage(int prevPage)
+{
+ int index;
+ int count = 0;
+
+ index = (prevPage + 1) % (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT);
+
+ while((PageInfo[index].Status != PAGE_STATUS_FREE) && (count ++ < (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT)))
+ {
+ index = (index + 1) % (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT);
+ }
+
+ if (PageInfo[index].Status == PAGE_STATUS_FREE)
+ {
+ return index;
+ }
+
+ return -1;
+}
+
+/* Mark the page read as complete. */
+static void prvPageReadComplete(int pageIndex)
+{
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ TRACE_ENTER_CRITICAL_SECTION();
+ PageInfo[pageIndex].BytesRemaining = (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE);
+ PageInfo[pageIndex].WritePointer = &EventBuffer[pageIndex * (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE)];
+ PageInfo[pageIndex].Status = PAGE_STATUS_FREE;
+
+ TotalBytesRemaining += (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE);
+
+ TRACE_EXIT_CRITICAL_SECTION();
+}
+
+/* Get the current buffer page index and remaining number of bytes. */
+static int prvGetBufferPage(int32_t* bytesUsed)
+{
+ static int8_t lastPage = -1;
+ int count = 0;
+ int8_t index = (int8_t) ((lastPage + 1) % (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT));
+
+ while((PageInfo[index].Status != PAGE_STATUS_READ) && (count++ < (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT)))
+ {
+ index = (int8_t)((index + 1) % (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT));
+ }
+
+ if (PageInfo[index].Status == PAGE_STATUS_READ)
+ {
+ *bytesUsed = (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE) - PageInfo[index].BytesRemaining;
+ lastPage = index;
+ return index;
+ }
+
+ *bytesUsed = 0;
+
+ return -1;
+}
+
+/*******************************************************************************
+ * uint32_t prvPagedEventBufferTransfer(void)
+ *
+ * Transfers one buffer page of trace data, if a full page is available, using
+ * the macro TRC_STREAM_PORT_WRITE_DATA as defined in trcStreamingPort.h.
+ *
+ * This function is intended to be called the periodic TzCtrl task with a suitable
+ * delay (e.g. 10-100 ms).
+ *
+ * Returns the number of bytes sent. If non-zero, it is good to call this
+ * again, in order to send any additional data waiting in the buffer.
+ * If zero, wait a while before calling again.
+ *
+ * In case of errors from the streaming interface, it registers a warning
+ * (PSF_WARNING_STREAM_PORT_WRITE) provided by xTraceGetLastError().
+ *
+ *******************************************************************************/
+uint32_t prvPagedEventBufferTransfer(void)
+{
+ int8_t pageToTransfer = -1;
+ int32_t bytesTransferredTotal = 0;
+ int32_t bytesTransferredNow = 0;
+ int32_t bytesToTransfer;
+
+ pageToTransfer = (int8_t)prvGetBufferPage(&bytesToTransfer);
+
+ /* bytesToTransfer now contains the number of "valid" bytes in the buffer page, that should be transmitted.
+ There might be some unused junk bytes in the end, that must be ignored. */
+
+ if (pageToTransfer > -1)
+ {
+ while (1) /* Keep going until we have transferred all that we intended to */
+ {
+ if (TRC_STREAM_PORT_WRITE_DATA(
+ &EventBuffer[pageToTransfer * (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE) + bytesTransferredTotal],
+ (uint32_t)(bytesToTransfer - bytesTransferredTotal),
+ &bytesTransferredNow) == 0)
+ {
+ /* Write was successful. Update the number of transferred bytes. */
+ bytesTransferredTotal += bytesTransferredNow;
+
+ if (bytesTransferredTotal == bytesToTransfer)
+ {
+ /* All bytes have been transferred. Mark the buffer page as "Read Complete" (so it can be written to) and return OK. */
+ prvPageReadComplete(pageToTransfer);
+ return (uint32_t)bytesTransferredTotal;
+ }
+ }
+ else
+ {
+ /* Some error from the streaming interface... */
+ vTraceStop();
+ return 0;
+ }
+ }
+ }
+ return 0;
+}
+
+/*******************************************************************************
+ * void* prvPagedEventBufferGetWritePointer(int sizeOfEvent)
+ *
+ * Returns a pointer to an available location in the buffer able to store the
+ * requested size.
+ *
+ * Return value: The pointer.
+ *
+ * Parameters:
+ * - sizeOfEvent: The size of the event that is to be placed in the buffer.
+ *
+*******************************************************************************/
+void* prvPagedEventBufferGetWritePointer(int sizeOfEvent)
+{
+ void* ret;
+ static int currentWritePage = -1;
+
+ if (currentWritePage == -1)
+ {
+ currentWritePage = prvAllocateBufferPage(currentWritePage);
+ if (currentWritePage == -1)
+ {
+ DroppedEventCounter++;
+ return NULL;
+ }
+ }
+
+ if (PageInfo[currentWritePage].BytesRemaining - sizeOfEvent < 0)
+ {
+ PageInfo[currentWritePage].Status = PAGE_STATUS_READ;
+
+ TotalBytesRemaining -= PageInfo[currentWritePage].BytesRemaining; // Last trailing bytes
+
+ if (TotalBytesRemaining < TotalBytesRemaining_LowWaterMark)
+ TotalBytesRemaining_LowWaterMark = TotalBytesRemaining;
+
+ currentWritePage = prvAllocateBufferPage(currentWritePage);
+ if (currentWritePage == -1)
+ {
+ DroppedEventCounter++;
+ return NULL;
+ }
+ }
+ ret = PageInfo[currentWritePage].WritePointer;
+ PageInfo[currentWritePage].WritePointer += sizeOfEvent;
+ PageInfo[currentWritePage].BytesRemaining = (uint16_t)(PageInfo[currentWritePage].BytesRemaining -sizeOfEvent);
+
+ TotalBytesRemaining = (TotalBytesRemaining-(uint16_t)sizeOfEvent);
+
+ if (TotalBytesRemaining < TotalBytesRemaining_LowWaterMark)
+ TotalBytesRemaining_LowWaterMark = TotalBytesRemaining;
+
+ return ret;
+}
+
+/*******************************************************************************
+ * void prvPagedEventBufferInit(char* buffer)
+ *
+ * Assigns the buffer to use and initializes the PageInfo structure.
+ *
+ * Return value: void
+ *
+ * Parameters:
+ * - char* buffer: pointer to the trace data buffer, allocated by the caller.
+ *
+*******************************************************************************/
+void prvPagedEventBufferInit(char* buffer)
+{
+ int i;
+ TRACE_ALLOC_CRITICAL_SECTION();
+
+ EventBuffer = buffer;
+
+ TRACE_ENTER_CRITICAL_SECTION();
+ for (i = 0; i < (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT); i++)
+ {
+ PageInfo[i].BytesRemaining = (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE);
+ PageInfo[i].WritePointer = &EventBuffer[i * (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE)];
+ PageInfo[i].Status = PAGE_STATUS_FREE;
+ }
+ TRACE_EXIT_CRITICAL_SECTION();
+
+}
+
+#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/
+
+#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/