You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
FreeRTOS/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcExtensions.h

423 lines
15 KiB
C

/*******************************************************************************
* Trace Recorder Library for Tracealyzer v4.4.0
* 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_ */