[修改] 增加freeRTOS

1. 版本FreeRTOSv202212.01,命名为kernel;
This commit is contained in:
2023-05-06 16:43:01 +00:00
commit a345df017b
20944 changed files with 11094377 additions and 0 deletions

View File

@ -0,0 +1,21 @@
Tracealyzer Stream Port for Amazon FreeRTOS TCP/WIFI
Percepio AB
www.percepio.com
----------------------------------------------------
This directory contains a "stream port" for the Tracealyzer recorder library,
i.e., the specific code needed to use a particular interface for streaming a
Tracealyzer RTOS trace. The stream port is defined by a set of macros in
trcStreamPort.h, found in the "include" directory.
This particular stream port is for streaming via a TCP socket in Amazon
FreeRTOS (AFR) directly to a host computer on the local network, typically
using Wifi. Read more in trcStreamPort.h.
To use this stream port, make sure that include/trcStreamPort.h is found
by the compiler (i.e., add this folder to your project's include paths) and
add all included source files to your build. Make sure no other versions of
trcStreamPort.h are included by mistake!
See also http://percepio.com/2016/10/05/rtos-tracing
and https://percepio.com/2018/10/11/tuning-your-custom-trace-streaming/

View File

@ -0,0 +1,127 @@
/*
* Trace Recorder for Tracealyzer v4.6.0
* Copyright 2021 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* This stream port provides trace streaming using the Amazon FreeRTOS sockets
* layer and is intended for streaming over Wifi directly to a computer on the
* local Wifi network.
*
* Note that this does NOT use the TLS encryption available in Amazon
* FreeRTOS, due to performance and memory usage concerns. However, it does not
* use any AWS services either, and is intended for your local network only.
*
* This should be started using vTraceEnable(TRC_START) and this call should be
* made AFTER the kernel has started and the Wifi interface is ready.
*
* In the Tracealyzer setting -> "PSF Streaming Settings" make sure that the
* "Target Connection" setting is "TCP (Target Initiated)".
*
* To use this, make sure to start the trace recording in Tracealyzer before
* you start your target system. This ensures that Tracealyzer is ready when
* the target system connects.
*
* And don't forget to enter the IP address of the Tracealyzer host computer
* in trcStreamPort.h.
*
* NOTES:
*
* 1: The tracing will increase the stack usage of you application, so you
* may want to increase configMINIMAL_STACK_SIZE in your FreeRTOSConfig.h.
*
* 2: To reduce the amount of trace data, we recommend disabling the tracing
* of OS Ticks and memory allocation events.
* See TRC_CFG_INCLUDE_OSTICK_EVENTS in trcConfig.h.
*
* 3: The transmission of trace data is done in the TzCtrl task. To avoid that
* the trace streaming is blocked during the (long) MQTT connection phase,
* make sure the scheduling priority of TzCtrl is higher than the MQTT task.
* Otherwise, if you prefer to run the TzCtrl task at lower priority to avoid
* interfering with your application, wait with the vTraceEnable call until
* after the MQTT connection is established.
* See TRC_CFG_CTRL_TASK_PRIORITY in trcStreamingConfig.h.
*
* 4: The Wifi transmission of trace data often uses FreeRTOS functions, that
* are traced and thus produce additional trace data. This may cause a fast
* increase in trace data rate, that may saturate the trace buffer and cause
* data loss (i.e. incomplete traces).
* To eliminate this effect and reduce the amount of trace data produced, we
* recommend excluding all FreeRTOS objects that are used by Wifi stack.
* This is done using vTraceSetFilterGroup and vTraceSetFilterMask:
*
* // Just before wifi initialization:
*
* // All objects created after this point are assigned to group 15.
* vTraceSetFilterGroup(FilterGroup15);
*
* // Only trace objects assigned to group 0 (the default group).
* vTraceSetFilterMask(FilterGroup0);
*
* // The wifi stack initialization... (creates semaphores etc.)
* if ( eWifi_Connected == prvWifiConnect() )
* {
* yMainState = eMain_StartApplication;
*
* // When connected, restore the FilterGroup setting to Group 0, so
* // that later created objects are included, like the TzCtrl task
* // created in vTraceEnable. Excluding tasks is not recommended!
* vTraceSetFilterGroup(FilterGroup0);
*
* // Then call vTraceEnable to start the tracing.
* vTraceEnable(TRC_START);
* }
*
* 5: If you still get "red sections" in Tracealyzer (lost data), you need
* to adjust the other settings in trcStreamingConfig.h.
*
* - TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT
* Increase this, as long as you have memory to spare.
*
* - TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE
* Increase this, as long as you have memory to spare.
* But don't exceed the maximum payload size of the Wifi chip, which
* is often limited to 1000-1500 bytes. Some chips crash if you try to
* send to large chunks...
*
* - TRC_CFG_CTRL_TASK_DELAY
* Decrease this to flush the trace buffer more frequently.
*
* See also http://percepio.com/2016/10/05/rtos-tracing
* and https://percepio.com/2018/10/11/tuning-your-custom-trace-streaming/
*/
#ifndef TRC_STREAM_PORT_H
#define TRC_STREAM_PORT_H
#ifdef __cplusplus
extern "C" {
#endif
#define HOST_IPADDRESS_0 192
#define HOST_IPADDRESS_1 168
#define HOST_IPADDRESS_2 10
#define HOST_IPADDRESS_3 116
#define HOST_PORT 12000
void prvInitSocket(void);
int32_t prvReadFromSocket(void* ptrData, uint32_t size, int32_t* ptrBytesRead);
int32_t prvWriteToSocket(void* ptrData, uint32_t size, int32_t* ptrBytesWritten);
#define TRC_STREAM_PORT_INIT() \
TRC_STREAM_PORT_MALLOC(); \
prvInitSocket();
#define TRC_STREAM_PORT_USE_INTERNAL_BUFFER 1
#define TRC_STREAM_PORT_WRITE_DATA(_ptrData, _size, _ptrBytesWritten) prvWriteToSocket(_ptrData, _size, _ptrBytesWritten)
#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) prvReadFromSocket(_ptrData, _size, _ptrBytesRead)
#ifdef __cplusplus
}
#endif
#endif /* TRC_STREAM_PORT_H */

View File

@ -0,0 +1,157 @@
/*
* Trace Recorder for Tracealyzer v4.6.0
* Copyright 2021 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* This stream port provides trace streaming using the Amazon FreeRTOS sockets
* layer and is intended for streaming over Wifi directly to a computer on the
* local Wifi network.
*
* Note that this does NOT use the TLS encryption available in Amazon
* FreeRTOS, due to performance and memory usage concerns. However, it does not
* use any AWS services either, and is intended for your local network only.
*
* This should be started using vTraceEnable(TRC_START) and this call should be
* made AFTER the kernel has started and the Wifi interface is ready.
*
* In the Tracealyzer setting -> "PSF Streaming Settings" make sure that the
* "Target Connection" setting is "TCP (Target Initiated)".
*
* To use this, make sure to start the trace recording in Tracealyzer before
* you start your target system. This ensures that Tracealyzer is ready when
* the target system connects.
*
* And don't forget to enter the IP address of the Tracealyzer host computer
* in trcStreamPort.h.
*
* NOTES:
*
* 1: The tracing will increase the stack usage of you application, so you
* may want to increase configMINIMAL_STACK_SIZE in your FreeRTOSConfig.h.
*
* 2: To reduce the amount of trace data, we recommend disabling the tracing
* of OS Ticks and memory allocation events.
* See TRC_CFG_INCLUDE_OSTICK_EVENTS in trcConfig.h.
*
* 3: The transmission of trace data is done in the TzCtrl task. To avoid that
* the trace streaming is blocked during the (long) MQTT connection phase,
* make sure the scheduling priority of TzCtrl is higher than the MQTT task.
* Otherwise, if you prefer to run the TzCtrl task at lower priority to avoid
* interfering with your application, wait with the vTraceEnable call until
* after the MQTT connection is established.
* See TRC_CFG_CTRL_TASK_PRIORITY in trcStreamingConfig.h.
*
* 4: The Wifi transmission of trace data often uses FreeRTOS functions, that
* are traced and thus produce additional trace data. This may cause a fast
* increase in trace data rate, that may saturate the trace buffer and cause
* data loss (i.e. incomplete traces).
* To eliminate this effect and reduce the amount of trace data produced, we
* recommend excluding all FreeRTOS objects that are used by Wifi stack.
* This is done using vTraceSetFilterGroup and vTraceSetFilterMask:
*
* // Just before wifi initialization:
*
* // All objects created after this point are assigned to group 15.
* vTraceSetFilterGroup(FilterGroup15);
*
* // Only trace objects assigned to group 0 (the default group).
* vTraceSetFilterMask(FilterGroup0);
*
* // The wifi stack initialization... (creates semaphores etc.)
* if ( eWifi_Connected == prvWifiConnect() )
* {
* yMainState = eMain_StartApplication;
*
* // When connected, restore the FilterGroup setting to Group 0, so
* // that later created objects are included, like the TzCtrl task
* // created in vTraceEnable. Excluding tasks is not recommended!
* vTraceSetFilterGroup(FilterGroup0);
*
* // Then call vTraceEnable to start the tracing.
* vTraceEnable(TRC_START);
* }
*
* 5: If you still get "red sections" in Tracealyzer (lost data), you need
* to adjust the other settings in trcStreamingConfig.h.
*
* - TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT
* Increase this, as long as you have memory to spare.
*
* - TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE
* Increase this, as long as you have memory to spare.
* But don't exceed the maximum payload size of the Wifi chip, which
* is often limited to 1000-1500 bytes. Some chips crash if you try to
* send to large chunks...
*
* - TRC_CFG_CTRL_TASK_DELAY
* Decrease this to flush the trace buffer more frequently.
*
* See also http://percepio.com/2016/10/05/rtos-tracing
* and https://percepio.com/2018/10/11/tuning-your-custom-trace-streaming/
*/
#include <trcRecorder.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#include <aws_secure_sockets.h>
SocketsSockaddr_t addr = {sizeof(SocketsSockaddr_t), SOCKETS_AF_INET, 0, 0};
#define IPv4(a,b,c,d) (uint32_t)((d << 24) + (c << 16) + (b << 8) + a)
Socket_t sock = 0;
void prvInitSocket(void)
{
int32_t status;
SOCKETS_Init();
sock = SOCKETS_Socket(SOCKETS_AF_INET, SOCKETS_SOCK_STREAM, SOCKETS_IPPROTO_TCP);
configPRINTF( ( "Connecting to %d.%d.%d.%d, port %d\r\n", HOST_IPADDRESS_0, HOST_IPADDRESS_1, HOST_IPADDRESS_2, HOST_IPADDRESS_3, HOST_PORT) );
addr.ulAddress = IPv4(HOST_IPADDRESS_0, HOST_IPADDRESS_1, HOST_IPADDRESS_2, HOST_IPADDRESS_3);
addr.usPort = SOCKETS_htons(HOST_PORT);
status = SOCKETS_Connect(sock, &addr, sizeof( SocketsSockaddr_t ) );
if (status != SOCKETS_ERROR_NONE)
{
//prvTraceError(PSF_ERROR_STREAM_PORT_FAIL);
configPRINTF( ( "Failed to connect, status: %d\r\n", status) );
}
else
{
configPRINTF( ( "Connected.\r\n") );
}
}
int32_t prvWriteToSocket(void* ptrData, uint32_t size, int32_t* ptrBytesWritten)
{
uint32_t bytesWritten = SOCKETS_Send(sock, ptrData, size, 0);
if (ptrBytesWritten != 0)
*ptrBytesWritten = (int32_t)bytesWritten;
if (bytesWritten != size)
{
return -1;
}
return 0;
}
int32_t prvReadFromSocket(void* ptrData, uint32_t size, int32_t* ptrBytesRead)
{
// Not yet implemented, since not necessary.
return 0;
}
#endif
#endif

View File

@ -0,0 +1,55 @@
/*
* Trace Recorder for Tracealyzer v4.6.0
* Copyright 2021 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
*/
FUNC void tzSetEnable(int enable)
{
if (enable == 1)
{
printf("Starting Tracealyzer recorder\n");
// Forward the ITM data to file
exec("ITMLOG 1 > .\\tracealyzer.psf");
// Send start command to Tracealyzer (not required if using vTraceEnable(TRC_START))
exec("E CHAR tz_host_command_data = 1, 1, 0, 0, 0, 0, 0xFD, 0xFF");
exec("tz_host_command_bytes_to_read = 8");
}
else if (enable == 0)
{
printf("Stopping Tracealyzer recorder...\n");
// Send stop command to Tracealyzer, to stop writing ITM data.
exec("E CHAR tz_host_command_data = 1, 0, 0, 0, 0, 0, 0xFE, 0xFF");
exec("tz_host_command_bytes_to_read = 8");
_sleep_(2000); // Wait a while to let all data be written the host file.
// Stop forwarding the ITM data to file and close the file.
exec("ITMLOG 1 OFF");
printf("Tracealyzer recorder stopped.\n");
}
else printf("Usage: tzSetEnable(0 or 1), where 0 is disable (stops recorder) and 1 enable (starts recording)");
}
// The Tracealyzer ITM stream port for Keil µVision can be used in two ways.
//
// 1. Start tracing directly from startup.
// Make sure tzSetEnable(1) is called below and vTraceEnable(TRC_START) in your target startup.
//
// 2. Start the trace manually, using the "Start Recording" button in Keil µVision.
// In this case, comment out the below call to tzSetEnable and make sure you call vTraceEnable(TRC_INIT) in your target startup (not TRC_START).
tzSetEnable(1);
DEFINE BUTTON "Start Recording", "tzSetEnable(1)";
DEFINE BUTTON "Stop Recording", "tzSetEnable(0)";

View File

@ -0,0 +1,34 @@
Tracealyzer Stream Port for ARM Cortex-M ITM
Percepio AB
www.percepio.com
--------------------------------------------
This directory contains a "stream port" for the Tracealyzer recorder library,
i.e., the specific code needed to use a particular interface for streaming a
Tracealyzer RTOS trace. The stream port is defined by a set of macros in
trcStreamPort.h, found in the "include" directory.
This particular stream port targets ARM's ITM interface, which together with
a fast debug probe such as a Keil ULINKpro or ULINKplus provides excellent
performance. This stream port does not use any RAM buffer for the trace, but
writes the data directly to the ITM registers. This is very fast.
To setup Keil uVision for ITM tracing with a Keil ULINKpro (or ULINKplus),
see Percepio Application Note PA-021, https://percepio.com/2018/05/04/keil-itm-support/
To setup IAR Embedded Workbench for ITM tracing with an IAR I-Jet,
see Percepio Application Note PA-023, https://percepio.com/iar
To setup Lauterbach TRACE32 for ITM tracing with a uTrace,
see Percepio Application Note PA-033, https://percepio.com/apn/PA033-TRACE32%20ITM%20Streaming.pdf
Learn more:
- Tracealyzer User Manual (Help -> User Manual)
- https://percepio.com/gettingstarted
- Percepio Application Note PA-021 (Keil), https://percepio.com/2018/05/04/keil-itm-support/
- Percepio Application Note PA-023 (IAR), https://percepio.com/iar
- Percepio Application Note PA-033 (Lauterbach), https://percepio.com/apn/PA033-TRACE32%20ITM%20Streaming.pdf
- About ITM trace, https://percepio.com/2016/06/09/arm-itm/
- About the recorder and custom streaming, http://percepio.com/2016/10/05/rtos-tracing
For questions, please contact support@percepio.com

View File

@ -0,0 +1,35 @@
/*
* Trace Recorder for Tracealyzer v4.6.0
* Copyright 2021 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The configuration for trace streaming ("stream ports").
*/
#ifndef TRC_STREAM_PORT_CONFIG_H
#define TRC_STREAM_PORT_CONFIG_H
#ifdef __cplusplus
extern "C" {
#endif
/*******************************************************************************
* TRC_CFG_STREAM_PORT_ITM_PORT
*
* Valid values: 0 - 31
*
* What ITM port to use for the ITM software events. Make sure the IDE is
* configured for the same channel.
*
* Default: 1 (0 is typically terminal output and 31 is used by Keil)
*
******************************************************************************/
#define TRC_CFG_STREAM_PORT_ITM_PORT 1
#ifdef __cplusplus
}
#endif
#endif /* TRC_STREAM_PORT_CONFIG_H */

View File

@ -0,0 +1,113 @@
/*
* Trace Recorder for Tracealyzer v4.6.0
* Copyright 2021 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The interface definitions for trace streaming ("stream ports").
* This "stream port" sets up the recorder to use ARM ITM as streaming channel.
*
* To setup Keil uVision for ITM tracing with a Keil ULINKpro (or ULINKplus),
* see Percepio Application Note PA-021, available at
* https://percepio.com/2018/05/04/keil-itm-support/
*
* To setup IAR Embedded Workbench for ITM tracing with an IAR I-Jet,
* see Percepio Application Note PA-023, https://percepio.com/iar
*
* NOTE: This stream port may block the application in case the ITM port
* is not ready for more data (the TPIU FIFO has become full). This is
* necessary to avoid data loss, as the TPIU FIFO is often quite small.
*
* --- Direct vs. Indirect ITM streaming ---
* Direct streaming: By default, this stream port writes directly to the ITM
* register mode without any RAM buffer. This assumes you have a fast debug
* probe, like aKeil ULINKpro or IAR I-Jet, to avoid excessive blocking.
* In case the ITM blocking appears to disturb your application, make sure your
* debugger is configured for maximum performance, as described in the above
* Application Nodes.
*
* Indirect streaming: If direct streaming gives too much overhead, you may
* instead try indirect ITM streaming. This is done by enabling the internal
* RAM buffer, like below. This reconfigures the recorder to store the events
* in the internal RAM buffer instead of writing them directly to the ITM port.
*
* Set TRC_STREAM_PORT_USE_INTERNAL_BUFFER to 1 to use the indirect mode.
*
* This increases RAM usage but eliminates peaks in the trace data rate.
* Moreover, the ITM writes are then performed in a separate task (TzCtrl).
* You find relevant settings (buffer size etc.) in trcStreamingConfig.h.
*
* See also https://percepio.com/2018/10/11/tuning-your-custom-trace-streaming
*
* --- One-way vs. Two-way Communication ---
* The ITM port only provides one-way communication, from target to host.
* This is sufficient if you start the tracing from the target application,
* using vTraceEnable(TRC_START). Just make sure to start the Tracealyzer
* recording before you start the target system.
*
* In case you prefer to interactively start and stop the tracing from the host
* computer, you need two-way communication to send commands to the recorder.
* This is possible by writing such "start" and "stop" commands to a special
* buffer, monitored by the recorder library, using the debugger IDE.
* See trcStreamingPort.c and also the example macro for Keil uVision
* (Keil-uVision-Tracealyzer-ITM-Exporter.ini).
*/
#ifndef TRC_STREAM_PORT_H
#define TRC_STREAM_PORT_H
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#include <stdint.h>
#include <trcTypes.h>
#include <trcStreamPortConfig.h>
#ifdef __cplusplus
extern "C" {
#endif
#if (!defined(TRC_CFG_STREAM_PORT_ITM_PORT) || (TRC_CFG_STREAM_PORT_ITM_PORT) < 0) || ((TRC_CFG_STREAM_PORT_ITM_PORT) > 31)
#error "Invalid ITM port defined in trcStreamPortConfig.h."
#endif
/* Important for the ITM port - no RAM buffer, direct writes. In most other ports this can be skipped (default is 1) */
#define TRC_USE_INTERNAL_BUFFER 0
typedef struct TraceStreamPortBuffer
{
uint8_t buffer[sizeof(TraceUnsignedBaseType_t)];
} TraceStreamPortBuffer_t;
traceResult prvTraceItmWrite(void* ptrData, uint32_t size, int32_t* ptrBytesWritten);
traceResult prvTraceItmRead(void* ptrData, uint32_t uiSize, int32_t* piBytesRead);
traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer);
#define xTraceStreamPortAllocate(uiSize, ppvData) ((void)uiSize, xTraceStaticBufferGet(ppvData))
#define xTraceStreamPortCommit(pvData, uiSize, piBytesCommitted) prvTraceItmWrite(pvData, uiSize, piBytesCommitted)
#define xTraceStreamPortWriteData(pvData, uiSize, piBytesWritten) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4((void)pvData, (void)uiSize, (void)piBytesWritten, TRC_SUCCESS)
#define xTraceStreamPortReadData(pvData, uiSize, piBytesRead) prvTraceItmRead(pvData, uiSize, piBytesRead)
#define xTraceStreamPortOnEnable(uiStartOption) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2((void)(uiStartOption), TRC_SUCCESS)
#define xTraceStreamPortOnDisable() TRC_COMMA_EXPR_TO_STATEMENT_EXPR_1(TRC_SUCCESS)
#define xTraceStreamPortOnTraceBegin() TRC_COMMA_EXPR_TO_STATEMENT_EXPR_1(TRC_SUCCESS)
#define xTraceStreamPortOnTraceEnd() TRC_COMMA_EXPR_TO_STATEMENT_EXPR_1(TRC_SUCCESS)
#ifdef __cplusplus
}
#endif
#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/
#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/
#endif /* TRC_STREAM_PORT_H */

View File

@ -0,0 +1,161 @@
/*
* Trace Recorder for Tracealyzer v4.6.0
* Copyright 2021 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* Supporting functions for trace streaming, used by the "stream ports"
* for reading and writing data to the interface.
* Existing ports can easily be modified to fit another setup, e.g., a
* different TCP/IP stack, or to define your own stream port.
*
* This stream port is for ITM streaming on Arm Cortex-M devices.
*
* To setup Keil uVision for ITM tracing with a Keil ULINKpro (or ULINKplus),
* see Percepio Application Note PA-021, available at
* https://percepio.com/2018/05/04/keil-itm-support/
*
* To setup IAR Embedded Workbench for ITM tracing with an IAR I-Jet,
* see Percepio Application Note PA-023, https://percepio.com/iar
*
* NOTE: This stream port may block the application in case the ITM port
* is not ready for more data (the TPIU FIFO has become full). This is
* necessary to avoid data loss, as the TPIU FIFO is often quite small.
*
* --- Direct vs. Indirect ITM streaming ---
* Direct streaming: By default, this stream port writes directly to the ITM
* register mode without any RAM buffer. This assumes you have a fast debug
* probe, like aKeil ULINKpro or IAR I-Jet, to avoid excessive blocking.
* In case the ITM blocking appears to disturb your application, make sure your
* debugger is configured for maximum performance, as described in the above
* Application Nodes.
*
* Indirect streaming: If direct streaming gives too much overhead, you may
* instead try indirect ITM streaming. This is done by enabling the internal
* RAM buffer, like below. This reconfigures the recorder to store the events
* in the internal RAM buffer instead of writing them directly to the ITM port.
*
* Set TRC_STREAM_PORT_USE_INTERNAL_BUFFER to 1 to use the indirect mode.
*
* This increases RAM usage but eliminates peaks in the trace data rate.
* Moreover, the ITM writes are then performed in a separate task (TzCtrl).
* You find relevant settings (buffer size etc.) in trcStreamingConfig.h.
*
* See also https://percepio.com/2018/10/11/tuning-your-custom-trace-streaming
*
* --- One-way vs. Two-way Communication ---
* The ITM port only provides one-way communication, from target to host.
* This is sufficient if you start the tracing from the target application,
* using vTraceEnable(TRC_START). Just make sure to start the Tracealyzer
* recording before you start the target system.
*
* In case you prefer to interactively start and stop the tracing from the host
* computer, you need two-way communication to send commands to the recorder.
* This is possible by writing such "start" and "stop" commands to a special
* buffer, monitored by the recorder library, using the debugger IDE.
* See trcStreamingPort.c and also the example macro for Keil uVision
* (Keil-uVision-Tracealyzer-ITM-Exporter.ini).
*/
#include <trcRecorder.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
typedef struct TraceStreamPortFile
{
uint8_t buffer[sizeof(TraceUnsignedBaseType_t)];
} TraceStreamPortFile_t;
static TraceStreamPortFile_t* pxStreamPortFile;
/* This will be set by the debugger when there is data to be read */
volatile int32_t tz_host_command_bytes_to_read = 0;
/* This will be filled with data from the debugger */
volatile char tz_host_command_data[32];
/* These variables are used for reading commands from the host, using read_from_host().
* This is not required if using vTraceEnable(TRC_START).
* A debugger IDE may write to these functions using a macro.
* An example for Keil is included (Keil-uVision-Tracealyzer-ITM-Exporter.ini). */
#define itm_write_32(__data) \
{\
if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk) && /* Trace enabled? */ \
(ITM->TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled? */ \
(ITM->TER & (1UL << (TRC_CFG_STREAM_PORT_ITM_PORT)))) /* ITM port enabled? */ \
{ \
while (ITM->PORT[TRC_CFG_STREAM_PORT_ITM_PORT].u32 == 0) { /* Do nothing */ } /* Block until room in ITM FIFO - This stream port is always in "blocking mode", since intended for high-speed ITM! */ \
ITM->PORT[TRC_CFG_STREAM_PORT_ITM_PORT].u32 = __data; /* Write the data */ \
} \
}
/* This is assumed to execute from within the recorder, with interrupts disabled */
traceResult prvTraceItmWrite(void* ptrData, uint32_t size, int32_t* ptrBytesWritten)
{
uint32_t* ptr32 = (uint32_t*)ptrData;
TRC_ASSERT(size % 4 == 0);
TRC_ASSERT(ptrBytesWritten != 0);
*ptrBytesWritten = 0;
while (*ptrBytesWritten < (int32_t)size)
{
itm_write_32(*ptr32);
ptr32++;
*ptrBytesWritten += 4;
}
return TRC_SUCCESS;
}
/* This reads "command" data from a RAM buffer, written by a host macro in the debugger */
traceResult prvTraceItmRead(void* ptrData, uint32_t uiSize, int32_t* piBytesRead)
{
int32_t i;
uint8_t* bytesBuffer = (uint8_t*)ptrData;
TRC_ASSERT(piBytesRead != 0);
/* Check if the debugger has updated tz_host_command_bytes_to_read */
if (tz_host_command_bytes_to_read > 0)
{
if (tz_host_command_bytes_to_read != (int32_t)uiSize)
{
/* Sanity check. */
return TRC_FAIL;
}
*piBytesRead = (int32_t)tz_host_command_bytes_to_read;
/* Read the bytes */
for (i = 0; i < tz_host_command_bytes_to_read; i++)
{
bytesBuffer[i] = tz_host_command_data[i];
}
/* Reset */
tz_host_command_bytes_to_read = 0;
}
return TRC_SUCCESS;
}
traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer)
{
TRC_ASSERT_EQUAL_SIZE(TraceStreamPortBuffer_t, TraceStreamPortFile_t);
TRC_ASSERT(pxBuffer != 0);
pxStreamPortFile = (TraceStreamPortFile_t*)pxBuffer;
return TRC_SUCCESS;
}
#endif
#endif

View File

@ -0,0 +1,18 @@
Tracealyzer Stream Port for Files
Percepio AB
www.percepio.com
-------------------------------------------------
This directory contains a "stream port" for the Tracealyzer recorder library,
i.e., the specific code needed to use a particular interface for streaming a
Tracealyzer RTOS trace. The stream port is defined by a set of macros in
trcStreamPort.h, found in the "include" directory.
This particular stream port is for streaming to a file via stdio.h (fwrite).
To use this stream port, make sure that include/trcStreamPort.h is found
by the compiler (i.e., add this folder to your project's include paths) and
add all included source files to your build. Make sure no other versions of
trcStreamPort.h are included by mistake!
See also http://percepio.com/2016/10/05/rtos-tracing.

View File

@ -0,0 +1,39 @@
/*
* Trace Recorder for Tracealyzer v4.6.0
* Copyright 2021 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The configuration for trace streaming ("stream ports").
*/
#ifndef TRC_STREAM_PORT_CONFIG_H
#define TRC_STREAM_PORT_CONFIG_H
#ifdef __cplusplus
extern "C" {
#endif
/* Default file name */
#ifndef TRC_CFG_STREAM_PORT_TRACE_FILE
#define TRC_CFG_STREAM_PORT_TRACE_FILE "trace.psf"
#endif
/* This define will determine whether to use the internal buffer or not.
If file writing creates additional trace events (i.e. it uses semaphores or mutexes),
then the internal buffer must be enabled to avoid infinite recursion. */
#define TRC_CFG_STREAM_PORT_USE_INTERNAL_BUFFER 0
/*******************************************************************************
* Configuration Macro: TRC_CFG_STREAM_PORT_BUFFER_SIZE
*
* Specifies the size of the internal buffer, if one is used.
******************************************************************************/
#define TRC_CFG_STREAM_PORT_BUFFER_SIZE 10000
#ifdef __cplusplus
}
#endif
#endif /* TRC_STREAM_PORT_CONFIG_H */

View File

@ -0,0 +1,84 @@
/*
* Trace Recorder for Tracealyzer v4.6.0
* Copyright 2021 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The interface definitions for trace streaming ("stream ports").
* This "stream port" sets up the recorder to stream the trace to file.
*/
#ifndef TRC_STREAM_PORT_H
#define TRC_STREAM_PORT_H
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#include <stdint.h>
#include <trcTypes.h>
#include <trcStreamPortConfig.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
#define TRC_USE_INTERNAL_BUFFER (TRC_CFG_STREAM_PORT_USE_INTERNAL_BUFFER)
/* Default file name */
#ifndef TRC_CFG_STREAM_PORT_TRACE_FILE
#define TRC_CFG_STREAM_PORT_TRACE_FILE "trace.psf"
#endif
typedef struct TraceStreamPortFile
{
FILE* pxFile;
#if (TRC_USE_INTERNAL_BUFFER)
uint8_t buffer[TRC_STREAM_PORT_BUFFER_SIZE];
#endif
} TraceStreamPortFile_t;
extern TraceStreamPortFile_t* pxStreamPortFile;
#define TRC_STREAM_PORT_BUFFER_SIZE (sizeof(TraceStreamPortFile_t))
typedef struct TraceStreamPortBuffer
{
uint8_t buffer[TRC_STREAM_PORT_BUFFER_SIZE];
} TraceStreamPortBuffer_t;
traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer);
#define xTraceStreamPortAllocate(uiSize, ppvData) ((void)(uiSize), xTraceStaticBufferGet(ppvData))
#if (TRC_USE_INTERNAL_BUFFER == 1)
/* Push to internal buffer. It will call on xTraceStreamPortWriteData() periodically. */
#define xTraceStreamPortCommit(pvData, uiSize, piBytesCommitted) xTraceInternalEventBufferPush(pvData, uiSize, piBytesCommitted)
#else
/* Write directly to file */
#define xTraceStreamPortCommit(pvData, uiSize, piBytesCommitted) xTraceStreamPortWriteData(pvData, uiSize, piBytesCommitted)
#endif
#define xTraceStreamPortWriteData(pvData, uiSize, piBytesWritten) (*(piBytesWritten) = fwrite(pvData, 1, uiSize, pxStreamPortFile->pxFile), TRC_SUCCESS)
#define xTraceStreamPortReadData(pvData, uiSize, piBytesRead) ((void)(pvData), (void)(uiSize), (void)(piBytesRead), TRC_SUCCESS)
#define xTraceStreamPortOnEnable(uiStartOption) ((void)(uiStartOption), TRC_SUCCESS)
#define xTraceStreamPortOnDisable() (TRC_SUCCESS)
traceResult xTraceStreamPortOnTraceBegin(void);
traceResult xTraceStreamPortOnTraceEnd(void);
#ifdef __cplusplus
}
#endif
#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/
#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/
#endif /* TRC_STREAM_PORT_H */

View File

@ -0,0 +1,82 @@
/*
* Trace Recorder for Tracealyzer v4.6.0
* Copyright 2021 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* Supporting functions for trace streaming, used by the "stream ports"
* for reading and writing data to the interface.
* Existing ports can easily be modified to fit another setup, e.g., a
* different TCP/IP stack, or to define your own stream port.
*/
#include <trcRecorder.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
TraceStreamPortFile_t* pxStreamPortFile;
traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer)
{
TRC_ASSERT_EQUAL_SIZE(TraceStreamPortBuffer_t, TraceStreamPortFile_t);
TRC_ASSERT(pxBuffer != 0);
pxStreamPortFile = (TraceStreamPortFile_t*)pxBuffer;
pxStreamPortFile->pxFile = 0;
#if (TRC_USE_INTERNAL_BUFFER == 1)
return xTraceInternalEventBufferInitialize(pxStreamPortFile->buffer, sizeof(pxStreamPortFile->buffer));
#else
return TRC_SUCCESS;
#endif
}
traceResult xTraceStreamPortOnTraceBegin(void)
{
if (pxStreamPortFile == 0)
{
return TRC_FAIL;
}
if (pxStreamPortFile->pxFile == 0)
{
errno_t err = fopen_s(&pxStreamPortFile->pxFile, TRC_CFG_STREAM_PORT_TRACE_FILE, "wb");
if (err != 0)
{
printf("Could not open trace file, error code %d.\n", err);
return TRC_FAIL;
}
else
{
printf("Trace file created.\n");
}
}
return TRC_SUCCESS;
}
traceResult xTraceStreamPortOnTraceEnd(void)
{
if (pxStreamPortFile == 0)
{
return TRC_FAIL;
}
if (pxStreamPortFile->pxFile != 0)
{
fclose(pxStreamPortFile->pxFile);
pxStreamPortFile->pxFile = 0;
printf("Trace file closed.\n");
}
return TRC_SUCCESS;
}
#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/
#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/

View File

@ -0,0 +1,21 @@
Tracealyzer Stream Port for SEGGER J-Link
Percepio AB
www.percepio.com
-----------------------------------------
This directory contains a "stream port" for the Tracealyzer recorder library,
i.e., the specific code needed to use a particular interface for streaming a
Tracealyzer RTOS trace. The stream port is defined by a set of macros in
trcStreamPort.h, found in the "include" directory.
This particular stream port targets SEGGER J-Link debug probes, using the RTT
interface provided by SEGGER.
To use this stream port, make sure that include/trcStreamPort.h is found
by the compiler (i.e., add this folder to your project's include paths) and
add all included source files to your build. Make sure no other versions of
trcStreamPort.h are included by mistake!
Note that this stream port also contains SEGGER's RTT driver.
See also http://percepio.com/2016/10/05/rtos-tracing.

View File

@ -0,0 +1,123 @@
/*
* Trace Recorder for Tracealyzer v4.6.0
* Copyright 2021 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The configuration for trace streaming ("stream ports").
*/
#ifndef TRC_STREAM_PORT_CONFIG_H
#define TRC_STREAM_PORT_CONFIG_H
#ifdef __cplusplus
extern "C" {
#endif
/* This define will determine whether to use the internal buffer or not.
If file writing creates additional trace events (i.e. it uses semaphores or mutexes),
then the internal buffer must be enabled to avoid infinite recursion. */
#define TRC_CFG_STREAM_PORT_USE_INTERNAL_BUFFER 0
/**
* @def TRC_CFG_INTERNAL_BUFFER_SIZE
*
* @brief Configures the size of the internal buffer if used.
* is enabled.
*/
#define TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_SIZE 5000
/**
* @def TRC_CFG_STREAM_PORT_RTT_UP_BUFFER_SIZE
*
* @brief Defines the size of the "up" RTT buffer (target -> host) to use for writing
* the trace data, for RTT buffer 1 or higher.
*
* This setting is ignored for RTT buffer 0, which can't be reconfigured
* in runtime and therefore hard-coded to use the defines in SEGGER_RTT_Conf.h.
*
* Default buffer size for Tracealyzer is 5000 bytes.
*
* If you have a stand-alone J-Link probe, the can be decreased to around 1 KB.
* But integrated J-Link OB interfaces are slower and needs about 5-10 KB,
* depending on the amount of data produced.
*/
#define TRC_CFG_STREAM_PORT_RTT_UP_BUFFER_SIZE 5000
/**
* @def TRC_CFG_STREAM_PORT_RTT_DOWN_BUFFER_SIZE
*
* @brief Defines the size of the "down" RTT buffer (host -> target) to use for reading
* commands from Tracealyzer, for RTT buffer 1 or higher.
*
* Default buffer size for Tracealyzer is 32 bytes.
*
* This setting is ignored for RTT buffer 0, which can't be reconfigured
* in runtime and therefore hard-coded to use the defines in SEGGER_RTT_Conf.h.
*/
#define TRC_CFG_STREAM_PORT_RTT_DOWN_BUFFER_SIZE 32
/**
* @def TRC_CFG_STREAM_PORT_RTT_UP_BUFFER_INDEX
*
* @brief Defines the RTT buffer to use for writing the trace data. Make sure that
* the PC application has the same setting (File->Settings).
*
* Default: 1
*
* We don't recommend using RTT buffer 0, since mainly intended for terminals.
* If you prefer to use buffer 0, it must be configured in SEGGER_RTT_Conf.h.
*/
#define TRC_CFG_STREAM_PORT_RTT_UP_BUFFER_INDEX 1
/**
* @def TRC_CFG_STREAM_PORT_RTT_DOWN_BUFFER_INDEX
*
* @brief Defines the RTT buffer to use for reading the trace data. Make sure that
* the PC application has the same setting (File->Settings).
*
* Default: 1
*
* We don't recommend using RTT buffer 0, since mainly intended for terminals.
* If you prefer to use buffer 0, it must be configured in SEGGER_RTT_Conf.h.
*/
#define TRC_CFG_STREAM_PORT_RTT_DOWN_BUFFER_INDEX 1
/**
* @def TRC_CFG_STREAM_PORT_RTT_MODE
*
* @brief This stream port for J-Link streaming relies on SEGGER RTT, that contains an
* internal RAM buffer read by the J-Link probes during execution.
*
* Possible values:
* - SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL
* - SEGGER_RTT_MODE_NO_BLOCK_SKIP (default)
*
* Using SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL ensure that you get a
* complete and valid trace. This may however cause blocking if your streaming
* interface isn't fast enough, which may disturb the real-time behavior.
*
* We therefore recommend SEGGER_RTT_MODE_NO_BLOCK_SKIP. In this mode,
* Tracealyzer will report lost events if the transfer is not
* fast enough. In that case, try increasing the size of the "up buffer".
*/
#define TRC_CFG_STREAM_PORT_RTT_MODE SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL
/**
* @def TRC_CFG_STREAM_PORT_RTT_NO_LOCK_WRITE
*
* @brief Sets if RTT should write without locking or not when writing
* RTT data. This should normally be disabled with an exception being
* Zephyr, where the SEGGER RTT locks aren't necessary and causes
* problems if enabled.
*
* Default: 0
*/
#define TRC_CFG_STREAM_PORT_RTT_NO_LOCK_WRITE 0
#ifdef __cplusplus
}
#endif
#endif /* TRC_STREAM_PORT_CONFIG_H */

View File

@ -0,0 +1,238 @@
/*********************************************************************
* SEGGER MICROCONTROLLER GmbH & Co. KG *
* Solutions for real time microcontroller applications *
**********************************************************************
* *
* (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG *
* *
* www.segger.com Support: support@segger.com *
* *
**********************************************************************
* *
* SEGGER RTT * Real Time Transfer for embedded targets *
* *
**********************************************************************
* *
* All rights reserved. *
* *
* * This software may in its unmodified form be freely redistributed *
* in source, linkable, or executable form. *
* * The source code may be modified, provided the source code *
* retains the above copyright notice, this list of conditions and *
* the following disclaimer. *
* * Modified versions of this software in source, executable, or *
* linkable form may not be distributed without prior consent of *
* SEGGER. *
* * This software may only be used for communication with SEGGER *
* J-Link debug probes. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
* DAMAGE. *
* *
**********************************************************************
* *
* RTT version: 6.00e *
* *
**********************************************************************
---------------------------END-OF-HEADER------------------------------
File : SEGGER_RTT.h
Purpose : Implementation of SEGGER real-time transfer which allows
real-time communication on targets which support debugger
memory accesses while the CPU is running.
Revision: $Rev: 4079 $
----------------------------------------------------------------------
*/
#ifndef SEGGER_RTT_H
#define SEGGER_RTT_H
#include "SEGGER_RTT_Conf.h"
/*********************************************************************
*
* Defines, fixed
*
**********************************************************************
*/
/*********************************************************************
*
* Types
*
**********************************************************************
*/
//
// Description for a circular buffer (also called "ring buffer")
// which is used as up-buffer (T->H)
//
typedef struct {
const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4"
char* pBuffer; // Pointer to start of buffer
unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty.
unsigned WrOff; // Position of next item to be written by either target.
volatile unsigned RdOff; // Position of next item to be read by host. Must be volatile since it may be modified by host.
unsigned Flags; // Contains configuration flags
} SEGGER_RTT_BUFFER_UP;
//
// Description for a circular buffer (also called "ring buffer")
// which is used as down-buffer (H->T)
//
typedef struct {
const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4"
char* pBuffer; // Pointer to start of buffer
unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty.
volatile unsigned WrOff; // Position of next item to be written by host. Must be volatile since it may be modified by host.
unsigned RdOff; // Position of next item to be read by target (down-buffer).
unsigned Flags; // Contains configuration flags
} SEGGER_RTT_BUFFER_DOWN;
//
// RTT control block which describes the number of buffers available
// as well as the configuration for each buffer
//
//
typedef struct {
char acID[16]; // Initialized to "SEGGER RTT"
int MaxNumUpBuffers; // Initialized to SEGGER_RTT_MAX_NUM_UP_BUFFERS (type. 2)
int MaxNumDownBuffers; // Initialized to SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (type. 2)
SEGGER_RTT_BUFFER_UP aUp[SEGGER_RTT_MAX_NUM_UP_BUFFERS]; // Up buffers, transferring information up from target via debug probe to host
SEGGER_RTT_BUFFER_DOWN aDown[SEGGER_RTT_MAX_NUM_DOWN_BUFFERS]; // Down buffers, transferring information down from host via debug probe to target
} SEGGER_RTT_CB;
/*********************************************************************
*
* Global data
*
**********************************************************************
*/
extern SEGGER_RTT_CB _SEGGER_RTT;
/*********************************************************************
*
* RTT API functions
*
**********************************************************************
*/
#ifdef __cplusplus
extern "C" {
#endif
int SEGGER_RTT_AllocDownBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags);
int SEGGER_RTT_AllocUpBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags);
int SEGGER_RTT_ConfigUpBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags);
int SEGGER_RTT_ConfigDownBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags);
int SEGGER_RTT_GetKey (void);
unsigned SEGGER_RTT_HasData (unsigned BufferIndex);
int SEGGER_RTT_HasKey (void);
void SEGGER_RTT_Init (void);
unsigned SEGGER_RTT_Read (unsigned BufferIndex, void* pBuffer, unsigned BufferSize);
unsigned SEGGER_RTT_ReadNoLock (unsigned BufferIndex, void* pData, unsigned BufferSize);
int SEGGER_RTT_SetNameDownBuffer (unsigned BufferIndex, const char* sName);
int SEGGER_RTT_SetNameUpBuffer (unsigned BufferIndex, const char* sName);
int SEGGER_RTT_SetFlagsDownBuffer (unsigned BufferIndex, unsigned Flags);
int SEGGER_RTT_SetFlagsUpBuffer (unsigned BufferIndex, unsigned Flags);
int SEGGER_RTT_WaitKey (void);
unsigned SEGGER_RTT_Write (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
unsigned SEGGER_RTT_WriteNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
unsigned SEGGER_RTT_WriteSkipNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
unsigned SEGGER_RTT_WriteString (unsigned BufferIndex, const char* s);
void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
//
// Function macro for performance optimization
//
#define SEGGER_RTT_HASDATA(n) (_SEGGER_RTT.aDown[n].WrOff - _SEGGER_RTT.aDown[n].RdOff)
/*********************************************************************
*
* RTT "Terminal" API functions
*
**********************************************************************
*/
int 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, ...);
#ifdef __cplusplus
}
#endif
/*********************************************************************
*
* Defines
*
**********************************************************************
*/
//
// Operating modes. Define behavior if buffer is full (not enough space for entire message)
//
#define SEGGER_RTT_MODE_NO_BLOCK_SKIP (0U) // Skip. Do not block, output nothing. (Default)
#define SEGGER_RTT_MODE_NO_BLOCK_TRIM (1U) // Trim: Do not block, output as much as fits.
#define SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL (2U) // Block: Wait until there is space in the buffer.
#define SEGGER_RTT_MODE_MASK (3U)
//
// Control sequences, based on ANSI.
// Can be used to control color, and clear the screen
//
#define RTT_CTRL_RESET "" // Reset to default colors
#define RTT_CTRL_CLEAR "" // Clear screen, reposition cursor to top left
#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 ""
#endif
/*************************** End of file ****************************/

View File

@ -0,0 +1,263 @@
/*********************************************************************
* SEGGER MICROCONTROLLER GmbH & Co. KG *
* Solutions for real time microcontroller applications *
**********************************************************************
* *
* (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG *
* *
* www.segger.com Support: support@segger.com *
* *
**********************************************************************
* *
* SEGGER RTT * Real Time Transfer for embedded targets *
* *
**********************************************************************
* *
* All rights reserved. *
* *
* * This software may in its unmodified form be freely redistributed *
* in source, linkable, or executable form. *
* * The source code may be modified, provided the source code *
* retains the above copyright notice, this list of conditions and *
* the following disclaimer. *
* * Modified versions of this software in source, executable, or *
* linkable form may not be distributed without prior consent of *
* SEGGER. *
* * This software may only be used for communication with SEGGER *
* J-Link debug probes. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
* DAMAGE. *
* *
**********************************************************************
* *
* RTT version: 6.00e *
* *
**********************************************************************
----------------------------------------------------------------------
File : SEGGER_RTT_Conf.h
Purpose : Implementation of SEGGER real-time transfer (RTT) which
allows real-time communication on targets which support
debugger memory accesses while the CPU is running.
Revision: $Rev: 3892 $
---------------------------END-OF-HEADER------------------------------
*/
#ifndef SEGGER_RTT_CONF_H
#define SEGGER_RTT_CONF_H
#ifdef __IAR_SYSTEMS_ICC__
#include <intrinsics.h>
#endif
/*********************************************************************
*
* Defines, configurable
*
**********************************************************************
*/
#define SEGGER_RTT_MAX_NUM_UP_BUFFERS (3) // Max. number of up-buffers (T->H) available on this target (Default: 3)
#define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (3) // Max. number of down-buffers (H->T) available on this target (Default: 3)
#define BUFFER_SIZE_UP (64) // Size of the buffer for terminal output of target, up to host (Default: 1k)
#define BUFFER_SIZE_DOWN (16) // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16)
#define SEGGER_RTT_PRINTF_BUFFER_SIZE (64u) // Size of buffer for RTT printf to bulk-send chars via RTT (Default: 64)
#define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP // Mode for pre-initialized terminal channel (buffer 0)
// This can be used to place the RTT control block in the right memory range, if no found automatically.
// This example is for NXP LPC54018, needs to be adapted for each MCU family.
//#define SEGGER_RTT_SECTION ".data.$RAM2"
//
// Target is not allowed to perform other RTT operations while string still has not been stored completely.
// Otherwise we would probably end up with a mixed string in the buffer.
// If using RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here.
//
// SEGGER_RTT_MAX_INTERRUPT_PRIORITY can be used in the sample lock routines on Cortex-M3/4.
// Make sure to mask all interrupts which can send RTT data, i.e. generate SystemView events, or cause task switches.
// When high-priority interrupts must not be masked while sending RTT data, SEGGER_RTT_MAX_INTERRUPT_PRIORITY needs to be adjusted accordingly.
// (Higher priority = lower priority number)
// Default value for embOS: 128u
// Default configuration in FreeRTOS: configMAX_SYSCALL_INTERRUPT_PRIORITY: ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
// In case of doubt mask all interrupts: 1 << (8 - BASEPRI_PRIO_BITS) i.e. 1 << 5 when 3 bits are implemented in NVIC
// or define SEGGER_RTT_LOCK() to completely disable interrupts.
//
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) // Interrupt priority to lock on SEGGER_RTT_LOCK on Cortex-M3/4 (Default: 0x20)
/*********************************************************************
*
* RTT lock configuration for SEGGER Embedded Studio,
* Rowley CrossStudio and GCC
*/
#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__)
#ifdef __ARM_ARCH_6M__
#define SEGGER_RTT_LOCK() { \
unsigned int LockState; \
__asm volatile ("mrs %0, primask \n\t" \
"mov r1, $1 \n\t" \
"msr primask, r1 \n\t" \
: "=r" (LockState) \
: \
: "r1" \
);
#define SEGGER_RTT_UNLOCK() __asm volatile ("msr primask, %0 \n\t" \
: \
: "r" (LockState) \
: \
); \
}
#elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__))
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
#endif
#define SEGGER_RTT_LOCK() { \
unsigned int LockState; \
__asm volatile ("mrs %0, basepri \n\t" \
"mov r1, %1 \n\t" \
"msr basepri, r1 \n\t" \
: "=r" (LockState) \
: "i"(SEGGER_RTT_MAX_INTERRUPT_PRIORITY) \
: "r1" \
);
#define SEGGER_RTT_UNLOCK() __asm volatile ("msr basepri, %0 \n\t" \
: \
: "r" (LockState) \
: \
); \
}
#elif defined(__ARM_ARCH_7A__)
#define SEGGER_RTT_LOCK() { \
unsigned int LockState; \
__asm volatile ("mrs r1, CPSR \n\t" \
"mov %0, r1 \n\t" \
"orr r1, r1, #0xC0 \n\t" \
"msr CPSR_c, r1 \n\t" \
: "=r" (LockState) \
: \
: "r1" \
);
#define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t" \
"mrs r1, CPSR \n\t" \
"bic r1, r1, #0xC0 \n\t" \
"and r0, r0, #0xC0 \n\t" \
"orr r1, r1, r0 \n\t" \
"msr CPSR_c, r1 \n\t" \
: \
: "r" (LockState) \
: "r0", "r1" \
); \
}
#else
#define SEGGER_RTT_LOCK()
#define SEGGER_RTT_UNLOCK()
#endif
#endif
/*********************************************************************
*
* RTT lock configuration for IAR EWARM
*/
#ifdef __ICCARM__
#if (defined (__ARM6M__) && (__CORE__ == __ARM6M__))
#define SEGGER_RTT_LOCK() { \
unsigned int LockState; \
LockState = __get_PRIMASK(); \
__set_PRIMASK(1);
#define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \
}
#elif ((defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) || (defined (__ARM7M__) && (__CORE__ == __ARM7M__)))
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
#endif
#define SEGGER_RTT_LOCK() { \
unsigned int LockState; \
LockState = __get_BASEPRI(); \
__set_BASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY);
#define SEGGER_RTT_UNLOCK() __set_BASEPRI(LockState); \
}
#endif
#endif
/*********************************************************************
*
* RTT lock configuration for IAR RX
*/
#ifdef __ICCRX__
#define SEGGER_RTT_LOCK() { \
unsigned long LockState; \
LockState = __get_interrupt_state(); \
__disable_interrupt();
#define SEGGER_RTT_UNLOCK() __set_interrupt_state(LockState); \
}
#endif
/*********************************************************************
*
* RTT lock configuration for KEIL ARM
*/
#ifdef __CC_ARM
#if (defined __TARGET_ARCH_6S_M)
#define SEGGER_RTT_LOCK() { \
unsigned int LockState; \
register unsigned char PRIMASK __asm( "primask"); \
LockState = PRIMASK; \
PRIMASK = 1u; \
__schedule_barrier();
#define SEGGER_RTT_UNLOCK() PRIMASK = LockState; \
__schedule_barrier(); \
}
#elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M))
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
#endif
#define SEGGER_RTT_LOCK() { \
unsigned int LockState; \
register unsigned char BASEPRI __asm( "basepri"); \
LockState = BASEPRI; \
BASEPRI = SEGGER_RTT_MAX_INTERRUPT_PRIORITY; \
__schedule_barrier();
#define SEGGER_RTT_UNLOCK() BASEPRI = LockState; \
__schedule_barrier(); \
}
#endif
#endif
/*********************************************************************
*
* RTT lock configuration fallback
*/
#ifndef SEGGER_RTT_LOCK
#define SEGGER_RTT_LOCK() // Lock RTT (nestable) (i.e. disable interrupts)
#endif
#ifndef SEGGER_RTT_UNLOCK
#define SEGGER_RTT_UNLOCK() // Unlock RTT (nestable) (i.e. enable previous interrupt lock state)
#endif
#endif
/*************************** End of file ****************************/

View File

@ -0,0 +1,143 @@
/*
* Trace Recorder for Tracealyzer v4.6.0
* Copyright 2021 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The interface definitions for trace streaming ("stream ports").
* This "stream port" sets up the recorder to use SEGGER RTT as streaming channel.
*
* Note that this stream port is more complex than the typical case, since
* the J-Link interface uses a separate RAM buffer in SEGGER_RTT.c, instead
* of the default buffer included in the recorder core. The other stream ports
* offer more typical examples of how to define a custom streaming interface.
*/
#ifndef TRC_STREAM_PORT_H
#define TRC_STREAM_PORT_H
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#ifdef __cplusplus
extern "C" {
#endif
#include <trcTypes.h>
#include <trcStreamPortConfig.h>
#include <SEGGER_RTT_Conf.h>
#include <SEGGER_RTT.h>
#define TRC_USE_INTERNAL_BUFFER (TRC_CFG_STREAM_PORT_USE_INTERNAL_BUFFER)
/* Aligned */
#define TRC_STREAM_PORT_INTERNAL_BUFFER_SIZE ((((TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_SIZE) + sizeof(TraceUnsignedBaseType_t) - 1) / sizeof(TraceUnsignedBaseType_t)) * sizeof(TraceUnsignedBaseType_t))
/* Aligned */
#define TRC_STREAM_PORT_RTT_UP_BUFFER_SIZE ((((TRC_CFG_STREAM_PORT_RTT_UP_BUFFER_SIZE) + sizeof(TraceUnsignedBaseType_t) - 1) / sizeof(TraceUnsignedBaseType_t)) * sizeof(TraceUnsignedBaseType_t))
/* Aligned */
#define TRC_STREAM_PORT_RTT_DOWN_BUFFER_SIZE ((((TRC_CFG_STREAM_PORT_RTT_DOWN_BUFFER_SIZE) + sizeof(TraceUnsignedBaseType_t) - 1) / sizeof(TraceUnsignedBaseType_t)) * sizeof(TraceUnsignedBaseType_t))
/**
* @brief A structure representing the trace stream port buffer.
*/
typedef struct TraceStreamPortBuffer
{
#if (TRC_USE_INTERNAL_BUFFER == 1)
uint8_t bufferInternal[TRC_STREAM_PORT_INTERNAL_BUFFER_SIZE];
#endif
uint8_t bufferUp[TRC_STREAM_PORT_RTT_UP_BUFFER_SIZE];
uint8_t bufferDown[TRC_STREAM_PORT_RTT_DOWN_BUFFER_SIZE];
} TraceStreamPortBuffer_t;
/**
* @internal Stream port initialize callback.
*
* This function is called by the recorder as part of its initialization phase.
*
* @param[in] pxBuffer Buffer
*
* @retval TRC_FAIL Initialization failed
* @retval TRC_SUCCESS Success
*/
traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer);
/**
* @brief Allocates data from the stream port.
*
* @param[in] uiSize Allocation size
* @param[out] ppvData Allocation data pointer
*
* @retval TRC_FAIL Allocate failed
* @retval TRC_SUCCESS Success
*/
#define xTraceStreamPortAllocate(uiSize, ppvData) ((void)(uiSize), xTraceStaticBufferGet(ppvData))
/**
* @brief Commits data to the stream port, depending on the implementation/configuration of the
* stream port this data might be directly written to the stream port interface, buffered, or
* something else.
*
* @param[in] pvData Data to commit
* @param[in] uiSize Data to commit size
* @param[out] piBytesCommitted Bytes committed
*
* @retval TRC_FAIL Commit failed
* @retval TRC_SUCCESS Success
*/
#if (TRC_USE_INTERNAL_BUFFER == 1)
#define xTraceStreamPortCommit xTraceInternalEventBufferPush
#else
#define xTraceStreamPortCommit xTraceStreamPortWriteData
#endif
/**
* @brief Writes data through the stream port interface.
*
* @param[in] pvData Data to write
* @param[in] uiSize Data to write size
* @param[out] piBytesWritten Bytes written
*
* @retval TRC_FAIL Write failed
* @retval TRC_SUCCESS Success
*/
#if (defined(TRC_CFG_STREAM_PORT_RTT_NO_LOCK_WRITE) && TRC_CFG_STREAM_PORT_RTT_NO_LOCK_WRITE == 1)
#define xTraceStreamPortWriteData(pvData, uiSize, piBytesWritten) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(*(piBytesWritten) = (int32_t)SEGGER_RTT_WriteNoLock((TRC_CFG_STREAM_PORT_RTT_UP_BUFFER_INDEX), (const char*)pvData, uiSize), TRC_SUCCESS)
#else
#define xTraceStreamPortWriteData(pvData, uiSize, piBytesWritten) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(*(piBytesWritten) = (int32_t)SEGGER_RTT_Write((TRC_CFG_STREAM_PORT_RTT_UP_BUFFER_INDEX), (const char*)pvData, uiSize), TRC_SUCCESS)
#endif
/**
* @brief Reads data through the stream port interface.
*
* @param[in] pvData Destination data buffer
* @param[in] uiSize Destination data buffer size
* @param[out] piBytesRead Bytes read
*
* @retval TRC_FAIL Read failed
* @retval TRC_SUCCESS Success
*/
#define xTraceStreamPortReadData(pvData, uiSize, piBytesRead) ((SEGGER_RTT_HASDATA(TRC_CFG_STREAM_PORT_RTT_DOWN_BUFFER_INDEX)) ? (*(piBytesRead) = (int32_t)SEGGER_RTT_Read((TRC_CFG_STREAM_PORT_RTT_DOWN_BUFFER_INDEX), (char*)(pvData), uiSize), TRC_SUCCESS) : TRC_SUCCESS)
traceResult xTraceStreamPortOnEnable(uint32_t uiStartOption);
#define xTraceStreamPortOnDisable() (void)(TRC_SUCCESS)
#define xTraceStreamPortOnTraceBegin() (void)(TRC_SUCCESS)
#define xTraceStreamPortOnTraceEnd() (void)(TRC_SUCCESS)
#ifdef __cplusplus
}
#endif
#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/
#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/
#endif /* TRC_STREAM_PORT_H */

View File

@ -0,0 +1,64 @@
/*
* Trace Recorder for Tracealyzer v4.6.0
* Copyright 2021 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* Supporting functions for trace streaming, used by the "stream ports"
* for reading and writing data to the interface.
*
* Note that this stream port is more complex than the typical case, since
* the J-Link interface uses a separate RAM buffer in SEGGER_RTT.c, instead
* of the default buffer included in the recorder core. The other stream ports
* offer more typical examples of how to define a custom streaming interface.
*/
#include <trcRecorder.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
typedef struct TraceStreamPortRTT {
#if (TRC_USE_INTERNAL_BUFFER == 1)
uint8_t bufferInternal[TRC_STREAM_PORT_INTERNAL_BUFFER_SIZE];
#endif
uint8_t bufferUp[TRC_STREAM_PORT_RTT_UP_BUFFER_SIZE];
uint8_t bufferDown[TRC_STREAM_PORT_RTT_DOWN_BUFFER_SIZE];
} TraceStreamPortRTT_t;
static TraceStreamPortRTT_t* pxStreamPortRTT;
traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer)
{
TRC_ASSERT_EQUAL_SIZE(TraceStreamPortBuffer_t, TraceStreamPortRTT_t);
if (pxBuffer == 0)
{
return TRC_FAIL;
}
pxStreamPortRTT = (TraceStreamPortRTT_t*)pxBuffer;
#if (TRC_USE_INTERNAL_BUFFER == 1)
return xTraceInternalEventBufferInitialize(pxStreamPortRTT->bufferInternal, sizeof(pxStreamPortRTT->bufferInternal));
#else
return TRC_SUCCESS;
#endif
}
traceResult xTraceStreamPortOnEnable(uint32_t uiStartOption)
{
(void)uiStartOption;
/* Configure the RTT buffers */
SEGGER_RTT_ConfigUpBuffer(TRC_CFG_STREAM_PORT_RTT_UP_BUFFER_INDEX, "TzData", pxStreamPortRTT->bufferUp, sizeof(pxStreamPortRTT->bufferUp), TRC_CFG_STREAM_PORT_RTT_MODE);
SEGGER_RTT_ConfigDownBuffer(TRC_CFG_STREAM_PORT_RTT_DOWN_BUFFER_INDEX, "TzCtrl", pxStreamPortRTT->bufferDown, sizeof(pxStreamPortRTT->bufferDown), TRC_CFG_STREAM_PORT_RTT_MODE);
return TRC_SUCCESS;
}
#endif
#endif

View File

@ -0,0 +1,19 @@
Tracealyzer Stream Port for Ring Buffer
-------------------------------------------------
This directory contains a "stream port" for the Tracealyzer recorder library,
i.e., the specific code needed to use a particular interface for streaming a
Tracealyzer RTOS trace. The stream port is defined by a set of macros in
trcStreamPort.h, found in the "include" directory.
This particular stream port is for streaming to a ring buffer.
To use this stream port, make sure that include/trcStreamPort.h is found
by the compiler (i.e., add this folder to your project's include paths) and
add all included source files to your build. Make sure no other versions of
trcStreamPort.h are included by mistake!
See also http://percepio.com/2016/10/05/rtos-tracing.
Percepio AB
www.percepio.com

View File

@ -0,0 +1,60 @@
/*
* Trace Recorder for Tracealyzer v4.6.0
* Copyright 2021 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The configuration for trace streaming ("stream ports").
*/
#ifndef TRC_STREAM_PORT_CONFIG_H
#define TRC_STREAM_PORT_CONFIG_H
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#include <trcTypes.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Type flags */
#define TRC_STREAM_PORT_RINGBUFFER_MODE_STOP_WHEN_FULL (0U)
#define TRC_STREAM_PORT_RINGBUFFER_MODE_OVERWRITE_WHEN_FULL (1U)
/**
* @def TRC_CFG_STREAM_PORT_BUFFER_SIZE
*
* @brief Defines the size of the ring buffer use for storing trace events.
*/
#define TRC_CFG_STREAM_PORT_BUFFER_SIZE 10000
/**
* @def TRC_CFG_STREAM_PORT_BUFFER_MODE
*
* @brief Configures the behavior of the ring buffer when full.
*
* With TRC_CFG_STREAM_PORT_MODE set to TRC_STREAM_PORT_RINGBUFFER_MODE_OVERWRITE_WHEN_FULL, the
* events are stored in a ring buffer, i.e., where the oldest events are
* overwritten when the buffer becomes full. This allows you to get the last
* events leading up to an interesting state, e.g., an error, without having
* to store the whole run since startup.
*
* When TRC_CFG_STREAM_PORT_MODE is TRC_STREAM_PORT_RINGBUFFER_MODE_STOP_WHEN_FULL, the
* recording is stopped when the buffer becomes full. This is useful for
* recording events following a specific state, e.g., the startup sequence.
*/
#define TRC_CFG_STREAM_PORT_RINGBUFFER_MODE TRC_STREAM_PORT_RINGBUFFER_MODE_OVERWRITE_WHEN_FULL
#ifdef __cplusplus
}
#endif
#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/
#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/
#endif /* TRC_STREAM_PORT_CONFIG_H */

View File

@ -0,0 +1,201 @@
/*
* Trace Recorder for Tracealyzer v4.6.0
* Copyright 2021 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The interface definitions for trace streaming ("stream ports").
* This "stream port" sets up the recorder to stream to a Ring Buffer.
*/
#ifndef TRC_STREAM_PORT_H
#define TRC_STREAM_PORT_H
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#include <trcTypes.h>
#include <trcStreamPortConfig.h>
#include <trcRecorder.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @def TRC_EXTERNAL_BUFFERS
*
* @brief This Stream Port houses the EntryTable and Timestamp buffers
*/
#define TRC_EXTERNAL_BUFFERS 1
/**
* @def TRC_SEND_NAME_ONLY_ON_DELETE
*
* @brief This Stream Port requires additional information to be sent when objects are deleted
*/
#define TRC_SEND_NAME_ONLY_ON_DELETE 1
/**
* @def TRC_USE_INTERNAL_BUFFER
*
* @brief This Stream Port uses the Multi Core Buffer directly.
*/
#define TRC_USE_INTERNAL_BUFFER 0
#define TRC_STREAM_PORT_BUFFER_SIZE ((((TRC_CFG_STREAM_PORT_BUFFER_SIZE) + sizeof(uint32_t) - 1) / sizeof(uint32_t)) * sizeof(uint32_t))
/**
* @brief
*/
typedef struct TraceMultiCoreBuffer
{
uint32_t uiSize;
uint8_t uiBuffer[TRC_STREAM_PORT_BUFFER_SIZE];
} TraceMultiCoreBuffer_t;
/**
* @brief
*/
typedef struct TraceRingBuffer
{
volatile uint8_t START_MARKERS[12];
TraceHeaderBuffer_t xHeaderBuffer;
TraceTimestampBuffer_t xTimestampInfo;
TraceEntryTableBuffer_t xEntryTableBuffer;
TraceMultiCoreBuffer_t xEventBuffer;
volatile uint8_t END_MARKERS[12];
} TraceRingBuffer_t;
/**
* @brief
*/
typedef struct TraceStreamPortData
{
TraceMultiCoreEventBuffer_t xMultiCoreEventBuffer;
TraceRingBuffer_t xRingBuffer;
} TraceStreamPortData_t;
extern TraceStreamPortData_t* pxStreamPortData;
/**
* @def TRC_STREAM_PORT_BUFFER_SIZE
* @brief The buffer size, aligned to base type.
*/
#define TRC_STREAM_PORT_DATA_BUFFER_SIZE (sizeof(TraceStreamPortData_t))
/**
* @brief A structure representing the trace stream port buffer.
*/
typedef struct TraceStreamPortBuffer
{
uint8_t buffer[(TRC_STREAM_PORT_DATA_BUFFER_SIZE)];
} TraceStreamPortBuffer_t;
/**
* @internal Stream port initialize callback.
*
* This function is called by the recorder as part of its initialization phase.
*
* @param[in] pxBuffer Buffer
*
* @retval TRC_FAIL Initialization failed
* @retval TRC_SUCCESS Success
*/
traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer);
/**
* @brief Allocates data from the stream port.
*
* @param[in] uiSize Allocation size
* @param[out] ppvData Allocation data pointer
*
* @retval TRC_FAIL Allocate failed
* @retval TRC_SUCCESS Success
*/
#define xTraceStreamPortAllocate(uiSize, ppvData) ((void)uiSize, xTraceStaticBufferGet(ppvData))
/**
* @brief Commits data to the stream port, depending on the implementation/configuration of the
* stream port this data might be directly written to the stream port interface, buffered, or
* something else.
*
* @param[in] pvData Data to commit
* @param[in] uiSize Data to commit size
* @param[out] piBytesCommitted Bytes commited
*
* @retval TRC_FAIL Commit failed
* @retval TRC_SUCCESS Success
*/
traceResult xTraceStreamPortCommit(void* pvData, uint32_t uiSize, int32_t* piBytesCommitted);
/**
* @brief Writes data through the stream port interface.
*
* @param[in] pvData Data to write
* @param[in] uiSize Data to write size
* @param[out] piBytesWritten Bytes written
*
* @retval TRC_FAIL Write failed
* @retval TRC_SUCCESS Success
*/
#define xTraceStreamPortWriteData(pvData, uiSize, piBytesWritten) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4((void)pvData, (void)uiSize, (void)piBytesWritten, TRC_SUCCESS)
/**
* @brief Reads data through the stream port interface.
*
* @param[in] pvData Destination data buffer
* @param[in] uiSize Destination data buffer size
* @param[out] piBytesRead Bytes read
*
* @retval TRC_FAIL Read failed
* @retval TRC_SUCCESS Success
*/
#define xTraceStreamPortReadData(pvData, uiSize, piBytesRead) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4((void)pvData, (void)uiSize, (void)piBytesRead, TRC_SUCCESS)
/**
* @brief Callback for when recorder is enabled
*
* @param[in] uiStartOption Start option used when enabling trace recorder
*
* @retval TRC_FAIL Read failed
* @retval TRC_SUCCESS Success
*/
#define xTraceStreamPortOnEnable(uiStartOption) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2((void)(uiStartOption), TRC_SUCCESS)
/**
* @brief Callback for when recorder is disabled
*
* @retval TRC_FAIL Read failed
* @retval TRC_SUCCESS Success
*/
#define xTraceStreamPortOnDisable() TRC_COMMA_EXPR_TO_STATEMENT_EXPR_1(TRC_SUCCESS)
/**
* @brief Callback for when tracing begins
*
* @retval TRC_FAIL Read failed
* @retval TRC_SUCCESS Success
*/
traceResult xTraceStreamPortOnTraceBegin();
/**
* @brief Callback for when tracing ends
*
* @retval TRC_FAIL Read failed
* @retval TRC_SUCCESS Success
*/
#define xTraceStreamPortOnTraceEnd() TRC_COMMA_EXPR_TO_STATEMENT_EXPR_1(TRC_SUCCESS)
#ifdef __cplusplus
}
#endif
#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/
#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/
#endif /* TRC_STREAM_PORT_H */

View File

@ -0,0 +1,130 @@
/*
* Trace Recorder for Tracealyzer v4.6.0
* Copyright 2021 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* Supporting functions for trace streaming, used by the "stream ports"
* for reading and writing data to the interface.
* This "stream port" sets up the recorder to stream to a Ring Buffer.
*/
#include <trcRecorder.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
/* Backwards compatibility with plugins */
typedef TraceRingBuffer_t RecorderData;
RecorderData* RecorderDataPtr = 0;
TraceStreamPortData_t* pxStreamPortData;
traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer)
{
TraceRingBuffer_t* pxRingBuffer;
TRC_ASSERT_EQUAL_SIZE(TraceStreamPortBuffer_t, TraceStreamPortData_t);
if (pxBuffer == 0)
{
return TRC_FAIL;
}
pxStreamPortData = (TraceStreamPortData_t*)pxBuffer;
RecorderDataPtr = pxRingBuffer = &pxStreamPortData->xRingBuffer;
pxRingBuffer->xEventBuffer.uiSize = sizeof(pxRingBuffer->xEventBuffer.uiBuffer);
#if (TRC_CFG_STREAM_PORT_RINGBUFFER_MODE == TRC_STREAM_PORT_RINGBUFFER_MODE_OVERWRITE_WHEN_FULL)
if (xTraceMultiCoreEventBufferInitialize(&pxStreamPortData->xMultiCoreEventBuffer, TRC_EVENT_BUFFER_OPTION_OVERWRITE, pxRingBuffer->xEventBuffer.uiBuffer, sizeof(pxRingBuffer->xEventBuffer.uiBuffer)) == TRC_FAIL)
{
return TRC_FAIL;
}
#else
if (xTraceMultiCoreEventBufferInitialize(&pxStreamPortData->xMultiCoreEventBuffer, TRC_EVENT_BUFFER_OPTION_SKIP, pxRingBuffer->xEventBuffer.uiBuffer, sizeof(pxRingBuffer->xEventBuffer.uiBuffer)) == TRC_FAIL)
{
return TRC_FAIL;
}
#endif
if (xTraceHeaderInitialize(&pxRingBuffer->xHeaderBuffer) == TRC_FAIL)
{
return TRC_FAIL;
}
if (xTraceEntryTableInitialize(&pxRingBuffer->xEntryTableBuffer) == TRC_FAIL)
{
return TRC_FAIL;
}
if (xTraceTimestampInitialize(&pxRingBuffer->xTimestampInfo) == TRC_FAIL)
{
return TRC_FAIL;
}
pxRingBuffer->END_MARKERS[0] = 0x0A;
pxRingBuffer->END_MARKERS[1] = 0x0B;
pxRingBuffer->END_MARKERS[2] = 0x0C;
pxRingBuffer->END_MARKERS[3] = 0x0D;
pxRingBuffer->END_MARKERS[4] = 0x71;
pxRingBuffer->END_MARKERS[5] = 0x72;
pxRingBuffer->END_MARKERS[6] = 0x73;
pxRingBuffer->END_MARKERS[7] = 0x74;
pxRingBuffer->END_MARKERS[8] = 0xF1;
pxRingBuffer->END_MARKERS[9] = 0xF2;
pxRingBuffer->END_MARKERS[10] = 0xF3;
pxRingBuffer->END_MARKERS[11] = 0xF4;
pxRingBuffer->START_MARKERS[0] = 0x05;
pxRingBuffer->START_MARKERS[1] = 0x06;
pxRingBuffer->START_MARKERS[2] = 0x07;
pxRingBuffer->START_MARKERS[3] = 0x08;
pxRingBuffer->START_MARKERS[4] = 0x75;
pxRingBuffer->START_MARKERS[5] = 0x76;
pxRingBuffer->START_MARKERS[6] = 0x77;
pxRingBuffer->START_MARKERS[7] = 0x78;
pxRingBuffer->START_MARKERS[8] = 0xF5;
pxRingBuffer->START_MARKERS[9] = 0xF6;
pxRingBuffer->START_MARKERS[10] = 0xF7;
pxRingBuffer->START_MARKERS[11] = 0xF8;
return TRC_SUCCESS;
}
traceResult xTraceStreamPortCommit(void* pvData, uint32_t uiSize, int32_t* piBytesCommitted)
{
if (pvData == 0)
{
return TRC_FAIL;
}
xTraceMultiCoreEventBufferPush(&pxStreamPortData->xMultiCoreEventBuffer, pvData, uiSize, piBytesCommitted);
#if (TRC_CFG_STREAM_PORT_RINGBUFFER_MODE == TRC_STREAM_PORT_RINGBUFFER_MODE_STOP_WHEN_FULL)
/* If no bytes was written it means that the buffer is full and we should stop
* tracing.
*/
if (uiSize > 0 && *piBytesCommitted == 0) {
xTraceDisable();
return TRC_FAIL;
}
#endif
return TRC_SUCCESS;
}
traceResult xTraceStreamPortOnTraceBegin()
{
return xTraceMultiCoreEventBufferClear(&pxStreamPortData->xMultiCoreEventBuffer);
}
#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/
#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/

View File

@ -0,0 +1,93 @@
Tracealyzer Stream Port for STM32 USB CDC (Virtual COM Port)
Percepio AB
https://percepio.com
------------------------------------------------------------
This directory contains a "stream port" for the Tracealyzer recorder library,
allowing for streaming the trace data over a USB connection. The stream port is defined by a set of macros in
trcStreamPort.h, found in the "include" directory, that relies on functions in trcStreamingPort.c.
This particular stream port targets STM32 devices using USB CDC (virtual COM port).
It was been tested with STM32F767 and STM32L475.
--- Prerequisites ---
- An STM32 device with a USB connector for application use.
- Tracealyzer 4 with a license for FreeRTOS, SafeRTOS or Micrium µC/OS-III.
- STM32CubeIDE or the stand-alone STM32CubeMX configuration tool.
--- Instructions ---
1. Follow the general instructions (Section 1) at https://percepio.com/gettingstarted-freertos/
and verify that Snapshot mode works. The basic integration of the recorder library is the same.
2. Open the Device Configuration Tool (STM32CubeMX), e.g. by double-clicking on the .ioc file in your STM32CubeIDE project.
2.1. Under "Middleware", enable "USB_DEVICE" and...
- In "USB_DEVICE Mode and Configuration", set the "Class for FS IP" to "Communication Device Class (Virtual Com Port)".
- Under Configuration -> Parameter Settings, set the TX and RX buffer sizes to a small value (e.g. 1).
The default TX and RX buffers are not used by the trace recorder library, so this avoids wasting RAM.
2.2. Under "Connectivity", open "USB_OTG_FS" and...
- In "USB_OTG_FS Mode and Configuration", make sure "Mode" is set to "Device_Only"
- Under "Configuration", open "NVIC Settings" and make sure "USB OTG FS global interrupt" is enabled.
3. Open trcConfig.h and set TRC_CFG_RECORDER_MODE to TRC_RECORDER_MODE_STREAMING.
4. Copy trcStreamingPort.c and include/trcStreamPort.h into your project.
5. Make sure you have "vTraceEnable(TRC_INIT);" in main.c (not TRC_START or so).
This should be placed after the HW setup but before making any RTOS calls.
6. Plug in a USB cable to the connector labeled "USB OTG" or similar (i.e. for application use).
7. Build the project and start it. Check that your computer finds a new USB device (there should be a notification).
8. Check the number of the new COM port, that should have appeared. This is NOT "STLink Virtual COM port".
9. Start Tracealyzer and open Recording Settings and select Target Connection: SerialPort.
You can also access these settings via File -> Settings -> PSF Streaming Settings.
10. Enter the number of the COM port in the "Device" field. The settings (data
bits, data rate etc.) are irrelevant for USB serial connections and not used.
11. While the target is running, select Record Streaming Trace in Tracealyzer.
You should now see a live display of the trace, while it is being received.
Make sure there are no warnings about "Dropped Events" (in that case, see Troubleshooting, below).
Note that you can still debug and use breakpoints while streaming the trace.
--- Further reading ---
- http://percepio.com/2017/02/03/usb-trace-streaming-st-nucleo-f767zi-board
- http://percepio.com/2016/10/05/rtos-tracing
- https://percepio.com/2018/10/11/tuning-your-custom-trace-streaming/
--- Troubleshooting ---
A. If you get an error about "multiple definition of SysTick_Handler", open
FreeRTOSConfig.h (found in Core/Inc) and add this line in the bottom,
after the definition of xPortSysTickHandler.
#undef xPortSysTickHandler
B. If you get "Missed Events" in the Live Stream window, it is typically because
your application produces more trace data than can be transferred, so the trace
buffer overflows.
You may try the following to start with:
- Increase TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT and/or TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE in trcStreamingConfig.h
- Decrease TRC_CFG_CTRL_TASK_DELAY in trcConfig.h
- Increase TRC_CFG_CTRL_TASK_PRIORITY in trcConfig.h
Also see the "tuning" guide at https://percepio.com/2018/10/11/tuning-your-custom-trace-streaming/
Also note that this USB stream port has a diagnostics option that might come handy.
Enable USB_PERF_DIAGNOSTICS in trcStreamPort.h. This will save additional "user events"
each time a buffer page is transmitted, showing the number of bytes sent and the
remaining capacity in the trace buffer (if this goes down to zero, data is lost).
#define USB_PERF_DIAGNOSTICS 1
If you need assistence, feel free to contact support@percepio.com.

View File

@ -0,0 +1,39 @@
/*
* Trace Recorder for Tracealyzer v4.6.0
* Copyright 2021 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The configuration for trace streaming ("stream ports").
*/
#ifndef TRC_STREAM_PORT_CONFIG_H
#define TRC_STREAM_PORT_CONFIG_H
#ifdef __cplusplus
extern "C" {
#endif
/* The time to wait if the USB interface is busy. */
#define TRC_CFG_STREAM_PORT_DELAY_ON_BUSY 3
/*******************************************************************************
* Configuration Macro: TRC_CFG_STREAM_PORT_USB_BUFFER_SIZE
*
* Specifies the size of the usb buffer.
******************************************************************************/
#define TRC_CFG_STREAM_PORT_USB_BUFFER_SIZE 64
/*******************************************************************************
* Configuration Macro: TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_SIZE
*
* Specifies the size of the internal buffer.
******************************************************************************/
#define TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_SIZE 10000
#ifdef __cplusplus
}
#endif
#endif /* TRC_STREAM_PORT_CONFIG_H */

View File

@ -0,0 +1,110 @@
/*
* Trace Recorder for Tracealyzer v4.6.0
* Copyright 2021 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The interface definitions for trace streaming ("stream ports").
* This "stream port" sets up the recorder to use USB CDC as streaming channel.
* The example is for STM32 using STM32Cube.
*/
#ifndef TRC_STREAM_PORT_H
#define TRC_STREAM_PORT_H
#include <trcTypes.h>
#include <trcStreamPortConfig.h>
#ifdef __cplusplus
extern "C" {
#endif
#define TRC_USE_INTERNAL_BUFFER 1
#define TRC_STREAM_PORT_USB_BUFFER_SIZE ((((TRC_CFG_STREAM_PORT_USB_BUFFER_SIZE) + sizeof(TraceUnsignedBaseType_t) - 1) / sizeof(TraceUnsignedBaseType_t)) * sizeof(TraceUnsignedBaseType_t))
#define TRC_STREAM_PORT_INTERNAL_BUFFER_SIZE ((((TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_SIZE) + sizeof(TraceUnsignedBaseType_t) - 1) / sizeof(TraceUnsignedBaseType_t)) * sizeof(TraceUnsignedBaseType_t))
typedef struct TraceStreamPortBuffer
{
uint8_t buffer[(TRC_STREAM_PORT_USB_BUFFER_SIZE) + (TRC_STREAM_PORT_INTERNAL_BUFFER_SIZE) + sizeof(TraceUnsignedBaseType_t)];
} TraceStreamPortBuffer_t;
traceResult prvTraceCDCReceive(void* data, uint32_t uiSize, int32_t* piBytesReceived);
traceResult prvTraceCDCTransmit(void* pvData, uint32_t uiSize, int32_t* piBytesSent);
/**
* @internal Stream port initialize callback.
*
* This function is called by the recorder as part of its initialization phase.
*
* @param[in] pxBuffer Buffer
*
* @retval TRC_FAIL Initialization failed
* @retval TRC_SUCCESS Success
*/
traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer);
/**
* @brief Allocates data from the stream port.
*
* @param[in] uiSize Allocation size
* @param[out] ppvData Allocation data pointer
*
* @retval TRC_FAIL Allocate failed
* @retval TRC_SUCCESS Success
*/
#define xTraceStreamPortAllocate(uiSize, ppvData) ((void)uiSize, xTraceStaticBufferGet(ppvData))
/**
* @brief Commits data to the stream port, depending on the implementation/configuration of the
* stream port this data might be directly written to the stream port interface, buffered, or
* something else.
*
* @param[in] pvData Data to commit
* @param[in] uiSize Data to commit size
* @param[out] piBytesCommitted Bytes committed
*
* @retval TRC_FAIL Commit failed
* @retval TRC_SUCCESS Success
*/
#define xTraceStreamPortCommit xTraceInternalEventBufferPush
/**
* @brief Writes data through the stream port interface.
*
* @param[in] pvData Data to write
* @param[in] uiSize Data to write size
* @param[out] piBytesWritten Bytes written
*
* @retval TRC_FAIL Write failed
* @retval TRC_SUCCESS Success
*/
#define xTraceStreamPortWriteData prvTraceCDCTransmit
/**
* @brief Reads data through the stream port interface.
*
* @param[in] pvData Destination data buffer
* @param[in] uiSize Destination data buffer size
* @param[out] piBytesRead Bytes read
*
* @retval TRC_FAIL Read failed
* @retval TRC_SUCCESS Success
*/
#define xTraceStreamPortReadData prvTraceCDCReceive
#define xTraceStreamPortOnEnable(uiStartOption) ((void)(uiStartOption), TRC_SUCCESS)
#define xTraceStreamPortOnDisable() (TRC_SUCCESS)
#define xTraceStreamPortOnTraceBegin() (TRC_SUCCESS)
#define xTraceStreamPortOnTraceEnd() (TRC_SUCCESS)
#ifdef __cplusplus
}
#endif
#endif /* TRC_STREAM_PORT_H */

View File

@ -0,0 +1,151 @@
/*
* Trace Recorder for Tracealyzer v4.6.0
* Copyright 2021 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* Supporting functions for trace streaming ("stream ports").
* This "stream port" sets up the recorder to use USB CDC as streaming channel.
* The example is for STM32 using STM32Cube.
*/
#include <trcRecorder.h>
#include <usb_device.h>
#include <usbd_CDC_if.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
static void prvCDCInit(void);
static int8_t CDC_Receive_FS_modified(uint8_t* pbuf, uint32_t *puiLength);
extern USBD_CDC_ItfTypeDef USBD_Interface_fops_FS;
static int8_t(*CDC_Receive_FS)(uint8_t* Buf, uint32_t* Len);
typedef struct TraceStreamPortUSBCommandBuffer {
TraceUnsignedBaseType_t idx;
uint8_t bufferUSB[TRC_STREAM_PORT_USB_BUFFER_SIZE];
uint8_t bufferInternal[TRC_STREAM_PORT_INTERNAL_BUFFER_SIZE];
} TraceStreamPortUSBBuffers_t;
TraceStreamPortUSBBuffers_t* pxUSBBuffers;
static int8_t CDC_Receive_FS_modified(uint8_t* pBuffer, uint32_t *puiLength)
{
for(uint32_t i = 0; i < *puiLength; i++)
{
pxUSBBuffers->bufferUSB[pxUSBBuffers->idx] = pBuffer[i];
pxUSBBuffers->idx++;
}
CDC_Receive_FS(pBuffer, puiLength);
return (USBD_OK);
}
static void prvCDCInit(void)
{
/* Store the original "Receive" function, from the static initialization */
CDC_Receive_FS = USBD_Interface_fops_FS.Receive;
/* Update the function pointer with our modified variant */
USBD_Interface_fops_FS.Receive = CDC_Receive_FS_modified;
pxUSBBuffers->idx = 0;
MX_USB_DEVICE_Init();
}
/* The READ function, used in trcStreamPort.h */
traceResult prvTraceCDCReceive(void *data, uint32_t uiSize, int32_t* piBytesReceived)
{
uint32_t i, uiDiff;
if(pxUSBBuffers->idx > 0)
{
if ((TraceUnsignedBaseType_t)uiSize >= pxUSBBuffers->idx) // More than what is stored, number of bytes will be .idx
{
TRC_MEMCPY(data, pxUSBBuffers->bufferUSB, pxUSBBuffers->idx);
*piBytesReceived = (int32_t)pxUSBBuffers->idx;
pxUSBBuffers->idx = 0; // Make the buffer ready for a new command
}
else // If some data in the buffer is not read
{
uiDiff = pxUSBBuffers->idx - uiSize;
TRC_MEMCPY(data, pxUSBBuffers->bufferUSB, uiSize);
for(i = 0; i < uiDiff; i++)
{
pxUSBBuffers->bufferUSB[i] = pxUSBBuffers->bufferUSB[i + uiSize];
}
*piBytesReceived = uiSize;
pxUSBBuffers->idx = uiDiff;
}
}
else
{
*piBytesReceived = 0;
}
return TRC_SUCCESS;
}
/* The WRITE function, used in trcStreamPort.h */
traceResult prvTraceCDCTransmit(void* pvData, uint32_t uiSize, int32_t * piBytesSent )
{
static int fail_counter = 0;
int32_t result;
*piBytesSent = 0;
result = CDC_Transmit_FS(pvData, uiSize);
if (result == USBD_OK)
{
fail_counter = 0;
*piBytesSent = uiSize;
return TRC_SUCCESS;
}
else
{
fail_counter++;
/* We keep trying to send more pvData. If busy, we delay for a while. This function will be called again afterwards. */
xTraceKernelPortDelay(TRC_CFG_STREAM_PORT_DELAY_ON_BUSY);
if (fail_counter >= 100)
{
/* If many unsuccessful attempts in a row, something is very wrong. Returning -1 will stop the recorder. */
return TRC_FAIL;
}
}
return TRC_SUCCESS;
}
traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer)
{
TRC_ASSERT_EQUAL_SIZE(TraceStreamPortBuffer_t, TraceStreamPortUSBBuffers_t);
if (pxBuffer == 0)
{
return TRC_FAIL;
}
pxUSBBuffers = (TraceStreamPortUSBBuffers_t*)pxBuffer;
prvCDCInit();
return xTraceInternalEventBufferInitialize(pxUSBBuffers->bufferInternal, sizeof(pxUSBBuffers->bufferInternal));
}
#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/
#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/

View File

@ -0,0 +1,49 @@
Tracealyzer Stream Port for TCP/IP (lwIP example)
Percepio AB
www.percepio.com
-------------------------------------------------
This directory contains a "stream port" for the Tracealyzer recorder library,
i.e., the specific code needed to use a particular interface for streaming a
Tracealyzer RTOS trace. The stream port is defined by a set of macros in
trcStreamPort.h, found in the "include" directory.
This particular stream port targets TCP/IP. This example assumes lwIP but is
easy to modify for other TCP/IP stacks.
Instructions:
1. Integrate the trace recorder and configure it for streaming, as described
in the Tracealyzer User Manual. For FreeRTOS this is found at:
https://percepio.com/docs/FreeRTOS/manual/index.html#Creating_and_Loading_Traces___Introduction
2. Make sure all .c and .h files from this stream port folder is included in
your build, and that no other variant of trcStreamPort.h is included.
3. In lwipopts.h, make sure you have this line:
#define LWIP_SOCKET 1
4. Make sure that vTraceEnable(TRC_INIT) is called during the startup, before
any RTOS calls are made.
5. In Tracealyzer, open File -> Settings -> PSF Streaming Settings and
select Target Connection: TCP. Enter the IP address of the target system
and the port number (by default 12000).
6. Start your target system, wait a few seconds to ensure that the lwIP is operational,
then select Start Recording in Tracealyzer.
Troubleshooting:
- If the tracing suddenly stops, check the "errno" value in trcSocketSend (trcStreamingPort.c).
You can see the error code definitions in lwip/errno.h. If errno is ENOMEM, may you need to
increase MEM_SIZE in lwipopts.h.
- Since lwIP performs a lot of semaphore and mutex operations, we recommend filtering out
such events from the trace, at least those caused by the transmission of trace data in the
TzCtrl task. This can be done using vTraceSetFilterGroup() and vTraceSetFilterMask().
Note that lwIP is not included in the stream port, but assumed to exist in the project already.
See also http://percepio.com/2016/10/05/rtos-tracing.

View File

@ -0,0 +1,41 @@
/*
* Trace Recorder for Tracealyzer v4.6.0
* Copyright 2021 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The configuration for trace streaming ("stream ports").
*/
#ifndef TRC_STREAM_PORT_CONFIG_H
#define TRC_STREAM_PORT_CONFIG_H
#ifdef __cplusplus
extern "C" {
#endif
/* This define will determine whether to use the internal buffer or not.
If file writing creates additional trace events (i.e. it uses semaphores or mutexes),
then the internal buffer must be enabled to avoid infinite recursion. */
#define TRC_CFG_STREAM_PORT_USE_INTERNAL_BUFFER 0
/*******************************************************************************
* Configuration Macro: TRC_CFG_STREAM_PORT_TCPIP_PORT
*
* Specifies the TCP/IP port.
******************************************************************************/
#define TRC_CFG_STREAM_PORT_TCPIP_PORT 8888
/*******************************************************************************
* Configuration Macro: TRC_CFG_STREAM_PORT_BUFFER_SIZE
*
* Specifies the size of the internal buffer, if one is used.
******************************************************************************/
#define TRC_CFG_STREAM_PORT_BUFFER_SIZE 10000
#ifdef __cplusplus
}
#endif
#endif /* TRC_STREAM_PORT_CONFIG_H */

View File

@ -0,0 +1,75 @@
/*
* Trace Recorder for Tracealyzer v4.6.0
* Copyright 2021 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The interface definitions for trace streaming ("stream ports").
* This "stream port" sets up the recorder to use TCP/IP as streaming channel.
* The example is for lwIP.
*/
#ifndef TRC_STREAM_PORT_H
#define TRC_STREAM_PORT_H
#include <stdint.h>
#include <trcTypes.h>
#include <trcStreamPortConfig.h>
#ifdef __cplusplus
extern "C" {
#endif
#define TRC_USE_INTERNAL_BUFFER (TRC_CFG_STREAM_PORT_USE_INTERNAL_BUFFER)
/**
* @def TRC_STREAM_PORT_BUFFER_SIZE
*
* @brief The buffer size, aligned to base type.
*/
#define TRC_STREAM_PORT_BUFFER_SIZE ((((TRC_CFG_STREAM_PORT_BUFFER_SIZE) + sizeof(TraceUnsignedBaseType_t) - 1) / sizeof(TraceUnsignedBaseType_t)) * sizeof(TraceUnsignedBaseType_t))
typedef struct TraceStreamPortBuffer
{
#if (TRC_USE_INTERNAL_BUFFER)
uint8_t buffer[(TRC_STREAM_PORT_BUFFER_SIZE)];
#else
TraceUnsignedBaseType_t buffer[1];
#endif
} TraceStreamPortBuffer_t;
int32_t prvTraceTcpWrite(void* pvData, uint32_t uiSize, int32_t* piBytesWritten);
int32_t prvTraceTcpRead(void* pvData, uint32_t uiSize, int32_t* piBytesRead);
traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer);
#define xTraceStreamPortAllocate(uiSize, ppvData) ((void)(uiSize), xTraceStaticBufferGet(ppvData))
#if (TRC_USE_INTERNAL_BUFFER == 1)
/* Push to internal buffer. It will call on xTraceStreamPortWriteData() periodically. */
#define xTraceStreamPortCommit xTraceInternalEventBufferPush
#else
/* Write directly */
#define xTraceStreamPortCommit xTraceStreamPortWriteData
#endif
#define xTraceStreamPortWriteData(pvData, uiSize, piBytesWritten) (prvTraceTcpWrite(pvData, uiSize, piBytesWritten) == 0 ? TRC_SUCCESS : TRC_FAIL)
#define xTraceStreamPortReadData(pvData, uiSize, piBytesRead) (prvTraceTcpRead(pvData, uiSize, piBytesRead) == 0 ? TRC_SUCCESS : TRC_FAIL)
#define xTraceStreamPortOnEnable(uiStartOption) ((void)(uiStartOption), TRC_SUCCESS)
#define xTraceStreamPortOnDisable() (TRC_SUCCESS)
#define xTraceStreamPortOnTraceBegin() (TRC_SUCCESS)
traceResult xTraceStreamPortOnTraceEnd(void);
#ifdef __cplusplus
}
#endif
#endif /* TRC_STREAM_PORT_H */

View File

@ -0,0 +1,205 @@
/*
* Trace Recorder for Tracealyzer v4.6.0
* Copyright 2021 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* Supporting functions for trace streaming, used by the "stream ports"
* for reading and writing data to the interface.
* Existing ports can easily be modified to fit another setup, e.g., a
* different TCP/IP stack, or to define your own stream port.
*/
#include <trcRecorder.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
/* TCP/IP includes - for lwIP in this case */
#include <lwip/tcpip.h>
#include <lwip/sockets.h>
#include <lwip/errno.h>
int sock = -1, new_sd = -1;
int flags = 0;
int remoteSize;
struct sockaddr_in address, remote;
typedef struct TraceStreamPortTCPIP
{
#if (TRC_USE_INTERNAL_BUFFER)
uint8_t buffer[(TRC_STREAM_PORT_BUFFER_SIZE)];
#else
TraceUnsignedBaseType_t buffer[1];
#endif
} TraceStreamPortTCPIP_t;
static TraceStreamPortTCPIP_t* pxStreamPortFile;
static int32_t prvSocketSend(void* pvData, uint32_t uiSize, int32_t* piBytesWritten);
static int32_t prvSocketReceive(void* pvData, uint32_t uiSize, int32_t* bytesRead);
static int32_t prvSocketInitializeListener();
static int32_t prvSocketAccept();
static void prvCloseAllSockets();
static int32_t prvSocketSend( void* pvData, uint32_t uiSize, int32_t* piBytesWritten )
{
if (new_sd < 0)
return -1;
if (piBytesWritten == 0)
return -1;
*piBytesWritten = send( new_sd, pvData, uiSize, 0 );
if (*piBytesWritten < 0)
{
/* EWOULDBLOCK may be expected when buffers are full */
if ((errno != 0) && (errno != EWOULDBLOCK))
{
closesocket(new_sd);
new_sd = -1;
return -1;
}
else
*piBytesWritten = 0;
}
return 0;
}
static int32_t prvSocketReceive( void* pvData, uint32_t uiSize, int32_t* bytesRead )
{
if (new_sd < 0)
return -1;
*bytesRead = recv( new_sd, pvData, uiSize, 0 );
/* EWOULDBLOCK may be expected when there is no pvData to receive */
if (errno != 0 && errno != EWOULDBLOCK)
{
closesocket(new_sd);
new_sd = -1;
return -1;
}
return 0;
}
static int32_t prvSocketInitializeListener()
{
if (sock >= 0)
return 0;
sock = lwip_socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0)
return -1;
address.sin_family = AF_INET;
address.sin_port = htons(TRC_CFG_STREAM_PORT_TCPIP_PORT);
address.sin_addr.s_addr = INADDR_ANY;
if (bind(sock, (struct sockaddr *)&address, sizeof (address)) < 0)
{
closesocket(sock);
sock = -1;
return -1;
}
if (lwip_listen(sock, 5) < 0)
{
closesocket(sock);
sock = -1;
return -1;
}
return 0;
}
static int32_t prvSocketAccept()
{
if (sock < 0)
return -1;
if (new_sd >= 0)
return 0;
remoteSize = sizeof( remote );
new_sd = accept( sock, (struct sockaddr *)&remote, (socklen_t*)&remoteSize );
if( new_sd < 0 )
{
closesocket(new_sd);
new_sd = -1;
closesocket(sock);
sock = -1;
return -1;
}
flags = fcntl( new_sd, F_GETFL, 0 );
fcntl( new_sd, F_SETFL, flags | O_NONBLOCK );
return 0;
}
static void prvCloseAllSockets()
{
if (new_sd > 0)
{
closesocket(new_sd);
}
if (sock > 0)
{
closesocket(sock);
}
}
/************** MODIFY THE ABOVE PART TO USE YOUR TPC/IP STACK ****************/
int32_t prvTraceTcpWrite(void* pvData, uint32_t uiSize, int32_t *piBytesWritten)
{
prvSocketInitializeListener();
prvSocketAccept();
return prvSocketSend(pvData, uiSize, piBytesWritten);
}
int32_t prvTraceTcpRead(void* pvData, uint32_t uiSize, int32_t *piBytesRead)
{
prvSocketInitializeListener();
prvSocketAccept();
return prvSocketReceive(pvData, uiSize, piBytesRead);
}
traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer)
{
TRC_ASSERT_EQUAL_SIZE(TraceStreamPortBuffer_t, TraceStreamPortTCPIP_t);
if (pxBuffer == 0)
{
return TRC_FAIL;
}
pxStreamPortFile = (TraceStreamPortTCPIP_t*)pxBuffer;
#if (TRC_USE_INTERNAL_BUFFER == 1)
return xTraceInternalEventBufferInitialize(pxStreamPortFile->buffer, sizeof(pxStreamPortFile->buffer));
#else
return TRC_SUCCESS;
#endif
}
traceResult xTraceStreamPortOnTraceEnd(void)
{
prvCloseAllSockets();
return TRC_SUCCESS;
}
#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/
#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/

View File

@ -0,0 +1,37 @@
Tracealyzer Stream Port for TCP/IP (Win32 example)
Percepio AB
www.percepio.com
-------------------------------------------------
This directory contains a "stream port" for the Tracealyzer recorder library,
i.e., the I/O code needed for streaming a Tracealyzer RTOS trace over specific
interface. The stream port is defined by a set of macros in trcStreamPort.h,
found in the "include" directory.
This particular stream port is for streaming over TCP/IP on Windows, intended
for the FreeRTOS Windows port (WIN32-MSVC). To try it:
1. Open the WIN32-MSVC demo project found in the FreeRTOS demo folder. You
need will Visual Studio, but there are free versions (Express or Community).
2. Make sure the project includes a recent version or the recorder library
(v3.1.x).
3. Make sure the recorder library is configured for streaming mode (see
trcConfig.h).
4. Make sure the project's include paths contains trcStreamPort.h found in
this include folder (and not any other stream port), and the related code
in this folder.
5. Build and start the Win32 demo application. It should begin waiting for
a connection.
6. In Tracealyzer, open File -> Settings... -> Streaming Trace Settings.
Specify target connection: TCP, host: 127.0.0.1 (i.e. localhost) and port 8888.
7. In Tracealyzer, now open File -> Connect to Target System... and there
click "Start Recording". Now you should see a live CPU load graph and some
counters. Let it record for a few seconds, then click "Stop Recording" and then "View Trace".
See also http://percepio.com/2016/10/05/rtos-tracing.

View File

@ -0,0 +1,41 @@
/*
* Trace Recorder for Tracealyzer v4.6.0
* Copyright 2021 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The configuration for trace streaming ("stream ports").
*/
#ifndef TRC_STREAM_PORT_CONFIG_H
#define TRC_STREAM_PORT_CONFIG_H
#ifdef __cplusplus
extern "C" {
#endif
/* This define will determine whether to use the internal buffer or not.
If file writing creates additional trace events (i.e. it uses semaphores or mutexes),
then the internal buffer must be enabled to avoid infinite recursion. */
#define TRC_CFG_STREAM_PORT_USE_INTERNAL_BUFFER 0
/*******************************************************************************
* Configuration Macro: TRC_CFG_STREAM_PORT_TCPIP_PORT
*
* Specifies the TCP/IP port.
******************************************************************************/
#define TRC_CFG_STREAM_PORT_TCPIP_PORT 8888
/*******************************************************************************
* Configuration Macro: TRC_CFG_STREAM_PORT_BUFFER_SIZE
*
* Specifies the size of the internal buffer, if one is used.
******************************************************************************/
#define TRC_CFG_STREAM_PORT_BUFFER_SIZE 10000
#ifdef __cplusplus
}
#endif
#endif /* TRC_STREAM_PORT_CONFIG_H */

View File

@ -0,0 +1,81 @@
/*
* Trace Recorder for Tracealyzer v4.6.0
* Copyright 2021 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The interface definitions for trace streaming ("stream ports").
* This "stream port" sets up the recorder to use TCP/IP as streaming channel.
* The example is for Windows sockets (Winsock), for use with Windows ports.
*/
#ifndef TRC_STREAM_PORT_H
#define TRC_STREAM_PORT_H
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#include <stdint.h>
#include <trcTypes.h>
#include <trcStreamPortConfig.h>
#ifdef __cplusplus
extern "C" {
#endif
#define TRC_USE_INTERNAL_BUFFER (TRC_CFG_STREAM_PORT_USE_INTERNAL_BUFFER)
/**
* @def TRC_STREAM_PORT_BUFFER_SIZE
*
* @brief The buffer size, aligned to base type.
*/
#define TRC_STREAM_PORT_BUFFER_SIZE ((((TRC_CFG_STREAM_PORT_BUFFER_SIZE) + sizeof(TraceUnsignedBaseType_t) - 1) / sizeof(TraceUnsignedBaseType_t)) * sizeof(TraceUnsignedBaseType_t))
typedef struct TraceStreamPortBuffer
{
#if (TRC_USE_INTERNAL_BUFFER)
uint8_t buffer[(TRC_STREAM_PORT_BUFFER_SIZE)];
#else
TraceUnsignedBaseType_t buffer[1];
#endif
} TraceStreamPortBuffer_t;
int32_t prvTraceWriteToSocket(void* data, uint32_t size, int32_t* ptrBytesWritten);
int32_t prvTraceReadFromSocket(void* data, uint32_t bufsize, int32_t* ptrBytesRead);
traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer);
#define xTraceStreamPortAllocate(uiSize, ppvData) ((void)(uiSize), xTraceStaticBufferGet(ppvData))
#if (TRC_USE_INTERNAL_BUFFER == 1)
/* Push to internal buffer. It will call on xTraceStreamPortWriteData() periodically. */
#define xTraceStreamPortCommit xTraceInternalEventBufferPush
#else
/* Write directly */
#define xTraceStreamPortCommit xTraceStreamPortWriteData
#endif
#define xTraceStreamPortWriteData(pvData, uiSize, piBytesWritten) (prvTraceWriteToSocket(pvData, uiSize, piBytesWritten) == 0 ? TRC_SUCCESS : TRC_FAIL)
#define xTraceStreamPortReadData(pvData, uiSize, piBytesRead) (prvTraceReadFromSocket(pvData, uiSize, piBytesRead) == 0 ? TRC_SUCCESS : TRC_FAIL)
#define xTraceStreamPortOnEnable(uiStartOption) ((void)(uiStartOption), TRC_SUCCESS)
#define xTraceStreamPortOnDisable() (TRC_SUCCESS)
#define xTraceStreamPortOnTraceBegin() (TRC_SUCCESS)
traceResult xTraceStreamPortOnTraceEnd(void);
#ifdef __cplusplus
}
#endif
#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/
#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/
#endif /* TRC_STREAM_PORT_H */

View File

@ -0,0 +1,238 @@
/*
* Trace Recorder for Tracealyzer v4.6.0
* Copyright 2021 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* Supporting functions for trace streaming, used by the "stream ports"
* for reading and writing data to the interface.
* Existing ports can easily be modified to fit another setup, e.g., a
* different TCP/IP stack, or to define your own stream port.
*/
#include<stdio.h>
#include<winsock2.h>
#include <trcRecorder.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#pragma comment(lib,"ws2_32.lib") //Winsock Library
typedef struct TraceStreamPortTCPIP
{
#if (TRC_USE_INTERNAL_BUFFER)
uint8_t buffer[(TRC_STREAM_PORT_BUFFER_SIZE)];
#else
TraceUnsignedBaseType_t buffer[1];
#endif
} TraceStreamPortTCPIP_t;
static TraceStreamPortTCPIP_t* pxStreamPortFile;
static SOCKET server_socket = (UINT_PTR)0, trace_socket = (UINT_PTR)0;
struct sockaddr_in server, client;
static int prvInitServerSocketIfNeeded(void);
static int prvInitWinsockIfNeeded(void);
static int prvInitTraceSocketIfNeeded(void);
static void prvCloseAllSockets(void);
static int prvInitWinsockIfNeeded(void)
{
WSADATA wsa;
if (server_socket)
return 0;
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
return -1;
}
return 0;
}
static int prvInitServerSocketIfNeeded(void)
{
if (prvInitWinsockIfNeeded() < 0)
{
return -1;
}
if (server_socket)
return 0;
if ((server_socket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
return -1;
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(TRC_CFG_STREAM_PORT_TCPIP_PORT);
if (bind(server_socket, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
{
closesocket(server_socket);
WSACleanup();
server_socket = (UINT_PTR)0;
return -1;
}
if (listen(server_socket, 3) < 0)
{
closesocket(server_socket);
WSACleanup();
server_socket = (UINT_PTR)0;
return -1;
}
return 0;
}
static int prvInitTraceSocketIfNeeded(void)
{
int c;
if (!server_socket)
return -1;
if (trace_socket)
return 0;
c = sizeof(struct sockaddr_in);
trace_socket = accept(server_socket, (struct sockaddr *)&client, &c);
if (trace_socket == INVALID_SOCKET)
{
trace_socket = (UINT_PTR)0;
closesocket(server_socket);
WSACleanup();
server_socket = (UINT_PTR)0;
return -1;
}
return 0;
}
int32_t prvTraceWriteToSocket(void* data, uint32_t size, int32_t *ptrBytesWritten)
{
int ret;
if (prvInitServerSocketIfNeeded() < 0)
{
return -1;
}
if (prvInitTraceSocketIfNeeded() < 0)
{
return -1;
}
if (!trace_socket)
{
if (ptrBytesWritten != 0)
{
*ptrBytesWritten = 0;
}
return -1;
}
ret = send(trace_socket, data, size, 0);
if (ret <= 0)
{
if (ptrBytesWritten != 0)
{
*ptrBytesWritten = 0;
}
closesocket(trace_socket);
trace_socket = (UINT_PTR)0;
return ret;
}
if (ptrBytesWritten != 0)
{
*ptrBytesWritten = ret;
}
return 0;
}
int32_t prvTraceReadFromSocket(void* data, uint32_t bufsize, int32_t *ptrBytesRead)
{
unsigned long bytesAvailable = 0;
if (prvInitServerSocketIfNeeded() < 0)
return -1;
if (prvInitTraceSocketIfNeeded() < 0)
return -1;
if (ioctlsocket(trace_socket, FIONREAD, &bytesAvailable) != NO_ERROR)
{
closesocket(trace_socket);
trace_socket = (UINT_PTR)0;
return -1;
}
if (bytesAvailable > 0)
{
*ptrBytesRead = recv(trace_socket, data, bufsize, 0);
if (*ptrBytesRead == SOCKET_ERROR)
{
closesocket(trace_socket);
trace_socket = (UINT_PTR)0;
return -1;
}
}
return 0;
}
static void prvCloseAllSockets(void)
{
if (trace_socket != 0)
{
closesocket(trace_socket);
trace_socket = 0;
}
if (server_socket != 0)
{
closesocket(server_socket);
server_socket = 0;
}
}
traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer)
{
TRC_ASSERT_EQUAL_SIZE(TraceStreamPortBuffer_t, TraceStreamPortTCPIP_t);
if (pxBuffer == 0)
{
return TRC_FAIL;
}
pxStreamPortFile = (TraceStreamPortTCPIP_t*)pxBuffer;
#if (TRC_USE_INTERNAL_BUFFER == 1)
return xTraceInternalEventBufferInitialize(pxStreamPortFile->buffer, sizeof(pxStreamPortFile->buffer));
#else
return TRC_SUCCESS;
#endif
}
traceResult xTraceStreamPortOnTraceEnd(void)
{
prvCloseAllSockets();
return TRC_SUCCESS;
}
#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/
#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/

View File

@ -0,0 +1,35 @@
/*
* Trace Recorder for Tracealyzer v4.6.0
* Copyright 2021 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The configuration for trace streaming ("stream ports").
*/
#ifndef TRC_STREAM_PORT_CONFIG_H
#define TRC_STREAM_PORT_CONFIG_H
#ifdef __cplusplus
extern "C" {
#endif
/* This define will determine whether to use the internal buffer or not.
If file writing creates additional trace events (i.e. it uses semaphores or mutexes),
then the internal buffer must be enabled to avoid infinite recursion. */
#define TRC_CFG_STREAM_PORT_USE_INTERNAL_BUFFER 1
/**
* @def TRC_CFG_INTERNAL_BUFFER_SIZE
*
* @brief Configures the size of the internal buffer if used.
* is enabled.
*/
#define TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_SIZE 35000
#ifdef __cplusplus
}
#endif
#endif /* TRC_STREAM_PORT_CONFIG_H */

View File

@ -0,0 +1,130 @@
/*
* Trace Recorder for Tracealyzer v4.6.0
* Copyright 2021 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The interface definitions for trace streaming ("stream ports").
* This "stream port" sets up the recorder to use XMOS xScope as a streaming channel.
*/
#ifndef TRC_STREAMING_PORT_H
#define TRC_STREAMING_PORT_H
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#ifdef __cplusplus
extern "C" {
#endif
#include <trcTypes.h>
#include <trcStreamPortConfig.h>
#define TRC_USE_INTERNAL_BUFFER (TRC_CFG_STREAM_PORT_USE_INTERNAL_BUFFER)
/* Aligned */
#define TRC_STREAM_PORT_INTERNAL_BUFFER_SIZE ((((TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_SIZE) + sizeof(TraceUnsignedBaseType_t) - 1) / sizeof(TraceUnsignedBaseType_t)) * sizeof(TraceUnsignedBaseType_t))
/**
* @brief A structure representing the trace stream port buffer.
*/
typedef struct TraceStreamPortBuffer
{
#if (TRC_USE_INTERNAL_BUFFER == 1)
uint8_t uiBufferInternal[TRC_STREAM_PORT_INTERNAL_BUFFER_SIZE];
#endif
uint8_t uiBuffer[4];
} TraceStreamPortBuffer_t;
/**
* @internal Stream port initialize callback.
*
* This function is called by the recorder as part of its initialization phase.
*
* @param[in] pxBuffer Buffer
* @retval TRC_FAIL Initialization failed
* @retval TRC_SUCCESS Success
*/
traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer);
/**
* @brief Stream port begin callback.
*
* This function is called by the recorder as part of its begin phase.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceStreamPortOnBegin(void);
/**
* @brief Stream port end callback.
*
* This function is called by the recorder as part of its end phase.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceStreamPortOnEnd(void);
/**
* @brief Allocates data from the stream port.
*
* @param[in] uiSize Allocation size
* @param[out] ppvData Allocation data pointer
*
* @retval TRC_FAIL Allocate failed
* @retval TRC_SUCCESS Success
*/
traceResult xTraceStreamPortAllocate(uint32_t uiSize, void** ppvData);
/**
* @brief Commits data to the stream port, depending on the implementation/configuration of the
* stream port this data might be directly written to the stream port interface, buffered, or
* something else.
*
* @param[in] pvData Data to commit
* @param[in] uiSize Data to commit size
* @param[out] piBytesCommitted Bytes commited
*
* @retval TRC_FAIL Commit failed
* @retval TRC_SUCCESS Success
*/
traceResult xTraceStreamPortCommit(void* pvData, uint32_t uiSize, int32_t* piBytesCommitted);
/**
* @brief Writes data through the stream port interface.
*
* @param[in] pvData Data to write
* @param[in] uiSize Data to write size
* @param[out] piBytesWritten Bytes written
*
* @retval TRC_FAIL Write failed
* @retval TRC_SUCCESS Success
*/
traceResult xTraceStreamPortWriteData(void* pvData, uint32_t uiSize, int32_t* piBytesWritten);
/**
* @brief Reads data through the stream port interface.
*
* @param[in] pvData Destination data buffer
* @param[in] uiSize Destination data buffer size
* @param[out] piBytesRead Bytes read
*
* @retval TRC_FAIL Read failed
* @retval TRC_SUCCESS Success
*/
traceResult xTraceStreamPortReadData(void* pvData, uint32_t uiSize, int32_t* piBytesRead);
#ifdef __cplusplus
}
#endif
#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/
#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/
#endif /* TRC_STREAMING_PORT_H */

View File

@ -0,0 +1,101 @@
/*
* Trace Recorder for Tracealyzer v4.6.0
* Copyright 2021 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* Supporting functions for trace streaming, used by the "stream ports"
* for reading and writing data to the interface.
*/
#include <trcRecorder.h>
#include <xscope.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
typedef struct TraceStreamPortXS {
#if (TRC_USE_INTERNAL_BUFFER == 1)
uint8_t uiBufferInternal[TRC_STREAM_PORT_INTERNAL_BUFFER_SIZE];
#endif
uint8_t uiBuffer[4];
} TraceStreamPortXS_t;
static TraceStreamPortXS_t* pxStreamPortXS;
traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer)
{
TRC_ASSERT_EQUAL_SIZE(TraceStreamPortBuffer_t, TraceStreamPortXS_t);
if (pxBuffer == 0)
{
return TRC_FAIL;
}
pxStreamPortXS = (TraceStreamPortXS_t*)pxBuffer;
#if (TRC_USE_INTERNAL_BUFFER == 1)
return xTraceInternalEventBufferInitialize(pxStreamPortXS->uiBufferInternal, sizeof(pxStreamPortXS->uiBufferInternal));
#else
return TRC_SUCCESS;
#endif
}
traceResult xTraceStreamPortOnBegin(void)
{
return TRC_SUCCESS;
}
traceResult xTraceStreamPortOnEnd(void)
{
return TRC_SUCCESS;
}
traceResult xTraceStreamPortAllocate(uint32_t uiSize, void** ppvData)
{
(void)uiSize;
return xTraceStaticBufferGet(ppvData);
}
traceResult xTraceStreamPortCommit(void* pvData, uint32_t uiSize, int32_t* piBytesCommitted)
{
if (pvData == 0)
{
return TRC_FAIL;
}
#if (TRC_USE_INTERNAL_BUFFER == 1)
/* Push to internal buffer. It will call on xTraceStreamPortWriteData() periodically. */
return xTraceInternalEventBufferPush(pvData, uiSize, piBytesCommitted);
#else
/* Write directly to file */
return xTraceStreamPortWriteData(pvData, uiSize, piBytesCommitted);
#endif
}
traceResult xTraceStreamPortWriteData(void* pvData, uint32_t uiSize, int32_t* piBytesWritten)
{
/* xscope_bytes is supposed to be thread safe, so we do not bother with any
* critical sections here. */
xscope_bytes(0, uiSize, (unsigned char*)pvData);
if (piBytesWritten != 0) {
/* Since xScope always write all bytes (not all might be received) we flag this as
* a full write */
*piBytesWritten = (int32_t)uiSize;
}
return TRC_SUCCESS;
}
traceResult xTraceStreamPortReadData(void* pvData, uint32_t uiSize, int32_t* piBytesRead)
{
return TRC_SUCCESS;
}
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */