Update FreeRTOS+Trace recorder library to v3.0.2

Add streaming version of the FreeRTOS+Trace recorder, also V3.0.2
This commit is contained in:
Richard Barry
2015-10-09 13:30:09 +00:00
parent f218cf5680
commit 96ff3925d2
32 changed files with 6067 additions and 123 deletions
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,45 @@
Release notes, Trace Recorder Library for Tracealyzer v3.0.2
September 29, 2015. Percepio AB.
Changes:
v3.0.2
- Fixed bug in tracing of nested interrupts.
- Made locally used variables and functions static.
v3.0.1
- Added vTraceOnTraceBegin()/vTraceOnTraceEnd() in trcKernelPort.c to allow custom cleanup via macros TRC_STREAM_PORT_ON_TRACE_BEGIN()/TRC_STREAM_PORT_ON_TRACE_END().
v3.0.0
- Modified trcTCPIP functions to take bytes written/read as parameters and instead return potential errors.
- Added vTraceOnTraceBegin()/vTraceOnTraceEnd() in trcKernelPort that in turn uses macros from trcStreamPort.h to allow transfer method defined (as well as user defined) actions where appropriate. Currently only used by TCP/IP to re-initialize the paged event buffer so no old data is sent on trace start.
v2.8.6
- Changed void* to uint32_t to ensure 32bit for vTraceStoreEvent1(), vTraceStoreEvent2() and vTraceStoreEvent3().
- Added prefix TRC to most macros to avoid conflicts.
- Moved all trace stream macros to trcStreamPort.h.
- Now allows users to define their own trace stream macros. First specify TRC_RECORDER_TRANSFER_METHOD_CUSTOM and then modify the TRC_STREAM_CUSTOM_XXXXXXXXX macros.
- Added trcPagedEventBuffer that can be used to avoid endless recursion for trace stream methods that use kernel objects (semaphores, mutexes) when sending data.
- Added trcTCPIP/trcTCPIPConfig for easy trace stream integration with custom TCP/IP stacks.
v2.8.5
- Added internal OS tick counter that can be used by certain kernel ports to keep track of the actual OS tick, in case it can be delayed.
- Updated generic macro names.
- Removed usage of strlen().
- Added support for width and padding formats for %d, %u, %x and %X.
- Reduced RAM usage for certain cases by redefining unused buffers.
- Fixed traceTAKE_MUTEX_RECURSIVE_FAILED being called traceTAKE_MUTEX_RECURSIVE resulting in duplicate defines.
- Implemented fix for missing parameter "xCopyPosition" when using "xSemaphoreGiveFromISR()" in FreeRTOS v8.
- Added prefix to internal defines to avoid conflicts.
- Fixed possible memory alignment issue which could cause hard fault.
- Made sure TzCtrl runs every 100ms instead of every 100 OS ticks.
- Moved project specific includes to trcConfig.h.
- Added a few backwards compatibility macros.
v2.8.2
- Improved vTracePrintF() parsing.
- Added vTracePrint() that performs no formatting.
- Removed need for passing parameter to vTraceStoreISREnd() on embOS port. This parameter is detected automatically.
- Added vTraceStoreISREndManual(param) that can be used on kernel ports that doesn't automatically detect pending task switches after interrupts.
v2.8.1
- New J-Link drivers fixes the RTT Buffer Index != 0 issue.
- trcRecorder.c hotfixed to handle missing defines in embOS that haven't made it to release yet.
v2.8.0
- Initial release. Only RTT Buffer Index 0 works in this version.
For questions, contact support@percepio.com or sales@percepio.com
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,110 @@
/*********************************************************************
* SEGGER MICROCONTROLLER SYSTEME GmbH *
* Solutions for real time microcontroller applications *
**********************************************************************
* *
* (c) 1996-2014 SEGGER Microcontroller Systeme GmbH *
* *
* Internet: www.segger.com Support: support@segger.com *
* *
**********************************************************************
----------------------------------------------------------------------
File : SEGGER_RTT.h
Date : 17 Dec 2014
Purpose : Implementation of SEGGER real-time terminal which allows
real-time terminal communication on targets which support
debugger memory accesses while the CPU is running.
---------------------------END-OF-HEADER------------------------------
*/
/*********************************************************************
*
* Defines
*
**********************************************************************
*/
#define SEGGER_RTT_MODE_MASK (3 << 0)
#define SEGGER_RTT_MODE_NO_BLOCK_SKIP (0)
#define SEGGER_RTT_MODE_NO_BLOCK_TRIM (1 << 0)
#define SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL (1 << 1)
#define RTT_CTRL_RESET ""
#define RTT_CTRL_CLEAR ""
#define RTT_CTRL_TEXT_BLACK ""
#define RTT_CTRL_TEXT_RED ""
#define RTT_CTRL_TEXT_GREEN ""
#define RTT_CTRL_TEXT_YELLOW ""
#define RTT_CTRL_TEXT_BLUE ""
#define RTT_CTRL_TEXT_MAGENTA ""
#define RTT_CTRL_TEXT_CYAN ""
#define RTT_CTRL_TEXT_WHITE ""
#define RTT_CTRL_TEXT_BRIGHT_BLACK ""
#define RTT_CTRL_TEXT_BRIGHT_RED ""
#define RTT_CTRL_TEXT_BRIGHT_GREEN ""
#define RTT_CTRL_TEXT_BRIGHT_YELLOW ""
#define RTT_CTRL_TEXT_BRIGHT_BLUE ""
#define RTT_CTRL_TEXT_BRIGHT_MAGENTA ""
#define RTT_CTRL_TEXT_BRIGHT_CYAN ""
#define RTT_CTRL_TEXT_BRIGHT_WHITE ""
#define RTT_CTRL_BG_BLACK ""
#define RTT_CTRL_BG_RED ""
#define RTT_CTRL_BG_GREEN ""
#define RTT_CTRL_BG_YELLOW ""
#define RTT_CTRL_BG_BLUE ""
#define RTT_CTRL_BG_MAGENTA ""
#define RTT_CTRL_BG_CYAN ""
#define RTT_CTRL_BG_WHITE ""
#define RTT_CTRL_BG_BRIGHT_BLACK ""
#define RTT_CTRL_BG_BRIGHT_RED ""
#define RTT_CTRL_BG_BRIGHT_GREEN ""
#define RTT_CTRL_BG_BRIGHT_YELLOW ""
#define RTT_CTRL_BG_BRIGHT_BLUE ""
#define RTT_CTRL_BG_BRIGHT_MAGENTA ""
#define RTT_CTRL_BG_BRIGHT_CYAN ""
#define RTT_CTRL_BG_BRIGHT_WHITE ""
/*********************************************************************
*
* RTT API functions
*
**********************************************************************
*/
int SEGGER_RTT_Read (unsigned BufferIndex, char* pBuffer, unsigned BufferSize);
int SEGGER_RTT_Write (unsigned BufferIndex, const char* pBuffer, unsigned NumBytes);
int SEGGER_RTT_WriteString (unsigned BufferIndex, const char* s);
int SEGGER_RTT_GetKey (void);
int SEGGER_RTT_WaitKey (void);
int SEGGER_RTT_HasKey (void);
int SEGGER_RTT_ConfigUpBuffer (unsigned BufferIndex, const char* sName, char* pBuffer, int BufferSize, int Flags);
int SEGGER_RTT_ConfigDownBuffer (unsigned BufferIndex, const char* sName, char* pBuffer, int BufferSize, int Flags);
void SEGGER_RTT_Init (void);
/*********************************************************************
*
* RTT "Terminal" API functions
*
**********************************************************************
*/
void SEGGER_RTT_SetTerminal (char TerminalId);
int SEGGER_RTT_TerminalOut (char TerminalId, const char* s);
/*********************************************************************
*
* RTT printf functions (require SEGGER_RTT_printf.c)
*
**********************************************************************
*/
int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...);
/*************************** End of file ****************************/
@@ -0,0 +1,57 @@
/*********************************************************************
* SEGGER MICROCONTROLLER SYSTEME GmbH *
* Solutions for real time microcontroller applications *
**********************************************************************
* *
* (c) 1996-2014 SEGGER Microcontroller Systeme GmbH *
* *
* Internet: www.segger.com Support: support@segger.com *
* *
**********************************************************************
----------------------------------------------------------------------
File : SEGGER_RTT_Conf.h
Date : 17 Dec 2014
Purpose : Implementation of SEGGER real-time terminal which allows
real-time terminal communication on targets which support
debugger memory accesses while the CPU is running.
---------------------------END-OF-HEADER------------------------------
*/
/*********************************************************************
*
* Defines, configurable
*
**********************************************************************
*/
#define SEGGER_RTT_MAX_NUM_UP_BUFFERS (2) // Max. number of up-buffers (T->H) available on this target (Default: 2)
#define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (2) // Max. number of down-buffers (H->T) available on this target (Default: 2)
#define BUFFER_SIZE_UP (10 * 1024) // Size of the buffer for terminal output of target, up to host (Default: 1k)
#define BUFFER_SIZE_DOWN (32) // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16)
#define SEGGER_RTT_PRINTF_BUFFER_SIZE (64) // Size of buffer for RTT printf to bulk-send chars via RTT (Default: 64)
//
// 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.
// If using RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here.
//
#define SEGGER_RTT_LOCK()
#define SEGGER_RTT_UNLOCK()
//
// Define SEGGER_RTT_IN_RAM as 1
// when using RTT in RAM targets (init and data section both in RAM).
// This prevents the host to falsly identify the RTT Callback Structure
// in the init segment as the used Callback Structure.
//
// When defined as 1,
// the first call to an RTT function will modify the ID of the RTT Callback Structure.
// To speed up identifying on the host,
// especially when RTT functions are not called at the beginning of execution,
// SEGGER_RTT_Init() should be called at the start of the application.
//
#define SEGGER_RTT_IN_RAM (0)
/*************************** End of file ****************************/
@@ -0,0 +1,443 @@
/*********************************************************************
* SEGGER MICROCONTROLLER GmbH & Co. KG *
* Solutions for real time microcontroller applications *
**********************************************************************
* *
* (c) 2014-2014 SEGGER Microcontroller GmbH & Co. KG *
* *
* Internet: www.segger.com Support: support@segger.com *
* *
**********************************************************************
----------------------------------------------------------------------
File : SEGGER_RTT_printf.c
Date : 17 Dec 2014
Purpose : Replacement for printf to write formatted data via RTT
---------------------------END-OF-HEADER------------------------------
*/
#include "SEGGER_RTT.h"
#include "SEGGER_RTT_Conf.h"
/*********************************************************************
*
* Defines, configurable
*
**********************************************************************
*/
#ifndef SEGGER_RTT_PRINTF_BUFFER_SIZE
#define SEGGER_RTT_PRINTF_BUFFER_SIZE (64)
#endif
#include <stdlib.h>
#include <stdarg.h>
#define FORMAT_FLAG_LEFT_JUSTIFY (1 << 0)
#define FORMAT_FLAG_PAD_ZERO (1 << 1)
#define FORMAT_FLAG_PRINT_SIGN (1 << 2)
#define FORMAT_FLAG_ALTERNATE (1 << 3)
/*********************************************************************
*
* Types
*
**********************************************************************
*/
typedef struct {
char* pBuffer;
int BufferSize;
int Cnt;
int ReturnValue;
unsigned RTTBufferIndex;
} SEGGER_RTT_PRINTF_DESC;
/*********************************************************************
*
* Function prototypes
*
**********************************************************************
*/
int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList);
/*********************************************************************
*
* Static code
*
**********************************************************************
*/
/*********************************************************************
*
* _StoreChar
*/
static void _StoreChar(SEGGER_RTT_PRINTF_DESC * p, char c) {
int Cnt;
Cnt = p->Cnt;
if ((Cnt + 1) <= p->BufferSize) {
*(p->pBuffer + Cnt) = c;
p->Cnt = Cnt + 1;
p->ReturnValue++;
}
//
// Write part of string, when the buffer is full
//
if (p->Cnt == p->BufferSize) {
if (SEGGER_RTT_Write(p->RTTBufferIndex, p->pBuffer, p->Cnt) != p->Cnt) {
p->ReturnValue = -1;
} else {
p->Cnt = 0;
}
}
}
/*********************************************************************
*
* _PrintUnsigned
*/
static void _PrintUnsigned(SEGGER_RTT_PRINTF_DESC * pBufferDesc, unsigned v, unsigned Base, int NumDigits, unsigned FieldWidth, unsigned FormatFlags) {
static const char _aV2C[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
unsigned Div;
unsigned Digit = 1;
unsigned Number;
unsigned Width;
char c;
Number = v;
//
// Get actual field width
//
Width = 1;
while (Number >= Base) {
Number = (Number / Base);
Width++;
}
if ((unsigned)NumDigits > Width) {
Width = NumDigits;
}
//
// Print leading chars if necessary
//
if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0) {
if (FieldWidth != 0) {
if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && (NumDigits == 0)) {
c = '0';
} else {
c = ' ';
}
while ((FieldWidth != 0) && (Width < FieldWidth--)) {
_StoreChar(pBufferDesc, c);
if (pBufferDesc->ReturnValue < 0) {
return;
}
}
}
}
//
// Count how many digits are required by precision
//
while (((v / Digit) >= Base) | (NumDigits-- > 1)) {
Digit *= Base;
}
//
// Output digits
//
do {
Div = v / Digit;
v -= Div * Digit;
_StoreChar(pBufferDesc, _aV2C[Div]);
if (pBufferDesc->ReturnValue < 0) {
break;
}
Digit /= Base;
} while (Digit);
//
// Print trailing spaces if necessary
//
if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == FORMAT_FLAG_LEFT_JUSTIFY) {
if (FieldWidth != 0) {
while ((FieldWidth != 0) && (Width < FieldWidth--)) {
_StoreChar(pBufferDesc, ' ');
if (pBufferDesc->ReturnValue < 0) {
return;
}
}
}
}
}
/*********************************************************************
*
* _PrintInt
*/
static void _PrintInt(SEGGER_RTT_PRINTF_DESC * pBufferDesc, int v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) {
unsigned Width;
unsigned Number;
Number = (v < 0) ? -v : v;
//
// Get actual field width
//
Width = 1;
while (Number >= Base) {
Number = (Number / Base);
Width++;
}
if (NumDigits > Width) {
Width = NumDigits;
}
if ((FieldWidth > 0) && ((v < 0) || ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN))) {
FieldWidth--;
}
//
// Print leading spaces if necessary
//
if ((((FormatFlags & FORMAT_FLAG_PAD_ZERO) == 0) || (NumDigits != 0)) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0)) {
if (FieldWidth != 0) {
while ((FieldWidth != 0) && (Width < FieldWidth--)) {
_StoreChar(pBufferDesc, ' ');
if (pBufferDesc->ReturnValue < 0) {
return;
}
}
}
}
//
// Print sign if necessary
//
if (v < 0) {
v = -v;
_StoreChar(pBufferDesc, '-');
if (pBufferDesc->ReturnValue < 0) {
return;
}
} else if ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN) {
_StoreChar(pBufferDesc, '+');
if (pBufferDesc->ReturnValue < 0) {
return;
}
}
//
// Print leading zeros if necessary
//
if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0) && (NumDigits == 0)) {
if (FieldWidth != 0) {
while ((FieldWidth != 0) && (Width < FieldWidth--)) {
_StoreChar(pBufferDesc, '0');
if (pBufferDesc->ReturnValue < 0) {
return;
}
}
}
}
//
// Print number without sign
//
_PrintUnsigned(pBufferDesc, v, Base, NumDigits, FieldWidth, FormatFlags);
}
/*********************************************************************
*
* Public code
*
**********************************************************************
*/
/*********************************************************************
*
* SEGGER_RTT_vprintf
*
* Function description
* Stores a formatted string in SEGGER RTT control block.
* This data is read by the host.
*
* Parameters
* BufferIndex Index of "Up"-buffer to be used. (e.g. 0 for "Terminal")
* sFormat Pointer to format string
* pParamList Pointer to the list of arguments for the format string
*
* Return values
* >= 0: Number of bytes which have been stored in the "Up"-buffer.
* < 0: Error
*/
int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList) {
char c;
SEGGER_RTT_PRINTF_DESC BufferDesc;
int v;
unsigned NumDigits;
unsigned FormatFlags;
unsigned FieldWidth;
char acBuffer[SEGGER_RTT_PRINTF_BUFFER_SIZE];
BufferDesc.pBuffer = acBuffer;
BufferDesc.BufferSize = SEGGER_RTT_PRINTF_BUFFER_SIZE;
BufferDesc.Cnt = 0;
BufferDesc.RTTBufferIndex = BufferIndex;
BufferDesc.ReturnValue = 0;
do {
c = *sFormat++;
if (c == 0) {
break;
}
if (c == '%') {
//
// Filter out flags
//
FormatFlags = 0;
do {
c = *sFormat;
switch (c) {
case '-': FormatFlags |= FORMAT_FLAG_LEFT_JUSTIFY; sFormat++; break;
case '0': FormatFlags |= FORMAT_FLAG_PAD_ZERO; sFormat++; break;
case '+': FormatFlags |= FORMAT_FLAG_PRINT_SIGN; sFormat++; break;
case '#': FormatFlags |= FORMAT_FLAG_ALTERNATE; sFormat++; break;
default: goto FilterFieldWidth; break;
}
} while (1);
//
// filter out field with
//
FilterFieldWidth:
FieldWidth = 0;
do {
c = *sFormat;
if (c < '0' || c > '9') {
break;
}
sFormat++;
FieldWidth = FieldWidth * 10 + (c - '0');
} while (1);
//
// Filter out precision (number of digits to display)
//
NumDigits = 0;
c = *sFormat;
if (c == '.') {
sFormat++;
do {
c = *sFormat;
if (c < '0' || c > '9') {
break;
}
sFormat++;
NumDigits = NumDigits * 10 + (c - '0');
} while (1);
}
//
// Filter out length modifier
//
c = *sFormat;
do {
if (c == 'l' || c == 'h') {
c = *sFormat++;
continue;
}
break;
} while (1);
//
// Handle specifiers
//
switch (c) {
case 'c': {
char c0;
v = va_arg(*pParamList, int);
c0 = (char)v;
_StoreChar(&BufferDesc, c0);
break;
}
case 'd':
v = va_arg(*pParamList, int);
_PrintInt(&BufferDesc, v, 10, NumDigits, FieldWidth, FormatFlags);
break;
case 'u':
v = va_arg(*pParamList, int);
_PrintUnsigned(&BufferDesc, v, 10, NumDigits, FieldWidth, FormatFlags);
break;
case 'x':
case 'X':
v = va_arg(*pParamList, int);
_PrintUnsigned(&BufferDesc, v, 16, NumDigits, FieldWidth, FormatFlags);
break;
case 's':
{
const char * s = va_arg(*pParamList, const char *);
do {
c = *s++;
if (c == 0) {
break;
}
_StoreChar(&BufferDesc, c);
} while (BufferDesc.ReturnValue >= 0);
}
break;
case 'p':
v = va_arg(*pParamList, int);
_PrintUnsigned(&BufferDesc, v, 16, 8, 8, 0);
break;
case '%':
_StoreChar(&BufferDesc, '%');
break;
}
sFormat++;
} else {
_StoreChar(&BufferDesc, c);
}
} while (BufferDesc.ReturnValue >= 0);
if (BufferDesc.ReturnValue > 0) {
//
// Write remaining data, if any
//
if (BufferDesc.Cnt != 0) {
SEGGER_RTT_Write(BufferIndex, acBuffer, BufferDesc.Cnt);
}
BufferDesc.ReturnValue += BufferDesc.Cnt;
}
return BufferDesc.ReturnValue;
}
/*********************************************************************
*
* SEGGER_RTT_printf
*
* Function description
* Stores a formatted string in SEGGER RTT control block.
* This data is read by the host.
*
* Parameters
* BufferIndex Index of "Up"-buffer to be used. (e.g. 0 for "Terminal")
* sFormat Pointer to format string, followed by the arguments for conversion
*
* Return values
* >= 0: Number of bytes which have been stored in the "Up"-buffer.
* < 0: Error
*
* Notes
* (1) Conversion specifications have following syntax:
* %[flags][FieldWidth][.Precision]ConversionSpecifier
* (2) Supported flags:
* -: Left justify within the field width
* +: Always print sign extension for signed conversions
* 0: Pad with 0 instead of spaces. Ignored when using '-'-flag or precision
* Supported conversion specifiers:
* c: Print the argument as one char
* d: Print the argument as a signed integer
* u: Print the argument as an unsigned integer
* x: Print the argument as an hexadecimal integer
* s: Print the string pointed to by the argument
* p: Print the argument as an 8-digit hexadecimal integer. (Argument shall be a pointer to void.)
*/
int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...) {
va_list ParamList;
va_start(ParamList, sFormat);
return SEGGER_RTT_vprintf(BufferIndex, sFormat, &ParamList);
}
/*************************** End of file ****************************/
@@ -0,0 +1,326 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v3.0.2
* Percepio AB, www.percepio.com
*
* trcConfig.h
*
* Configuration parameters for the streaming version trace recorder library.
* Before using the trace recorder library, please check that the default
* settings are appropriate for your system, and if necessary adjust these.
*
* Terms of Use
* This software (the "Tracealyzer Recorder Library") is the intellectual
* property of Percepio AB and may not be sold or in other ways commercially
* redistributed without explicit written permission by Percepio AB.
*
* Separate conditions applies for the SEGGER branded source code included.
*
* The recorder library is free for use together with Percepio products.
* You may distribute the recorder library in its original form, but public
* distribution of modified versions require approval by Percepio AB.
*
* Disclaimer
* The trace tool and recorder library is being delivered to you AS IS and
* Percepio AB makes no warranty as to its use or performance. Percepio AB does
* not and cannot warrant the performance or results you may obtain by using the
* software or documentation. Percepio AB 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 AB, 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 AB 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, 2015.
* www.percepio.com
******************************************************************************/
#ifndef TRC_CONFIG_H
#define TRC_CONFIG_H
#ifdef __cplusplus
extern “C” {
#endif
/*******************************************************************************
* Configuration Macro: TRC_RECORDER_HARDWARE_PORT
*
* Specify what hardware is used.
*
* See trcHardwarePort.h for available ports, or to define your own.
******************************************************************************/
#define TRC_RECORDER_HARDWARE_PORT TRC_PORT_ARM_Cortex_M
/******************************************************************************
* BSP and other project specific includes
*
* Include the necessary header files.
*****************************************************************************/
#include "board.h"
/******************************************************************************
* TRC_FREERTOS_VERSION
*
* Specify what version of FreeRTOS that is used. This is necessary compensate
* for renamed symbols in the FreeRTOS kernel (does not build if incorrect).
*
* TRC_FREERTOS_VERSION_7_3_OR_7_4 (= 1) If using FreeRTOS v7.3.0 - v7.4.2
* TRC_FREERTOS_VERSION_7_5_OR_7_6 (= 2) If using FreeRTOS v7.5.0 - v7.6.0
* TRC_FREERTOS_VERSION_8_0_OR_LATER (= 3) If using FreeRTOS v8.0.0 or later
*****************************************************************************/
#define TRC_FREERTOS_VERSION_NOT_SET 0
#define TRC_FREERTOS_VERSION_7_3_OR_7_4 1
#define TRC_FREERTOS_VERSION_7_5_OR_7_6 2
#define TRC_FREERTOS_VERSION_8_0_OR_LATER 3
#define TRC_FREERTOS_VERSION TRC_FREERTOS_VERSION_8_0_OR_LATER
/*******************************************************************************
* Configuration Macro: TRC_SYMBOL_TABLE_SLOTS
*
* The maximum number of symbols names that can be stored. This includes:
* - Task names
* - Named ISRs (vTraceSetISRProperties)
* - Named kernel objects (vTraceStoreKernelObjectName)
* - User event channels (vTraceStoreUserEventChannelName)
*
* If this value is too small, not all symbol names will be stored and the
* trace display will be affected. In that case, there will be warnings
* (as User Events) from TzCtrl task, that monitors this.
******************************************************************************/
#define TRC_SYMBOL_TABLE_SLOTS 30
/*******************************************************************************
* Configuration Macro: TRC_SYMBOL_MAX_LENGTH
*
* The maximum length of symbol names, including:
* - Task names
* - Named ISRs (vTraceSetISRProperties)
* - Named kernel objects (vTraceStoreKernelObjectName)
* - User event channel names (vTraceStoreUserEventChannelName)
*
* If longer symbol names are used, they will be truncated by the recorder,
* which will affect the trace display. In that case, there will be warnings
* (as User Events) from TzCtrl task, that monitors this.
******************************************************************************/
#define TRC_SYMBOL_MAX_LENGTH 25
/*******************************************************************************
* Configuration Macro: TRC_OBJECT_DATA_SLOTS
*
* The maximum number of object data entries (used for task priorities) that can
* be stored at the same time. Must be sufficient for all tasks, otherwise there
* will be warnings (as User Events) from TzCtrl task, that monitors this.
******************************************************************************/
#define TRC_OBJECT_DATA_SLOTS 20
/*******************************************************************************
* Configuration Macro: TRC_RTT_UP_BUFFER_INDEX
*
* Defines the RTT buffer to use for writing the trace data. Make sure that
* the PC application has the same setting (File->Settings).
*
******************************************************************************/
#define TRC_RTT_UP_BUFFER_INDEX 0
/*******************************************************************************
* Configuration Macro: TRC_RTT_DOWN_BUFFER_INDEX
*
* Defines the RTT buffer to use for reading the trace data. Make sure that
* the PC application has the same setting (File->Settings).
*
******************************************************************************/
#define TRC_RTT_DOWN_BUFFER_INDEX 0
/*******************************************************************************
* Configuration Macro: TRC_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_CTRL_TASK_STACK_SIZE (configMINIMAL_STACK_SIZE * 2)
/*******************************************************************************
* Configuration Macro: TRC_CTRL_TASK_PRIORITY
*
* The priority of the TzCtrl task, that receive commands from.
* We are aiming to remove this extra task in future versions.
******************************************************************************/
#define TRC_CTRL_TASK_PRIORITY 1
/*******************************************************************************
* Configuration Macro: TRC_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_CTRL_TASK_DELAY ((10 * configTICK_RATE_HZ) / 1000)
/*******************************************************************************
* Configuration Macro: TRC_MEASURE_BLOCKING_TIME
*
* If using SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL, this activates detection and
* warnings in case of blocking in SEGGER_RTT_Write (if too small buffer).
*
* If enabling this option (set to 1) warnings are given as User Events if
* blocking occurs, including the longest blocking time. These warnings are
* given on the channel "Blocking on trace buffer".
*
* Note: If you get such warnings, you can study the blocking time in the User
* Event Signal Plot to get an overview of the magnitude of the blocking and
* decide if acceptable.
*
* To eliminate or at least reduce occurrences of blocking:
*
* - Verify the J-Link Speed in the Settings dialog of the PC application.
* Default is 4 MHz, but can be increased a lot depending on your J-Link.
*
* Note: If you set the speed higher than your J-Link can manage, the J-Link
* driver will instead use the fastest supported speed. The actual speed used
* is shown in the title of the trace receiver window.
*
* - Increase the buffer size (BUFFER_SIZE_UP in SEGGER_RTT_Conf.h).
*
* - Reduce the amount of data produced, e.g., by removing frequent User Events.
******************************************************************************/
#define TRC_MEASURE_BLOCKING_TIME 0
/*******************************************************************************
* Configuration Macro: TRC_BLOCKING_MIN_CYCLES
*
* Threshold value for deciding if SEGGER_RTT_Write has blocked. Most events
* take 200-300 cycles on ARM Cortex-M MCUs, so anything above 500 cycles should
* be due to blocking on a full buffer (i.e., waiting for the debugger to read
* the RTT buffer data and make room for more...).
******************************************************************************/
#define TRC_BLOCKING_MIN_CYCLES 500
/*******************************************************************************
* Configuration Macro: TRC_RECORDER_BUFFER_ALLOCATION
*
* Specifies how the recorder buffer is allocated.
*
* Values:
* TRC_RECORDER_BUFFER_ALLOCATION_STATIC
* TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC
******************************************************************************/
#define TRC_RECORDER_BUFFER_ALLOCATION TRC_RECORDER_BUFFER_ALLOCATION_STATIC
/*******************************************************************************
* Configuration Macro: TRC_RECORDER_TRANSFER_METHOD
*
* Specifies what type of transfer method is used.
*
* Values:
* TRC_RECORDER_TRANSFER_METHOD_JLINK_RTT_BLOCK
* TRC_RECORDER_TRANSFER_METHOD_JLINK_RTT_NOBLOCK
* TRC_RECORDER_TRANSFER_METHOD_TCPIP
* TRC_RECORDER_TRANSFER_METHOD_CUSTOM
******************************************************************************/
#define TRC_RECORDER_TRANSFER_METHOD TRC_RECORDER_TRANSFER_METHOD_JLINK_RTT_BLOCK
/*******************************************************************************
* Configuration Macro: TRC_STREAM_CUSTOM_BLOCKING_TRANSFER
*
* Note: Only active if TRC_RECORDER_TRANSFER_METHOD_CUSTOM is used.
*
* Specifies how the custom transfer method handles full buffers.
*
* Values:
* 0 - The custom transfer method skips sending the data if the buffer is full.
* 1 - The custom transfer method blocks on send if the buffer is full.
******************************************************************************/
#define TRC_STREAM_CUSTOM_BLOCKING_TRANSFER
/*******************************************************************************
* Configuration Macro: TRC_STREAM_CUSTOM_ALLOCATE_FIELDS
*
* Note: Only active if TRC_RECORDER_TRANSFER_METHOD_CUSTOM is used.
*
* Macro that should allocate any buffers needed for the transfer method.
* See trcStreamPort.h for examples.
******************************************************************************/
#define TRC_STREAM_CUSTOM_ALLOCATE_FIELDS()
/*******************************************************************************
* Configuration Macro: TRC_STREAM_CUSTOM_INIT
*
* Note: Only active if TRC_RECORDER_TRANSFER_METHOD_CUSTOM is used.
*
* Used to initialize and set up the transfer method.
* See trcStreamPort.h for examples.
******************************************************************************/
#define TRC_STREAM_CUSTOM_INIT()
/*******************************************************************************
* Configuration Macro: TRC_STREAM_CUSTOM_ALLOCATE_EVENT
*
* Note: Only active if TRC_RECORDER_TRANSFER_METHOD_CUSTOM is used.
*
* Specifies how the trace events that should be sent using the transfer method
* are allocated first.
* See trcStreamPort.h for examples.
******************************************************************************/
#define TRC_STREAM_CUSTOM_ALLOCATE_EVENT(_type, _ptr, _size)
/*******************************************************************************
* Configuration Macro: TRC_STREAM_CUSTOM_COMMIT_EVENT
*
* Note: Only active if TRC_RECORDER_TRANSFER_METHOD_CUSTOM is used.
*
* Specifies how trace events are sent/written.
* See trcStreamPort.h for examples.
******************************************************************************/
#define TRC_STREAM_CUSTOM_COMMIT_EVENT(_ptr, _size)
/*******************************************************************************
* Configuration Macro: TRC_STREAM_CUSTOM_READ_DATA
*
* Note: Only active if TRC_RECORDER_TRANSFER_METHOD_CUSTOM is used.
*
* Specifies how data is read using the transfer method.
* See trcStreamPort.h for examples.
******************************************************************************/
#define TRC_STREAM_CUSTOM_READ_DATA(_ptrData, _size, _ptrBytesRead)
/*******************************************************************************
* Configuration Macro: TRC_STREAM_CUSTOM_PERIODIC_SEND_DATA
*
* Note: Only active if TRC_RECORDER_TRANSFER_METHOD_CUSTOM is used.
*
* Specifies how data is sent periodically. Used by certain transfer methods.
* See trcStreamPort.h for examples.
******************************************************************************/
#define TRC_STREAM_CUSTOM_PERIODIC_SEND_DATA(_ptrBytesSent)
/*******************************************************************************
* Configuration Macro: TRC_STREAM_CUSTOM_ON_TRACE_BEGIN
*
* Note: Only active if TRC_RECORDER_TRANSFER_METHOD_CUSTOM is used.
*
* Called on tracing is started. Use this to perform any necessary steps to
* properly start the trace, such as clearing buffers.
******************************************************************************/
#define TRC_STREAM_CUSTOM_ON_TRACE_BEGIN()
/*******************************************************************************
* Configuration Macro: TRC_STREAM_CUSTOM_ON_TRACE_END
*
* Note: Only active if TRC_RECORDER_TRANSFER_METHOD_CUSTOM is used.
*
* Called when tracing is disabled. Use this to perform any necessary steps to
* properly shut down the tracing, such as clearing buffers.
******************************************************************************/
#define TRC_STREAM_CUSTOM_ON_TRACE_END()
#ifdef __cplusplus
}
#endif
#endif /* TRC_CONFIG_H */
@@ -0,0 +1,194 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v3.0.2
* Percepio AB, www.percepio.com
*
* trcHardwarePort.h
*
* The hardware abstraction layer for the trace recorder library.
*
* Terms of Use
* This software (the "Tracealyzer Recorder Library") is the intellectual
* property of Percepio AB and may not be sold or in other ways commercially
* redistributed without explicit written permission by Percepio AB.
*
* Separate conditions applies for the SEGGER branded source code included.
*
* The recorder library is free for use together with Percepio products.
* You may distribute the recorder library in its original form, but public
* distribution of modified versions require approval by Percepio AB.
*
* Disclaimer
* The trace tool and recorder library is being delivered to you AS IS and
* Percepio AB makes no warranty as to its use or performance. Percepio AB does
* not and cannot warrant the performance or results you may obtain by using the
* software or documentation. Percepio AB 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 AB, 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 AB 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, 2015.
* www.percepio.com
******************************************************************************/
#ifndef TRC_HARDWARE_PORT_H
#define TRC_HARDWARE_PORT_H
#ifdef __cplusplus
extern “C” {
#endif
#include <stdint.h>
/******************************************************************************
* Hardware ports
* To get accurate timestamping, a hardware timer is necessary. Below are the
* available ports. Some of these are "unofficial", meaning that
* they have not yet been verified by Percepio but have been contributed by
* external developers. They should work, otherwise let us know by emailing
* support@percepio.com. Some work on any OS platform, while other are specific
* to a certain operating system.
*****************************************************************************/
/****** Port Name ***************************** Code */
#define TRC_PORT_APPLICATION_DEFINED -1
#define TRC_PORT_NOT_SET 0
#define TRC_PORT_ARM_Cortex_M 1
#define TRC_PORT_ARM_CORTEX_A9 2
#define TRC_PORT_Renesas_RX600 3
#define TRC_PORT_TEXAS_INSTRUMENTS_TMS570_RM48 4
#define TRC_PORT_MICROCHIP_PIC32_MX_MZ 5
/*******************************************************************************
*
* HWTC Macros - Hardware Timer/Counter Isolation Layer
*
* These two HWTC macros provides a hardware isolation layer representing a
* generic hardware timer/counter used for the timestamping.
*
* HWTC_COUNT: The current value of the counter. This is expected to be reset
* a each tick interrupt. Thus, when the tick handler starts, the counter has
* already wrapped.
*
* HWTC_TYPE: Defines the type of timer/counter used for HWTC_COUNT:
*
* - FREE_RUNNING_32BIT_INCR:
* Free-running 32-bit timer, counting upwards from 0 - > 0xFFFFFFFF
*
* - FREE_RUNNING_32BIT_DECR
* Free-running 32-bit counter, counting downwards from 0xFFFFFFFF -> 0
*
* - OS_TIMER_INCR
* Interrupt timer, counts upwards from 0 until HWTC_PERIOD-1
*
* - OS_TIMER_DECR
* Interrupt timer, counts downwards from HWTC_PERIOD-1 until 0
*
*******************************************************************************
*
* IRQ_PRIORITY_ORDER
*
* Macro which should be defined as an integer of 0 or 1.
*
* It is only used only to sort and colorize the interrupts in priority order,
* in case you record interrupts using the vTraceStoreISRBegin and
* vTraceStoreISREnd routines. 1 indicates higher value is more important.
*
******************************************************************************/
#define TRC_FREE_RUNNING_32BIT_INCR 1
#define TRC_FREE_RUNNING_32BIT_DECR 2
#define TRC_OS_TIMER_INCR 3
#define TRC_OS_TIMER_DECR 4
#if (TRC_RECORDER_HARDWARE_PORT == TRC_PORT_ARM_Cortex_M)
#define HWTC_TYPE TRC_OS_TIMER_DECR
#define HWTC_COUNT (*((uint32_t*)0xE000E018)) /* SysTick counter */
#define IRQ_PRIORITY_ORDER 0
#elif (TRC_RECORDER_HARDWARE_PORT == TRC_PORT_Renesas_RX600)
#include "iodefine.h"
#define HWTC_TYPE TRC_OS_TIMER_INCR
#define HWTC_COUNT (CMT0.CMCNT)
#define IRQ_PRIORITY_ORDER 1
#elif (TRC_RECORDER_HARDWARE_PORT == TRC_PORT_MICROCHIP_PIC32_MX_MZ)
#define HWTC_TYPE TRC_OS_TIMER_INCR
#define HWTC_COUNT (TMR1)
#define IRQ_PRIORITY_ORDER 0
#elif (TRC_RECORDER_HARDWARE_PORT == TRC_PORT_TEXAS_INSTRUMENTS_TMS570_RM48)
#define RTIFRC0 *((uint32_t *)0xFFFFFC10)
#define RTICOMP0 *((uint32_t *)0xFFFFFC50)
#define RTIUDCP0 *((uint32_t *)0xFFFFFC54)
#define HWTC_TYPE TRC_OS_TIMER_INCR
#define HWTC_COUNT (RTIFRC0 - (RTICOMP0 - RTIUDCP0))
#define IRQ_PRIORITY_ORDER 0
#elif (TRC_RECORDER_HARDWARE_PORT == TRC_PORT_ARM_CORTEX_A9)
/* INPUT YOUR PERIPHERAL BASE ADDRESS HERE */
#define CA9_MPCORE_PERIPHERAL_BASE_ADDRESS 0xSOMETHING
#define CA9_MPCORE_PRIVATE_MEMORY_OFFSET 0x0600
#define CA9_MPCORE_PRIVCTR_PERIOD_REG (*(volatile uint32_t*)(CA9_MPCORE_PERIPHERAL_BASE_ADDRESS + CA9_MPCORE_PRIVATE_MEMORY_OFFSET + 0x00))
#define CA9_MPCORE_PRIVCTR_COUNTER_REG (*(volatile uint32_t*)(CA9_MPCORE_PERIPHERAL_BASE_ADDRESS + CA9_MPCORE_PRIVATE_MEMORY_OFFSET + 0x04))
#define CA9_MPCORE_PRIVCTR_CONTROL_REG (*(volatile uint32_t*)(CA9_MPCORE_PERIPHERAL_BASE_ADDRESS + CA9_MPCORE_PRIVATE_MEMORY_OFFSET + 0x08))
#define CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_MASK 0x0000FF00
#define CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_SHIFT 8
#define CA9_MPCORE_PRIVCTR_PRESCALER (((CA9_MPCORE_PRIVCTR_CONTROL_REG & CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_MASK) >> CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_SHIFT) + 1)
#define HWTC_TYPE TRC_OS_TIMER_DECR
#define HWTC_COUNT CA9_MPCORE_PRIVCTR_COUNTER_REG
#define IRQ_PRIORITY_ORDER 0
#elif (TRC_RECORDER_HARDWARE_PORT == TRC_PORT_APPLICATION_DEFINED)
#if !( defined (HWTC_TYPE) && defined (HWTC_COUNT) && defined (IRQ_PRIORITY_ORDER))
#error RECORDER_HARDWARE_PORT is PORT_APPLICATION_DEFINED but not all of the necessary constants have been defined.
#endif
#elif (TRC_RECORDER_HARDWARE_PORT != TRC_PORT_NOT_SET)
#error "RECORDER_HARDWARE_PORT had unsupported value!"
#define TRC_RECORDER_HARDWARE_PORT PORT_NOT_SET
#endif
#if (TRC_RECORDER_HARDWARE_PORT != TRC_PORT_NOT_SET)
#ifndef HWTC_COUNT
#error "HWTC_COUNT is not set!"
#endif
#ifndef HWTC_TYPE
#error "HWTC_TYPE is not set!"
#endif
#ifndef IRQ_PRIORITY_ORDER
#error "IRQ_PRIORITY_ORDER is not set!"
#elif (IRQ_PRIORITY_ORDER != 0) && (IRQ_PRIORITY_ORDER != 1)
#error "IRQ_PRIORITY_ORDER has bad value!"
#endif
#endif
#ifdef __cplusplus
}
#endif
#endif /* TRC_HARDWARE_PORT_H */
@@ -0,0 +1,267 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v3.0.2
* Percepio AB, www.percepio.com
*
* trcKernelPort.c
*
* The kernel-specific code for integration with FreeRTOS.
*
* Terms of Use
* This software (the "Tracealyzer Recorder Library") is the intellectual
* property of Percepio AB and may not be sold or in other ways commercially
* redistributed without explicit written permission by Percepio AB.
*
* Separate conditions applies for the SEGGER branded source code included.
*
* The recorder library is free for use together with Percepio products.
* You may distribute the recorder library in its original form, but public
* distribution of modified versions require approval by Percepio AB.
*
* Disclaimer
* The trace tool and recorder library is being delivered to you AS IS and
* Percepio AB makes no warranty as to its use or performance. Percepio AB does
* not and cannot warrant the performance or results you may obtain by using the
* software or documentation. Percepio AB 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 AB, 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 AB 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, 2015.
* www.percepio.com
******************************************************************************/
#include "trcKernelPort.h"
#if (USE_TRACEALYZER_RECORDER == 1)
#include <stdint.h>
#include "trcRecorder.h"
#include "trcStreamPort.h"
#include "task.h"
/* TzCtrl task TCB */
static xTaskHandle HandleTzCtrl;
/* Called by TzCtrl task periodically (every 100 ms) */
static void CheckRecorderStatus(void);
/* The TzCtrl task - receives commands from Tracealyzer (start/stop) */
static portTASK_FUNCTION( TzCtrl, pvParameters );
/* 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;
#define TRC_PORT_MALLOC(size) pvPortMalloc(size)
#if ((TRC_STREAM_PORT_BLOCKING_TRANSFER == 1) && (TRC_MEASURE_BLOCKING_TIME == 1))
/*** Used in blocking transfer mode, if enabled TRC_MEASURE_BLOCKING_TIME **************/
/* The highest number of cycles used by SEGGER_RTT_Write. */
static volatile int32_t blockingCyclesMax;
/* The number of times SEGGER_RTT_Write has blocked due to a full buffer. */
static volatile uint32_t blockingCount;
/* User Event Channel for giving warnings regarding blocking */
static char* trcDiagnosticsChannel;
#endif /*((TRC_STREAM_PORT_BLOCKING_TRANSFER==1) && (TRC_MEASURE_BLOCKING_TIME))*/
TRC_STREAM_PORT_ALLOCATE_FIELDS()
/* User Event Channel for giving warnings regarding NoRoomForSymbol etc. */
char* trcWarningChannel;
/* 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;
/*******************************************************************************
* prvTraceGetCurrentTaskHandle
*
* Function that returns the handle to the currently executing task.
*
******************************************************************************/
void* prvTraceGetCurrentTaskHandle(void)
{
return xTaskGetCurrentTaskHandle();
}
/*******************************************************************************
* prvIsNewTCB
*
* Function that returns the handle to the currently executing task.
*
******************************************************************************/
static void* pCurrentTCB = NULL;
uint32_t prvIsNewTCB(void* pNewTCB)
{
if (pCurrentTCB != pNewTCB)
{
pCurrentTCB = pNewTCB;
return 1;
}
return 0;
}
/*******************************************************************************
* CheckRecorderStatus
*
* Called by TzCtrl task periodically (every 100 ms - seems reasonable).
* Checks a number of diagnostic variables and give warnings as user events,
* in most cases including a suggested solution.
******************************************************************************/
static void CheckRecorderStatus(void)
{
if (NoRoomForSymbol > NoRoomForSymbol_last)
{
vTracePrintF(trcWarningChannel, "TRC_SYMBOL_TABLE_SLOTS too small. Add %d slots.",
NoRoomForSymbol);
NoRoomForSymbol_last = NoRoomForSymbol;
}
if (NoRoomForObjectData > NoRoomForObjectData_last)
{
vTracePrintF(trcWarningChannel, "TRC_OBJECT_DATA_SLOTS too small. Add %d slots.",
NoRoomForObjectData);
NoRoomForObjectData_last = NoRoomForObjectData;
}
if (LongestSymbolName > LongestSymbolName_last)
{
if (LongestSymbolName > TRC_SYMBOL_MAX_LENGTH)
{
vTracePrintF(trcWarningChannel, "TRC_SYMBOL_MAX_LENGTH too small. Add %d chars.",
LongestSymbolName);
}
LongestSymbolName_last = LongestSymbolName;
}
if (MaxBytesTruncated > MaxBytesTruncated_last)
{
/* Some string event generated a too long string that was truncated.
This may happen for the following functions:
- vTracePrintF
- vTracePrintF
- vTraceStoreKernelObjectName
- vTraceStoreUserEventChannelName
- vTraceSetISRProperties
A PSF event may store maximum 60 bytes payload, including data arguments
and string characters. For User Events, also the User Event Channel ptr
must be squeezed in, if a channel is specified. */
vTracePrintF(trcWarningChannel, "String event too long, up to %d bytes truncated.",
MaxBytesTruncated);
MaxBytesTruncated_last = MaxBytesTruncated;
}
#if ((TRC_STREAM_PORT_BLOCKING_TRANSFER==1) && (TRC_MEASURE_BLOCKING_TIME))
if (blockingCount > 0)
{
/* At least one case of blocking since the last check and this is
the longest case. */
vTracePrintF(trcDiagnosticsChannel, "Longest since last: %d us",
(uint32_t)blockingCyclesMax/(TRACE_CPU_CLOCK_HZ/1000000));
blockingCyclesMax = 0;
}
#endif
}
/*******************************************************************************
* vTraceOnTraceBegin
*
* Called on trace begin.
******************************************************************************/
void vTraceOnTraceBegin(void)
{
TRC_STREAM_PORT_ON_TRACE_BEGIN();
}
/*******************************************************************************
* vTraceOnTraceEnd
*
* Called on trace end.
******************************************************************************/
void vTraceOnTraceEnd(void)
{
TRC_STREAM_PORT_ON_TRACE_END();
}
/*******************************************************************************
* TzCtrl
*
* Task for receiving commands from Tracealyzer and for recorder diagnostics.
*
******************************************************************************/
static portTASK_FUNCTION( TzCtrl, pvParameters )
{
TracealyzerCommandType msg;
int bytes = 0;
while (1)
{
bytes = 0;
TRC_STREAM_PORT_READ_DATA(&msg, sizeof(TracealyzerCommandType), &bytes);
if (bytes != 0)
{
if (bytes == sizeof(TracealyzerCommandType))
{
if (isValidCommand(&msg))
{
processCommand(&msg); /* Start or Stop currently... */
}
}
}
do
{
bytes = 0;
TRC_STREAM_PORT_PERIODIC_SEND_DATA(&bytes);
}
while (bytes != 0);
CheckRecorderStatus();
vTaskDelay(TRC_CTRL_TASK_DELAY); /* 10ms */
}
}
/*******************************************************************************
* Trace_Init
*
* The main initialization routine for the trace recorder. Configures the stream
* and activates the TzCtrl task.
* Also sets up the diagnostic User Event channels used by TzCtrl task.
*
******************************************************************************/
void Trace_Init(void)
{
TRC_STREAM_PORT_INIT();
trcWarningChannel = vTraceStoreUserEventChannelName("Warnings from Recorder");
#if ((TRC_STREAM_PORT_BLOCKING_TRANSFER==1) && (TRC_MEASURE_BLOCKING_TIME))
trcDiagnosticsChannel = vTraceStoreUserEventChannelName("Blocking on trace buffer");
#endif
/* Creates the TzCtrl task - receives trace commands (start, stop, ...) */
xTaskCreate( TzCtrl, "TzCtrl", configMINIMAL_STACK_SIZE, NULL, TRC_CTRL_TASK_PRIORITY, &HandleTzCtrl );
}
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,302 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v3.0.2
* Percepio AB, www.percepio.com
*
* trcPagedEventBuffer.c
*
* Implements a paged buffer that can be used by TCP/IP or custom transfer
* methods.
*
* Terms of Use
* This software (the "Tracealyzer Recorder Library") is the intellectual
* property of Percepio AB and may not be sold or in other ways commercially
* redistributed without explicit written permission by Percepio AB.
*
* Separate conditions applies for the SEGGER branded source code included.
*
* The recorder library is free for use together with Percepio products.
* You may distribute the recorder library in its original form, but public
* distribution of modified versions require approval by Percepio AB.
*
* Disclaimer
* The trace tool and recorder library is being delivered to you AS IS and
* Percepio AB makes no warranty as to its use or performance. Percepio AB does
* not and cannot warrant the performance or results you may obtain by using the
* software or documentation. Percepio AB 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 AB, 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 AB 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, 2015.
* www.percepio.com
******************************************************************************/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "trcConfig.h"
#include "trcPagedEventBuffer.h"
#include "trcPagedEventBufferConfig.h"
#include "trcKernelPort.h"
uint32_t DroppedEventCounter = 0; // Total number of dropped events (failed allocations)
uint32_t TotalBytesRemaining_LowWaterMark = TRC_PAGED_EVENT_BUFFER_PAGE_COUNT * TRC_PAGED_EVENT_BUFFER_PAGE_SIZE;
#if (USE_TRACEALYZER_RECORDER == 1)
#define PAGE_STATUS_FREE 0
#define PAGE_STATUS_WRITE 1
#define PAGE_STATUS_READ 2
uint32_t TotalBytesRemaining = TRC_PAGED_EVENT_BUFFER_PAGE_COUNT * TRC_PAGED_EVENT_BUFFER_PAGE_SIZE;
typedef struct{
uint8_t Status;
uint16_t BytesRemaining;
char* WritePointer;
} PageType;
PageType PageInfo[TRC_PAGED_EVENT_BUFFER_PAGE_COUNT];
char* EventBuffer = NULL;
static void prvPageReadComplete(int pageIndex);
static int prvAllocateBufferPage(int prevPage);
static int prvAllocateBufferPage(int prevPage)
{
int index;
int count = 0;
index = (prevPage + 1) % TRC_PAGED_EVENT_BUFFER_PAGE_COUNT;
while((PageInfo[index].Status != PAGE_STATUS_FREE) && (count ++ < TRC_PAGED_EVENT_BUFFER_PAGE_COUNT))
{
index = (index + 1) % TRC_PAGED_EVENT_BUFFER_PAGE_COUNT;
}
if (PageInfo[index].Status == PAGE_STATUS_FREE)
{
return index;
}
return -1;
}
static void prvPageReadComplete(int pageIndex)
{
TRACE_ALLOC_CRITICAL_SECTION();
TRACE_ENTER_CRITICAL_SECTION();
PageInfo[pageIndex].BytesRemaining = TRC_PAGED_EVENT_BUFFER_PAGE_SIZE;
PageInfo[pageIndex].WritePointer = &EventBuffer[pageIndex * TRC_PAGED_EVENT_BUFFER_PAGE_SIZE];
PageInfo[pageIndex].Status = PAGE_STATUS_FREE;
TotalBytesRemaining += TRC_PAGED_EVENT_BUFFER_PAGE_SIZE;
TRACE_EXIT_CRITICAL_SECTION();
}
static int prvGetBufferPage(int32_t* bytesUsed)
{
static int8_t lastPage = -1;
int count = 0;
int8_t index = (lastPage + 1) % TRC_PAGED_EVENT_BUFFER_PAGE_COUNT;
while((PageInfo[index].Status != PAGE_STATUS_READ) && (count++ < TRC_PAGED_EVENT_BUFFER_PAGE_COUNT))
{
index = (index + 1) % TRC_PAGED_EVENT_BUFFER_PAGE_COUNT;
}
if (PageInfo[index].Status == PAGE_STATUS_READ)
{
*bytesUsed = TRC_PAGED_EVENT_BUFFER_PAGE_SIZE - PageInfo[index].BytesRemaining;
lastPage = index;
return index;
}
*bytesUsed = 0;
return -1;
}
/*******************************************************************************
int32_t vPagedEventBufferTransfer(int32_t (*writeFunc)(void* data,
uint32_t size),
int32_t* nofBytes)
Transfers one block of trace data, if available for reading. Returns the number
of bytes transfered, or a negative error code. If data was transferred (return
value > 0), it can be good to call this function again until all data available
has been transfered.
This function is intended to be called by a periodic task with a suitable
delay (e.g. 10-100 ms).
Example:
TickType_t lastWakeTime = xTaskGetTickCount();
while(1)
{
do{
// Transfer all available data
status = vPagedEventBufferTransfer(MyWrite, ptrBytes);
}while(status > 0);
if (status < 0)
{
// A negative return value is an error code...
}
vTraceDelayUntil(lastWakeTime, 50); // 50 ms -> 20 times/sec
}
Return value: returnvalue of writeFunc (0 == OK)
Parameters:
- writeFunc
Function pointer (example: int32_t write(void* data, uint32_t size))
The function passed as writeFunc should write "size" bytes from "data" to the
socket/file/channel, and return a status code where 0 means OK,
and any other non-zero value means an error.
- int32_t* nofBytes
Pointer to an integer assigned the number of bytes that was transfered.
*******************************************************************************/
int32_t vPagedEventBufferTransfer(int32_t (*writeFunc)(void* data, uint32_t size, int32_t* ptrBytesWritten), int32_t* nofBytes)
{
static int firstTime = 1;
int8_t pageToTransfer = -1;
pageToTransfer = prvGetBufferPage(nofBytes);
if (firstTime)
{
firstTime = 0;
}
if (pageToTransfer > -1)
{
if (writeFunc(&EventBuffer[pageToTransfer * TRC_PAGED_EVENT_BUFFER_PAGE_SIZE], *nofBytes, nofBytes) == 0)
{
prvPageReadComplete(pageToTransfer);
return 0;
}
else
{
return 1;
}
}
return 0;
}
/*******************************************************************************
void* vPagedEventBufferGetWritePointer(int sizeOfEvent)
Returns a pointer to an available location in the buffer able to store the
requested size.
Return value: The pointer.
Parameters:
- sizeOfEvent
The size of the event that is to be placed in the buffer.
*******************************************************************************/
void* vPagedEventBufferGetWritePointer(int sizeOfEvent)
{
void* ret;
static int currentWritePage = -1;
if (currentWritePage == -1)
{
currentWritePage = prvAllocateBufferPage(currentWritePage);
if (currentWritePage == -1)
{
DroppedEventCounter++;
return NULL;
}
}
if (PageInfo[currentWritePage].BytesRemaining - sizeOfEvent < 0)
{
PageInfo[currentWritePage].Status = PAGE_STATUS_READ;
TotalBytesRemaining -= PageInfo[currentWritePage].BytesRemaining; // Last trailing bytes
if (TotalBytesRemaining < TotalBytesRemaining_LowWaterMark)
TotalBytesRemaining_LowWaterMark = TotalBytesRemaining;
currentWritePage = prvAllocateBufferPage(currentWritePage);
if (currentWritePage == -1)
{
DroppedEventCounter++;
return NULL;
}
}
ret = PageInfo[currentWritePage].WritePointer;
PageInfo[currentWritePage].WritePointer += sizeOfEvent;
PageInfo[currentWritePage].BytesRemaining -= sizeOfEvent;
TotalBytesRemaining -= sizeOfEvent;
if (TotalBytesRemaining < TotalBytesRemaining_LowWaterMark)
TotalBytesRemaining_LowWaterMark = TotalBytesRemaining;
return ret;
}
/*******************************************************************************
void vPagedEventBufferInit(char* buffer)
Assigns the buffer to use and initializes the PageInfo structure.
Return value: void
Parameters:
- buffer
Pointer to the buffer location that is dynamically or statically allocated by
the caller.
*******************************************************************************/
void vPagedEventBufferInit(char* buffer)
{
TRACE_ALLOC_CRITICAL_SECTION();
int i;
EventBuffer = buffer;
TRACE_ENTER_CRITICAL_SECTION();
for (i = 0; i < TRC_PAGED_EVENT_BUFFER_PAGE_COUNT; i++)
{
PageInfo[i].BytesRemaining = TRC_PAGED_EVENT_BUFFER_PAGE_SIZE;
PageInfo[i].WritePointer = &EventBuffer[i * TRC_PAGED_EVENT_BUFFER_PAGE_SIZE];
PageInfo[i].Status = PAGE_STATUS_FREE;
}
TRACE_EXIT_CRITICAL_SECTION();
}
#endif
@@ -0,0 +1,61 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v3.0.2
* Percepio AB, www.percepio.com
*
* trcPagedEventBuffer.h
*
* Implements a paged buffer that can be used by TCP/IP or custom transfer
* methods.
*
* Terms of Use
* This software (the "Tracealyzer Recorder Library") is the intellectual
* property of Percepio AB and may not be sold or in other ways commercially
* redistributed without explicit written permission by Percepio AB.
*
* Separate conditions applies for the SEGGER branded source code included.
*
* The recorder library is free for use together with Percepio products.
* You may distribute the recorder library in its original form, but public
* distribution of modified versions require approval by Percepio AB.
*
* Disclaimer
* The trace tool and recorder library is being delivered to you AS IS and
* Percepio AB makes no warranty as to its use or performance. Percepio AB does
* not and cannot warrant the performance or results you may obtain by using the
* software or documentation. Percepio AB 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 AB, 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 AB 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, 2015.
* www.percepio.com
******************************************************************************/
#ifndef TRC_PAGED_EVENT_BUFFER_H
#define TRC_PAGED_EVENT_BUFFER_H
#ifdef __cplusplus
extern “C” {
#endif
void vPagedEventBufferInit(char* buffer);
void* vPagedEventBufferGetWritePointer(int sizeOfEvent);
int32_t vPagedEventBufferTransfer(int32_t (*writeFunc)(void* data, uint32_t size, int32_t* ptrBytesWritten), int32_t* nofBytes);
void vPagedEventBufferReset(void);
#ifdef __cplusplus
}
#endif
#endif /*TRC_PAGED_EVENT_BUFFER_H*/
@@ -0,0 +1,56 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v3.0.2
* Percepio AB, www.percepio.com
*
* trcPagedEventBuffer.h
*
* Configuration for the paged event buffer that can be used by TCP/IP or
* custom transfer methods.
*
* Terms of Use
* This software (the "Tracealyzer Recorder Library") is the intellectual
* property of Percepio AB and may not be sold or in other ways commercially
* redistributed without explicit written permission by Percepio AB.
*
* Separate conditions applies for the SEGGER branded source code included.
*
* The recorder library is free for use together with Percepio products.
* You may distribute the recorder library in its original form, but public
* distribution of modified versions require approval by Percepio AB.
*
* Disclaimer
* The trace tool and recorder library is being delivered to you AS IS and
* Percepio AB makes no warranty as to its use or performance. Percepio AB does
* not and cannot warrant the performance or results you may obtain by using the
* software or documentation. Percepio AB 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 AB, 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 AB 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, 2015.
* www.percepio.com
******************************************************************************/
#ifndef TRC_PAGED_EVENT_BUFFER_CONFIG_H
#define TRC_PAGED_EVENT_BUFFER_CONFIG_H
#ifdef __cplusplus
extern “C” {
#endif
#define TRC_PAGED_EVENT_BUFFER_PAGE_COUNT 5
#define TRC_PAGED_EVENT_BUFFER_PAGE_SIZE 1440
#ifdef __cplusplus
}
#endif
#endif /*TRC_PAGED_EVENT_BUFFER_CONFIG_H*/
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,363 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v3.0.2
* Percepio AB, www.percepio.com
*
* trcRecorder.c
*
* Public interface and configurations for the trace recorder library.
*
* Terms of Use
* This software (the "Tracealyzer Recorder Library") is the intellectual
* property of Percepio AB and may not be sold or in other ways commercially
* redistributed without explicit written permission by Percepio AB.
*
* Separate conditions applies for the SEGGER branded source code included.
*
* The recorder library is free for use together with Percepio products.
* You may distribute the recorder library in its original form, but public
* distribution of modified versions require approval by Percepio AB.
*
* Disclaimer
* The trace tool and recorder library is being delivered to you AS IS and
* Percepio AB makes no warranty as to its use or performance. Percepio AB does
* not and cannot warrant the performance or results you may obtain by using the
* software or documentation. Percepio AB 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 AB, 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 AB 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, 2015.
* www.percepio.com
******************************************************************************/
#ifndef _TRC_RECORDER_H
#define _TRC_RECORDER_H
#ifdef __cplusplus
extern “C” {
#endif
#include "trcConfig.h"
#include "trcKernelPort.h"
#include "trcHardwarePort.h"
#if (USE_TRACEALYZER_RECORDER == 1)
/*** User API *****************************************************************/
/******************************************************************************
* vTracePrint
*
* Generates "User Events", with unformatted text.
*
* User Events can be used for very efficient application logging, and are shown
* as yellow labels in the main trace view.
*
* You may group User Events into User Event Channels. The yellow User Event
* labels shows the logged string, preceeded by the channel name within
* brackets. For example:
*
* "[MyChannel] Hello World!"
*
* The User Event Channels are shown in the View Filter, which makes it easy to
* select what User Events you wish to display. User Event Channels are created
* using vTraceStoreUserEventChannelName().
*
* Example:
*
* char* error_uechannel = vTraceStoreUserEventChannelName("Errors");
* ...
* vTracePrint(error_uechannel, "Shouldn't reach this code!");
*
******************************************************************************/
void vTracePrint(const char* chn, const char* str);
/******************************************************************************
* vTracePrintF
*
* Generates "User Events", with formatted text and data, similar to a "printf".
* It is very fast since the actual formatting is done on the host side when the
* trace is displayed.
*
* User Events can be used for very efficient application logging, and are shown
* as yellow labels in the main trace view.
* An advantage of User Events is that data can be plotted in the "User Event
* Signal Plot" view, visualizing any data you log as User Events, discrete
* states or control system signals (e.g. system inputs or outputs).
*
* You may group User Events into User Event Channels. The yellow User Event
* labels show the logged string, preceeded by the channel name within brackets.
*
* Example:
*
* "[MyChannel] Hello World!"
*
* The User Event Channels are shown in the View Filter, which makes it easy to
* select what User Events you wish to display. User Event Channels are created
* using vTraceStoreUserEventChannelName().
*
* Example:
*
* char* adc_uechannel = vTraceStoreUserEventChannelName("ADC User Events");
* ...
* vTracePrint(adc_uechannel,
* "ADC channel %d: %lf volts",
* ch, (double)adc_reading/(double)scale);
*
* All data arguments are assumed to be 32 bt wide. The following formats are
* supported in v2.8:
* %d - signed integer
* %u - unsigned integer
* %X - hexadecimal (uppercase)
* %x - hexadecimal (lowercase)
* %s - string (currently, this must be an earlier stored symbol name)
*
* Up to 15 data arguments are allowed, with a total size of maximum 60 byte
* including 8 byte for the base event fields and the format string. So with
* one data argument, the maximum string length is 48 chars. If this is exceeded
* the string is truncated (4 bytes at a time).
*
******************************************************************************/
void vTracePrintF(const char* chn, const char* fmt, ...);
/*******************************************************************************
* vTraceStoreUserEventChannelName(const char* name)
*
* Parameter name: the channel name to store (const string literal)
*
* Stores a name for a user event channel, returns the handle (just a pointer
* to the provided string). Typically assigned to a "channel" variable that
* keeps it for later calls to vTracePrintF();
******************************************************************************/
char* vTraceStoreUserEventChannelName(const char* name);
/*******************************************************************************
* vTraceStoreKernelObjectName(void* object, const char* name)
*
* Parameter object: pointer to the kernel object that shall be named
* Parameter name: the name to store (const string literal)
*
* Stores a name for kernel objects (Semaphore, Mailbox, etc.).
******************************************************************************/
void vTraceStoreKernelObjectName(void* object, const char* name);
/*******************************************************************************
* vTraceSetISRProperties(const char* name, char priority)
*
* Parameter name: the name to give the the ISR, also serves as handle.
* Parameter priority: the priority level of the ISR.
*
* Stores a name and priority level for an Interrupt Service Routine, to allow
* for better visualization. The string address is used as a unique handle.
*
* Example:
*
* vTraceSetISRProperties("ISRTimer1", ISRPriorityTimer1);
* ...
* void ISR_handler()
* {
* vTraceStoreISRBegin("ISRTimer1");
* ...
* vTraceStoreISREnd(0);
* }
******************************************************************************/
void vTraceSetISRProperties(const char* name, char priority);
/*******************************************************************************
* vTraceStoreISRBegin(void* handle);
*
* Parameter handle: ID of the ISR, which is "name" in vTraceSetISRProperties
*
* Registers the beginning of an Interrupt Service Routine (ISR), i.e., or an
* exception handler.
*
* Example:
*
* vTraceSetISRProperties("ISRTimer1", ISRPriorityTimer1);
* ...
* void ISR_handler()
* {
* vTraceStoreISRBegin("ISRTimer1");
* ...
* vTraceStoreISREnd(0);
* }
******************************************************************************/
void vTraceStoreISRBegin(void* handle);
/*******************************************************************************
* vTraceStoreISREnd
*
* Registers the end of an Interrupt Service Routine.
*
* This function attempts to automatically detect if a task switch will take
* place when interrupt ends. If this is possible depends on the kernel port.
*
* Example:
* #define PRIO_ISR_TIMER1 3 // the hardware priority of the interrupt
* ...
* vTraceSetISRProperties("ISRTimer1", PRIO_ISR_TIMER1);
* ...
* void ISR_handler()
* {
* vTraceStoreISRBegin("ISRTimer1");
* ...
* vTraceStoreISREnd();
* }
*
******************************************************************************/
void vTraceStoreISREnd(void);
/*******************************************************************************
* vTraceStoreISREndManual
*
* Registers the end of an Interrupt Service Routine.
*
* The parameter isTaskSwitchRequired indicates if the interrupt has requested a
* task-switch (= 1) or if the interrupt returns to the earlier context (= 0)
*
* Example:
* #define PRIO_ISR_TIMER1 3 // the hardware priority of the interrupt
* ...
* vTraceSetISRProperties("ISRTimer1", PRIO_ISR_TIMER1);
* ...
* void ISR_handler()
* {
* vTraceStoreISRBegin("ISRTimer1");
* ...
* vTraceStoreISREndManual(0);
* }
*
******************************************************************************/
void vTraceStoreISREndManual(int isTaskSwitchRequired);
/*******************************************************************************
* vTraceInstanceFinishNow
*
* Creates an event that ends the current task instance at this very instant.
* This makes the viewer to splits the current fragment at this point and begin
* a new actor instance, even if no task-switch has occurred.
*****************************************************************************/
void vTraceInstanceFinishedNow(void);
/*******************************************************************************
* vTraceInstanceFinishedNext
*
* Marks the current "task instance" as finished on the next kernel call.
*
* If that kernel call is blocking, the instance ends after the blocking event
* and the corresponding return event is then the start of the next instance.
* If the kernel call is not blocking, the viewer instead splits the current
* fragment right before the kernel call, which makes this call the first event
* of the next instance.
*****************************************************************************/
void vTraceInstanceFinishedNext(void);
/******************************************************************************/
/*** INTERNAL FUNCTIONS *******************************************************/
/******************************************************************************/
/* Saves a symbol name (task name etc.) in symbol table */
void vTraceSaveSymbol(void *address, const char *name);
/* Deletes a symbol name (task name etc.) from symbol table */
void vTraceDeleteSymbol(void *address);
/* Saves an object data entry (task base priority) in object data table */
void vTraceSaveObjectData(void *address, uint32_t data);
/* Removes an object data entry (task base priority) from object data table */
void vTraceDeleteObjectData(void *address);
/* Store an event with zero parameters (event ID only) */
void vTraceStoreEvent0(uint16_t eventID);
/* Store an event with one 32-bit parameter (pointer address or an int) */
void vTraceStoreEvent1(uint16_t eventID, uint32_t param1);
/* Store an event with two 32-bit parameters */
void vTraceStoreEvent2(uint16_t eventID, uint32_t param1, uint32_t param2);
/* Store an event with three 32-bit parameters */
void vTraceStoreEvent3( uint16_t eventID,
uint32_t param1,
uint32_t param2,
uint32_t param3);
/* Stores an event with <nParam> 32-bit integer parameters */
void vTraceStoreEvent(int nParam, uint16_t EventID, ...);
/* Stories an event with a string and <nParam> 32-bit integer parameters */
void vTraceStoreStringEvent(int nArgs, uint16_t eventID, const char* str, ...);
/* The data structure for commands (a bit overkill) */
typedef struct
{
unsigned char cmdCode;
unsigned char param1;
unsigned char param2;
unsigned char param3;
unsigned char param4;
unsigned char param5;
unsigned char checksumLSB;
unsigned char checksumMSB;
} TracealyzerCommandType;
/* Checks if the provided command is a valid command */
int isValidCommand(TracealyzerCommandType* cmd);
/* Executed the received command (Start or Stop) */
void processCommand(TracealyzerCommandType* cmd);
/* Backwards compatibility macros with old recorder */
#define vTraceInitTraceData() Trace_Init()
#define uiTraceStart() (1)
#define vTraceStart()
#define vTraceStop()
#else /*(USE_TRACEALYZER_RECORDER == 1)*/
#define vTraceStoreEvent0(e)
#define vTraceStoreEvent1(e, param1)
#define vTraceStoreEvent2(e, param1, param2)
#define vTraceStoreEvent3(e, param1, param2, param3)
#define vTraceStoreUserEventChannelName(x) 0
#define vTracePrint(chn, ...)
#define vTracePrintF(chn, ...)
#define vTraceInstanceFinishedNow()
#define vTraceInstanceFinishedNext()
#define vTraceStoreISRBegin(x)
#define vTraceStoreISREnd()
#define vTraceStoreISREndManual(x)
#define vTraceSetISRProperties(a, b)
#define vTraceStoreKernelObjectName(a, b)
/* Backwards compatibility macros with old recorder */
#define vTraceInitTraceData()
#define uiTraceStart() (1)
#define vTraceStart()
#define vTraceStop()
#endif /*(USE_TRACEALYZER_RECORDER == 1)*/
extern void psfError(int errCode);
#define PSF_ASSERT(_assert, _err) if (! (_assert)){ psfError(_err); return; }
#define PSF_ERROR_NONE 0
#define PSF_ERROR_EVENT_CODE_TOO_LARGE 1
#define PSF_ERROR_ISR_NESTING_OVERFLOW 2
#ifdef __cplusplus
}
#endif
#endif /* _TRC_RECORDER_H */
@@ -0,0 +1,219 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v3.0.2
* Percepio AB, www.percepio.com
*
* trcStreamPort.h
*
* This file defines the trace streaming interface used by the
* Trace Recorder Library. It comes preconfigured for use with SEGGER's RTT and
* a TCP/IP (needs additional configuration in trcTCPIPConfig.h).
*
* Terms of Use
* This software (the "Tracealyzer Recorder Library") is the intellectual
* property of Percepio AB and may not be sold or in other ways commercially
* redistributed without explicit written permission by Percepio AB.
*
* Separate conditions applies for the SEGGER branded source code included.
*
* The recorder library is free for use together with Percepio products.
* You may distribute the recorder library in its original form, but public
* distribution of modified versions require approval by Percepio AB.
*
* Disclaimer
* The trace tool and recorder library is being delivered to you AS IS and
* Percepio AB makes no warranty as to its use or performance. Percepio AB does
* not and cannot warrant the performance or results you may obtain by using the
* software or documentation. Percepio AB 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 AB, 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 AB 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, 2015.
* www.percepio.com
******************************************************************************/
#ifndef _TRC_STREAM_PORT_H
#define _TRC_STREAM_PORT_H
#ifdef __cplusplus
extern “C” {
#endif
#if (USE_TRACEALYZER_RECORDER == 1)
#define TRC_RECORDER_TRANSFER_METHOD_JLINK_RTT_BLOCK (0x01)
#define TRC_RECORDER_TRANSFER_METHOD_JLINK_RTT_NOBLOCK (0x02)
#define TRC_RECORDER_TRANSFER_METHOD_TCPIP (0x03)
#define TRC_RECORDER_TRANSFER_METHOD_CUSTOM (0xFF)
#define TRC_RECORDER_BUFFER_ALLOCATION_STATIC (0x00)
#define TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC (0x01)
/*******************************************************************************
* TRC_RECORDER_TRANSFER_METHOD_JLINK_RTT_BLOCK / NOBLOCK
******************************************************************************/
#if TRC_RECORDER_TRANSFER_METHOD == TRC_RECORDER_TRANSFER_METHOD_JLINK_RTT_BLOCK || TRC_RECORDER_TRANSFER_METHOD == TRC_RECORDER_TRANSFER_METHOD_JLINK_RTT_NOBLOCK
#if TRC_RECORDER_TRANSFER_METHOD == TRC_RECORDER_TRANSFER_METHOD_JLINK_RTT_BLOCK
#define TRC_STREAM_PORT_BLOCKING_TRANSFER 1
#define RTT_MODE SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL
#else
#define TRC_STREAM_PORT_BLOCKING_TRANSFER 0
#define RTT_MODE SEGGER_RTT_MODE_NO_BLOCK_SKIP
#endif
#include "SEGGER_RTT_Conf.h"
#include "SEGGER_RTT.h"
/* Up-buffer. If index is defined as 0, the internal RTT buffers will be used instead of this. */ \
#if TRC_RTT_UP_BUFFER_INDEX == 0
#define TRC_RTT_ALLOC_UP() static char* _TzTraceData = NULL; /* Not actually used. Ignore allocation method. */
#define TRC_STREAM_PORT_MALLOC() /* Static allocation. Not used. */
#else
#if TRC_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_STATIC
#define TRC_RTT_ALLOC_UP() static char _TzTraceData[BUFFER_SIZE_UP]; /* Static allocation */
#define TRC_STREAM_PORT_MALLOC() /* Static allocation. Not used. */
#else
#define TRC_RTT_ALLOC_UP() static char* _TzTraceData = NULL; /* Dynamic allocation */
#define TRC_STREAM_PORT_MALLOC() _TzTraceData = TRC_PORT_MALLOC(BUFFER_SIZE_UP);
#endif
#endif
/* Down-buffer. If index is defined as 0, the internal RTT buffers will be used instead of this. */ \
#if TRC_RTT_DOWN_BUFFER_INDEX == 0
#define TRC_RTT_ALLOC_DOWN() static char* _TzCtrlData = NULL; /* Not actually used. Ignore allocation method. */
#else
#define TRC_RTT_ALLOC_DOWN() static char _TzCtrlData[BUFFER_SIZE_DOWN]; /* This buffer should be ~32bytes. Ignore allocation method. */
#endif
#define TRC_STREAM_PORT_ALLOCATE_FIELDS() \
TRC_RTT_ALLOC_UP() /* Macro that will result in proper UP buffer allocation */ \
TRC_RTT_ALLOC_DOWN() /* Macro that will result in proper DOWN buffer allocation */
#define TRC_STREAM_PORT_INIT() \
TRC_STREAM_PORT_MALLOC(); /*Dynamic allocation or empty if static */ \
SEGGER_RTT_ConfigUpBuffer(TRC_RTT_UP_BUFFER_INDEX, "TzData", _TzTraceData, sizeof(_TzTraceData), RTT_MODE ); \
SEGGER_RTT_ConfigDownBuffer(TRC_RTT_DOWN_BUFFER_INDEX, "TzCtrl", _TzCtrlData, sizeof(_TzCtrlData), 0);
#define TRC_STREAM_PORT_ALLOCATE_EVENT(_type, _ptrData, _size) uint8_t tmpEvt[_size]; _type* _ptrData = (_type*)tmpEvt;
#define TRC_STREAM_PORT_COMMIT_EVENT(_ptrData, _size) SEGGER_RTT_Write(TRC_RTT_UP_BUFFER_INDEX, (const char*)_ptrData, _size);
#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) *_ptrBytesRead = SEGGER_RTT_Read(TRC_RTT_DOWN_BUFFER_INDEX, (char*)_ptrData, _size);
#define TRC_STREAM_PORT_PERIODIC_SEND_DATA(_ptrBytesSent)
#define TRC_STREAM_PORT_ON_TRACE_BEGIN() /* Do nothing */
#define TRC_STREAM_PORT_ON_TRACE_END() /* Do nothing */
#endif /*TRC_RECORDER_TRANSFER_METHOD == TRC_RECORDER_TRANSFER_METHOD_JLINK_RTT_BLOCK || TRC_RECORDER_TRANSFER_METHOD == TRC_RECORDER_TRANSFER_METHOD_JLINK_RTT_NOBLOCK*/
/*******************************************************************************
* TRC_RECORDER_TRANSFER_METHOD_TCPIP
*
* This TCP/IP implementation is using a secondary buffer consisting of multiple
* pages to avoid the endless recursive calls that occurr when "socket_send"
* uses kernel objects such as mutexes and semaphores, which in turn needs to be
* traced. To use your own TCP/IP stack, modify the functions declared in
* trcTCPIPConfig.h.
******************************************************************************/
#if TRC_RECORDER_TRANSFER_METHOD == TRC_RECORDER_TRANSFER_METHOD_TCPIP
#include "trcTCPIP.h"
#include "trcPagedEventBuffer.h"
#include "trcPagedEventBufferConfig.h"
#define TRC_STREAM_PORT_BLOCKING_TRANSFER 0
#if TRC_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_STATIC
#define TRC_STREAM_PORT_ALLOCATE_FIELDS() static char _TzTraceData[TRC_PAGED_EVENT_BUFFER_PAGE_COUNT * TRC_PAGED_EVENT_BUFFER_PAGE_SIZE]; /* Static allocation. */
#define TRC_STREAM_PORT_MALLOC() /* Static allocation. Not used. */
#else
#define TRC_STREAM_PORT_ALLOCATE_FIELDS() static char* _TzTraceData = NULL; /* Dynamic allocation. */
#define TRC_STREAM_PORT_MALLOC() _TzTraceData = TRC_PORT_MALLOC(TRC_PAGED_EVENT_BUFFER_PAGE_COUNT * TRC_PAGED_EVENT_BUFFER_PAGE_SIZE);
#endif
#define TRC_STREAM_PORT_INIT() \
TRC_STREAM_PORT_MALLOC(); /*Dynamic allocation or empty if static */ \
vPagedEventBufferInit(_TzTraceData);
#define TRC_STREAM_PORT_ALLOCATE_EVENT(_type, _ptrData, _size) _type* _ptrData; _ptrData = (_type*)vPagedEventBufferGetWritePointer(_size);
#define TRC_STREAM_PORT_COMMIT_EVENT(_ptrData, _size) /* Not needed since we write immediately into the buffer received above by TRC_STREAM_PORT_ALLOCATE_EVENT, and the TRC_STREAM_PORT_PERIODIC_SEND_DATA defined below will take care of the actual trace transfer. */
#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) trcTcpRead(_ptrData, _size, _ptrBytesRead);
#define TRC_STREAM_PORT_PERIODIC_SEND_DATA(_ptrBytesSent) vPagedEventBufferTransfer(trcTcpWrite, _ptrBytesSent);
#define TRC_STREAM_PORT_ON_TRACE_BEGIN() vPagedEventBufferInit(_TzTraceData);
#define TRC_STREAM_PORT_ON_TRACE_END() /* Do nothing */
#endif /*TRC_RECORDER_TRANSFER_METHOD == TRC_RECORDER_TRANSFER_METHOD_TCPIP*/
/*******************************************************************************
* TRC_RECORDER_TRANSFER_METHOD_CUSTOM
*
* Implement the following macros in trcConfig.h. If your transfer method uses
* kernel objects when sending data you will need to use a secondary buffer to
* store the trace data before sending it. For this reason we provide
* trcPagedEventBuffer. Look at the TCP/IP macros above to see how to use it.
******************************************************************************/
#if TRC_RECORDER_TRANSFER_METHOD == TRC_RECORDER_TRANSFER_METHOD_CUSTOM
/* When using the custom transfer method, define TRC_STREAM_CUSTOM_XXXXXXXXXXXXX in trcConfig.h */
#define TRC_STREAM_PORT_BLOCKING_TRANSFER TRC_STREAM_CUSTOM_BLOCKING_TRANSFER
#define TRC_STREAM_PORT_ALLOCATE_FIELDS() TRC_STREAM_CUSTOM_ALLOCATE_FIELDS()
#define TRC_STREAM_PORT_INIT() TRC_STREAM_CUSTOM_INIT()
#define TRC_STREAM_PORT_ALLOCATE_EVENT(_type, _ptr, _size) TRC_STREAM_CUSTOM_ALLOCATE_EVENT(_type, _ptr, _size)
#define TRC_STREAM_PORT_COMMIT_EVENT(_ptr, _size) TRC_STREAM_CUSTOM_COMMIT_EVENT(_ptr, _size)
#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) TRC_STREAM_CUSTOM_READ_DATA(_ptrData, _size, _ptrBytesRead)
#define TRC_STREAM_PORT_PERIODIC_SEND_DATA(_ptrBytesSent) TRC_STREAM_CUSTOM_PERIODIC_SEND_DATA(_ptrBytesSent)
#define TRC_STREAM_PORT_ON_TRACE_BEGIN() TRC_STREAM_CUSTOM_ON_TRACE_BEGIN()
#define TRC_STREAM_PORT_ON_TRACE_END() TRC_STREAM_CUSTOM_ON_TRACE_END()
#endif /*TRC_RECORDER_TRANSFER_METHOD == TRC_RECORDER_TRANSFER_METHOD_CUSTOM*/
#ifndef TRC_STREAM_PORT_ALLOCATE_FIELDS
#error "Selected TRC_RECORDER_TRANSFER_METHOD does not define TRC_STREAM_PORT_ALLOCATE_FIELDS!"
#endif
#ifndef TRC_STREAM_PORT_ALLOCATE_EVENT
#error "Selected TRC_RECORDER_TRANSFER_METHOD does not define TRC_STREAM_PORT_ALLOCATE_EVENT!"
#endif
#ifndef TRC_STREAM_PORT_COMMIT_EVENT
#error "Selected TRC_RECORDER_TRANSFER_METHOD does not define TRC_STREAM_PORT_COMMIT_EVENT!"
#endif
#ifndef TRC_STREAM_PORT_INIT
#error "Selected TRC_RECORDER_TRANSFER_METHOD does not define TRC_STREAM_PORT_INIT!"
#endif
#ifndef TRC_STREAM_PORT_BLOCKING_TRANSFER
#error "Selected TRC_RECORDER_TRANSFER_METHOD does not define TRC_STREAM_PORT_BLOCKING_TRANSFER!"
#endif
#ifndef TRC_STREAM_PORT_READ_DATA
#error "Selected TRC_RECORDER_TRANSFER_METHOD does not define TRC_STREAM_PORT_READ_DATA!"
#endif
#ifndef TRC_STREAM_PORT_PERIODIC_SEND_DATA
#error "Selected TRC_RECORDER_TRANSFER_METHOD does not define TRC_STREAM_PORT_PERIODIC_SEND_DATA!"
#endif
#ifndef TRC_STREAM_PORT_ON_TRACE_BEGIN
#error "Selected TRC_RECORDER_TRANSFER_METHOD does not define TRC_STREAM_PORT_ON_TRACE_BEGIN!"
#endif
#ifndef TRC_STREAM_PORT_ON_TRACE_END
#error "Selected TRC_RECORDER_TRANSFER_METHOD does not define TRC_STREAM_PORT_ON_TRACE_END!"
#endif
#endif /*(USE_TRACEALYZER_RECORDER == 1)*/
#ifdef __cplusplus
}
#endif
#endif /* _TRC_STREAM_PORT_H */
@@ -0,0 +1,58 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v3.0.2
* Percepio AB, www.percepio.com
*
* trcTCPIP.c
*
* Simple generic TCP/IP layer. Modify trcTCPIPConfig.h to adapt it to any
* custom stack.
*
* Terms of Use
* This software (the "Tracealyzer Recorder Library") is the intellectual
* property of Percepio AB and may not be sold or in other ways commercially
* redistributed without explicit written permission by Percepio AB.
*
* Separate conditions applies for the SEGGER branded source code included.
*
* The recorder library is free for use together with Percepio products.
* You may distribute the recorder library in its original form, but public
* distribution of modified versions require approval by Percepio AB.
*
* Disclaimer
* The trace tool and recorder library is being delivered to you AS IS and
* Percepio AB makes no warranty as to its use or performance. Percepio AB does
* not and cannot warrant the performance or results you may obtain by using the
* software or documentation. Percepio AB 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 AB, 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 AB 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, 2015.
* www.percepio.com
******************************************************************************/
#include <stdint.h>
#include "trcTCPIP.h"
#include "trcTCPIPConfig.h"
int32_t trcTcpWrite(void* data, uint32_t size, int32_t *ptrBytesWritten)
{
return trcSocketSend(data, size, ptrBytesWritten);
}
int32_t trcTcpRead(void* data, uint32_t size, int32_t *ptrBytesRead)
{
trcSocketInitializeListener();
trcSocketAccept();
return trcSocketReceive(data, size, ptrBytesRead);
}
@@ -0,0 +1,56 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v3.0.2
* Percepio AB, www.percepio.com
*
* trcTCPIP.h
*
* Simple generic TCP/IP layer. Modify trcTCPIPConfig.h to adapt it to any
* custom stack.
*
* Terms of Use
* This software (the "Tracealyzer Recorder Library") is the intellectual
* property of Percepio AB and may not be sold or in other ways commercially
* redistributed without explicit written permission by Percepio AB.
*
* Separate conditions applies for the SEGGER branded source code included.
*
* The recorder library is free for use together with Percepio products.
* You may distribute the recorder library in its original form, but public
* distribution of modified versions require approval by Percepio AB.
*
* Disclaimer
* The trace tool and recorder library is being delivered to you AS IS and
* Percepio AB makes no warranty as to its use or performance. Percepio AB does
* not and cannot warrant the performance or results you may obtain by using the
* software or documentation. Percepio AB 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 AB, 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 AB 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, 2015.
* www.percepio.com
******************************************************************************/
#ifndef TRC_TCPIP_H
#define TRC_TCPIP_H
#ifdef __cplusplus
extern “C” {
#endif
int32_t trcTcpWrite(void* data, uint32_t size, int32_t *ptrBytesWritten);
int32_t trcTcpRead(void* data, uint32_t size, int32_t *ptrBytesRead);
#ifdef __cplusplus
}
#endif
#endif /*TRC_TCPIP_H*/
@@ -0,0 +1,163 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v3.0.2
* Percepio AB, www.percepio.com
*
* trcTCPIPConfig.h
*
* Trace TCP/IP configuration. Modify these includes and functions to perform
* the same functionality using your specific TCP/IP stack.
* Will only be included by trcTCPIP.c.
*
* Terms of Use
* This software (the "Tracealyzer Recorder Library") is the intellectual
* property of Percepio AB and may not be sold or in other ways commercially
* redistributed without explicit written permission by Percepio AB.
*
* Separate conditions applies for the SEGGER branded source code included.
*
* The recorder library is free for use together with Percepio products.
* You may distribute the recorder library in its original form, but public
* distribution of modified versions require approval by Percepio AB.
*
* Disclaimer
* The trace tool and recorder library is being delivered to you AS IS and
* Percepio AB makes no warranty as to its use or performance. Percepio AB does
* not and cannot warrant the performance or results you may obtain by using the
* software or documentation. Percepio AB 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 AB, 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 AB 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, 2015.
* www.percepio.com
******************************************************************************/
#ifndef TRC_TCPIP_CONFIG_H
#define TRC_TCPIP_CONFIG_H
#ifdef __cplusplus
extern “C” {
#endif
/* TCP/IP includes*/
#include "tcpip.h"
#define TRC_TCPIP_PORT 12000
socket* sock = NULL;
socket* listenerSocket = NULL;
int32_t trcSocketSend(void* data, int32_t size, int32_t* bytesWritten)
{
int32_t error;
if (sock == NULL)
return 1;
error = socket_send(sock, data, size, (size_t*)bytesWritten, 0);
if (error)
{
socket_close(sock);
sock = NULL;
}
return (int32_t)error;
}
int32_t trcSocketReceive(void* data, int32_t size, int32_t* bytesRead)
{
int32_t error;
if (sock == NULL)
return 1;
error = socket_receive(sock, data, size, (size_t*)bytesRead, SOCKET_WAIT_ALL);
if (error != ERROR_NONE && error != ERROR_TIMEOUT) /* Timeout may be expected when there is no data */
{
socket_close(sock);
sock = NULL;
return error;
}
return 0;
}
int32_t trcSocketInitializeListener()
{
int32_t error;
if (listenerSocket)
return 0;
//Start of exception handling block
do
{
listenerSocket = socket_open(SOCKET_STREAM, SOCKET_TCP);
if(listenerSocket == NULL)
{
error = 1;
break;
}
error = socket_set_timeout(listenerSocket, INFINITE);
if(error) break;
error = socket_set_tx_buffer_size(listenerSocket, 1440 * 2);
if(error) break;
error = socket_set_rx_buffer_size(listenerSocket, 128);
if(error) break;
error = socket_bind_to_interface(listenerSocket, pNetInterface);
if(error) break;
error = socket_bind(listenerSocket, ADDR_ANY, TRC_TCPIP_PORT);
if(error) break;
error = socket_listen(listenerSocket);
if(error) break;
} while(0);
if(error)
{
socket_close(listenerSocket);
listenerSocket = NULL;
}
return error;
}
int32_t trcSocketAccept()
{
ip_addr clientIpAddr;
uint16_t clientPort;
if (sock != NULL)
return 0;
if (listenerSocket == NULL)
return 1;
/* Wait for connection */
sock = socket_accept(listenerSocket, &clientIpAddr, &clientPort);
if(sock != NULL)
{
socket_set_timeout(sock, 20);
}
else
return 1;
return 0;
}
#ifdef __cplusplus
}
#endif
#endif /*TRC_TCPIP_CONFIG_H*/
@@ -1,5 +1,5 @@
/*******************************************************************************
* Tracealyzer v2.7.7 Recorder Library
* Tracealyzer v3.0.2 Recorder Library
* Percepio AB, www.percepio.com
*
* trcConfig.h
@@ -38,7 +38,7 @@
*
* Tabs are used for indent in this file (1 tab = 4 spaces)
*
* Copyright Percepio AB, 2012-2015.
* Copyright Percepio AB, 2014.
* www.percepio.com
******************************************************************************/
@@ -116,7 +116,7 @@
* recording is stopped when the buffer becomes full. This is useful for
* recording events following a specific state, e.g., the startup sequence.
*****************************************************************************/
#define TRACE_RECORDER_STORE_MODE TRACE_STORE_MODE_STOP_WHEN_FULL
#define TRACE_RECORDER_STORE_MODE TRACE_STORE_MODE_RING_BUFFER
/*******************************************************************************
* TRACE_SCHEDULING_ONLY
@@ -126,8 +126,8 @@
* If this setting is enabled (= 1), only scheduling events are recorded.
* If disabled (= 0), all events are recorded.
*
* Users of FreeRTOS+Trace Free Edition only displays scheduling events, so this
* option can be used to avoid storing unsupported events.
* For users of "Free Edition", that only displays scheduling events, this
* option can be used to avoid storing other events.
*
* Default value is 0 (store all enabled events).
*
@@ -1,10 +1,10 @@
/*******************************************************************************
* Tracealyzer v2.7.7 Recorder Library
* Tracealyzer v3.0.2 Recorder Library
* Percepio AB, www.percepio.com
*
* trcKernel.c
* trcBase.h
*
* Functions used by trcKernelHooks.h for storing various kernel events.
* Core functionality of the Tracealyzer recorder library.
*
* Terms of Use
* This software is copyright Percepio AB. The recorder library is free for
@@ -33,7 +33,7 @@
*
* Tabs are used for indent in this file (1 tab = 4 spaces)
*
* Copyright Percepio AB, 2012-2015.
* Copyright Percepio AB, 2014.
* www.percepio.com
******************************************************************************/
@@ -65,8 +65,10 @@
/* Max number of event codes supported */
#define NEventCodes 0x100
extern volatile int recorder_busy; // This is used to keep track of the recorder's critical sections, to determine if it is busy
// Our local critical sections for the recorder - updates an internal busy flag
/* Keeps track of the recorder's critical sections */
extern volatile int recorder_busy;
/* Our local critical sections for the recorder */
#define trcCRITICAL_SECTION_BEGIN() {TRACE_ENTER_CRITICAL_SECTION(); recorder_busy++;}
#define trcCRITICAL_SECTION_END() {recorder_busy--; TRACE_EXIT_CRITICAL_SECTION();}
@@ -145,7 +147,7 @@ typedef struct
/* This is used to calculate the index in the dynamic object table
(handle - 1 - nofStaticObjects = index)*/
#if (USE_16BIT_OBJECT_HANDLES == 1)
#if (USE_16BIT_OBJECT_HANDLES == 1)
objectHandleType NumberOfObjectsPerClass[2*((TRACE_NCLASSES+1)/2)];
#else
objectHandleType NumberOfObjectsPerClass[4*((TRACE_NCLASSES+3)/4)];
@@ -242,7 +244,7 @@ typedef struct
uint8_t type;
uint8_t unused1;
uint8_t unused2;
uint8_t dts;
uint8_t dts;
} TaskInstanceStatusEvent;
typedef struct
@@ -335,7 +337,7 @@ typedef struct
/* Used to determine Kernel and Endianess */
uint16_t version;
/* Currently 3, since v2.6.0 */
/* Currently 3 */
uint8_t minor_version;
/* This should be 0 if lower IRQ priority values implies higher priority
@@ -374,7 +376,7 @@ typedef struct
/* Not used, remains for compatibility and future use */
uint8_t notused[28];
/* The amount of heap memory remaining at the last malloc or free event */
uint32_t heapMemUsage;
@@ -1,5 +1,5 @@
/*******************************************************************************
* Tracealyzer v2.7.7 Recorder Library
* Tracealyzer v3.0.2 Recorder Library
* Percepio AB, www.percepio.com
*
* trcHardwarePort.h
@@ -34,7 +34,7 @@
*
* Tabs are used for indent in this file (1 tab = 4 spaces)
*
* Copyright Percepio AB, 2012-2015.
* Copyright Percepio AB, 2014.
* www.percepio.com
******************************************************************************/
@@ -1,5 +1,5 @@
/*******************************************************************************
* Tracealyzer v2.7.7 Recorder Library
* Tracealyzer v3.0.2 Recorder Library
* Percepio AB, www.percepio.com
*
* trcKernel.h
@@ -31,7 +31,7 @@
* 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.
*
* Copyright Percepio AB, 2012-2015.
* Copyright Percepio AB, 2013.
* www.percepio.com
******************************************************************************/
@@ -1,5 +1,5 @@
/*******************************************************************************
* Tracealyzer v2.7.7 Recorder Library
* Tracealyzer v3.0.2 Recorder Library
* Percepio AB, www.percepio.com
*
* trcKernelHooks.h
@@ -40,7 +40,7 @@
* 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.
*
* Copyright Percepio AB, 2012-2015.
* Copyright Percepio AB, 2013.
* www.percepio.com
******************************************************************************/
@@ -1,8 +1,8 @@
/*******************************************************************************
* Tracealyzer v2.7.7 Recorder Library
* Tracealyzer v3.0.2 Recorder Library
* Percepio AB, www.percepio.com
*
* trcKernelPortFreeRTOS.h
* trcKernelPort.h
*
* Kernel-specific functionality for FreeRTOS, used by the recorder library.
*
@@ -33,7 +33,7 @@
*
* Tabs are used for indent in this file (1 tab = 4 spaces)
*
* Copyright Percepio AB, 2012-2015.
* Copyright Percepio AB, 2014.
* www.percepio.com
******************************************************************************/
@@ -56,16 +56,21 @@ extern int uiInEventGroupSetBitsFromISR;
#define TRACE_CPU_CLOCK_HZ configCPU_CLOCK_HZ /* Defined in "FreeRTOSConfig.h" */
#if (SELECTED_PORT == PORT_ARM_CortexM)
/* If you get warnings regarding __get_PRIMASK and __set_PRIMASK, make sure that ARM's CMSIS API is included
by the recorder using your chip vendor header file (e.g., "board.h", "stm32f4xx.h", "lpc17xx.h") */
#define TRACE_SR_ALLOC_CRITICAL_SECTION() int __irq_status;
/* Uses CMSIS API */
#define TRACE_SR_ALLOC_CRITICAL_SECTION() int __irq_status;
#define TRACE_ENTER_CRITICAL_SECTION() {__irq_status = __get_PRIMASK(); __set_PRIMASK(1);}
#define TRACE_EXIT_CRITICAL_SECTION() {__set_PRIMASK(__irq_status);}
#endif
#if (SELECTED_PORT == PORT_ARM_CORTEX_M0)
#define TRACE_SR_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 ((SELECTED_PORT == PORT_ARM_CORTEX_A9) || (SELECTED_PORT == PORT_Renesas_RX600) || (SELECTED_PORT == PORT_MICROCHIP_PIC32MX) || (SELECTED_PORT == PORT_MICROCHIP_PIC32MZ))
#define TRACE_SR_ALLOC_CRITICAL_SECTION() int __irq_status;
#define TRACE_ENTER_CRITICAL_SECTION() {__irq_status = portSET_INTERRUPT_MASK_FROM_ISR();}
@@ -471,7 +476,6 @@ void* prvTraceGetCurrentTaskHandle(void);
#define TRACE_GET_CLASS_TRACE_CLASS(CLASS, kernelClass) TraceObjectClassTable[kernelClass]
#define TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject) TRACE_GET_CLASS_TRACE_CLASS(CLASS, prvTraceGetObjectType(pxObject))
/* Note: Timer tracing only supported on FreeRTOS v8 or later, so "Timer_t" is safe to use! */
#define TRACE_GET_TIMER_NUMBER(tmr) ( ( objectHandleType ) ((Timer_t*)tmr)->uxTimerNumber )
#define TRACE_SET_TIMER_NUMBER(tmr) ((Timer_t*)tmr)->uxTimerNumber = xTraceGetObjectHandle(TRACE_CLASS_TIMER);
#define TRACE_GET_TIMER_NAME(pxTimer) pxTimer->pcTimerName
@@ -553,6 +557,12 @@ void* prvTraceGetCurrentTaskHandle(void);
#define traceTASK_SUSPEND( pxTaskToSuspend ) \
trcKERNEL_HOOKS_TASK_SUSPEND(TASK_SUSPEND, pxTaskToSuspend);
/* Called from special case with timer only */
#undef traceTASK_DELAY_SUSPEND
#define traceTASK_DELAY_SUSPEND( pxTaskToSuspend ) \
trcKERNEL_HOOKS_TASK_SUSPEND(TASK_SUSPEND, pxTaskToSuspend); \
trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED();
/* Called on vTaskDelay - note the use of FreeRTOS variable xTicksToDelay */
#undef traceTASK_DELAY
#define traceTASK_DELAY() \
@@ -1064,11 +1074,3 @@ vTraceSetObjectName(TRACE_CLASS_EVENTGROUP, (objectHandleType)uxEventGroupGetNum
#endif
#endif /* TRCKERNELPORTFREERTOS_H_ */
@@ -1,5 +1,5 @@
/*******************************************************************************
* Tracealyzer v2.7.7 Recorder Library
* Tracealyzer v3.0.2 Recorder Library
* Percepio AB, www.percepio.com
*
* trcTypes.h
@@ -33,7 +33,7 @@
*
* Tabs are used for indent in this file (1 tab = 4 spaces)
*
* Copyright Percepio AB, 2012-2015.
* Copyright Percepio AB, 2014.
* www.percepio.com
******************************************************************************/
@@ -1,5 +1,5 @@
/*******************************************************************************
* Tracealyzer v2.7.7 Recorder Library
* Tracealyzer v3.0.2 Recorder Library
* Percepio AB, www.percepio.com
*
* trcUser.h
@@ -32,7 +32,7 @@
*
* Tabs are used for indent in this file (1 tab = 4 spaces)
*
* Copyright Percepio AB, 2012-2015.
* Copyright Percepio AB, 2014.
* www.percepio.com
******************************************************************************/
@@ -385,7 +385,7 @@ void vTraceUserEvent(traceLabel eventLabel);
*
* Calling xTraceOpenLabel multiple times will not create duplicate entries, but
* it is of course faster to just do it once, and then keep the handle for later
* use. If you don´t have any data arguments, only a text label/string, it is
* use. If you don�t have any data arguments, only a text label/string, it is
* better to use vTraceUserEvent - it is faster.
*
* Format specifiers supported:
@@ -4,10 +4,10 @@ Tracealyzer Trace Recorder Library
Percepio AB
www.percepio.com
This directory contains the a generic trace recorder library for Tracealyzer v2.7.
This directory contains the a generic trace recorder library for Tracealyzer v3.0.2.
For information on how to upload the trace data from your target system RAM to
Tracealyzer, see the User Manual (e.g., http://percepio.com/docs/FreeRTOS/manual/Recorder.html)
Tracealyzer, see the User Manual.
Files included
--------------
@@ -1,5 +1,5 @@
/*******************************************************************************
* Tracealyzer v2.7.7 Recorder Library
* Tracealyzer v3.0.2 Recorder Library
* Percepio AB, www.percepio.com
*
* trcBase.c
@@ -33,11 +33,11 @@
*
* Tabs are used for indent in this file (1 tab = 4 spaces)
*
* Copyright Percepio AB, 2012-2015.
* Copyright Percepio AB, 2014.
* www.percepio.com
******************************************************************************/
#include "trcBase.h"
#include "trcBase.h"
#if (USE_TRACEALYZER_RECORDER == 1)
@@ -48,7 +48,7 @@
******************************************************************************/
/* Tasks and kernel objects can be explicitly excluded from the trace to reduce
buffer usage. This structure handles the exclude flags for all objects and tasks.
buffer usage. This structure handles the exclude flags for all objects and tasks.
Note that slot 0 is not used, since not a valid handle. */
uint8_t excludedObjects[(TRACE_KERNEL_OBJECT_COUNT + TRACE_NCLASSES) / 8 + 1] = { 0 };
@@ -58,43 +58,43 @@ This structure handle the exclude flags for all event codes */
uint8_t excludedEventCodes[NEventCodes / 8 + 1] = { 0 };
/* A set of stacks that keeps track of available object handles for each class.
The stacks are empty initially, meaning that allocation of new handles will be
The stacks are empty initially, meaning that allocation of new handles will be
based on a counter (for each object class). Any delete operation will
return the handle to the corresponding stack, for reuse on the next allocate.*/
objectHandleStackType objectHandleStacks = { { 0 }, { 0 }, { 0 }, { 0 }, { 0 } };
/* Initial HWTC_COUNT value, for detecting if the time-stamping source is
enabled. If using the OS periodic timer for time-stamping, this might not
/* Initial HWTC_COUNT value, for detecting if the time-stamping source is
enabled. If using the OS periodic timer for time-stamping, this might not
have been configured on the earliest events during the startup. */
uint32_t init_hwtc_count;
/*******************************************************************************
* RecorderData
*
* The main data structure. This is the data read by the Tracealyzer tools,
* typically through a debugger RAM dump. The recorder uses the pointer
* The main data structure. This is the data read by the Tracealyzer tools,
* typically through a debugger RAM dump. The recorder uses the pointer
* RecorderDataPtr for accessing this, to allow for dynamic allocation.
*
* On the NXP LPC17xx you may use the secondary RAM bank (AHB RAM) for this
* purpose. For instance, the LPC1766 has 32 KB AHB RAM which allows for
* allocating a buffer size of at least 7500 events without affecting the main
* RAM. To place RecorderData in this RAM bank using IAR Embedded Workbench
* RAM. To place RecorderData in this RAM bank using IAR Embedded Workbench
* for ARM, use this pragma right before the declaration:
*
* #pragma location="AHB_RAM_MEMORY"
*
* This of course works for other hardware architectures with additional RAM
* banks as well, just replace "AHB_RAM_MEMORY" with the section name from the
* banks as well, just replace "AHB_RAM_MEMORY" with the section name from the
* linker .map file, or simply the desired address.
*
* For portability reasons, we don't add the pragma directly in trcBase.c, but
* For portability reasons, we don't add the pragma directly in trcBase.c, but
* in a header file included below. To include this header, you need to enable
* USE_LINKER_PRAGMA, defined in trcConfig.h.
*
* If using GCC, you need to modify the declaration as follows:
*
* RecorderDataType RecorderData __attribute__ ((section ("name"))) = ...
*
*
* Remember to replace "name" with the correct section name.
******************************************************************************/
@@ -113,9 +113,9 @@ RecorderDataType* RecorderDataPtr = NULL;
/* This version of the function dynamically allocates the trace data */
void prvTraceInitTraceData()
{
{
init_hwtc_count = HWTC_COUNT;
#if TRACE_DATA_ALLOCATION == TRACE_DATA_ALLOCATION_STATIC
RecorderDataPtr = &RecorderData;
#elif TRACE_DATA_ALLOCATION == TRACE_DATA_ALLOCATION_DYNAMIC
@@ -132,7 +132,7 @@ void prvTraceInitTraceData()
vTraceError("No recorder data structure allocated!");
return;
}
(void)memset(RecorderDataPtr, 0, sizeof(RecorderDataType));
RecorderDataPtr->startmarker0 = 0x00;
@@ -166,7 +166,7 @@ void prvTraceInitTraceData()
RecorderDataPtr->SymbolTable.symTableSize = SYMBOL_TABLE_SIZE;
RecorderDataPtr->SymbolTable.nextFreeSymbolIndex = 1;
#if (INCLUDE_FLOAT_SUPPORT == 1)
RecorderDataPtr->exampleFloatEncoding = (float)1.0; /* otherwise already zero */
RecorderDataPtr->exampleFloatEncoding = 1.0f; /* otherwise already zero */
#endif
RecorderDataPtr->debugMarker2 = 0xF2F2F2F2;
(void)strncpy(RecorderDataPtr->systemInfo, "Trace Recorder Demo", 80);
@@ -196,7 +196,7 @@ void prvTraceInitTraceData()
/* Fix the start markers of the trace data structure */
vInitStartMarkers();
#ifdef PORT_SPECIFIC_INIT
PORT_SPECIFIC_INIT();
#endif
@@ -242,15 +242,15 @@ void* xTraceNextFreeEventBufferSlot(void)
uint16_t uiIndexOfObject(objectHandleType objecthandle, uint8_t objectclass)
{
TRACE_ASSERT(objectclass < TRACE_NCLASSES,
TRACE_ASSERT(objectclass < TRACE_NCLASSES,
"uiIndexOfObject: Invalid value for objectclass", 0);
TRACE_ASSERT(objecthandle > 0 && objecthandle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
TRACE_ASSERT(objecthandle > 0 && objecthandle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
"uiIndexOfObject: Invalid value for objecthandle", 0);
if ((objectclass < TRACE_NCLASSES) && (objecthandle > 0) &&
if ((objectclass < TRACE_NCLASSES) && (objecthandle > 0) &&
(objecthandle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass]))
{
return (uint16_t)(RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[objectclass] +
return (uint16_t)(RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[objectclass] +
(RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[objectclass] * (objecthandle-1)));
}
@@ -286,7 +286,7 @@ objectHandleType xTraceGetObjectHandle(traceObjectClass objectclass)
objectHandleType handle;
static int indexOfHandle;
TRACE_ASSERT(objectclass < TRACE_NCLASSES,
TRACE_ASSERT(objectclass < TRACE_NCLASSES,
"xTraceGetObjectHandle: Invalid value for objectclass", (objectHandleType)0);
indexOfHandle = objectHandleStacks.indexOfNextAvailableHandle[objectclass];
@@ -335,9 +335,9 @@ void vTraceFreeObjectHandle(traceObjectClass objectclass, objectHandleType handl
{
int indexOfHandle;
TRACE_ASSERT(objectclass < TRACE_NCLASSES,
TRACE_ASSERT(objectclass < TRACE_NCLASSES,
"vTraceFreeObjectHandle: Invalid value for objectclass", );
TRACE_ASSERT(handle > 0 && handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
TRACE_ASSERT(handle > 0 && handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
"vTraceFreeObjectHandle: Invalid value for handle", );
/* Check that there is room to push the handle on the stack */
@@ -421,10 +421,10 @@ traceLabel prvTraceOpenSymbol(const char* name, traceLabel userEventChannel)
uint8_t len;
uint8_t crc;
TRACE_SR_ALLOC_CRITICAL_SECTION();
len = 0;
crc = 0;
TRACE_ASSERT(name != NULL, "prvTraceOpenSymbol: name == NULL", (traceLabel)0);
prvTraceGetChecksum(name, &crc, &len);
@@ -470,9 +470,9 @@ void vTraceError(const char* msg)
{
traceErrorMessage = (char*)msg;
(void)strncpy(RecorderDataPtr->systemInfo, traceErrorMessage, 80);
RecorderDataPtr->internalErrorOccured = 1;
RecorderDataPtr->internalErrorOccured = 1;
}
}
/******************************************************************************
@@ -496,7 +496,7 @@ void prvCheckDataToBeOverwrittenForMultiEntryEvents(uint8_t nofEntriesToCheck)
unsigned int i = 0;
unsigned int e = 0;
TRACE_ASSERT(nofEntriesToCheck != 0,
TRACE_ASSERT(nofEntriesToCheck != 0,
"prvCheckDataToBeOverwrittenForMultiEntryEvents: nofEntriesToCheck == 0", );
while (i < nofEntriesToCheck)
@@ -535,12 +535,12 @@ void prvCheckDataToBeOverwrittenForMultiEntryEvents(uint8_t nofEntriesToCheck)
* Updates the index of the event buffer.
******************************************************************************/
void prvTraceUpdateCounters(void)
{
{
if (RecorderDataPtr->recorderActive == 0)
{
return;
}
RecorderDataPtr->numEvents++;
RecorderDataPtr->nextFreeIndex++;
@@ -584,9 +584,9 @@ uint16_t prvTraceGetDTS(uint16_t param_maxDTS)
if (RecorderDataPtr->frequency == 0 && init_hwtc_count != HWTC_COUNT)
{
/* If HWTC_PERIOD is mapped to the timer reload register,
it might not be initialized before the scheduler has been started.
it might not be initialized before the scheduler has been started.
We therefore store the frequency of the timer when the counter
register has changed from its initial value.
register has changed from its initial value.
(Note that this function is called also by vTraceStart and
uiTraceStart, which might be called before the scheduler
has been started.) */
@@ -605,9 +605,9 @@ uint16_t prvTraceGetDTS(uint16_t param_maxDTS)
* If necessary, whole seconds are extracted using division while the rest
* comes from the modulo operation.
**************************************************************************/
vTracePortGetTimeStamp(&timestamp);
vTracePortGetTimeStamp(&timestamp);
/***************************************************************************
* Since dts is unsigned the result will be correct even if timestamp has
* wrapped around.
@@ -818,14 +818,14 @@ void prvTraceGetChecksum(const char *pname, uint8_t* pcrc, uint8_t* plength)
#if (USE_16BIT_OBJECT_HANDLES == 1)
void prvTraceStoreXID(objectHandleType handle);
void prvTraceStoreXID(objectHandleType handle);
/******************************************************************************
* prvTraceStoreXID
*
* Stores an XID (eXtended IDentifier) event.
* This is used if an object/task handle is larger than 255.
* The parameter "handle" is the full (16 bit) handle, assumed to be 256 or
* The parameter "handle" is the full (16 bit) handle, assumed to be 256 or
* larger. Handles below 256 should not use this function.
*
* NOTE: this function MUST be called from within a critical section.
@@ -844,7 +844,7 @@ void prvTraceStoreXID(objectHandleType handle)
xid->type = XID;
/* This function is (only) used when objectHandleType is 16 bit... */
xid->xps_16 = handle;
xid->xps_16 = handle;
prvTraceUpdateCounters();
}
@@ -853,11 +853,11 @@ void prvTraceStoreXID(objectHandleType handle)
unsigned char prvTraceGet8BitHandle(objectHandleType handle)
{
if (handle > 255)
{
{
prvTraceStoreXID(handle);
/* The full handle (16 bit) is stored in the XID event.
/* The full handle (16 bit) is stored in the XID event.
This code (255) is used instead of zero (which is an error code).*/
return 255;
return 255;
}
return (unsigned char)(handle & 0xFF);
}
@@ -1,15 +1,16 @@
/*******************************************************************************
* Tracealyzer v2.7.7 Recorder Library
* Tracealyzer v3.0.2 Recorder Library
* Percepio AB, www.percepio.com
*
* trcBase.c
* trcHardwarePort.c
*
* Core functionality of the trace recorder library.
* Contains together with trcHardwarePort.h all hardware portability issues of
* the trace recorder library.
*
* Terms of Use
* This software is copyright Percepio AB. The recorder library is free for
* use together with Percepio products. You may distribute the recorder library
* in its original form, including modifications in trcHardwarePort.c/.h
* in its original form, including modifications in trcPort.c and trcPort.h
* given that these modification are clearly marked as your own modifications
* and documented in the initial comment section of these source files.
* This software is the intellectual property of Percepio AB and may not be
@@ -33,7 +34,7 @@
*
* Tabs are used for indent in this file (1 tab = 4 spaces)
*
* Copyright Percepio AB, 2012-2015.
* Copyright Percepio AB, 2014.
* www.percepio.com
******************************************************************************/
@@ -1,5 +1,5 @@
/*******************************************************************************
* Tracealyzer v2.7.7 Recorder Library
* Tracealyzer v3.0.2 Recorder Library
* Percepio AB, www.percepio.com
*
* trcKernel.c
@@ -33,7 +33,7 @@
*
* Tabs are used for indent in this file (1 tab = 4 spaces)
*
* Copyright Percepio AB, 2012-2015.
* Copyright Percepio AB, 2014.
* www.percepio.com
******************************************************************************/
@@ -48,9 +48,9 @@ int8_t nISRactive = 0;
objectHandleType handle_of_last_logged_task = 0;
uint8_t inExcludedTask = 0;
#if (INCLUDE_MEMMANG_EVENTS == 1)
/* Current heap usage. Always updated. */
static uint32_t heapMemUsage = 0;
#if (INCLUDE_MEMMANG_EVENTS == 1) && (TRACE_SCHEDULING_ONLY == 0)
/* Current heap usage. Always updated. */
static uint32_t heapMemUsage = 0;
#endif
#if (TRACE_SCHEDULING_ONLY == 0)
@@ -639,9 +639,9 @@ void vTraceSetPriorityProperty(uint8_t objectclass, objectHandleType id, uint8_t
uint8_t uiTraceGetPriorityProperty(uint8_t objectclass, objectHandleType id)
{
TRACE_ASSERT(objectclass < TRACE_NCLASSES,
"uiTraceGetPriorityProperty: Invalid objectclass number (>= TRACE_NCLASSES)", 0);
"uiTraceGetPriorityProperty: objectclass >= TRACE_NCLASSES", 0);
TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
"uiTraceGetPriorityProperty: Task handle exceeds NTask. You may need to increase this constant in trcConfig.h.", 0);
"uiTraceGetPriorityProperty: Invalid value for id", 0);
return TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, id);
}
@@ -1,5 +1,5 @@
/*******************************************************************************
* Tracealyzer v2.7.7 Recorder Library
* Tracealyzer v3.0.2 Recorder Library
* Percepio AB, www.percepio.com
*
* trcUser.c
@@ -33,12 +33,9 @@
*
* Tabs are used for indent in this file (1 tab = 4 spaces)
*
* Copyright Percepio AB, 2012-2015.
* Copyright Percepio AB, 2014.
* www.percepio.com
******************************************************************************/
#include "FreeRTOS.h"
#include "task.h"
#include "trcUser.h"
#if (USE_TRACEALYZER_RECORDER == 1)
@@ -367,6 +364,7 @@ void vTraceTaskInstanceFinishDirect(void)
#define MAX_ISR_NESTING 16
static uint8_t isrstack[MAX_ISR_NESTING];
int32_t isPendingContextSwitch = 0;
/*******************************************************************************
* vTraceSetISRProperties
@@ -572,11 +570,15 @@ void vTraceStoreISRBegin(objectHandleType handle)
return;
}
trcCRITICAL_SECTION_BEGIN();
if (nISRactive == 0)
isPendingContextSwitch = 0; /* We are at the start of a possible ISR chain. No context switches should have been triggered now. */
if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)
{
TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[TRACE_CLASS_ISR], "vTraceStoreISRBegin: Invalid value for handle", );
dts4 = (uint16_t)prvTraceGetDTS(0xFFFF);
if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */
@@ -632,6 +634,8 @@ void vTraceStoreISREnd(int pendingISR)
{
TSEvent* ts;
uint16_t dts5;
uint8_t hnd8 = 0, type = 0;
TRACE_SR_ALLOC_CRITICAL_SECTION();
if (! RecorderDataPtr->recorderActive || ! handle_of_last_logged_task)
@@ -652,24 +656,28 @@ void vTraceStoreISREnd(int pendingISR)
}
trcCRITICAL_SECTION_BEGIN();
if (pendingISR == 0)
isPendingContextSwitch |= pendingISR; /* Is there a pending context switch right now? */
nISRactive--;
if (nISRactive > 0)
{
/* Return to another isr */
type = TS_ISR_RESUME;
hnd8 = prvTraceGet8BitHandle(isrstack[nISRactive - 1]); /* isrstack[nISRactive] is the handle of the ISR we're currently exiting. isrstack[nISRactive - 1] is the handle of the ISR that was executing previously. */
}
else if (isPendingContextSwitch == 0)
{
/* No context switch has been triggered by any ISR in the chain. Return to task */
type = TS_TASK_RESUME;
hnd8 = prvTraceGet8BitHandle(handle_of_last_logged_task);
}
else
{
/* Context switch has been triggered by some ISR. We expect a proper context switch event shortly so we do nothing. */
}
if (type != 0)
{
uint8_t hnd8, type;
dts5 = (uint16_t)prvTraceGetDTS(0xFFFF);
if (nISRactive > 1)
{
/* return to another isr */
type = TS_ISR_RESUME;
hnd8 = prvTraceGet8BitHandle(isrstack[nISRactive]);
}
else
{
/* return to task */
type = TS_TASK_RESUME;
hnd8 = prvTraceGet8BitHandle(handle_of_last_logged_task);
}
ts = (TSEvent*)xTraceNextFreeEventBufferSlot();
if (ts != NULL)
{
@@ -684,7 +692,6 @@ void vTraceStoreISREnd(int pendingISR)
ptrLastISRExitEvent = (uint8_t*)ts;
#endif
}
nISRactive--;
#if (SELECTED_PORT == PORT_ARM_CortexM)
DWTCycleCountAtLastISRExit = REG_DWT_CYCCNT;
@@ -1251,7 +1258,7 @@ void vTraceChannelUserEvent(UserEventChannel channelPair)
*
* Calling xTraceOpenLabel multiple times will not create duplicate entries, but
* it is of course faster to just do it once, and then keep the handle for later
* use. If you don´t have any data arguments, only a text label/string, it is
* use. If you don�t have any data arguments, only a text label/string, it is
* better to use vTraceUserEvent - it is faster.
*
* Format specifiers supported: