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