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.
423 lines
15 KiB
C
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_ */
|