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>
pull/195/head
Ming Yue 5 years ago committed by GitHub
parent 70dcbe4527
commit d248555de5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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_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 or later
* 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
@ -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.
*
@ -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"

@ -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 */

@ -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 */

@ -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_ */

@ -1,5 +1,5 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v4.1.5
* Trace Recorder Library for Tracealyzer v4.3.11
* Percepio AB, www.percepio.com
*
* trcHardwarePort.h
@ -240,7 +240,7 @@
#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
#define TRC_IRQ_PRIORITY_ORDER 1
#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_TEXAS_INSTRUMENTS_TMS570_RM48)
@ -344,24 +344,90 @@
#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)
/* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
/* OFFICIAL PORT */
#include "system.h"
#include "sys/alt_timestamp.h"
#include <system.h>
#include <altera_avalon_timer_regs.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 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)
/* INPUT YOUR PERIPHERAL BASE ADDRESS HERE */
#define TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS 0xSOMETHING
/**************************************************************************
* 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))
@ -387,6 +453,20 @@
#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 */

@ -1,5 +1,5 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v4.1.5
* Trace Recorder Library for Tracealyzer v4.3.11
* Percepio AB, www.percepio.com
*
* Terms of Use
@ -56,21 +56,29 @@ extern "C" {
/*** 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_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 /* 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
#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)
@ -80,18 +88,28 @@ extern "C" {
/* 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 */
#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
******************************************************************************/
@ -171,6 +189,14 @@ void vTraceSetMessageBufferName(void* object, const char* name);
#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 */
@ -179,6 +205,8 @@ void vTraceSetMessageBufferName(void* object, const char* name);
#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) */
@ -227,12 +255,39 @@ unsigned char prvTraceIsSchedulerSuspended(void);
#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))
#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()
@ -241,7 +296,7 @@ unsigned char prvTraceIsSchedulerSuspended(void);
#endif
#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_POWERPC_Z4)
#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X)
#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();}
@ -298,7 +353,6 @@ 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);
@ -357,14 +411,37 @@ void prvTraceSetStreamBufferNumberHigh16(void* handle, uint16_t value);
#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)
/* 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_7_4) */
#define TRACE_GET_OBJECT_FILTER(CLASS, pxObject) 1
#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_7_4) */
#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 ********************************************/
@ -711,6 +788,10 @@ extern traceObjectClass TraceQueueClassTable[5];
#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*/
@ -741,7 +822,15 @@ extern traceObjectClass TraceQueueClassTable[5];
#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) */
#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 *
@ -838,24 +927,34 @@ extern traceObjectClass TraceQueueClassTable[5];
/* 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)
#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_3_0)
#define traceTASK_INCREMENT_TICK( xTickCount ) \
if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || uxMissedTicks == 0) { trcKERNEL_HOOKS_INCREMENT_TICK(); } \
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 || xPendedTicks == 0) { trcKERNEL_HOOKS_INCREMENT_TICK(); } \
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() \
trcKERNEL_HOOKS_TASK_SWITCH(TRACE_GET_CURRENT_TASK());
uiTraceSystemState = TRC_STATE_IN_TASKSWITCH; \
trcKERNEL_HOOKS_TASK_SWITCH(TRACE_GET_CURRENT_TASK()); \
uiTraceSystemState = TRC_STATE_IN_APPLICATION;
/* Called on vTaskCreate */
#undef traceTASK_CREATE
@ -863,6 +962,7 @@ extern traceObjectClass TraceQueueClassTable[5];
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) */
@ -876,6 +976,7 @@ extern traceObjectClass TraceQueueClassTable[5];
{ 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)
@ -970,18 +1071,24 @@ extern traceObjectClass TraceQueueClassTable[5];
/* 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_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(TRACE_GET_OBJECT_EVENT_CODE(SEND, TRCFAILED, QUEUE, pxQueue), QUEUE, 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(TRACE_GET_OBJECT_EVENT_CODE(SEND, TRCBLOCK, QUEUE, pxQueue), QUEUE, 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
@ -1046,13 +1153,13 @@ extern traceObjectClass TraceQueueClassTable[5];
/* 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_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(TRACE_GET_OBJECT_EVENT_CODE(SEND_FROM_ISR, TRCFAILED, QUEUE, pxQueue), QUEUE, 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
@ -1094,7 +1201,7 @@ extern traceObjectClass TraceQueueClassTable[5];
trcKERNEL_HOOKS_TASK_RESUME_FROM_ISR(TASK_RESUME_FROM_ISR, pxTaskToResume);
#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X)
#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X)
#if (TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1)
@ -1104,7 +1211,13 @@ extern void vTraceStoreMemMangEvent(uint32_t ecode, uint32_t address, int32_t si
#undef traceMALLOC
#define traceMALLOC( pvAddress, uiSize ) \
if (pvAddress != 0) \
vTraceStoreMemMangEvent(MEM_MALLOC_SIZE, ( uint32_t ) pvAddress, (int32_t)uiSize);
{ \
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 ) \
@ -1174,7 +1287,7 @@ extern void vTraceStoreMemMangEvent(uint32_t ecode, uint32_t address, int32_t si
#endif /* (TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS == 1) */
#endif /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X) */
#endif /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X) */
#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1)
@ -1252,18 +1365,30 @@ extern void vTraceStoreMemMangEvent(uint32_t ecode, uint32_t address, int32_t si
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){ \
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)
@ -1275,11 +1400,20 @@ extern void vTraceStoreMemMangEvent(uint32_t ecode, uint32_t address, int32_t si
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) \
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); \
@ -1287,26 +1421,52 @@ extern void vTraceStoreMemMangEvent(uint32_t ecode, uint32_t address, int32_t si
#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)
@ -1615,6 +1775,10 @@ uint32_t prvIsNewTCB(void* pNewTCB);
#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 */
@ -1630,26 +1794,40 @@ uint32_t prvIsNewTCB(void* pNewTCB);
/* 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
#if TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_3_0
#define traceTASK_INCREMENT_TICK( xTickCount ) \
if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || uxMissedTicks == 0) { extern uint32_t uiTraceTickCount; uiTraceTickCount++; } \
if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || xPendedTicks == 0) { extern uint32_t uiTraceTickCount; uiTraceTickCount++; } \
OS_TICK_EVENT(uxSchedulerSuspended, xTickCount)
#else
#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)
#endif /* TRC_CFG_FREERTOS_VERSION <= TRC_FREERTOS_VERSION_7_4 */
#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)
@ -1664,7 +1842,8 @@ uint32_t prvIsNewTCB(void* pNewTCB);
#define traceTASK_CREATE(pxNewTCB) \
if (pxNewTCB != NULL) \
{ \
prvTraceSaveSymbol(pxNewTCB, pxNewTCB->pcTaskName); \
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); \
@ -1676,7 +1855,8 @@ uint32_t prvIsNewTCB(void* pNewTCB);
#define traceTASK_CREATE(pxNewTCB) \
if (pxNewTCB != NULL) \
{ \
prvTraceSaveSymbol(pxNewTCB, (const char*)pcName); \
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); \
@ -1699,7 +1879,8 @@ uint32_t prvIsNewTCB(void* pNewTCB);
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);
prvTraceDeleteObjectData(pxTaskToDelete); \
prvRemoveTaskFromStackMonitor(pxTaskToDelete);
#if (TRC_CFG_SCHEDULING_ONLY == 0)
@ -1832,19 +2013,19 @@ uint32_t prvIsNewTCB(void* pNewTCB);
/* Called in xQueueCreateCountingSemaphore, if the queue creation fails */
#undef traceCREATE_COUNTING_SEMAPHORE
#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X)
#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_OR_7_6)
#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)
#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) \
@ -1856,18 +2037,18 @@ uint32_t prvIsNewTCB(void* pNewTCB);
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 */
#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)
#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_OR_7_6)
#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)
#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);
@ -1875,7 +2056,7 @@ uint32_t prvIsNewTCB(void* pNewTCB);
#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 */
#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X */
/* This macro is not necessary as of FreeRTOS v9.0.0 */
@ -1927,6 +2108,12 @@ uint32_t prvIsNewTCB(void* pNewTCB);
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 ) \
@ -1967,28 +2154,6 @@ uint32_t prvIsNewTCB(void* pNewTCB);
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 ) \
@ -2218,13 +2383,29 @@ BaseType_t MyWrapper(__a, __b, const BaseType_t xCopyPosition)
#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) \
prvTraceStoreEvent2(PSF_EVENT_MALLOC, (uint32_t)pvAddress, uiSize);
{ \
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... */
@ -2236,8 +2417,8 @@ BaseType_t MyWrapper(__a, __b, const BaseType_t xCopyPosition)
#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); \
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);
@ -2247,7 +2428,7 @@ BaseType_t MyWrapper(__a, __b, const BaseType_t xCopyPosition)
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)
#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); \
@ -2264,9 +2445,9 @@ BaseType_t MyWrapper(__a, __b, const BaseType_t xCopyPosition)
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 */
#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 */
#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
@ -2381,68 +2562,113 @@ BaseType_t MyWrapper(__a, __b, const BaseType_t xCopyPosition)
#endif /* (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1) */
#undef traceTASK_NOTIFY_TAKE
#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0)
#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_9_0_0 */
#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_9_0_0 */
#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_9_0_0)
#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_9_0_0 */
#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_9_0_0 */
#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) \
prvTraceSaveSymbol(object, (const char*)name); \
prvTraceSaveObjectSymbol(object, (const char*)name); \
prvTraceStoreStringEvent(1, PSF_EVENT_OBJ_NAME, name, object);
#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1)

@ -1,5 +1,5 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v4.1.5
* Trace Recorder Library for Tracealyzer v4.3.11
* Percepio AB, www.percepio.com
*
* trcPortDefines.h
@ -130,8 +130,9 @@
#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 */
#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*/

@ -1,5 +1,5 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v4.1.5
* Trace Recorder Library for Tracealyzer v4.3.11
* Percepio AB, www.percepio.com
*
* trcRecorder.h
@ -51,29 +51,38 @@ extern "C" {
#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
#else /* (TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1) */
typedef uint8_t traceHandle;
#endif
#endif /* (TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1) */
#include "trcHardwarePort.h"
#include "trcKernelPort.h"
// Not available in snapshot mode
#define vTraceConsoleChannelPrintF(fmt, ...)
/* Not yet available in snapshot mode */
#define vTraceConsoleChannelPrintF(fmt, ...) (void)(fmt)
#define prvTraceStoreEvent0(...)
#define prvTraceStoreEvent1(...)
#define prvTraceStoreEvent2(...)
#define prvTraceStoreEvent3(...)
#define prvTraceStoreEvent(...)
#define prvTraceStoreStringEvent(...)
#endif
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT) */
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
@ -84,10 +93,14 @@ typedef const void* traceHandle;
#include "trcStreamingPort.h"
#include "trcKernelPort.h"
#endif
#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;
@ -223,7 +236,20 @@ void vTraceEnable(int startOption);
#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
#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
/******************************************************************************
@ -240,7 +266,7 @@ void vTracePrintF(traceString chn, const char* fmt, ...);
#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
#define vTracePrint(chn, str) (void)(chn), (void)(str) /* Comma operator is used to avoid "unused variable" compiler warnings in a single statement */
#endif
@ -276,7 +302,7 @@ void vTraceConsoleChannelPrintF(const char* fmt, ...);
#if (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)
traceString xTraceRegisterString(const char* name);
#else
#define xTraceRegisterString(x) (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 */
#endif
/*******************************************************************************
@ -430,7 +456,7 @@ void vTraceSetFrequency(uint32_t frequency);
#if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM)
void vTraceSetRecorderDataBuffer(void* pRecorderData);
#else
#define vTraceSetRecorderDataBuffer(pRecorderData)
#define vTraceSetRecorderDataBuffer(pRecorderData) /* If not CUSTOM, pRecorderData will be an undefined symbol (same as in TRC_ALLOC_CUSTOM_BUFFER), so no (void) here */
#endif
@ -476,7 +502,7 @@ void vTraceSetRecorderDataBuffer(void* pRecorderData);
#endif
#endif
#else
#define TRC_ALLOC_CUSTOM_BUFFER(bufname)
#define TRC_ALLOC_CUSTOM_BUFFER(bufname) /* If not CUSTOM, bufname will be an undefined symbol (same as in vTraceSetRecorderDataBuffer), so no (void) here */
#endif
/******************************************************************************
@ -732,12 +758,22 @@ void vTraceClear(void);
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) \
@ -856,6 +892,15 @@ void prvTraceStoreKernelCallWithParam(uint32_t evtcode, traceObjectClass objectC
#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);
@ -880,16 +925,16 @@ void prvTraceStoreObjectPropertiesOnCloseEvent(uint8_t evtcode, traceHandle hand
#if (TRC_CFG_INCLUDE_ISR_TRACING == 0)
#undef vTraceSetISRProperties
#define vTraceSetISRProperties(handle, name, priority)
#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
#define vTraceStoreISRBegin(x) (void)(x)
#undef vTraceStoreISREnd
#define vTraceStoreISREnd(x) (void)x
#define vTraceStoreISREnd(x) (void)(x)
#undef xTraceSetISRProperties
#define xTraceSetISRProperties(name, priority) 0
#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)*/
@ -928,17 +973,19 @@ void vTraceUBEvent(traceUBChannel channel);
#else /*((TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_SCHEDULING_ONLY == 0))*/
#undef vTracePrint
#define vTracePrint(chn, ...) (void)chn
#define vTracePrint(chn, ...) (void)(chn)
#undef vTracePrintF
#define vTracePrintF(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 */
#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) 0; (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 */
#undef xTraceRegisterChannelFormat
#define xTraceRegisterChannelFormat(eventLabel, formatStr) 0
#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, ...) {}
#define vTraceUBData(label, ...) (void)(label)
#undef vTraceChannelPrint
#define vTraceChannelPrint(label) {}
#define vTraceChannelPrint(label) (void)(label)
#endif /*(TRC_CFG_INCLUDE_USER_EVENTS == 1)*/
@ -1433,7 +1480,7 @@ if (!(eval)) \
#endif
/******************************************************************************
* TRC_STREAM_PORT_ON_TRACE_BEGIN
* TRC_STREAM_PORT_ON_TRACE_END
*
* Defining any actions needed in the stream port when the tracing stops.
* Empty by default.
@ -1450,12 +1497,34 @@ if (!(eval)) \
* 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);
#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
@ -1480,11 +1549,17 @@ if (!(eval)) \
/******************************************************************************
* 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
@ -1498,12 +1573,46 @@ if (!(eval)) \
#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) \
{ \
if (TRC_STREAM_PORT_WRITE_DATA(_ptrData, _size, 0) != 0)\
prvTraceWarning(PSF_WARNING_STREAM_PORT_WRITE); \
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
@ -1659,20 +1768,26 @@ void prvTraceWarning(int errCode);
#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 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
#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 (task name etc.) in symbol table */
void prvTraceSaveSymbol(const void *address, const char *name);
/* 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);
@ -1735,42 +1850,43 @@ int prvIsValidCommand(TracealyzerCommandType* cmd);
/* Executed the received command (Start or Stop) */
void prvProcessCommand(TracealyzerCommandType* cmd);
#define vTraceSetStopHook(x)
#define vTraceSetStopHook(x) (void)(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 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) 0
#define vTraceStoreKernelObjectName(a, b)
#define xTraceRegisterChannelFormat(eventLabel, formatStr) 0
#define vTraceChannelPrint(label)
#define vTraceUBData(label, ...)
#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)
#define vTraceSetFilterMask(x)
#define vTraceSetFilterGroup(x) (void)(x)
#define vTraceSetFilterMask(x) (void)(x)
#define prvTraceSetReadyEventsEnabled(status)
#define prvTraceSetReadyEventsEnabled(status) (void)(status)
#define vTraceExcludeTask(handle)
#define vTraceExcludeTask(handle) (void)(handle)
#define uiTraceStart() (1)
#define vTraceStart()
#define vTraceStop()
#ifndef vTraceSetRecorderDataBuffer
#define vTraceSetRecorderDataBuffer(pRecorderData)
#define vTraceSetRecorderDataBuffer(pRecorderData) /* No (void) here - ignore parameter since undefined symbol if custom allocation is not used */
#endif
#define vTraceConsoleChannelPrintF(fmt, ...)
#define vTraceConsoleChannelPrintF(fmt, ...) (void)(fmt)
#ifndef TRC_ALLOC_CUSTOM_BUFFER
#define TRC_ALLOC_CUSTOM_BUFFER(bufname)
@ -1778,7 +1894,7 @@ void prvProcessCommand(TracealyzerCommandType* cmd);
#define xTraceIsRecordingEnabled() (0)
#define vTraceSetStopHook(x)
#define vTraceSetStopHook(x) (void)(x)
#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/

@ -1,5 +1,5 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v4.1.4
* Trace Recorder Library for Tracealyzer v4.3.11
* Percepio AB, www.percepio.com
*
* trcConfig.h
@ -105,16 +105,25 @@ extern "C" {
* 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_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 or later
* 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 FREERTOS_VERSION_NOT_SET
/*******************************************************************************
* TRC_CFG_SCHEDULING_ONLY
@ -171,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.
*
@ -254,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 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
*
@ -287,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 0 /* TRC_ACKNOWLEDGED */
/* Specific configuration, depending on Streaming/Snapshot mode */
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)
#include "trcSnapshotConfig.h"

@ -1,5 +1,5 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v4.1.4
* Trace Recorder Library for Tracealyzer v4.3.11
* Percepio AB, www.percepio.com
*
* trcSnapshotConfig.h

@ -1,5 +1,5 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v4.1.4
* Trace Recorder Library for Tracealyzer v4.3.11
* Percepio AB, www.percepio.com
*
* trcStreamingConfig.h
@ -89,34 +89,6 @@ extern "C" {
******************************************************************************/
#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
*
@ -125,18 +97,20 @@ extern "C" {
*
* Note: not used by the J-Link RTT stream port (see trcStreamingPort.h instead)
******************************************************************************/
#define TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT 2
#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).
* 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 2500
#define TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE 500
/*******************************************************************************
* TRC_CFG_ISR_TAILCHAINING_THRESHOLD

@ -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.

@ -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

@ -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 */

@ -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

@ -13,12 +13,16 @@ 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/
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 https://percepio.com/2018/05/04/keil-itm-support/
- 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

@ -1,5 +1,5 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v4.1.5
* Trace Recorder Library for Tracealyzer v4.3.11
* Percepio AB, www.percepio.com
*
* trcStreamingPort.h
@ -7,6 +7,52 @@
* 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

@ -1,3 +1,96 @@
/*******************************************************************************
* 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"
@ -6,7 +99,12 @@
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.
/* 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 */

@ -1,5 +1,5 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v4.1.5
* Trace Recorder Library for Tracealyzer v4.3.11
* Percepio AB, www.percepio.com
*
* trcStreamingPort.h

@ -1,5 +1,5 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v4.1.5
* Trace Recorder Library for Tracealyzer v4.3.11
* Percepio AB, www.percepio.com
*
* trcStreamingPort.c

@ -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.

@ -1,5 +1,5 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v4.1.5
* Trace Recorder Library for Tracealyzer v4.3.11
* Percepio AB, www.percepio.com
*
* trcStreamingPort.h

@ -1,3 +1,52 @@
/*******************************************************************************
* 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"
@ -15,11 +64,6 @@ int32_t readFromRTT(void* ptrData, uint32_t size, int32_t* ptrBytesRead)
if (ptrBytesRead != NULL)
*ptrBytesRead = (int32_t)bytesRead;
if (bytesRead != size)
{
return -1;
}
}
return 0;
@ -32,11 +76,6 @@ int32_t writeToRTT(void* ptrData, uint32_t size, int32_t* ptrBytesWritten)
if (ptrBytesWritten != NULL)
*ptrBytesWritten = (int32_t)bytesWritten;
if (bytesWritten != size)
{
return -1;
}
return 0;
}

@ -9,12 +9,40 @@ 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!
Instructions:
Note that lwIP is not included, but assumed to exist in the project already.
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.

@ -1,5 +1,5 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v4.1.5
* Trace Recorder Library for Tracealyzer v4.3.11
* Percepio AB, www.percepio.com
*
* trcStreamingPort.h
@ -51,6 +51,8 @@
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);

@ -1,5 +1,5 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v4.1.5
* Trace Recorder Library for Tracealyzer v4.3.11
* Percepio AB, www.percepio.com
*
* trcStreamingPort.c
@ -53,8 +53,7 @@
/* TCP/IP includes - for lwIP in this case */
#include "lwip/tcpip.h"
#include "lwip/sockets.h"
int errno;
#include "lwip/errno.h"
#define TRC_TCPIP_PORT 12000
@ -75,7 +74,7 @@ int32_t trcSocketSend( void* data, int32_t size, int32_t* bytesWritten )
if (*bytesWritten < 0)
{
/* EWOULDBLOCK may be expected when buffers are full */
if (errno != 0 && errno != EWOULDBLOCK)
if ((errno != 0) && (errno != EWOULDBLOCK))
{
closesocket(new_sd);
new_sd = -1;
@ -94,8 +93,6 @@ int32_t trcSocketReceive( void* data, int32_t size, int32_t* bytesRead )
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)
{
@ -103,9 +100,6 @@ int32_t trcSocketReceive( void* data, int32_t size, int32_t* bytesRead )
new_sd = -1;
return -1;
}
else
*bytesRead = 0;
}
return 0;
}
@ -152,9 +146,6 @@ int32_t trcSocketAccept()
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);
@ -164,6 +155,9 @@ int32_t trcSocketAccept()
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 ****************/

@ -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

@ -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 */

@ -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)*/

@ -1,5 +1,5 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v4.1.5
* Trace Recorder Library for Tracealyzer v4.3.11
* Percepio AB, www.percepio.com
*
* trcStreamingPort.h

@ -1,3 +1,48 @@
/*******************************************************************************
* 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"

@ -23,6 +23,82 @@ 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.

@ -1,5 +1,5 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v4.1.5
* Trace Recorder Library for Tracealyzer v4.3.11
* Percepio AB, www.percepio.com
*
* trcKernelPort.c
@ -102,24 +102,55 @@
#include "task.h"
#include "queue.h"
#if (TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X)
#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) */
#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)
#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) */
#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)
#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 );
@ -134,7 +165,7 @@ uint32_t prvTraceGetQueueNumber(void* handle)
{
return (uint32_t)uxQueueGetQueueNumber(handle);
}
#endif /* (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_8_X) */
#endif /* (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_8_X_X) */
uint8_t prvTraceGetQueueType(void* handle)
{
@ -252,36 +283,161 @@ 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) */
#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 (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_CORTEX_A9)
#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
#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;
/* 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;
@ -294,9 +450,6 @@ static void prvCheckRecorderStatus(void);
extern void prvTraceWarning(int errCode);
/* The TzCtrl task - receives commands from Tracealyzer (start/stop) */
static portTASK_FUNCTION( TzCtrl, pvParameters );
/*******************************************************************************
* vTraceEnable
*
@ -316,8 +469,16 @@ void vTraceEnable(int startOption)
{
TRC_STREAM_PORT_INIT();
/* Note: Requires that TRC_CFG_INCLUDE_USER_EVENTS is 1. */
trcWarningChannel = xTraceRegisterString("Warnings from Recorder");
/* 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)
@ -418,7 +579,7 @@ 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)
#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X)
/*******************************************************************************
* vTraceSetEventGroupName(void* object, const char* name)
*
@ -431,7 +592,7 @@ 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) */
#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)
/*******************************************************************************
@ -505,7 +666,6 @@ unsigned char prvTraceIsSchedulerSuspended(void)
return xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED;
}
/*******************************************************************************
* prvCheckRecorderStatus
*
@ -515,40 +675,36 @@ unsigned char prvTraceIsSchedulerSuspended(void)
******************************************************************************/
static void prvCheckRecorderStatus(void)
{
if (NoRoomForSymbol > NoRoomForSymbol_last)
#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_last = NoRoomForSymbol;
NoRoomForSymbol = 0;
}
if (NoRoomForObjectData > NoRoomForObjectData_last)
{
if (NoRoomForObjectData > 0)
{
prvTraceWarning(PSF_WARNING_OBJECT_DATA_SLOTS);
}
NoRoomForObjectData_last = NoRoomForObjectData;
NoRoomForObjectData = 0;
}
if (LongestSymbolName > LongestSymbolName_last)
{
if (LongestSymbolName > (TRC_CFG_SYMBOL_MAX_LENGTH))
{
prvTraceWarning(PSF_WARNING_SYMBOL_MAX_LENGTH);
}
LongestSymbolName_last = LongestSymbolName;
LongestSymbolName = 0;
}
if (MaxBytesTruncated > MaxBytesTruncated_last)
{
if (MaxBytesTruncated > 0)
{
prvTraceWarning(PSF_WARNING_STRING_TOO_LONG);
}
MaxBytesTruncated_last = MaxBytesTruncated;
MaxBytesTruncated = 0;
}
}
@ -576,7 +732,8 @@ static portTASK_FUNCTION( TzCtrl, pvParameters )
if (status != 0)
{
prvTraceWarning(PSF_WARNING_STREAM_PORT_READ);
/* The connection has failed, stop tracing */
vTraceStop();
}
if ((status == 0) && (bytes == sizeof(TracealyzerCommandType)))
@ -599,7 +756,11 @@ static portTASK_FUNCTION( TzCtrl, pvParameters )
} while (bytes != 0);
if (xTraceIsRecordingEnabled())
{
prvCheckRecorderStatus();
prvReportStackUsage();
}
vTaskDelay(TRC_CFG_CTRL_TASK_DELAY);
}
@ -666,7 +827,7 @@ 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)
#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X)
/*******************************************************************************
* vTraceSetEventGroupName(void* object, const char* name)
*
@ -679,7 +840,7 @@ 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) */
#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)
/*******************************************************************************
@ -716,6 +877,95 @@ 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()
{

@ -1,5 +1,5 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v4.1.5
* Trace Recorder Library for Tracealyzer v4.3.11
* Percepio AB, www.percepio.com
*
* trcSnapshotRecorder.c
@ -81,6 +81,9 @@ 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;
@ -152,15 +155,6 @@ static uint32_t heapMemUsage = 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
*
@ -177,8 +171,6 @@ 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);
@ -198,58 +190,6 @@ uint16_t uiIndexOfObject(traceHandle objecthandle, uint8_t objectclass);
******************************************************************************/
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
*
@ -925,34 +865,39 @@ static uint8_t prvTraceUserEventFormat(const char* formatStr, va_list vl, uint8_
{
if (formatStr[formatStrIndex] == '%')
{
argCounter++;
if (argCounter > 15)
if (formatStr[formatStrIndex + 1] == '%')
{
prvTraceError("vTracePrintF - Too many arguments, max 15 allowed!");
return 0;
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,
case 'd':
i = writeInt32( buffer,
i,
(uint32_t)va_arg(vl, uint32_t));
break;
case 'x':
case 'X':
case 'u': i = writeInt32( buffer,
case 'u':
i = writeInt32( buffer,
i,
(uint32_t)va_arg(vl, uint32_t));
break;
case 's': i = writeInt16( buffer,
case 's':
i = writeInt16( buffer,
i,
xTraceRegisterString((char*)va_arg(vl, char*)));
break;
@ -961,7 +906,8 @@ static uint8_t prvTraceUserEventFormat(const char* formatStr, va_list vl, uint8_
/* 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,
case 'f':
i = writeFloat( buffer,
i,
(float)va_arg(vl, double));
break;
@ -971,7 +917,8 @@ static uint8_t prvTraceUserEventFormat(const char* formatStr, va_list vl, uint8_
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,
case 'f':
i = writeInt32( buffer,
i,
(uint32_t)va_arg(vl, double));
break;
@ -990,7 +937,8 @@ static uint8_t prvTraceUserEventFormat(const char* formatStr, va_list vl, uint8_
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 */
case 'f':
i = writeInt32( buffer, /* In this case, the value will not be shown anyway */
i,
(uint32_t)va_arg(vl, double));
@ -999,18 +947,19 @@ static uint8_t prvTraceUserEventFormat(const char* formatStr, va_list vl, uint8_
(uint32_t)va_arg(vl, double));
break;
#endif
}
break;
case 'h':
formatStrIndex++;
switch (formatStr[formatStrIndex])
{
case 'd': i = writeInt16( buffer,
case 'd':
i = writeInt16( buffer,
i,
(uint16_t)va_arg(vl, uint32_t));
break;
case 'u': i = writeInt16( buffer,
case 'u':
i = writeInt16( buffer,
i,
(uint16_t)va_arg(vl, uint32_t));
break;
@ -1020,17 +969,28 @@ static uint8_t prvTraceUserEventFormat(const char* formatStr, va_list vl, uint8_
formatStrIndex++;
switch (formatStr[formatStrIndex])
{
case 'd': i = writeInt8( buffer,
case 'd':
i = writeInt8( buffer,
i,
(uint8_t)va_arg(vl, uint32_t));
break;
case 'u': i = writeInt8( buffer,
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
@ -1333,13 +1293,20 @@ void vTracePrintF(traceString eventLabel, const char* formatStr, ...)
va_list vl;
va_start(vl, formatStr);
vTracePrintF_Helper(eventLabel, formatStr, vl);
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 vTracePrintF_Helper(traceString eventLabel, const char* formatStr, va_list vl)
void vTraceVPrintF(traceString eventLabel, const char* formatStr, va_list vl)
{
#if (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 0)
uint32_t noOfSlots;
@ -1347,7 +1314,7 @@ void vTracePrintF_Helper(traceString eventLabel, const char* formatStr, va_list
uint32_t tempDataBuffer[(3 + MAX_ARG_SIZE) / 4];
TRACE_ALLOC_CRITICAL_SECTION();
TRACE_ASSERT(formatStr != NULL, "vTracePrintF_Helper: formatStr == NULL", TRC_UNUSED);
TRACE_ASSERT(formatStr != NULL, "vTraceVPrintF: formatStr == NULL", TRC_UNUSED);
trcCRITICAL_SECTION_BEGIN();
@ -1679,7 +1646,9 @@ void vTraceStoreMemMangEvent(uint32_t ecode, uint32_t address, int32_t signed_si
trcCRITICAL_SECTION_BEGIN();
heapMemUsage = heapMemUsage + (uint32_t)signed_size;
/* Only update heapMemUsage if we have a valid address */
if (address != 0)
heapMemUsage += (uint32_t)signed_size;
if (RecorderDataPtr->recorderActive)
{

Loading…
Cancel
Save