Update trace recorder code.

Add TCP Echo server to the FreeR_Plus_TCP_Minimal_Window_Simulator project.
This commit is contained in:
Richard Barry 2018-07-02 22:29:02 +00:00
parent f7fc215247
commit d525d5092d
35 changed files with 4431 additions and 2436 deletions

View file

@ -0,0 +1,52 @@
/************************************************************
* Percepio Tracealyzer - ITM Trace Exporter for Keil uVision
* Copyright (c) 2018, Percepio AB.
* https://percepio.com
************************************************************/
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,28 @@
Tracealyzer Stream Port for ARM Cortex-M ITM
--------------------------------------------
2018-05-04
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
trcStreamingPort.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/
Learning more:
- Tracealyzer User Manual (Help -> User Manual)
- https://percepio.com/gettingstarted
- Percepio Application Note PA-021 https://percepio.com/2018/05/04/keil-itm-support/
- 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
Percepio AB
www.percepio.com

View file

@ -0,0 +1,91 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v4.1.1
* Percepio AB, www.percepio.com
*
* trcStreamingPort.h
*
* The interface definitions for trace streaming ("stream ports").
* This "stream port" sets up the recorder to use ARM ITM as streaming channel.
*
* Terms of Use
* This file is part of the trace recorder library (RECORDER), which is the
* intellectual property of Percepio AB (PERCEPIO) and provided under a
* license as follows.
* The RECORDER may be used free of charge for the purpose of recording data
* intended for analysis in PERCEPIO products. It may not be used or modified
* for other purposes without explicit permission from PERCEPIO.
* You may distribute the RECORDER in its original source code form, assuming
* this text (terms of use, disclaimer, copyright notice) is unchanged. You are
* allowed to distribute the RECORDER with minor modifications intended for
* configuration or porting of the RECORDER, e.g., to allow using it on a
* specific processor, processor family or with a specific communication
* interface. Any such modifications should be documented directly below
* this comment block.
*
* Disclaimer
* The RECORDER is being delivered to you AS IS and PERCEPIO makes no warranty
* as to its use or performance. PERCEPIO does not and cannot warrant the
* performance or results you may obtain by using the RECORDER or documentation.
* PERCEPIO make no warranties, express or implied, as to noninfringement of
* third party rights, merchantability, or fitness for any particular purpose.
* In no event will PERCEPIO, its technology partners, or distributors be liable
* to you for any consequential, incidental or special damages, including any
* lost profits or lost savings, even if a representative of PERCEPIO has been
* advised of the possibility of such damages, or for any claim by any third
* party. Some jurisdictions do not allow the exclusion or limitation of
* incidental, consequential or special damages, or the exclusion of implied
* warranties or limitations on how long an implied warranty may last, so the
* above limitations may not apply to you.
*
* Tabs are used for indent in this file (1 tab = 4 spaces)
*
* Copyright Percepio AB, 2018.
* www.percepio.com
******************************************************************************/
#ifndef TRC_STREAMING_PORT_H
#define TRC_STREAMING_PORT_H
#ifdef __cplusplus
extern "C" {
#endif
int32_t itm_write(void* ptrData, uint32_t size, int32_t* ptrBytesWritten);
int32_t read_from_host(void* ptrData, uint32_t size, int32_t* ptrBytesRead);
/*******************************************************************************
* TRC_CFG_ITM_PORT
*
* Possible 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_ITM_PORT 1
#if (TRC_CFG_ITM_PORT < 0) || (TRC_CFG_ITM_PORT > 31)
#error "Bad ITM port selected."
#endif
// Not used for ITM - no RAM buffer...
#define TRC_STREAM_PORT_ALLOCATE_FIELDS()
// Not used for ITM - assume the IDE configures the ITM setup
#define TRC_STREAM_PORT_INIT()
/* Important for the ITM port - no RAM buffer, direct writes. In most other ports this can be skipped (default is 1) */
#define TRC_STREAM_PORT_USE_INTERNAL_BUFFER 0
#define TRC_STREAM_PORT_WRITE_DATA(_ptrData, _size, _ptrBytesWritten) itm_write(_ptrData, _size, _ptrBytesWritten)
#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) read_from_host(_ptrData, _size, _ptrBytesRead)
#ifdef __cplusplus
}
#endif
#endif /* TRC_STREAMING_PORT_H */

View file

@ -0,0 +1,71 @@
#include "trcRecorder.h"
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
static void itm_write_32(uint32_t data);
volatile int32_t tz_host_command_bytes_to_read = 0; // This is set by the Tracealyzer host application (to the number of bytes written), after having written to tz_host_commands. Set to zero by the read function after the message in tz_host_commands has been read.
volatile char tz_host_command_data[32];
/* This reads "command" data from a RAM buffer, written by a host macro in the debugger */
int32_t read_from_host(void* ptrData, uint32_t size, int32_t* ptrBytesRead)
{
if ( tz_host_command_bytes_to_read > 0)
{
int i;
uint8_t * bytesBuffer = (uint8_t*) ptrData;
if (ptrBytesRead != NULL)
*ptrBytesRead = (int32_t)tz_host_command_bytes_to_read;
if (tz_host_command_bytes_to_read != size)
{
return -1;
}
for (i=0; i < tz_host_command_bytes_to_read; i++)
{
bytesBuffer[i] = tz_host_command_data[i];
}
tz_host_command_bytes_to_read = 0;
}
return 0;
}
static void itm_write_32(uint32_t data)
{
if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk) && // Trace enabled
(ITM->TCR & ITM_TCR_ITMENA_Msk) && // ITM enabled
(ITM->TER & (1UL << 0))) // ITM Port #0 enabled
{
while (ITM->PORT[TRC_CFG_ITM_PORT].u32 == 0); // Block until room in ITM FIFO - This stream port is always in "blocking mode", since intended for high-speed ITM!
ITM->PORT[TRC_CFG_ITM_PORT].u32 = data; // Write the data
}
}
/* This is assumed to execute from within the recorder, with interrupts disabled */
int32_t itm_write(void* ptrData, uint32_t size, int32_t* ptrBytesWritten)
{
uint32_t bytesWritten = 0;
uint32_t* ptr32 = (uint32_t*)ptrData;
if (size % 4 != 0) return -2;
while(bytesWritten < size)
{
itm_write_32(*ptr32);
ptr32++;
bytesWritten += 4;
}
*ptrBytesWritten = bytesWritten;
return 0;
}
#endif
#endif

View file

@ -0,0 +1,19 @@
Tracealyzer Stream Port for Files
-------------------------------------------------
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
trcStreamingPort.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/trcStreamingPort.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
trcStreamingPort.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,87 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v4.1.1
* Percepio AB, www.percepio.com
*
* trcStreamingPort.h
*
* The interface definitions for trace streaming ("stream ports").
* This "stream port" sets up the recorder to stream the trace to file.
*
* Terms of Use
* This file is part of the trace recorder library (RECORDER), which is the
* intellectual property of Percepio AB (PERCEPIO) and provided under a
* license as follows.
* The RECORDER may be used free of charge for the purpose of recording data
* intended for analysis in PERCEPIO products. It may not be used or modified
* for other purposes without explicit permission from PERCEPIO.
* You may distribute the RECORDER in its original source code form, assuming
* this text (terms of use, disclaimer, copyright notice) is unchanged. You are
* allowed to distribute the RECORDER with minor modifications intended for
* configuration or porting of the RECORDER, e.g., to allow using it on a
* specific processor, processor family or with a specific communication
* interface. Any such modifications should be documented directly below
* this comment block.
*
* Disclaimer
* The RECORDER is being delivered to you AS IS and PERCEPIO makes no warranty
* as to its use or performance. PERCEPIO does not and cannot warrant the
* performance or results you may obtain by using the RECORDER or documentation.
* PERCEPIO make no warranties, express or implied, as to noninfringement of
* third party rights, merchantability, or fitness for any particular purpose.
* In no event will PERCEPIO, its technology partners, or distributors be liable
* to you for any consequential, incidental or special damages, including any
* lost profits or lost savings, even if a representative of PERCEPIO has been
* advised of the possibility of such damages, or for any claim by any third
* party. Some jurisdictions do not allow the exclusion or limitation of
* incidental, consequential or special damages, or the exclusion of implied
* warranties or limitations on how long an implied warranty may last, so the
* above limitations may not apply to you.
*
* Tabs are used for indent in this file (1 tab = 4 spaces)
*
* Copyright Percepio AB, 2018.
* www.percepio.com
******************************************************************************/
#ifndef TRC_STREAMING_PORT_H
#define TRC_STREAMING_PORT_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
int32_t writeToFile(void* data, uint32_t size, int32_t *ptrBytesWritten);
void closeFile(void);
void openFile(char* fileName);
/* This define will determine whether to use the internal PagedEventBuffer or not.
If file writing creates additional trace events (i.e. it uses semaphores or mutexes),
then the paged event buffer must be enabled to avoid infinite recursion. */
#define TRC_STREAM_PORT_USE_INTERNAL_BUFFER 1
#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) 0 /* Does not read commands from Tz (yet) */
#define TRC_STREAM_PORT_WRITE_DATA(_ptrData, _size, _ptrBytesSent) writeToFile(_ptrData, _size, _ptrBytesSent)
#if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC)
#define TRC_STREAM_PORT_MALLOC() \
_TzTraceData = TRC_PORT_MALLOC((TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT) * (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE));
extern char* _TzTraceData;
#else
#define TRC_STREAM_PORT_MALLOC() /* Custom or static allocation. Not used. */
#endif
#define TRC_STREAM_PORT_INIT() \
TRC_STREAM_PORT_MALLOC(); \
openFile("trace.psf")
#define TRC_STREAM_PORT_ON_TRACE_END() closeFile()
#ifdef __cplusplus
}
#endif
#endif /* TRC_STREAMING_PORT_H */

View file

@ -0,0 +1,103 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v4.1.1
* Percepio AB, www.percepio.com
*
* trcStreamingPort.c
*
* 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.
*
* Terms of Use
* This file is part of the trace recorder library (RECORDER), which is the
* intellectual property of Percepio AB (PERCEPIO) and provided under a
* license as follows.
* The RECORDER may be used free of charge for the purpose of recording data
* intended for analysis in PERCEPIO products. It may not be used or modified
* for other purposes without explicit permission from PERCEPIO.
* You may distribute the RECORDER in its original source code form, assuming
* this text (terms of use, disclaimer, copyright notice) is unchanged. You are
* allowed to distribute the RECORDER with minor modifications intended for
* configuration or porting of the RECORDER, e.g., to allow using it on a
* specific processor, processor family or with a specific communication
* interface. Any such modifications should be documented directly below
* this comment block.
*
* Disclaimer
* The RECORDER is being delivered to you AS IS and PERCEPIO makes no warranty
* as to its use or performance. PERCEPIO does not and cannot warrant the
* performance or results you may obtain by using the RECORDER or documentation.
* PERCEPIO make no warranties, express or implied, as to noninfringement of
* third party rights, merchantability, or fitness for any particular purpose.
* In no event will PERCEPIO, its technology partners, or distributors be liable
* to you for any consequential, incidental or special damages, including any
* lost profits or lost savings, even if a representative of PERCEPIO has been
* advised of the possibility of such damages, or for any claim by any third
* party. Some jurisdictions do not allow the exclusion or limitation of
* incidental, consequential or special damages, or the exclusion of implied
* warranties or limitations on how long an implied warranty may last, so the
* above limitations may not apply to you.
*
* Tabs are used for indent in this file (1 tab = 4 spaces)
*
* Copyright Percepio AB, 2018.
* www.percepio.com
******************************************************************************/
#include "trcRecorder.h"
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
FILE* traceFile = NULL;
void openFile(char* fileName)
{
if (traceFile == NULL)
{
errno_t err = fopen_s(&traceFile, fileName, "wb");
if (err != 0)
{
printf("Could not open trace file, error code %d.\n", err);
exit(-1);
}
else {
printf("Trace file created.\n");
}
}
}
int32_t writeToFile(void* data, uint32_t size, int32_t *ptrBytesWritten)
{
int32_t written = 0;
if (traceFile != NULL)
{
written = fwrite(data, 1, size, traceFile);
}
else
{
written = 0;
}
if (ptrBytesWritten != 0)
*ptrBytesWritten = written;
if ((int32_t)size == written)
return 0;
else
return -1;
}
void closeFile(void)
{
if (traceFile != NULL)
{
fclose(traceFile);
traceFile = NULL;
printf("Trace file closed.\n");
}
}
#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/
#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/

View file

@ -1,505 +0,0 @@
/*********************************************************************
* 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_printf.c
Purpose : Replacement for printf to write formatted data via RTT
Revision: $Rev: 3667 $
----------------------------------------------------------------------
*/
#include "SEGGER_RTT.h"
#include "SEGGER_RTT_Conf.h"
/*********************************************************************
*
* Defines, configurable
*
**********************************************************************
*/
#ifndef SEGGER_RTT_PRINTF_BUFFER_SIZE
#define SEGGER_RTT_PRINTF_BUFFER_SIZE (64)
#endif
#include <stdlib.h>
#include <stdarg.h>
#define FORMAT_FLAG_LEFT_JUSTIFY (1u << 0)
#define FORMAT_FLAG_PAD_ZERO (1u << 1)
#define FORMAT_FLAG_PRINT_SIGN (1u << 2)
#define FORMAT_FLAG_ALTERNATE (1u << 3)
/*********************************************************************
*
* Types
*
**********************************************************************
*/
typedef struct {
char* pBuffer;
unsigned BufferSize;
unsigned Cnt;
int ReturnValue;
unsigned RTTBufferIndex;
} SEGGER_RTT_PRINTF_DESC;
/*********************************************************************
*
* Function prototypes
*
**********************************************************************
*/
int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList);
/*********************************************************************
*
* Static code
*
**********************************************************************
*/
/*********************************************************************
*
* _StoreChar
*/
static void _StoreChar(SEGGER_RTT_PRINTF_DESC * p, char c) {
unsigned Cnt;
Cnt = p->Cnt;
if ((Cnt + 1u) <= p->BufferSize) {
*(p->pBuffer + Cnt) = c;
p->Cnt = Cnt + 1u;
p->ReturnValue++;
}
//
// Write part of string, when the buffer is full
//
if (p->Cnt == p->BufferSize) {
if (SEGGER_RTT_Write(p->RTTBufferIndex, p->pBuffer, p->Cnt) != p->Cnt) {
p->ReturnValue = -1;
} else {
p->Cnt = 0u;
}
}
}
/*********************************************************************
*
* _PrintUnsigned
*/
static void _PrintUnsigned(SEGGER_RTT_PRINTF_DESC * pBufferDesc, unsigned v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) {
static const char _aV2C[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
unsigned Div;
unsigned Digit;
unsigned Number;
unsigned Width;
char c;
Number = v;
Digit = 1u;
//
// Get actual field width
//
Width = 1u;
while (Number >= Base) {
Number = (Number / Base);
Width++;
}
if (NumDigits > Width) {
Width = NumDigits;
}
//
// Print leading chars if necessary
//
if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) {
if (FieldWidth != 0u) {
if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && (NumDigits == 0u)) {
c = '0';
} else {
c = ' ';
}
while ((FieldWidth != 0u) && (Width < FieldWidth)) {
FieldWidth--;
_StoreChar(pBufferDesc, c);
if (pBufferDesc->ReturnValue < 0) {
break;
}
}
}
}
if (pBufferDesc->ReturnValue >= 0) {
//
// Compute Digit.
// Loop until Digit has the value of the highest digit required.
// Example: If the output is 345 (Base 10), loop 2 times until Digit is 100.
//
while (1) {
if (NumDigits > 1u) { // User specified a min number of digits to print? => Make sure we loop at least that often, before checking anything else (> 1 check avoids problems with NumDigits being signed / unsigned)
NumDigits--;
} else {
Div = v / Digit;
if (Div < Base) { // Is our divider big enough to extract the highest digit from value? => Done
break;
}
}
Digit *= Base;
}
//
// Output digits
//
do {
Div = v / Digit;
v -= Div * Digit;
_StoreChar(pBufferDesc, _aV2C[Div]);
if (pBufferDesc->ReturnValue < 0) {
break;
}
Digit /= Base;
} while (Digit);
//
// Print trailing spaces if necessary
//
if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == FORMAT_FLAG_LEFT_JUSTIFY) {
if (FieldWidth != 0u) {
while ((FieldWidth != 0u) && (Width < FieldWidth)) {
FieldWidth--;
_StoreChar(pBufferDesc, ' ');
if (pBufferDesc->ReturnValue < 0) {
break;
}
}
}
}
}
}
/*********************************************************************
*
* _PrintInt
*/
static void _PrintInt(SEGGER_RTT_PRINTF_DESC * pBufferDesc, int v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) {
unsigned Width;
int Number;
Number = (v < 0) ? -v : v;
//
// Get actual field width
//
Width = 1u;
while (Number >= (int)Base) {
Number = (Number / (int)Base);
Width++;
}
if (NumDigits > Width) {
Width = NumDigits;
}
if ((FieldWidth > 0u) && ((v < 0) || ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN))) {
FieldWidth--;
}
//
// Print leading spaces if necessary
//
if ((((FormatFlags & FORMAT_FLAG_PAD_ZERO) == 0u) || (NumDigits != 0u)) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u)) {
if (FieldWidth != 0u) {
while ((FieldWidth != 0u) && (Width < FieldWidth)) {
FieldWidth--;
_StoreChar(pBufferDesc, ' ');
if (pBufferDesc->ReturnValue < 0) {
break;
}
}
}
}
//
// Print sign if necessary
//
if (pBufferDesc->ReturnValue >= 0) {
if (v < 0) {
v = -v;
_StoreChar(pBufferDesc, '-');
} else if ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN) {
_StoreChar(pBufferDesc, '+');
} else {
}
if (pBufferDesc->ReturnValue >= 0) {
//
// Print leading zeros if necessary
//
if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) && (NumDigits == 0u)) {
if (FieldWidth != 0u) {
while ((FieldWidth != 0u) && (Width < FieldWidth)) {
FieldWidth--;
_StoreChar(pBufferDesc, '0');
if (pBufferDesc->ReturnValue < 0) {
break;
}
}
}
}
if (pBufferDesc->ReturnValue >= 0) {
//
// Print number without sign
//
_PrintUnsigned(pBufferDesc, (unsigned)v, Base, NumDigits, FieldWidth, FormatFlags);
}
}
}
}
/*********************************************************************
*
* Public code
*
**********************************************************************
*/
/*********************************************************************
*
* SEGGER_RTT_vprintf
*
* Function description
* Stores a formatted string in SEGGER RTT control block.
* This data is read by the host.
*
* Parameters
* BufferIndex Index of "Up"-buffer to be used. (e.g. 0 for "Terminal")
* sFormat Pointer to format string
* pParamList Pointer to the list of arguments for the format string
*
* Return values
* >= 0: Number of bytes which have been stored in the "Up"-buffer.
* < 0: Error
*/
int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList) {
char c;
SEGGER_RTT_PRINTF_DESC BufferDesc;
int v;
unsigned NumDigits;
unsigned FormatFlags;
unsigned FieldWidth;
char acBuffer[SEGGER_RTT_PRINTF_BUFFER_SIZE];
BufferDesc.pBuffer = acBuffer;
BufferDesc.BufferSize = SEGGER_RTT_PRINTF_BUFFER_SIZE;
BufferDesc.Cnt = 0u;
BufferDesc.RTTBufferIndex = BufferIndex;
BufferDesc.ReturnValue = 0;
do {
c = *sFormat;
sFormat++;
if (c == 0u) {
break;
}
if (c == '%') {
//
// Filter out flags
//
FormatFlags = 0u;
v = 1;
do {
c = *sFormat;
switch (c) {
case '-': FormatFlags |= FORMAT_FLAG_LEFT_JUSTIFY; sFormat++; break;
case '0': FormatFlags |= FORMAT_FLAG_PAD_ZERO; sFormat++; break;
case '+': FormatFlags |= FORMAT_FLAG_PRINT_SIGN; sFormat++; break;
case '#': FormatFlags |= FORMAT_FLAG_ALTERNATE; sFormat++; break;
default: v = 0; break;
}
} while (v);
//
// filter out field with
//
FieldWidth = 0u;
do {
c = *sFormat;
if ((c < '0') || (c > '9')) {
break;
}
sFormat++;
FieldWidth = (FieldWidth * 10u) + ((unsigned)c - '0');
} while (1);
//
// Filter out precision (number of digits to display)
//
NumDigits = 0u;
c = *sFormat;
if (c == '.') {
sFormat++;
do {
c = *sFormat;
if ((c < '0') || (c > '9')) {
break;
}
sFormat++;
NumDigits = NumDigits * 10u + ((unsigned)c - '0');
} while (1);
}
//
// Filter out length modifier
//
c = *sFormat;
do {
if ((c == 'l') || (c == 'h')) {
sFormat++;
c = *sFormat;
} else {
break;
}
} while (1);
//
// Handle specifiers
//
switch (c) {
case 'c': {
char c0;
v = va_arg(*pParamList, int);
c0 = (char)v;
_StoreChar(&BufferDesc, c0);
break;
}
case 'd':
v = va_arg(*pParamList, int);
_PrintInt(&BufferDesc, v, 10u, NumDigits, FieldWidth, FormatFlags);
break;
case 'u':
v = va_arg(*pParamList, int);
_PrintUnsigned(&BufferDesc, (unsigned)v, 10u, NumDigits, FieldWidth, FormatFlags);
break;
case 'x':
case 'X':
v = va_arg(*pParamList, int);
_PrintUnsigned(&BufferDesc, (unsigned)v, 16u, NumDigits, FieldWidth, FormatFlags);
break;
case 's':
{
const char * s = va_arg(*pParamList, const char *);
do {
c = *s;
s++;
if (c == '\0') {
break;
}
_StoreChar(&BufferDesc, c);
} while (BufferDesc.ReturnValue >= 0);
}
break;
case 'p':
v = va_arg(*pParamList, int);
_PrintUnsigned(&BufferDesc, (unsigned)v, 16u, 8u, 8u, 0u);
break;
case '%':
_StoreChar(&BufferDesc, '%');
break;
default:
break;
}
sFormat++;
} else {
_StoreChar(&BufferDesc, c);
}
} while (BufferDesc.ReturnValue >= 0);
if (BufferDesc.ReturnValue > 0) {
//
// Write remaining data, if any
//
if (BufferDesc.Cnt != 0u) {
SEGGER_RTT_Write(BufferIndex, acBuffer, BufferDesc.Cnt);
}
BufferDesc.ReturnValue += (int)BufferDesc.Cnt;
}
return BufferDesc.ReturnValue;
}
/*********************************************************************
*
* SEGGER_RTT_printf
*
* Function description
* Stores a formatted string in SEGGER RTT control block.
* This data is read by the host.
*
* Parameters
* BufferIndex Index of "Up"-buffer to be used. (e.g. 0 for "Terminal")
* sFormat Pointer to format string, followed by the arguments for conversion
*
* Return values
* >= 0: Number of bytes which have been stored in the "Up"-buffer.
* < 0: Error
*
* Notes
* (1) Conversion specifications have following syntax:
* %[flags][FieldWidth][.Precision]ConversionSpecifier
* (2) Supported flags:
* -: Left justify within the field width
* +: Always print sign extension for signed conversions
* 0: Pad with 0 instead of spaces. Ignored when using '-'-flag or precision
* Supported conversion specifiers:
* c: Print the argument as one char
* d: Print the argument as a signed integer
* u: Print the argument as an unsigned integer
* x: Print the argument as an hexadecimal integer
* s: Print the string pointed to by the argument
* p: Print the argument as an 8-digit hexadecimal integer. (Argument shall be a pointer to void.)
*/
int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...) {
int r;
va_list ParamList;
va_start(ParamList, sFormat);
r = SEGGER_RTT_vprintf(BufferIndex, sFormat, &ParamList);
va_end(ParamList);
return r;
}
/*************************** End of file ****************************/

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v3.1.2
* Trace Recorder Library for Tracealyzer v4.1.1
* Percepio AB, www.percepio.com
*
* trcStreamingPort.h
@ -7,6 +7,11 @@
* 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.
*
* Terms of Use
* This file is part of the trace recorder library (RECORDER), which is the
* intellectual property of Percepio AB (PERCEPIO) and provided under a
@ -39,7 +44,7 @@
*
* Tabs are used for indent in this file (1 tab = 4 spaces)
*
* Copyright Percepio AB, 2017.
* Copyright Percepio AB, 2018.
* www.percepio.com
******************************************************************************/
@ -113,17 +118,18 @@ extern "C" {
* internal RAM buffer read by the J-Link probes during execution.
*
* Possible values:
* - SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL (default)
* - SEGGER_RTT_MODE_NO_BLOCK_SKIP
* - SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL
* - SEGGER_RTT_MODE_NO_BLOCK_SKIP (default)
*
* We recommend using SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL, to ensure you get a
* 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 to try SEGGER_RTT_MODE_NO_BLOCK_SKIP as well.
* In this mode, Tracealyzer will report lost events if the transfer is not
*
* 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_RTT_MODE SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL
#define TRC_CFG_RTT_MODE SEGGER_RTT_MODE_NO_BLOCK_SKIP
#include "SEGGER_RTT_Conf.h"
#include "SEGGER_RTT.h"
@ -140,22 +146,18 @@ extern "C" {
#if TRC_CFG_RTT_UP_BUFFER_INDEX == 0
#define TRC_RTT_ALLOC_UP() static char* _TzTraceData = NULL; /* Not actually used. Ignore allocation method. */
#define TRC_STREAM_PORT_MALLOC() /* Static allocation. Not used. */
#define TRC_ALLOC_CUSTOM_BUFFER(bufname) /* Only for custom allocation */
#else
#if TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_STATIC
#define TRC_RTT_ALLOC_UP() char _TzTraceData[TRC_CFG_RTT_BUFFER_SIZE_UP]; /* Static allocation */
#define TRC_STREAM_PORT_MALLOC() /* Static allocation. Not used. */
#define TRC_ALLOC_CUSTOM_BUFFER(bufname) /* Only for custom allocation */
#endif
#if TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC
#define TRC_RTT_ALLOC_UP() char* _TzTraceData = NULL; /* Dynamic allocation */
#define TRC_STREAM_PORT_MALLOC() _TzTraceData = TRC_PORT_MALLOC(TRC_CFG_RTT_BUFFER_SIZE_UP);
#define TRC_ALLOC_CUSTOM_BUFFER(bufname) /* Only for custom allocation */
#endif
#if TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM
#define TRC_RTT_ALLOC_UP() char* _TzTraceData = NULL; /* Custom allocation, user needs to call vTraceSetRecorderDataBuffer before vTraceEnable, to assign this */
#define TRC_STREAM_PORT_MALLOC() /* Not used in custom mode */
#define TRC_ALLOC_CUSTOM_BUFFER(bufname) char bufname [TRC_CFG_RTT_BUFFER_SIZE_UP]; /* Not static in this case, since declared in user code */
#endif
#endif
@ -170,20 +172,22 @@ extern "C" {
TRC_RTT_ALLOC_UP() /* Macro that will result in proper UP buffer allocation */ \
TRC_RTT_ALLOC_DOWN() /* Macro that will result in proper DOWN buffer allocation */
int32_t readFromRTT(void* ptrData, uint32_t size, int32_t* ptrBytesRead);
int32_t writeToRTT(void* ptrData, uint32_t size, int32_t* ptrBytesWritten);
#define TRC_STREAM_PORT_INIT() \
TRC_STREAM_PORT_MALLOC(); /*Dynamic allocation or empty if static */ \
SEGGER_RTT_ConfigUpBuffer(TRC_CFG_RTT_UP_BUFFER_INDEX, "TzData", _TzTraceData, TRC_CFG_RTT_BUFFER_SIZE_UP, TRC_CFG_RTT_MODE ); \
SEGGER_RTT_ConfigDownBuffer(TRC_CFG_RTT_DOWN_BUFFER_INDEX, "TzCtrl", _TzCtrlData, TRC_CFG_RTT_BUFFER_SIZE_DOWN, TRC_CFG_RTT_MODE);
#define TRC_STREAM_PORT_ALLOCATE_EVENT(_type, _ptrData, _size) _type _tmpArray[_size / sizeof(_type)]; _type* _ptrData = _tmpArray;
#define TRC_STREAM_PORT_ALLOCATE_DYNAMIC_EVENT(_type, _ptrData, _size) _type _tmpArray[sizeof(largestEventType) / sizeof(_type)]; _type* _ptrData = _tmpArray;
#define TRC_STREAM_PORT_COMMIT_EVENT(_ptrData, _size) SEGGER_RTT_Write(TRC_CFG_RTT_UP_BUFFER_INDEX, (const char*)_ptrData, _size);
#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) if (SEGGER_RTT_HASDATA(TRC_CFG_RTT_DOWN_BUFFER_INDEX)) *_ptrBytesRead = (int)SEGGER_RTT_Read(TRC_CFG_RTT_DOWN_BUFFER_INDEX, (char*)_ptrData, _size);
#define TRC_STREAM_PORT_PERIODIC_SEND_DATA(_ptrBytesSent)
/* Important for the J-Link port, in most other ports this can be skipped (default is 1) */
#define TRC_STREAM_PORT_USE_INTERNAL_BUFFER 0
#define TRC_STREAM_PORT_WRITE_DATA(_ptrData, _size, _ptrBytesWritten) writeToRTT(_ptrData, _size, _ptrBytesWritten)
#define TRC_STREAM_PORT_ON_TRACE_BEGIN() /* Do nothing */
#define TRC_STREAM_PORT_ON_TRACE_END() /* Do nothing */
#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) readFromRTT(_ptrData, _size, _ptrBytesRead)
#ifdef __cplusplus
}

View file

@ -0,0 +1,44 @@
#include "trcRecorder.h"
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
int32_t readFromRTT(void* ptrData, uint32_t size, int32_t* ptrBytesRead)
{
uint32_t bytesRead = 0;
if (SEGGER_RTT_HASDATA(TRC_CFG_RTT_DOWN_BUFFER_INDEX))
{
bytesRead = SEGGER_RTT_Read((TRC_CFG_RTT_DOWN_BUFFER_INDEX), (char*)ptrData, size);
if (ptrBytesRead != NULL)
*ptrBytesRead = (int32_t)bytesRead;
if (bytesRead != size)
{
return -1;
}
}
return 0;
}
int32_t writeToRTT(void* ptrData, uint32_t size, int32_t* ptrBytesWritten)
{
uint32_t bytesWritten = SEGGER_RTT_Write((TRC_CFG_RTT_UP_BUFFER_INDEX), (const char*)ptrData, size);
if (ptrBytesWritten != NULL)
*ptrBytesWritten = (int32_t)bytesWritten;
if (bytesWritten != size)
{
return -1;
}
return 0;
}
#endif
#endif

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v3.1.2
* Trace Recorder Library for Tracealyzer v4.1.1
* Percepio AB, www.percepio.com
*
* trcStreamingPort.h
@ -40,7 +40,7 @@
*
* Tabs are used for indent in this file (1 tab = 4 spaces)
*
* Copyright Percepio AB, 2017.
* Copyright Percepio AB, 2018.
* www.percepio.com
******************************************************************************/
@ -51,37 +51,13 @@
extern "C" {
#endif
/*******************************************************************************
* TRC_RECORDER_TRANSFER_METHOD_TCPIP
*
* This stream port for TCP/IP uses a temporary buffer consisting of multiple
* pages, that are transmitted periodically by the TzCtrl task. You can modify
* the supporting functions to match your system. See trcStreamingPort.c
******************************************************************************/
int32_t trcTcpWrite(void* data, uint32_t size, int32_t *ptrBytesWritten);
int32_t trcTcpRead(void* data, uint32_t size, int32_t *ptrBytesRead);
#if TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_STATIC
#define TRC_STREAM_PORT_ALLOCATE_FIELDS() static char _TzTraceData[TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT * TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE]; /* Static allocation. */
#define TRC_STREAM_PORT_MALLOC() /* Static allocation. Not used. */
#else
#define TRC_STREAM_PORT_ALLOCATE_FIELDS() static char* _TzTraceData = NULL; /* Dynamic allocation. */
#define TRC_STREAM_PORT_MALLOC() _TzTraceData = TRC_PORT_MALLOC(TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT * TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE);
#endif
int32_t trcTcpWrite(void* data, uint32_t size, int32_t *ptrBytesWritten);
#define TRC_STREAM_PORT_INIT() \
TRC_STREAM_PORT_MALLOC(); /*Dynamic allocation or empty if static */ \
prvPagedEventBufferInit(_TzTraceData);
#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) trcTcpRead(_ptrData, _size, _ptrBytesRead)
#define TRC_STREAM_PORT_ALLOCATE_EVENT(_type, _ptrData, _size) _type* _ptrData; _ptrData = (_type*)prvPagedEventBufferGetWritePointer(_size);
#define TRC_STREAM_PORT_ALLOCATE_DYNAMIC_EVENT(_type, _ptrData, _size) TRC_STREAM_PORT_ALLOCATE_EVENT(_type, _ptrData, _size) /* We do the same thing as for non-dynamic event sizes */
#define TRC_STREAM_PORT_COMMIT_EVENT(_ptrData, _size) /* Not needed since we write immediately into the buffer received above by TRC_STREAM_PORT_ALLOCATE_EVENT, and the TRC_STREAM_PORT_PERIODIC_SEND_DATA defined below will take care of the actual trace transfer. */
#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) trcTcpRead(_ptrData, _size, _ptrBytesRead);
#define TRC_STREAM_PORT_PERIODIC_SEND_DATA(_ptrBytesSent) prvPagedEventBufferTransfer(trcTcpWrite, _ptrBytesSent);
#define TRC_STREAM_PORT_ON_TRACE_BEGIN() prvPagedEventBufferInit(_TzTraceData);
#define TRC_STREAM_PORT_ON_TRACE_END() /* Do nothing */
#define TRC_STREAM_PORT_WRITE_DATA(_ptrData, _size, _ptrBytesSent) trcTcpWrite(_ptrData, _size, _ptrBytesSent)
#ifdef __cplusplus
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v3.1.2
* Trace Recorder Library for Tracealyzer v4.1.1
* Percepio AB, www.percepio.com
*
* trcStreamingPort.c
@ -41,7 +41,7 @@
*
* Tabs are used for indent in this file (1 tab = 4 spaces)
*
* Copyright Percepio AB, 2017.
* Copyright Percepio AB, 2018.
* www.percepio.com
******************************************************************************/
@ -50,7 +50,7 @@
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
/* TCP/IP includes */
/* TCP/IP includes - for lwIP in this case */
#include "lwip/tcpip.h"
#include "lwip/sockets.h"
@ -68,11 +68,14 @@ int32_t trcSocketSend( void* data, int32_t size, int32_t* bytesWritten )
if (new_sd < 0)
return -1;
if (bytesWritten == NULL)
return -1;
*bytesWritten = send( new_sd, data, size, 0 );
if (*bytesWritten < 0)
{
/* EWOULDBLOCK may be expected when buffers are full */
if (errno != EWOULDBLOCK)
if (errno != 0 && errno != EWOULDBLOCK)
{
closesocket(new_sd);
new_sd = -1;
@ -94,7 +97,7 @@ int32_t trcSocketReceive( void* data, int32_t size, int32_t* bytesRead )
if ( *bytesRead < 0 )
{
/* EWOULDBLOCK may be expected when there is no data to receive */
if (errno != EWOULDBLOCK)
if (errno != 0 && errno != EWOULDBLOCK)
{
closesocket(new_sd);
new_sd = -1;

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v3.1.2
* Trace Recorder Library for Tracealyzer v4.1.1
* Percepio AB, www.percepio.com
*
* trcStreamingPort.h
@ -40,7 +40,7 @@
*
* Tabs are used for indent in this file (1 tab = 4 spaces)
*
* Copyright Percepio AB, 2017.
* Copyright Percepio AB, 2018.
* www.percepio.com
******************************************************************************/
@ -51,16 +51,6 @@
extern "C" {
#endif
/*******************************************************************************
* Implement the below macros to define your own stream port. If your transfer
* method uses RTOS functions, you should not send the data directly but use
* the recorder's internal buffer to store the trace data, for later transfer by
* the TzCtrl task. Check the predefined stream ports for examples on how to use
* the internal buffer (e.g., TCP/IP, UART or USB CDC).
*
* Read more at http://percepio.com/2016/10/05/rtos-tracing/
******************************************************************************/
/* Include files as needed, in this case it is files from STM32Cube FW_F7 V1.4.1 */
#include "usb_device.h"
#include "usbd_cdc.h"
@ -70,32 +60,21 @@ extern "C" {
/* Tested on STM32 devices using Keil/CMSIS USB stack */
extern USBD_CDC_ItfTypeDef USBD_Interface_fops_FS;
uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len);
int32_t trcCDCReceive(void *data, uint32_t size, int32_t* NumBytes);
int32_t trcCDCTransmit(void* data, uint32_t size, int32_t * noOfBytesSent );
#if TRC_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_STATIC
#define TRC_STREAM_PORT_ALLOCATE_FIELDS() static char _TzTraceData[TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT * TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE]; /* Static allocation. */
#define TRC_STREAM_PORT_MALLOC() /* Static allocation. Not used. */
#else
#define TRC_STREAM_PORT_ALLOCATE_FIELDS() static char* _TzTraceData = NULL; /* Dynamic allocation. */
#define TRC_STREAM_PORT_MALLOC() _TzTraceData = TRC_PORT_MALLOC(TRC_PAGED_EVENT_BUFFER_PAGE_COUNT * TRC_PAGED_EVENT_BUFFER_PAGE_SIZE);
#endif
int32_t trcCDCTransmit(void* data, uint32_t size, int32_t * noOfBytesSent );
#define TRC_STREAM_PORT_INIT() \
MX_USB_DEVICE_Init(); \
TRC_STREAM_PORT_MALLOC(); /*Dynamic allocation or empty if static */
#define TRC_STREAM_PORT_ALLOCATE_EVENT(_type, _ptrData, _size) _type* _ptrData; _ptrData = (_type*)prvPagedEventBufferGetWritePointer(_size);
#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) trcCDCReceive(_ptrData, _size, _ptrBytesRead)
#define TRC_STREAM_PORT_ALLOCATE_DYNAMIC_EVENT(_type, _ptrData, _size) TRC_STREAM_PORT_ALLOCATE_EVENT(_type, _ptrData, _size) /* We do the same thing as for non-dynamic event sizes */
#define TRC_STREAM_PORT_COMMIT_EVENT(_ptrData, _size) /* Not needed since we write immediately into the buffer received above by TRC_STREAM_PORT_ALLOCATE_EVENT, and the TRC_STREAM_PORT_PERIODIC_SEND_DATA defined below will take care of the actual trace transfer. */
#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) trcCDCReceive(_ptrData, _size, _ptrBytesRead);
#define TRC_STREAM_PORT_PERIODIC_SEND_DATA(_ptrBytesSent) prvPagedEventBufferTransfer(trcCDCTransmit, _ptrBytesSent);
#define TRC_STREAM_PORT_WRITE_DATA(_ptrData, _size, _ptrBytesSent) trcCDCTransmit(_ptrData, _size, _ptrBytesSent)
#define TRC_STREAM_PORT_ON_TRACE_BEGIN() { prvPagedEventBufferInit(_TzTraceData); }
#define TRC_STREAM_PORT_ON_TRACE_END() /* Do nothing */
#ifdef __cplusplus
}

View file

@ -1,7 +1,8 @@
#include "trcRecorder.h"
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#include "stdint.h"
@ -29,8 +30,8 @@ uint8_t UserRxBufferFS[APP_RX_DATA_SIZE];
uint8_t UserTxBufferFS[APP_TX_DATA_SIZE];
extern USBD_HandleTypeDef hUsbDeviceFS;
extern PCD_HandleTypeDef hpcd_USB_OTG_FS;
extern PCD_HandleTypeDef hpcd_USB_OTG_FS;
recBuf commandBuffer;
@ -186,6 +187,7 @@ uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
return result;
}
/* The READ function, used in trcStreamingPort.h */
int32_t trcCDCReceive(void *data, uint32_t size, int32_t* NumBytes)
{
uint32_t i,diff;
@ -217,13 +219,18 @@ int32_t trcCDCReceive(void *data, uint32_t size, int32_t* NumBytes)
return 0;
}
/* The WRITE function, used in trcStreamingPort.h */
int32_t trcCDCTransmit(void* data, uint32_t size, int32_t * noOfBytesSent )
{
int32_t result;
result=CDC_Transmit_FS(data,size);
*noOfBytesSent=size;
return result;
result=CDC_Transmit_FS(data, size);
*noOfBytesSent = size;
/* Return value should be 0 on success (not sure what the value of USBD_OK is) */
if (result == USBD_OK)
return 0;
else
return -1;
}
/**