mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-20 05:21:59 -04:00
Update trace recorder code.
Add TCP Echo server to the FreeR_Plus_TCP_Minimal_Window_Simulator project.
This commit is contained in:
parent
f7fc215247
commit
d525d5092d
|
@ -0,0 +1,288 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FreeRTOS tasks are used with FreeRTOS+TCP to create a TCP echo server on the
|
||||||
|
* standard echo port number (7).
|
||||||
|
*
|
||||||
|
* See the following web page for essential demo usage and configuration
|
||||||
|
* details:
|
||||||
|
* http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_Echo_Server.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/* FreeRTOS includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "semphr.h"
|
||||||
|
|
||||||
|
/* FreeRTOS+TCP includes. */
|
||||||
|
#include "FreeRTOS_IP.h"
|
||||||
|
#include "FreeRTOS_Sockets.h"
|
||||||
|
|
||||||
|
/* Remove the whole file if FreeRTOSIPConfig.h is set to exclude TCP. */
|
||||||
|
#if( ipconfigUSE_TCP == 1 )
|
||||||
|
|
||||||
|
/* The maximum time to wait for a closing socket to close. */
|
||||||
|
#define tcpechoSHUTDOWN_DELAY ( pdMS_TO_TICKS( 5000 ) )
|
||||||
|
|
||||||
|
/* The standard echo port number. */
|
||||||
|
#define tcpechoPORT_NUMBER 7
|
||||||
|
|
||||||
|
/* If ipconfigUSE_TCP_WIN is 1 then the Tx sockets will use a buffer size set by
|
||||||
|
ipconfigTCP_TX_BUFFER_LENGTH, and the Tx window size will be
|
||||||
|
configECHO_SERVER_TX_WINDOW_SIZE times the buffer size. Note
|
||||||
|
ipconfigTCP_TX_BUFFER_LENGTH is set in FreeRTOSIPConfig.h as it is a standard TCP/IP
|
||||||
|
stack constant, whereas configECHO_SERVER_TX_WINDOW_SIZE is set in
|
||||||
|
FreeRTOSConfig.h as it is a demo application constant. */
|
||||||
|
#ifndef configECHO_SERVER_TX_WINDOW_SIZE
|
||||||
|
#define configECHO_SERVER_TX_WINDOW_SIZE 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If ipconfigUSE_TCP_WIN is 1 then the Rx sockets will use a buffer size set by
|
||||||
|
ipconfigTCP_RX_BUFFER_LENGTH, and the Rx window size will be
|
||||||
|
configECHO_SERVER_RX_WINDOW_SIZE times the buffer size. Note
|
||||||
|
ipconfigTCP_RX_BUFFER_LENGTH is set in FreeRTOSIPConfig.h as it is a standard TCP/IP
|
||||||
|
stack constant, whereas configECHO_SERVER_RX_WINDOW_SIZE is set in
|
||||||
|
FreeRTOSConfig.h as it is a demo application constant. */
|
||||||
|
#ifndef configECHO_SERVER_RX_WINDOW_SIZE
|
||||||
|
#define configECHO_SERVER_RX_WINDOW_SIZE 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Uses FreeRTOS+TCP to listen for incoming echo connections, creating a task
|
||||||
|
* to handle each connection.
|
||||||
|
*/
|
||||||
|
static void prvConnectionListeningTask( void *pvParameters );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Created by the connection listening task to handle a single connection.
|
||||||
|
*/
|
||||||
|
static void prvServerConnectionInstance( void *pvParameters );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Stores the stack size passed into vStartSimpleTCPServerTasks() so it can be
|
||||||
|
reused when the server listening task creates tasks to handle connections. */
|
||||||
|
static uint16_t usUsedStackSize = 0;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartSimpleTCPServerTasks( uint16_t usStackSize, UBaseType_t uxPriority )
|
||||||
|
{
|
||||||
|
/* Create the TCP echo server. */
|
||||||
|
xTaskCreate( prvConnectionListeningTask, "ServerListener", usStackSize, NULL, uxPriority + 1, NULL );
|
||||||
|
|
||||||
|
/* Remember the requested stack size so it can be re-used by the server
|
||||||
|
listening task when it creates tasks to handle connections. */
|
||||||
|
usUsedStackSize = usStackSize;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvConnectionListeningTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
struct freertos_sockaddr xClient, xBindAddress;
|
||||||
|
Socket_t xListeningSocket, xConnectedSocket;
|
||||||
|
socklen_t xSize = sizeof( xClient );
|
||||||
|
static const TickType_t xReceiveTimeOut = portMAX_DELAY;
|
||||||
|
const BaseType_t xBacklog = 20;
|
||||||
|
|
||||||
|
#if( ipconfigUSE_TCP_WIN == 1 )
|
||||||
|
WinProperties_t xWinProps;
|
||||||
|
|
||||||
|
/* Fill in the buffer and window sizes that will be used by the socket. */
|
||||||
|
xWinProps.lTxBufSize = ipconfigTCP_TX_BUFFER_LENGTH;
|
||||||
|
xWinProps.lTxWinSize = configECHO_SERVER_TX_WINDOW_SIZE;
|
||||||
|
xWinProps.lRxBufSize = ipconfigTCP_RX_BUFFER_LENGTH;
|
||||||
|
xWinProps.lRxWinSize = configECHO_SERVER_RX_WINDOW_SIZE;
|
||||||
|
#endif /* ipconfigUSE_TCP_WIN */
|
||||||
|
|
||||||
|
/* Just to prevent compiler warnings. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
/* Attempt to open the socket. */
|
||||||
|
xListeningSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP );
|
||||||
|
configASSERT( xListeningSocket != FREERTOS_INVALID_SOCKET );
|
||||||
|
|
||||||
|
/* Set a time out so accept() will just wait for a connection. */
|
||||||
|
FreeRTOS_setsockopt( xListeningSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) );
|
||||||
|
|
||||||
|
/* Set the window and buffer sizes. */
|
||||||
|
#if( ipconfigUSE_TCP_WIN == 1 )
|
||||||
|
{
|
||||||
|
FreeRTOS_setsockopt( xListeningSocket, 0, FREERTOS_SO_WIN_PROPERTIES, ( void * ) &xWinProps, sizeof( xWinProps ) );
|
||||||
|
}
|
||||||
|
#endif /* ipconfigUSE_TCP_WIN */
|
||||||
|
|
||||||
|
/* Bind the socket to the port that the client task will send to, then
|
||||||
|
listen for incoming connections. */
|
||||||
|
xBindAddress.sin_port = tcpechoPORT_NUMBER;
|
||||||
|
xBindAddress.sin_port = FreeRTOS_htons( xBindAddress.sin_port );
|
||||||
|
FreeRTOS_bind( xListeningSocket, &xBindAddress, sizeof( xBindAddress ) );
|
||||||
|
FreeRTOS_listen( xListeningSocket, xBacklog );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Wait for a client to connect. */
|
||||||
|
xConnectedSocket = FreeRTOS_accept( xListeningSocket, &xClient, &xSize );
|
||||||
|
configASSERT( xConnectedSocket != FREERTOS_INVALID_SOCKET );
|
||||||
|
|
||||||
|
/* Spawn a task to handle the connection. */
|
||||||
|
xTaskCreate( prvServerConnectionInstance, "EchoServer", usUsedStackSize, ( void * ) xConnectedSocket, tskIDLE_PRIORITY, NULL );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvServerConnectionInstance( void *pvParameters )
|
||||||
|
{
|
||||||
|
int32_t lBytes, lSent, lTotalSent;
|
||||||
|
Socket_t xConnectedSocket;
|
||||||
|
static const TickType_t xReceiveTimeOut = pdMS_TO_TICKS( 5000 );
|
||||||
|
static const TickType_t xSendTimeOut = pdMS_TO_TICKS( 5000 );
|
||||||
|
TickType_t xTimeOnShutdown;
|
||||||
|
uint8_t *pucRxBuffer;
|
||||||
|
|
||||||
|
xConnectedSocket = ( Socket_t ) pvParameters;
|
||||||
|
|
||||||
|
/* Attempt to create the buffer used to receive the string to be echoed
|
||||||
|
back. This could be avoided using a zero copy interface that just returned
|
||||||
|
the same buffer. */
|
||||||
|
pucRxBuffer = ( uint8_t * ) pvPortMalloc( ipconfigTCP_MSS );
|
||||||
|
|
||||||
|
if( pucRxBuffer != NULL )
|
||||||
|
{
|
||||||
|
FreeRTOS_setsockopt( xConnectedSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) );
|
||||||
|
FreeRTOS_setsockopt( xConnectedSocket, 0, FREERTOS_SO_SNDTIMEO, &xSendTimeOut, sizeof( xReceiveTimeOut ) );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Zero out the receive array so there is NULL at the end of the string
|
||||||
|
when it is printed out. */
|
||||||
|
memset( pucRxBuffer, 0x00, ipconfigTCP_MSS );
|
||||||
|
|
||||||
|
/* Receive data on the socket. */
|
||||||
|
lBytes = FreeRTOS_recv( xConnectedSocket, pucRxBuffer, ipconfigTCP_MSS, 0 );
|
||||||
|
|
||||||
|
/* If data was received, echo it back. */
|
||||||
|
if( lBytes >= 0 )
|
||||||
|
{
|
||||||
|
lSent = 0;
|
||||||
|
lTotalSent = 0;
|
||||||
|
|
||||||
|
/* Call send() until all the data has been sent. */
|
||||||
|
while( ( lSent >= 0 ) && ( lTotalSent < lBytes ) )
|
||||||
|
{
|
||||||
|
lSent = FreeRTOS_send( xConnectedSocket, pucRxBuffer, lBytes - lTotalSent, 0 );
|
||||||
|
lTotalSent += lSent;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( lSent < 0 )
|
||||||
|
{
|
||||||
|
/* Socket closed? */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Socket closed? */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initiate a shutdown in case it has not already been initiated. */
|
||||||
|
FreeRTOS_shutdown( xConnectedSocket, FREERTOS_SHUT_RDWR );
|
||||||
|
|
||||||
|
/* Wait for the shutdown to take effect, indicated by FreeRTOS_recv()
|
||||||
|
returning an error. */
|
||||||
|
xTimeOnShutdown = xTaskGetTickCount();
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if( FreeRTOS_recv( xConnectedSocket, pucRxBuffer, ipconfigTCP_MSS, 0 ) < 0 )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while( ( xTaskGetTickCount() - xTimeOnShutdown ) < tcpechoSHUTDOWN_DELAY );
|
||||||
|
|
||||||
|
/* Finished with the socket, buffer, the task. */
|
||||||
|
vPortFree( pucRxBuffer );
|
||||||
|
FreeRTOS_closesocket( xConnectedSocket );
|
||||||
|
|
||||||
|
vTaskDelete( NULL );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* The whole file is excluded if TCP is not compiled in. */
|
||||||
|
#endif /* ipconfigUSE_TCP */
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SIMPLE_TCP_ECHO_SERVER_H
|
||||||
|
#define SIMPLE_TCP_ECHO_SERVER_H
|
||||||
|
|
||||||
|
void vStartSimpleTCPServerTasks( uint16_t usStackSize, BaseType_t uxPriority );
|
||||||
|
BaseType_t xAreTCPEchoServersStillRunning( void );
|
||||||
|
|
||||||
|
#endif /* SIMPLE_TCP_ECHO_SERVER_H */
|
|
@ -174,16 +174,16 @@ configure the real network connection to use. */
|
||||||
|
|
||||||
/* Default IP address configuration. Used in ipconfigUSE_DNS is set to 0, or
|
/* Default IP address configuration. Used in ipconfigUSE_DNS is set to 0, or
|
||||||
ipconfigUSE_DNS is set to 1 but a DNS server cannot be contacted. */
|
ipconfigUSE_DNS is set to 1 but a DNS server cannot be contacted. */
|
||||||
#define configIP_ADDR0 172
|
#define configIP_ADDR0 10
|
||||||
#define configIP_ADDR1 25
|
#define configIP_ADDR1 10
|
||||||
#define configIP_ADDR2 218
|
#define configIP_ADDR2 10
|
||||||
#define configIP_ADDR3 200
|
#define configIP_ADDR3 200
|
||||||
|
|
||||||
/* Default gateway IP address configuration. Used in ipconfigUSE_DNS is set to
|
/* Default gateway IP address configuration. Used in ipconfigUSE_DNS is set to
|
||||||
0, or ipconfigUSE_DNS is set to 1 but a DNS server cannot be contacted. */
|
0, or ipconfigUSE_DNS is set to 1 but a DNS server cannot be contacted. */
|
||||||
#define configGATEWAY_ADDR0 172
|
#define configGATEWAY_ADDR0 10
|
||||||
#define configGATEWAY_ADDR1 25
|
#define configGATEWAY_ADDR1 10
|
||||||
#define configGATEWAY_ADDR2 218
|
#define configGATEWAY_ADDR2 10
|
||||||
#define configGATEWAY_ADDR3 1
|
#define configGATEWAY_ADDR3 1
|
||||||
|
|
||||||
/* Default DNS server configuration. OpenDNS addresses are 208.67.222.222 and
|
/* Default DNS server configuration. OpenDNS addresses are 208.67.222.222 and
|
||||||
|
@ -197,7 +197,7 @@ to 1 but a DNS server cannot be contacted.*/
|
||||||
/* Default netmask configuration. Used in ipconfigUSE_DNS is set to 0, or
|
/* Default netmask configuration. Used in ipconfigUSE_DNS is set to 0, or
|
||||||
ipconfigUSE_DNS is set to 1 but a DNS server cannot be contacted. */
|
ipconfigUSE_DNS is set to 1 but a DNS server cannot be contacted. */
|
||||||
#define configNET_MASK0 255
|
#define configNET_MASK0 255
|
||||||
#define configNET_MASK1 255
|
#define configNET_MASK1 0
|
||||||
#define configNET_MASK2 0
|
#define configNET_MASK2 0
|
||||||
#define configNET_MASK3 0
|
#define configNET_MASK3 0
|
||||||
|
|
||||||
|
|
|
@ -154,6 +154,7 @@
|
||||||
<ClCompile Include="..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_UDP_IP.c" />
|
<ClCompile Include="..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_UDP_IP.c" />
|
||||||
<ClCompile Include="..\..\Source\FreeRTOS-Plus-TCP\portable\BufferManagement\BufferAllocation_2.c" />
|
<ClCompile Include="..\..\Source\FreeRTOS-Plus-TCP\portable\BufferManagement\BufferAllocation_2.c" />
|
||||||
<ClCompile Include="..\..\Source\FreeRTOS-Plus-TCP\portable\NetworkInterface\WinPCap\NetworkInterface.c" />
|
<ClCompile Include="..\..\Source\FreeRTOS-Plus-TCP\portable\NetworkInterface\WinPCap\NetworkInterface.c" />
|
||||||
|
<ClCompile Include="DemoTasks\SimpleTCPEchoServer.c" />
|
||||||
<ClCompile Include="DemoTasks\TCPEchoClient_SingleTasks.c" />
|
<ClCompile Include="DemoTasks\TCPEchoClient_SingleTasks.c" />
|
||||||
<ClCompile Include="DemoTasks\SimpleUDPClientAndServer.c" />
|
<ClCompile Include="DemoTasks\SimpleUDPClientAndServer.c" />
|
||||||
<ClCompile Include="demo_logging.c" />
|
<ClCompile Include="demo_logging.c" />
|
||||||
|
|
|
@ -97,6 +97,9 @@
|
||||||
<Filter>FreeRTOS+\FreeRTOS+TCP</Filter>
|
<Filter>FreeRTOS+\FreeRTOS+TCP</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="demo_logging.c" />
|
<ClCompile Include="demo_logging.c" />
|
||||||
|
<ClCompile Include="DemoTasks\SimpleTCPEchoServer.c">
|
||||||
|
<Filter>DemoTasks</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\Source\FreeRTOS-Plus-TCP\include\NetworkInterface.h">
|
<ClInclude Include="..\..\Source\FreeRTOS-Plus-TCP\include\NetworkInterface.h">
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#include "FreeRTOS_IP.h"
|
#include "FreeRTOS_IP.h"
|
||||||
#include "FreeRTOS_Sockets.h"
|
#include "FreeRTOS_Sockets.h"
|
||||||
#include "SimpleUDPClientAndServer.h"
|
#include "SimpleUDPClientAndServer.h"
|
||||||
|
#include "SimpleTCPEchoServer.h"
|
||||||
#include "TCPEchoClient_SingleTasks.h"
|
#include "TCPEchoClient_SingleTasks.h"
|
||||||
#include "demo_logging.h"
|
#include "demo_logging.h"
|
||||||
|
|
||||||
|
@ -55,6 +56,10 @@
|
||||||
#define mainECHO_CLIENT_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2 ) /* Not used in the Windows port. */
|
#define mainECHO_CLIENT_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2 ) /* Not used in the Windows port. */
|
||||||
#define mainECHO_CLIENT_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
|
#define mainECHO_CLIENT_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
|
||||||
|
|
||||||
|
/* Echo server task parameters. */
|
||||||
|
#define mainECHO_SERVER_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2 ) /* Not used in the Windows port. */
|
||||||
|
#define mainECHO_SERVER_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
|
||||||
|
|
||||||
/* Define a name that will be used for LLMNR and NBNS searches. */
|
/* Define a name that will be used for LLMNR and NBNS searches. */
|
||||||
#define mainHOST_NAME "RTOSDemo"
|
#define mainHOST_NAME "RTOSDemo"
|
||||||
#define mainDEVICE_NICK_NAME "windows_demo"
|
#define mainDEVICE_NICK_NAME "windows_demo"
|
||||||
|
@ -77,10 +82,14 @@ verify the echo reply, from within the same task (Tx and Rx are performed in the
|
||||||
same RTOS task). The IP address of the echo server must be configured using the
|
same RTOS task). The IP address of the echo server must be configured using the
|
||||||
configECHO_SERVER_ADDR0 to configECHO_SERVER_ADDR3 constants in
|
configECHO_SERVER_ADDR0 to configECHO_SERVER_ADDR3 constants in
|
||||||
FreeRTOSConfig.h.
|
FreeRTOSConfig.h.
|
||||||
|
|
||||||
|
mainCREATE_TCP_ECHO_SERVER_TASK: When set to 1 a task is created that accepts
|
||||||
|
connections on the standard echo port (port 7), then echos back any data
|
||||||
|
received on that connection.
|
||||||
*/
|
*/
|
||||||
#define mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS 1
|
#define mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS 1
|
||||||
#define mainCREATE_TCP_ECHO_TASKS_SINGLE 1
|
#define mainCREATE_TCP_ECHO_TASKS_SINGLE 1
|
||||||
|
#define mainCREATE_TCP_ECHO_SERVER_TASK 0
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -231,6 +240,12 @@ static BaseType_t xTasksAlreadyCreated = pdFALSE;
|
||||||
}
|
}
|
||||||
#endif /* mainCREATE_TCP_ECHO_TASKS_SINGLE */
|
#endif /* mainCREATE_TCP_ECHO_TASKS_SINGLE */
|
||||||
|
|
||||||
|
#if( mainCREATE_TCP_ECHO_SERVER_TASK == 1 )
|
||||||
|
{
|
||||||
|
vStartSimpleTCPServerTasks( mainECHO_SERVER_TASK_STACK_SIZE, mainECHO_SERVER_TASK_PRIORITY );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
xTasksAlreadyCreated = pdTRUE;
|
xTasksAlreadyCreated = pdTRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS+TCP V2.0.1
|
* FreeRTOS+TCP V2.0.3
|
||||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
@ -19,10 +19,8 @@
|
||||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* http://www.FreeRTOS.org
|
|
||||||
* http://aws.amazon.com/freertos
|
* http://aws.amazon.com/freertos
|
||||||
*
|
* http://www.FreeRTOS.org
|
||||||
* 1 tab == 4 spaces!
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Standard includes. */
|
/* Standard includes. */
|
||||||
|
@ -597,15 +595,19 @@ static void prvInitialiseDHCP( void )
|
||||||
xDHCPData.ulTransactionId++;
|
xDHCPData.ulTransactionId++;
|
||||||
}
|
}
|
||||||
|
|
||||||
xDHCPData.xUseBroadcast = 0;
|
/* Check for random number generator API failure. */
|
||||||
xDHCPData.ulOfferedIPAddress = 0UL;
|
if( 0 != xDHCPData.ulTransactionId )
|
||||||
xDHCPData.ulDHCPServerAddress = 0UL;
|
{
|
||||||
xDHCPData.xDHCPTxPeriod = dhcpINITIAL_DHCP_TX_PERIOD;
|
xDHCPData.xUseBroadcast = 0;
|
||||||
|
xDHCPData.ulOfferedIPAddress = 0UL;
|
||||||
|
xDHCPData.ulDHCPServerAddress = 0UL;
|
||||||
|
xDHCPData.xDHCPTxPeriod = dhcpINITIAL_DHCP_TX_PERIOD;
|
||||||
|
|
||||||
/* Create the DHCP socket if it has not already been created. */
|
/* Create the DHCP socket if it has not already been created. */
|
||||||
prvCreateDHCPSocket();
|
prvCreateDHCPSocket();
|
||||||
FreeRTOS_debug_printf( ( "prvInitialiseDHCP: start after %lu ticks\n", dhcpINITIAL_TIMER_PERIOD ) );
|
FreeRTOS_debug_printf( ( "prvInitialiseDHCP: start after %lu ticks\n", dhcpINITIAL_TIMER_PERIOD ) );
|
||||||
vIPReloadDHCPTimer( dhcpINITIAL_TIMER_PERIOD );
|
vIPReloadDHCPTimer( dhcpINITIAL_TIMER_PERIOD );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -675,18 +677,17 @@ const uint32_t ulMandatoryOptions = 2ul; /* DHCP server address, and the correct
|
||||||
state machine is expecting. */
|
state machine is expecting. */
|
||||||
ulProcessed++;
|
ulProcessed++;
|
||||||
}
|
}
|
||||||
|
else if( *pucByte == ( uint8_t ) dhcpMESSAGE_TYPE_NACK )
|
||||||
|
{
|
||||||
|
if( xExpectedMessageType == ( BaseType_t ) dhcpMESSAGE_TYPE_ACK )
|
||||||
|
{
|
||||||
|
/* Start again. */
|
||||||
|
xDHCPData.eDHCPState = eWaitingSendFirstDiscover;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( *pucByte == ( uint8_t ) dhcpMESSAGE_TYPE_NACK )
|
/* Don't process other message types. */
|
||||||
{
|
|
||||||
if( xExpectedMessageType == ( BaseType_t ) dhcpMESSAGE_TYPE_ACK )
|
|
||||||
{
|
|
||||||
/* Start again. */
|
|
||||||
xDHCPData.eDHCPState = eWaitingSendFirstDiscover;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Stop processing further options. */
|
|
||||||
ucLength = 0;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -292,7 +292,7 @@ void vListInsertGeneric( List_t * const pxList, ListItem_t * const pxNewListItem
|
||||||
pxWhere->pxPrevious = pxNewListItem;
|
pxWhere->pxPrevious = pxNewListItem;
|
||||||
|
|
||||||
/* Remember which list the item is in. */
|
/* Remember which list the item is in. */
|
||||||
pxNewListItem->pvContainer = ( void * ) pxList;
|
pxNewListItem->pxContainer = pxList;
|
||||||
|
|
||||||
( pxList->uxNumberOfItems )++;
|
( pxList->uxNumberOfItems )++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -510,7 +510,7 @@ from the FreeRTOSIPConfig.h configuration header file. */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ipconfigTCP_KEEP_ALIVE
|
#ifndef ipconfigTCP_KEEP_ALIVE
|
||||||
#define ipconfigTCP_KEEP_ALIVE 0
|
#define ipconfigTCP_KEEP_ALIVE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ipconfigDNS_USE_CALLBACKS
|
#ifndef ipconfigDNS_USE_CALLBACKS
|
||||||
|
@ -526,7 +526,7 @@ from the FreeRTOSIPConfig.h configuration header file. */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ipconfigTCP_HANG_PROTECTION
|
#ifndef ipconfigTCP_HANG_PROTECTION
|
||||||
#define ipconfigTCP_HANG_PROTECTION 0
|
#define ipconfigTCP_HANG_PROTECTION 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ipconfigTCP_IP_SANITY
|
#ifndef ipconfigTCP_IP_SANITY
|
||||||
|
|
|
@ -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
|
* Percepio AB, www.percepio.com
|
||||||
*
|
*
|
||||||
* trcHardwarePort.h
|
* trcHardwarePort.h
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
*
|
*
|
||||||
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
||||||
*
|
*
|
||||||
* Copyright Percepio AB, 2017.
|
* Copyright Percepio AB, 2018.
|
||||||
* www.percepio.com
|
* www.percepio.com
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
@ -344,7 +344,22 @@
|
||||||
#define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD)
|
#define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD)
|
||||||
#define TRC_IRQ_PRIORITY_ORDER 0
|
#define TRC_IRQ_PRIORITY_ORDER 0
|
||||||
|
|
||||||
|
#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Altera_NiosII)
|
||||||
|
|
||||||
|
/* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
|
||||||
|
|
||||||
|
#include "system.h"
|
||||||
|
#include "sys/alt_timestamp.h"
|
||||||
|
|
||||||
|
#define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
|
||||||
|
#define TRC_HWTC_COUNT (uint32_t)alt_timestamp()
|
||||||
|
#define TRC_HWTC_PERIOD 0xFFFFFFFF
|
||||||
|
#define TRC_HWTC_FREQ_HZ TIMESTAMP_TIMER_FREQ
|
||||||
|
#define TRC_HWTC_DIVISOR 1
|
||||||
|
#define TRC_IRQ_PRIORITY_ORDER 0
|
||||||
|
|
||||||
#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_CORTEX_A9)
|
#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_CORTEX_A9)
|
||||||
|
|
||||||
/* INPUT YOUR PERIPHERAL BASE ADDRESS HERE */
|
/* INPUT YOUR PERIPHERAL BASE ADDRESS HERE */
|
||||||
#define TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS 0xSOMETHING
|
#define TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS 0xSOMETHING
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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
|
* Percepio AB, www.percepio.com
|
||||||
*
|
*
|
||||||
* trcPortDefines.h
|
* trcPortDefines.h
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
*
|
*
|
||||||
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
||||||
*
|
*
|
||||||
* Copyright Percepio AB, 2017.
|
* Copyright Percepio AB, 2018.
|
||||||
* www.percepio.com
|
* www.percepio.com
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
@ -70,6 +70,23 @@
|
||||||
#define TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC (0x01)
|
#define TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC (0x01)
|
||||||
#define TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM (0x02)
|
#define TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM (0x02)
|
||||||
|
|
||||||
|
/* Filter Groups */
|
||||||
|
#define FilterGroup0 (uint16_t)0x0001
|
||||||
|
#define FilterGroup1 (uint16_t)0x0002
|
||||||
|
#define FilterGroup2 (uint16_t)0x0004
|
||||||
|
#define FilterGroup3 (uint16_t)0x0008
|
||||||
|
#define FilterGroup4 (uint16_t)0x0010
|
||||||
|
#define FilterGroup5 (uint16_t)0x0020
|
||||||
|
#define FilterGroup6 (uint16_t)0x0040
|
||||||
|
#define FilterGroup7 (uint16_t)0x0080
|
||||||
|
#define FilterGroup8 (uint16_t)0x0100
|
||||||
|
#define FilterGroup9 (uint16_t)0x0200
|
||||||
|
#define FilterGroup10 (uint16_t)0x0400
|
||||||
|
#define FilterGroup11 (uint16_t)0x0800
|
||||||
|
#define FilterGroup12 (uint16_t)0x1000
|
||||||
|
#define FilterGroup13 (uint16_t)0x2000
|
||||||
|
#define FilterGroup14 (uint16_t)0x4000
|
||||||
|
#define FilterGroup15 (uint16_t)0x8000
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Supported ports
|
* Supported ports
|
||||||
|
@ -116,5 +133,5 @@
|
||||||
#define TRC_HARDWARE_PORT_NXP_LPC210X 14 /* No Any */
|
#define TRC_HARDWARE_PORT_NXP_LPC210X 14 /* No Any */
|
||||||
#define TRC_HARDWARE_PORT_ARM_CORTEX_A9 15 /* Yes Any */
|
#define TRC_HARDWARE_PORT_ARM_CORTEX_A9 15 /* Yes Any */
|
||||||
#define TRC_HARDWARE_PORT_POWERPC_Z4 16 /* No FreeRTOS */
|
#define TRC_HARDWARE_PORT_POWERPC_Z4 16 /* No FreeRTOS */
|
||||||
|
#define TRC_HARDWARE_PORT_Altera_NiosII 17 /* No Any */
|
||||||
#endif /*TRC_PORTDEFINES_H*/
|
#endif /*TRC_PORTDEFINES_H*/
|
||||||
|
|
|
@ -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
|
* Percepio AB, www.percepio.com
|
||||||
*
|
*
|
||||||
* trcRecorder.h
|
* trcRecorder.h
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
*
|
*
|
||||||
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
||||||
*
|
*
|
||||||
* Copyright Percepio AB, 2017.
|
* Copyright Percepio AB, 2018.
|
||||||
* www.percepio.com
|
* www.percepio.com
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
@ -51,11 +51,11 @@ extern "C" {
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include "trcConfig.h"
|
#include "trcConfig.h"
|
||||||
#include "trcPortDefines.h"
|
#include "trcPortDefines.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)
|
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)
|
||||||
typedef uint16_t traceString;
|
typedef uint16_t traceString;
|
||||||
typedef uint8_t traceUBChannel;
|
typedef uint8_t traceUBChannel;
|
||||||
|
@ -85,6 +85,11 @@ typedef const void* traceHandle;
|
||||||
|
|
||||||
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
|
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
|
||||||
|
|
||||||
|
#define TRACE_GET_LOW16(value) ((uint16_t)((value) & 0x0000FFFF))
|
||||||
|
#define TRACE_GET_HIGH16(value) ((uint16_t)(((value) >> 16) & 0x0000FFFF))
|
||||||
|
#define TRACE_SET_LOW16(current, value) (((current) & 0xFFFF0000) | (value))
|
||||||
|
#define TRACE_SET_HIGH16(current, value) (((current) & 0x0000FFFF) | (((uint32_t)(value)) << 16))
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/*** Common API - both Snapshot and Streaming mode ****************************/
|
/*** Common API - both Snapshot and Streaming mode ****************************/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -208,11 +213,14 @@ void vTraceEnable(int startOption);
|
||||||
* In snapshot mode you are limited to maximum 15 arguments, that must not exceed
|
* In snapshot mode you are limited to maximum 15 arguments, that must not exceed
|
||||||
* 32 bytes in total (not counting the format string). If exceeded, the recorder
|
* 32 bytes in total (not counting the format string). If exceeded, the recorder
|
||||||
* logs an internal error (displayed when opening the trace) and stops recording.
|
* logs an internal error (displayed when opening the trace) and stops recording.
|
||||||
*
|
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
#if (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)
|
||||||
void vTracePrintF(traceString chn, const char* fmt, ...);
|
void vTracePrintF(traceString chn, const char* fmt, ...);
|
||||||
|
#else
|
||||||
|
#define vTracePrintF(chn, ...) (void)chn
|
||||||
|
#endif
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* vTracePrint
|
* vTracePrint
|
||||||
*
|
*
|
||||||
* A faster version of vTracePrintF, that only allows for logging a string.
|
* A faster version of vTracePrintF, that only allows for logging a string.
|
||||||
|
@ -222,9 +230,12 @@ void vTracePrintF(traceString chn, const char* fmt, ...);
|
||||||
* traceString chn = xTraceRegisterString("MyChannel");
|
* traceString chn = xTraceRegisterString("MyChannel");
|
||||||
* ...
|
* ...
|
||||||
* vTracePrint(chn, "Hello World!");
|
* vTracePrint(chn, "Hello World!");
|
||||||
*
|
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
#if (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)
|
||||||
void vTracePrint(traceString chn, const char* str);
|
void vTracePrint(traceString chn, const char* str);
|
||||||
|
#else
|
||||||
|
#define vTracePrint(chn, ...) (void)chn
|
||||||
|
#endif
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* xTraceRegisterString
|
* xTraceRegisterString
|
||||||
|
@ -235,9 +246,12 @@ void vTracePrint(traceString chn, const char* str);
|
||||||
* myEventHandle = xTraceRegisterString("MyUserEvent");
|
* myEventHandle = xTraceRegisterString("MyUserEvent");
|
||||||
* ...
|
* ...
|
||||||
* vTracePrintF(myEventHandle, "My value is: %d", myValue);
|
* vTracePrintF(myEventHandle, "My value is: %d", myValue);
|
||||||
*
|
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
#if (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)
|
||||||
traceString xTraceRegisterString(const char* name);
|
traceString xTraceRegisterString(const char* name);
|
||||||
|
#else
|
||||||
|
#define xTraceRegisterString(x) (x)
|
||||||
|
#endif
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* vTraceSet...Name(void* object, const char* name)
|
* vTraceSet...Name(void* object, const char* name)
|
||||||
|
@ -247,18 +261,8 @@ traceString xTraceRegisterString(const char* name);
|
||||||
*
|
*
|
||||||
* Kernel-specific functions for setting names of kernel objects, for display in
|
* Kernel-specific functions for setting names of kernel objects, for display in
|
||||||
* Tracealyzer.
|
* Tracealyzer.
|
||||||
*
|
|
||||||
* See trcKernelPort.h for details (since kernel-specific)
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* vTraceExclude...
|
|
||||||
*
|
|
||||||
* Kernel-specific macros for excluding specified events from the trace. Allows
|
|
||||||
* for capturing longer traces in snapshot mode by selective tracing.
|
|
||||||
*
|
|
||||||
* See trcKernelPort.h for details (kernel-specific)
|
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
/* See trcKernelPort.h for details (kernel-specific) */
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* xTraceSetISRProperties
|
* xTraceSetISRProperties
|
||||||
|
@ -277,7 +281,6 @@ traceString xTraceRegisterString(const char* name);
|
||||||
* ...
|
* ...
|
||||||
* vTraceStoreISREnd(0);
|
* vTraceStoreISREnd(0);
|
||||||
* }
|
* }
|
||||||
*
|
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
traceHandle xTraceSetISRProperties(const char* name, uint8_t priority);
|
traceHandle xTraceSetISRProperties(const char* name, uint8_t priority);
|
||||||
|
|
||||||
|
@ -298,7 +301,6 @@ traceHandle xTraceSetISRProperties(const char* name, uint8_t priority);
|
||||||
* ...
|
* ...
|
||||||
* vTraceStoreISREnd(0);
|
* vTraceStoreISREnd(0);
|
||||||
* }
|
* }
|
||||||
*
|
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void vTraceStoreISRBegin(traceHandle handle);
|
void vTraceStoreISRBegin(traceHandle handle);
|
||||||
|
|
||||||
|
@ -323,7 +325,6 @@ void vTraceStoreISRBegin(traceHandle handle);
|
||||||
* ...
|
* ...
|
||||||
* vTraceStoreISREnd(0);
|
* vTraceStoreISREnd(0);
|
||||||
* }
|
* }
|
||||||
*
|
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void vTraceStoreISREnd(int isTaskSwitchRequired);
|
void vTraceStoreISREnd(int isTaskSwitchRequired);
|
||||||
|
|
||||||
|
@ -352,7 +353,7 @@ void vTraceInstanceFinishedNext(void);
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* xTraceGetLastError
|
* xTraceGetLastError
|
||||||
*
|
*
|
||||||
* Returns the last error, if any.
|
* Returns the last error or warning as a string, or NULL if none.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
const char* xTraceGetLastError(void);
|
const char* xTraceGetLastError(void);
|
||||||
|
|
||||||
|
@ -420,8 +421,11 @@ void vTraceSetRecorderDataBuffer(void* pRecorderData);
|
||||||
*
|
*
|
||||||
* This translates to a single static allocation, on which you can apply linker
|
* This translates to a single static allocation, on which you can apply linker
|
||||||
* directives to place it in a particular memory region.
|
* directives to place it in a particular memory region.
|
||||||
|
*
|
||||||
* - Snapshot mode: "RecorderDataType <name>"
|
* - Snapshot mode: "RecorderDataType <name>"
|
||||||
* - Streaming mode: "char <name> [<size>]", with <size> from trcStreamingPort.h.
|
*
|
||||||
|
* - Streaming mode: "char <name> [<size>]",
|
||||||
|
* where <size> is defined in trcStreamingConfig.h.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
*
|
*
|
||||||
|
@ -434,17 +438,96 @@ void vTraceSetRecorderDataBuffer(void* pRecorderData);
|
||||||
* vTraceSetRecorderDataBuffer(&myTraceBuffer); // Note the "&"
|
* vTraceSetRecorderDataBuffer(&myTraceBuffer); // Note the "&"
|
||||||
* ...
|
* ...
|
||||||
* vTraceEnable(TRC_INIT); // Initialize the data structure
|
* vTraceEnable(TRC_INIT); // Initialize the data structure
|
||||||
*
|
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#ifndef TRC_ALLOC_CUSTOM_BUFFER
|
|
||||||
/* Definition for snapshot mode only. Also defined in trcStreamingPort.h */
|
|
||||||
#if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM)
|
#if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM)
|
||||||
#define TRC_ALLOC_CUSTOM_BUFFER(bufname) RecorderDataType bufname;
|
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)
|
||||||
|
#define TRC_ALLOC_CUSTOM_BUFFER(bufname) RecorderDataType bufname;
|
||||||
|
#elif (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
|
||||||
|
#ifdef TRC_CFG_RTT_BUFFER_SIZE_UP /* J-Link RTT */
|
||||||
|
#define TRC_ALLOC_CUSTOM_BUFFER(bufname) char bufname [TRC_CFG_RTT_BUFFER_SIZE_UP]; /* Not static in this case, since declared in user code */
|
||||||
|
#else
|
||||||
|
#define TRC_ALLOC_CUSTOM_BUFFER(bufname) char bufname [(TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT) * (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE)];
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
#define TRC_ALLOC_CUSTOM_BUFFER(bufname)
|
#define TRC_ALLOC_CUSTOM_BUFFER(bufname)
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* xTraceIsRecordingEnabled
|
||||||
|
*
|
||||||
|
* Returns true (1) if the recorder is enabled (i.e. is recording), otherwise 0.
|
||||||
|
******************************************************************************/
|
||||||
|
int xTraceIsRecordingEnabled(void);
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* vTraceSetFilterGroup
|
||||||
|
*
|
||||||
|
* Sets the "filter group" to assign when creating RTOS objects, such as tasks,
|
||||||
|
* queues, semaphores and mutexes. This together with vTraceSetFilterMask
|
||||||
|
* allows you to control what events that are recorded, based on the
|
||||||
|
* objects they refer to.
|
||||||
|
*
|
||||||
|
* There are 16 filter groups named FilterGroup0 .. FilterGroup15.
|
||||||
|
*
|
||||||
|
* Note: We don't recommend filtering out the Idle task, so make sure to call
|
||||||
|
* vTraceSetFilterGroup just before initializing the RTOS, in order to assign
|
||||||
|
* such "default" objects to the right Filter Group (typically group 0).
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
*
|
||||||
|
* // Assign tasks T1 to FilterGroup0 (default)
|
||||||
|
* <Create Task T1>
|
||||||
|
*
|
||||||
|
* // Assign Q1 and Q2 to FilterGroup1
|
||||||
|
* vTraceSetFilterGroup(FilterGroup1);
|
||||||
|
* <Create Queue Q1>
|
||||||
|
* <Create Queue Q2>
|
||||||
|
*
|
||||||
|
* // Assigns Q3 to FilterGroup2
|
||||||
|
* vTraceSetFilterGroup(FilterGroup2);
|
||||||
|
* <Create Queue Q3>
|
||||||
|
*
|
||||||
|
* // Only include FilterGroup0 and FilterGroup2, exclude FilterGroup1 (Q1 and Q2) from the trace
|
||||||
|
* vTraceSetFilterMask( FilterGroup0 | FilterGroup2 );
|
||||||
|
*
|
||||||
|
* // Assign the default RTOS objects (e.g. Idle task) to FilterGroup0
|
||||||
|
* vTraceSetFilterGroup(FilterGroup0);
|
||||||
|
* <Start the RTOS scheduler>
|
||||||
|
*
|
||||||
|
* Note that you may define your own names for the filter groups using
|
||||||
|
* preprocessor definitions, to make the code easier to understand.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
*
|
||||||
|
* #define BASE FilterGroup0
|
||||||
|
* #define USB_EVENTS FilterGroup1
|
||||||
|
* #define CAN_EVENTS FilterGroup2
|
||||||
|
*
|
||||||
|
* Note that filtering per event type (regardless of object) is also available
|
||||||
|
* in trcConfig.h.
|
||||||
|
******************************************************************************/
|
||||||
|
void vTraceSetFilterGroup(uint16_t filterGroup);
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* vTraceSetFilterMask
|
||||||
|
*
|
||||||
|
* Sets the "filter mask" that is used to filter the events by object. This can
|
||||||
|
* be used to reduce the trace data rate, i.e., if your streaming interface is
|
||||||
|
* a bottleneck or if you want longer snapshot traces without increasing the
|
||||||
|
* buffer size.
|
||||||
|
*
|
||||||
|
* Note: There are two kinds of filters in the recorder. The other filter type
|
||||||
|
* excludes all events of certain kinds (e.g., OS ticks). See trcConfig.h.
|
||||||
|
*
|
||||||
|
* The filtering is based on bitwise AND with the Filter Group ID, assigned
|
||||||
|
* to RTOS objects such as tasks, queues, semaphores and mutexes.
|
||||||
|
* This together with vTraceSetFilterGroup allows you to control what
|
||||||
|
* events that are recorded, based on the objects they refer to.
|
||||||
|
*
|
||||||
|
* See example for vTraceSetFilterGroup.
|
||||||
|
******************************************************************************/
|
||||||
|
void vTraceSetFilterMask(uint16_t filterMask);
|
||||||
|
|
||||||
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)
|
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)
|
||||||
|
|
||||||
|
@ -494,7 +577,6 @@ void vTraceSetStopHook(TRACE_STOP_HOOK stopHookFunction);
|
||||||
* error. In that case, check xTraceGetLastError to get the error message.
|
* error. In that case, check xTraceGetLastError to get the error message.
|
||||||
* Any error message is also presented when opening a trace file.
|
* Any error message is also presented when opening a trace file.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* Snapshot mode only!
|
* Snapshot mode only!
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
uint32_t uiTraceStart(void);
|
uint32_t uiTraceStart(void);
|
||||||
|
@ -527,11 +609,7 @@ void vTraceClear(void);
|
||||||
/*** INTERNAL SNAPSHOT FUNCTIONS *********************************************/
|
/*** INTERNAL SNAPSHOT FUNCTIONS *********************************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
#undef INCLUDE_xTaskGetSchedulerState
|
#define TRC_UNUSED
|
||||||
#define INCLUDE_xTaskGetSchedulerState 1
|
|
||||||
|
|
||||||
#undef INCLUDE_xTaskGetCurrentTaskHandle
|
|
||||||
#define INCLUDE_xTaskGetCurrentTaskHandle 1
|
|
||||||
|
|
||||||
#ifndef TRC_CFG_INCLUDE_OBJECT_DELETE
|
#ifndef TRC_CFG_INCLUDE_OBJECT_DELETE
|
||||||
#define TRC_CFG_INCLUDE_OBJECT_DELETE 0
|
#define TRC_CFG_INCLUDE_OBJECT_DELETE 0
|
||||||
|
@ -545,82 +623,105 @@ void vTraceClear(void);
|
||||||
#define TRC_CFG_INCLUDE_OSTICK_EVENTS 0
|
#define TRC_CFG_INCLUDE_OSTICK_EVENTS 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TRC_UNUSED
|
|
||||||
|
|
||||||
#if (TRC_CFG_INCLUDE_OBJECT_DELETE == 1)
|
|
||||||
/* This macro will remove the task and store it in the event buffer */
|
|
||||||
#undef trcKERNEL_HOOKS_TASK_DELETE
|
|
||||||
#define trcKERNEL_HOOKS_TASK_DELETE(SERVICE, pxTCB) \
|
|
||||||
prvTraceStoreKernelCall(TRACE_GET_TASK_EVENT_CODE(SERVICE, SUCCESS, CLASS, pxTCB), TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB)); \
|
|
||||||
prvTraceStoreObjectNameOnCloseEvent(TRACE_GET_TASK_NUMBER(pxTCB), TRACE_CLASS_TASK); \
|
|
||||||
prvTraceStoreObjectPropertiesOnCloseEvent(TRACE_GET_TASK_NUMBER(pxTCB), TRACE_CLASS_TASK); \
|
|
||||||
prvTraceSetPriorityProperty(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), TRACE_GET_TASK_PRIORITY(pxTCB)); \
|
|
||||||
prvTraceSetObjectState(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), TASK_STATE_INSTANCE_NOT_ACTIVE); \
|
|
||||||
prvTraceFreeObjectHandle(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB));
|
|
||||||
#else /*(TRC_CFG_INCLUDE_OBJECT_DELETE == 1)*/
|
|
||||||
#undef trcKERNEL_HOOKS_TASK_DELETE
|
|
||||||
#define trcKERNEL_HOOKS_TASK_DELETE(SERVICE, pxTCB)
|
|
||||||
#endif /*(TRC_CFG_INCLUDE_OBJECT_DELETE == 1)*/
|
|
||||||
|
|
||||||
#if (TRC_CFG_INCLUDE_OBJECT_DELETE == 1)
|
|
||||||
/* This macro will remove the object and store it in the event buffer */
|
|
||||||
#undef trcKERNEL_HOOKS_OBJECT_DELETE
|
|
||||||
#define trcKERNEL_HOOKS_OBJECT_DELETE(SERVICE, CLASS, pxObject) \
|
|
||||||
prvTraceStoreKernelCall(TRACE_GET_OBJECT_EVENT_CODE(SERVICE, SUCCESS, CLASS, pxObject), TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject)); \
|
|
||||||
prvTraceStoreObjectNameOnCloseEvent(TRACE_GET_OBJECT_NUMBER(CLASS, pxObject), TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject)); \
|
|
||||||
prvTraceStoreObjectPropertiesOnCloseEvent(TRACE_GET_OBJECT_NUMBER(CLASS, pxObject), TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject)); \
|
|
||||||
prvTraceFreeObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject));
|
|
||||||
#else /*TRC_CFG_INCLUDE_OBJECT_DELETE*/
|
|
||||||
#undef trcKERNEL_HOOKS_OBJECT_DELETE
|
|
||||||
#define trcKERNEL_HOOKS_OBJECT_DELETE(SERVICE, CLASS, pxObject)
|
|
||||||
#endif /*TRC_CFG_INCLUDE_OBJECT_DELETE*/
|
|
||||||
|
|
||||||
/* This macro will create a task in the object table */
|
/* This macro will create a task in the object table */
|
||||||
#undef trcKERNEL_HOOKS_TASK_CREATE
|
#undef trcKERNEL_HOOKS_TASK_CREATE
|
||||||
#define trcKERNEL_HOOKS_TASK_CREATE(SERVICE, CLASS, pxTCB) \
|
#define trcKERNEL_HOOKS_TASK_CREATE(SERVICE, CLASS, pxTCB) \
|
||||||
TRACE_SET_TASK_NUMBER(pxTCB) \
|
TRACE_SET_TASK_NUMBER(pxTCB); \
|
||||||
|
TRACE_SET_TASK_FILTER(pxTCB, CurrentFilterGroup); \
|
||||||
prvTraceSetObjectName(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), TRACE_GET_TASK_NAME(pxTCB)); \
|
prvTraceSetObjectName(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), TRACE_GET_TASK_NAME(pxTCB)); \
|
||||||
prvTraceSetPriorityProperty(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), TRACE_GET_TASK_PRIORITY(pxTCB)); \
|
prvTraceSetPriorityProperty(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), TRACE_GET_TASK_PRIORITY(pxTCB)); \
|
||||||
prvTraceStoreKernelCall(TRACE_GET_TASK_EVENT_CODE(SERVICE, SUCCESS, CLASS, pxTCB), TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB));
|
if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
|
||||||
|
if (TRACE_GET_TASK_FILTER(pxTCB) & CurrentFilterMask) \
|
||||||
|
prvTraceStoreKernelCall(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB));
|
||||||
|
|
||||||
|
/* This macro will remove the task and store it in the event buffer */
|
||||||
|
#undef trcKERNEL_HOOKS_TASK_DELETE
|
||||||
|
#define trcKERNEL_HOOKS_TASK_DELETE(SERVICE, SERVICE_NAME, SERVICE_PROP, pxTCB) \
|
||||||
|
if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
|
||||||
|
if (TRACE_GET_TASK_FILTER(pxTCB) & CurrentFilterMask) \
|
||||||
|
prvTraceStoreKernelCall(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB)); \
|
||||||
|
prvTraceStoreObjectNameOnCloseEvent(SERVICE_NAME, TRACE_GET_TASK_NUMBER(pxTCB), TRACE_CLASS_TASK); \
|
||||||
|
prvTraceStoreObjectPropertiesOnCloseEvent(SERVICE_PROP, TRACE_GET_TASK_NUMBER(pxTCB), TRACE_CLASS_TASK); \
|
||||||
|
prvTraceSetPriorityProperty(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), TRACE_GET_TASK_PRIORITY(pxTCB)); \
|
||||||
|
prvTraceSetObjectState(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), TASK_STATE_INSTANCE_NOT_ACTIVE); \
|
||||||
|
prvTraceFreeObjectHandle(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB));
|
||||||
|
|
||||||
/* This macro will create a failed create call to create a task */
|
|
||||||
#undef trcKERNEL_HOOKS_TASK_CREATE_FAILED
|
|
||||||
#define trcKERNEL_HOOKS_TASK_CREATE_FAILED(SERVICE, CLASS) \
|
|
||||||
prvTraceStoreKernelCall(TRACE_GET_TASK_EVENT_CODE(SERVICE, FAILED, CLASS, 0), TRACE_CLASS_TASK, 0);
|
|
||||||
|
|
||||||
/* This macro will setup a task in the object table */
|
/* This macro will setup a task in the object table */
|
||||||
#undef trcKERNEL_HOOKS_OBJECT_CREATE
|
#undef trcKERNEL_HOOKS_OBJECT_CREATE
|
||||||
#define trcKERNEL_HOOKS_OBJECT_CREATE(SERVICE, CLASS, pxObject)\
|
#define trcKERNEL_HOOKS_OBJECT_CREATE(SERVICE, CLASS, pxObject)\
|
||||||
TRACE_SET_OBJECT_NUMBER(CLASS, pxObject);\
|
TRACE_SET_OBJECT_NUMBER(CLASS, pxObject);\
|
||||||
|
TRACE_SET_OBJECT_FILTER(CLASS, pxObject, CurrentFilterGroup); \
|
||||||
prvMarkObjectAsUsed(TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject));\
|
prvMarkObjectAsUsed(TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject));\
|
||||||
prvTraceStoreKernelCall(TRACE_GET_OBJECT_EVENT_CODE(SERVICE, SUCCESS, CLASS, pxObject), TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject)); \
|
if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
|
||||||
|
if (TRACE_GET_OBJECT_FILTER(CLASS, pxObject) & CurrentFilterMask) \
|
||||||
|
prvTraceStoreKernelCall(SERVICE, TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject)); \
|
||||||
prvTraceSetObjectState(TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject), 0);
|
prvTraceSetObjectState(TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject), 0);
|
||||||
|
|
||||||
/* This macro will create a failed create call to create an object */
|
/* This macro will remove the object and store it in the event buffer */
|
||||||
#undef trcKERNEL_HOOKS_OBJECT_CREATE_FAILED
|
#undef trcKERNEL_HOOKS_OBJECT_DELETE
|
||||||
#define trcKERNEL_HOOKS_OBJECT_CREATE_FAILED(SERVICE, CLASS, kernelClass) \
|
#define trcKERNEL_HOOKS_OBJECT_DELETE(SERVICE, SERVICE_NAME, SERVICE_PROP, CLASS, pxObject) \
|
||||||
prvTraceStoreKernelCall(TRACE_GET_CLASS_EVENT_CODE(SERVICE, FAILED, CLASS, kernelClass), TRACE_GET_CLASS_TRACE_CLASS(CLASS, kernelClass), 0);
|
if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
|
||||||
|
if (TRACE_GET_OBJECT_FILTER(CLASS, pxObject) & CurrentFilterMask) \
|
||||||
|
prvTraceStoreKernelCall(SERVICE, TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject)); \
|
||||||
|
prvTraceStoreObjectNameOnCloseEvent(SERVICE_NAME, TRACE_GET_OBJECT_NUMBER(CLASS, pxObject), TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject)); \
|
||||||
|
prvTraceStoreObjectPropertiesOnCloseEvent(SERVICE_PROP, TRACE_GET_OBJECT_NUMBER(CLASS, pxObject), TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject)); \
|
||||||
|
prvTraceFreeObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject));
|
||||||
|
|
||||||
/* This macro will create a call to a kernel service with a certain result, with an object as parameter */
|
/* This macro will create a call to a kernel service with a certain result, with an object as parameter */
|
||||||
#undef trcKERNEL_HOOKS_KERNEL_SERVICE
|
#undef trcKERNEL_HOOKS_KERNEL_SERVICE
|
||||||
#define trcKERNEL_HOOKS_KERNEL_SERVICE(SERVICE, RESULT, CLASS, pxObject) \
|
#define trcKERNEL_HOOKS_KERNEL_SERVICE(SERVICE, CLASS, pxObject) \
|
||||||
prvTraceStoreKernelCall(TRACE_GET_OBJECT_EVENT_CODE(SERVICE, RESULT, CLASS, pxObject), TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject));
|
if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
|
||||||
|
if (TRACE_GET_OBJECT_FILTER(CLASS, pxObject) & CurrentFilterMask) \
|
||||||
|
prvTraceStoreKernelCall(SERVICE, TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject));
|
||||||
|
|
||||||
|
/* This macro will create a call to a kernel service with a certain result, with an object as parameter */
|
||||||
|
#undef trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM
|
||||||
|
#define trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(SERVICE, CLASS, pxObject, param) \
|
||||||
|
if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
|
||||||
|
if (TRACE_GET_OBJECT_FILTER(CLASS, pxObject) & CurrentFilterMask) \
|
||||||
|
prvTraceStoreKernelCallWithParam(SERVICE, TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject), (uint32_t)param);
|
||||||
|
|
||||||
|
/* This macro will create a call to a kernel service with a certain result, with an object as parameter */
|
||||||
|
#undef trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY
|
||||||
|
#define trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY(SERVICE, param) \
|
||||||
|
if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
|
||||||
|
prvTraceStoreKernelCallWithNumericParamOnly(SERVICE, (uint32_t)param);
|
||||||
|
|
||||||
|
/* This macro will create a call to a kernel service with a certain result, with an object as parameter */
|
||||||
|
#undef trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR
|
||||||
|
#define trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(SERVICE, CLASS, pxObject) \
|
||||||
|
if (TRACE_GET_OBJECT_FILTER(CLASS, pxObject) & CurrentFilterMask) \
|
||||||
|
prvTraceStoreKernelCall(SERVICE, TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject));
|
||||||
|
|
||||||
|
/* This macro will create a call to a kernel service with a certain result, with an object as parameter */
|
||||||
|
#undef trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM_FROM_ISR
|
||||||
|
#define trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM_FROM_ISR(SERVICE, CLASS, pxObject, param) \
|
||||||
|
if (TRACE_GET_OBJECT_FILTER(CLASS, pxObject) & CurrentFilterMask) \
|
||||||
|
prvTraceStoreKernelCallWithParam(SERVICE, TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject), (uint32_t)param);
|
||||||
|
|
||||||
|
/* This macro will create a call to a kernel service with a certain result, with an object as parameter */
|
||||||
|
#undef trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY_FROM_ISR
|
||||||
|
#define trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY_FROM_ISR(SERVICE, param) \
|
||||||
|
prvTraceStoreKernelCallWithNumericParamOnly(SERVICE, (uint32_t)param);
|
||||||
|
|
||||||
/* This macro will set the state for an object */
|
/* This macro will set the state for an object */
|
||||||
#undef trcKERNEL_HOOKS_SET_OBJECT_STATE
|
#undef trcKERNEL_HOOKS_SET_OBJECT_STATE
|
||||||
#define trcKERNEL_HOOKS_SET_OBJECT_STATE(CLASS, pxObject, STATE) \
|
#define trcKERNEL_HOOKS_SET_OBJECT_STATE(CLASS, pxObject, STATE) \
|
||||||
prvTraceSetObjectState(TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject), STATE);
|
prvTraceSetObjectState(TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject), (uint8_t)STATE);
|
||||||
|
|
||||||
/* This macro will flag a certain task as a finished instance */
|
/* This macro will flag a certain task as a finished instance */
|
||||||
#undef trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED
|
#undef trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED
|
||||||
#define trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED() \
|
#define trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED() \
|
||||||
prvTraceSetTaskInstanceFinished(TRACE_GET_TASK_NUMBER(TRACE_GET_CURRENT_TASK()));
|
if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
|
||||||
|
prvTraceSetTaskInstanceFinished(TRACE_GET_TASK_NUMBER(TRACE_GET_CURRENT_TASK()));
|
||||||
|
|
||||||
#if (TRC_CFG_INCLUDE_READY_EVENTS == 1)
|
#if (TRC_CFG_INCLUDE_READY_EVENTS == 1)
|
||||||
/* This macro will create an event to indicate that a task became Ready */
|
/* This macro will create an event to indicate that a task became Ready */
|
||||||
#undef trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE
|
#undef trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE
|
||||||
#define trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE(pxTCB) \
|
#define trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE(pxTCB) \
|
||||||
prvTraceStoreTaskReady(TRACE_GET_TASK_NUMBER(pxTCB));
|
if (TRACE_GET_TASK_FILTER(pxTCB) & CurrentFilterMask) \
|
||||||
|
prvTraceStoreTaskReady(TRACE_GET_TASK_NUMBER(pxTCB));
|
||||||
#else /*(TRC_CFG_INCLUDE_READY_EVENTS == 1)*/
|
#else /*(TRC_CFG_INCLUDE_READY_EVENTS == 1)*/
|
||||||
#undef trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE
|
#undef trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE
|
||||||
#define trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE(pxTCB)
|
#define trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE(pxTCB)
|
||||||
|
@ -629,7 +730,11 @@ void vTraceClear(void);
|
||||||
/* This macro will update the internal tick counter and call prvTracePortGetTimeStamp(0) to update the internal counters */
|
/* This macro will update the internal tick counter and call prvTracePortGetTimeStamp(0) to update the internal counters */
|
||||||
#undef trcKERNEL_HOOKS_INCREMENT_TICK
|
#undef trcKERNEL_HOOKS_INCREMENT_TICK
|
||||||
#define trcKERNEL_HOOKS_INCREMENT_TICK() \
|
#define trcKERNEL_HOOKS_INCREMENT_TICK() \
|
||||||
{ extern uint32_t uiTraceTickCount; uiTraceTickCount++; prvTracePortGetTimeStamp(0); }
|
{ \
|
||||||
|
extern uint32_t uiTraceTickCount; \
|
||||||
|
uiTraceTickCount++; \
|
||||||
|
prvTracePortGetTimeStamp(0); \
|
||||||
|
}
|
||||||
|
|
||||||
#if (TRC_CFG_INCLUDE_OSTICK_EVENTS == 1)
|
#if (TRC_CFG_INCLUDE_OSTICK_EVENTS == 1)
|
||||||
/* This macro will create an event indicating that the OS tick count has increased */
|
/* This macro will create an event indicating that the OS tick count has increased */
|
||||||
|
@ -644,48 +749,46 @@ void vTraceClear(void);
|
||||||
/* This macro will create a task switch event to the currently executing task */
|
/* This macro will create a task switch event to the currently executing task */
|
||||||
#undef trcKERNEL_HOOKS_TASK_SWITCH
|
#undef trcKERNEL_HOOKS_TASK_SWITCH
|
||||||
#define trcKERNEL_HOOKS_TASK_SWITCH( pxTCB ) \
|
#define trcKERNEL_HOOKS_TASK_SWITCH( pxTCB ) \
|
||||||
prvTraceStoreTaskswitch(TRACE_GET_TASK_NUMBER(pxTCB));
|
if (TRACE_GET_TASK_FILTER(pxTCB) & CurrentFilterMask) \
|
||||||
|
prvTraceStoreTaskswitch(TRACE_GET_TASK_NUMBER(pxTCB));
|
||||||
|
|
||||||
/* This macro will create an event to indicate that the task has been suspended */
|
/* This macro will create an event to indicate that the task has been suspended */
|
||||||
#undef trcKERNEL_HOOKS_TASK_SUSPEND
|
#undef trcKERNEL_HOOKS_TASK_SUSPEND
|
||||||
#define trcKERNEL_HOOKS_TASK_SUSPEND(SERVICE, pxTCB) \
|
#define trcKERNEL_HOOKS_TASK_SUSPEND(SERVICE, pxTCB) \
|
||||||
prvTraceStoreKernelCall(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB)); \
|
if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
|
||||||
|
if (TRACE_GET_TASK_FILTER(pxTCB) & CurrentFilterMask) \
|
||||||
|
prvTraceStoreKernelCall(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB)); \
|
||||||
prvTraceSetTaskInstanceFinished((uint8_t)TRACE_GET_TASK_NUMBER(pxTCB));
|
prvTraceSetTaskInstanceFinished((uint8_t)TRACE_GET_TASK_NUMBER(pxTCB));
|
||||||
|
|
||||||
/* This macro will create an event to indicate that a task has called a wait/delay function */
|
/* This macro will create an event to indicate that a task has called a wait/delay function */
|
||||||
#undef trcKERNEL_HOOKS_TASK_DELAY
|
#undef trcKERNEL_HOOKS_TASK_DELAY
|
||||||
#define trcKERNEL_HOOKS_TASK_DELAY(SERVICE, pxTCB, xValue) \
|
#define trcKERNEL_HOOKS_TASK_DELAY(SERVICE, pxTCB, xValue) \
|
||||||
prvTraceStoreKernelCallWithNumericParamOnly(SERVICE, xValue); \
|
if (TRACE_GET_TASK_FILTER(pxTCB) & CurrentFilterMask) \
|
||||||
prvTraceSetTaskInstanceFinished((uint8_t)TRACE_GET_TASK_NUMBER(pxTCB));
|
{ \
|
||||||
|
prvTraceStoreKernelCallWithNumericParamOnly(SERVICE, xValue); \
|
||||||
|
prvTraceSetTaskInstanceFinished((uint8_t)TRACE_GET_TASK_NUMBER(pxTCB)); \
|
||||||
|
}
|
||||||
|
|
||||||
/* This macro will create an event to indicate that a task has gotten its priority changed */
|
/* This macro will create an event to indicate that a task has gotten its priority changed */
|
||||||
#undef trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE
|
#undef trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE
|
||||||
#define trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE(SERVICE, pxTCB, uxNewPriority) \
|
#define trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE(SERVICE, pxTCB, uxNewPriority) \
|
||||||
prvTraceStoreKernelCallWithParam(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), prvTraceGetPriorityProperty(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB)));\
|
if (TRACE_GET_TASK_FILTER(pxTCB) & CurrentFilterMask) \
|
||||||
prvTraceSetPriorityProperty(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), (uint8_t)uxNewPriority);
|
{ \
|
||||||
|
prvTraceStoreKernelCallWithParam(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), prvTraceGetPriorityProperty(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB)));\
|
||||||
|
prvTraceSetPriorityProperty(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), (uint8_t)uxNewPriority); \
|
||||||
|
}
|
||||||
|
|
||||||
/* This macro will create an event to indicate that the task has been resumed */
|
/* This macro will create an event to indicate that the task has been resumed */
|
||||||
#undef trcKERNEL_HOOKS_TASK_RESUME
|
#undef trcKERNEL_HOOKS_TASK_RESUME
|
||||||
#define trcKERNEL_HOOKS_TASK_RESUME(SERVICE, pxTCB) \
|
#define trcKERNEL_HOOKS_TASK_RESUME(SERVICE, pxTCB) \
|
||||||
prvTraceStoreKernelCall(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB));
|
if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \
|
||||||
|
if (TRACE_GET_TASK_FILTER(pxTCB) & CurrentFilterMask) \
|
||||||
|
prvTraceStoreKernelCall(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB));
|
||||||
|
|
||||||
#undef trcKERNEL_HOOKS_TIMER_EVENT
|
#undef trcKERNEL_HOOKS_TASK_RESUME_FROM_ISR
|
||||||
#define trcKERNEL_HOOKS_TIMER_EVENT(SERVICE, pxTimer) \
|
#define trcKERNEL_HOOKS_TASK_RESUME_FROM_ISR(SERVICE, pxTCB) \
|
||||||
prvTraceStoreKernelCall(SERVICE, TRACE_CLASS_TIMER, TRACE_GET_TIMER_NUMBER(pxTimer));
|
if (TRACE_GET_TASK_FILTER(pxTCB) & CurrentFilterMask) \
|
||||||
|
prvTraceStoreKernelCall(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB));
|
||||||
/* This macro will create a timer in the object table and assign the timer a trace handle (timer number).*/
|
|
||||||
#undef trcKERNEL_HOOKS_TIMER_CREATE
|
|
||||||
#define trcKERNEL_HOOKS_TIMER_CREATE(SERVICE, pxTimer) \
|
|
||||||
TRACE_SET_TIMER_NUMBER(pxTimer); \
|
|
||||||
prvTraceSetObjectName(TRACE_CLASS_TIMER, TRACE_GET_TIMER_NUMBER(pxTimer), TRACE_GET_TIMER_NAME(pxTimer)); \
|
|
||||||
prvTraceStoreKernelCall(SERVICE, TRACE_CLASS_TIMER, TRACE_GET_TIMER_NUMBER(pxTimer));
|
|
||||||
|
|
||||||
#undef trcKERNEL_HOOKS_TIMER_DELETE
|
|
||||||
#define trcKERNEL_HOOKS_TIMER_DELETE(SERVICE, pxTimer) \
|
|
||||||
prvTraceStoreKernelCall(SERVICE, TRACE_CLASS_TIMER, TRACE_GET_TIMER_NUMBER(pxTimer)); \
|
|
||||||
prvTraceStoreObjectNameOnCloseEvent(TRACE_GET_TIMER_NUMBER(pxTimer), TRACE_CLASS_TIMER); \
|
|
||||||
prvTraceStoreObjectPropertiesOnCloseEvent(TRACE_GET_TIMER_NUMBER(pxTimer), TRACE_CLASS_TIMER); \
|
|
||||||
prvTraceFreeObjectHandle(TRACE_CLASS_TIMER, TRACE_GET_TIMER_NUMBER(pxTimer));
|
|
||||||
|
|
||||||
#if !defined TRC_CFG_INCLUDE_READY_EVENTS || TRC_CFG_INCLUDE_READY_EVENTS == 1
|
#if !defined TRC_CFG_INCLUDE_READY_EVENTS || TRC_CFG_INCLUDE_READY_EVENTS == 1
|
||||||
void prvTraceSetReadyEventsEnabled(int status);
|
void prvTraceSetReadyEventsEnabled(int status);
|
||||||
|
@ -725,15 +828,11 @@ void prvTraceSetObjectState(uint8_t objectclass, traceHandle id, uint8_t value);
|
||||||
|
|
||||||
void prvMarkObjectAsUsed(traceObjectClass objectclass, traceHandle handle);
|
void prvMarkObjectAsUsed(traceObjectClass objectclass, traceHandle handle);
|
||||||
|
|
||||||
|
void prvTraceStoreObjectNameOnCloseEvent(uint8_t evtcode, traceHandle handle,
|
||||||
#if (TRC_CFG_INCLUDE_OBJECT_DELETE == 1)
|
|
||||||
|
|
||||||
void prvTraceStoreObjectNameOnCloseEvent(traceHandle handle,
|
|
||||||
traceObjectClass objectclass);
|
traceObjectClass objectclass);
|
||||||
|
|
||||||
void prvTraceStoreObjectPropertiesOnCloseEvent(traceHandle handle,
|
void prvTraceStoreObjectPropertiesOnCloseEvent(uint8_t evtcode, traceHandle handle,
|
||||||
traceObjectClass objectclass);
|
traceObjectClass objectclass);
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Internal constants for task state */
|
/* Internal constants for task state */
|
||||||
#define TASK_STATE_INSTANCE_NOT_ACTIVE 0
|
#define TASK_STATE_INSTANCE_NOT_ACTIVE 0
|
||||||
|
@ -742,9 +841,6 @@ void prvTraceStoreObjectPropertiesOnCloseEvent(traceHandle handle,
|
||||||
|
|
||||||
#if (TRC_CFG_INCLUDE_ISR_TRACING == 0)
|
#if (TRC_CFG_INCLUDE_ISR_TRACING == 0)
|
||||||
|
|
||||||
//void prvTraceIncreaseISRActive(void);
|
|
||||||
|
|
||||||
//void prvTraceDecreaseISRActive(void);
|
|
||||||
#undef vTraceSetISRProperties
|
#undef vTraceSetISRProperties
|
||||||
#define vTraceSetISRProperties(handle, name, priority)
|
#define vTraceSetISRProperties(handle, name, priority)
|
||||||
|
|
||||||
|
@ -824,12 +920,6 @@ void vTraceUBEvent(traceUBChannel channel);
|
||||||
#define trcCRITICAL_SECTION_END_ON_CORTEX_M_ONLY() recorder_busy--;
|
#define trcCRITICAL_SECTION_END_ON_CORTEX_M_ONLY() recorder_busy--;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Structure to handle the exclude flags for all objects and tasks. We add some extra objects since index 0 is not used for each object class. */
|
|
||||||
extern uint8_t trcExcludedObjects[(TRACE_KERNEL_OBJECT_COUNT + TRACE_NCLASSES) / 8 + 1];
|
|
||||||
|
|
||||||
/* Structure to handle the exclude flags for all event codes */
|
|
||||||
extern uint8_t trcExcludedEventCodes[NEventCodes / 8 + 1];
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* ObjectHandleStack
|
* ObjectHandleStack
|
||||||
* This data-structure is used to provide a mechanism for 1-byte trace object
|
* This data-structure is used to provide a mechanism for 1-byte trace object
|
||||||
|
@ -838,6 +928,7 @@ extern uint8_t trcExcludedEventCodes[NEventCodes / 8 + 1];
|
||||||
* each object class active at any given moment. There can be more "historic"
|
* each object class active at any given moment. There can be more "historic"
|
||||||
* objects, that have been deleted - that number is only limited by the size of
|
* objects, that have been deleted - that number is only limited by the size of
|
||||||
* the symbol table.
|
* the symbol table.
|
||||||
|
*
|
||||||
* Note that handle zero (0) is not used, it is a code for an invalid handle.
|
* Note that handle zero (0) is not used, it is a code for an invalid handle.
|
||||||
*
|
*
|
||||||
* This data structure keeps track of the FREE handles, not the handles in use.
|
* This data structure keeps track of the FREE handles, not the handles in use.
|
||||||
|
@ -851,7 +942,6 @@ extern uint8_t trcExcludedEventCodes[NEventCodes / 8 + 1];
|
||||||
* is not a valid handle, that is a signal of additional handles needed.
|
* is not a valid handle, that is a signal of additional handles needed.
|
||||||
* If a zero is received when popping a new handle, it is replaced by the
|
* If a zero is received when popping a new handle, it is replaced by the
|
||||||
* index of the popped handle instead.
|
* index of the popped handle instead.
|
||||||
*
|
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -884,6 +974,7 @@ extern objectHandleStackType objectHandleStacks;
|
||||||
* represent the current state. If a property is changed during runtime, the OLD
|
* represent the current state. If a property is changed during runtime, the OLD
|
||||||
* value should be stored in the trace buffer, not the new value (since the new
|
* value should be stored in the trace buffer, not the new value (since the new
|
||||||
* value is found in the Object Property Table).
|
* value is found in the Object Property Table).
|
||||||
|
*
|
||||||
* For close events this mechanism is the old names are stored in the symbol
|
* For close events this mechanism is the old names are stored in the symbol
|
||||||
* table), for "priority set" (the old priority is stored in the event data)
|
* table), for "priority set" (the old priority is stored in the event data)
|
||||||
* and for "isActive", where the value decides if the task switch event type
|
* and for "isActive", where the value decides if the task switch event type
|
||||||
|
@ -927,7 +1018,7 @@ typedef struct
|
||||||
uint32_t nextFreeSymbolIndex;
|
uint32_t nextFreeSymbolIndex;
|
||||||
|
|
||||||
/* Size rounded up to closest multiple of 4, to avoid alignment issues*/
|
/* Size rounded up to closest multiple of 4, to avoid alignment issues*/
|
||||||
uint8_t symbytes[4*((TRC_CFG_SYMBOL_TABLE_SIZE+3)/4)];
|
uint8_t symbytes[4*(((TRC_CFG_SYMBOL_TABLE_SIZE)+3)/4)];
|
||||||
|
|
||||||
/* Used for lookups - Up to 64 linked lists within the symbol table
|
/* Used for lookups - Up to 64 linked lists within the symbol table
|
||||||
connecting all entries with the same 6 bit checksum.
|
connecting all entries with the same 6 bit checksum.
|
||||||
|
@ -979,8 +1070,8 @@ typedef struct
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
uint8_t objHandle; /* the handle of the closed object */
|
uint8_t objHandle; /* the handle of the closed object */
|
||||||
uint16_t symbolIndex; /* the name of the closed object */
|
uint16_t symbolIndex; /* the name of the closed object */
|
||||||
} ObjCloseNameEvent;
|
} ObjCloseNameEvent;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -1060,9 +1151,9 @@ typedef struct
|
||||||
uint8_t padding1;
|
uint8_t padding1;
|
||||||
uint8_t padding2;
|
uint8_t padding2;
|
||||||
uint8_t padding3;
|
uint8_t padding3;
|
||||||
ChannelFormatPair channels[TRC_CFG_UB_CHANNELS+1];
|
ChannelFormatPair channels[(TRC_CFG_UB_CHANNELS)+1];
|
||||||
uint8_t channelBuffer[(TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE + 3) & 0xFFFFFFFC]; /* 1 byte per slot, with padding for 4 byte alignment */
|
uint8_t channelBuffer[((TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE) + 3) & 0xFFFFFFFC]; /* 1 byte per slot, with padding for 4 byte alignment */
|
||||||
uint8_t dataBuffer[TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE * 4]; /* 4 bytes per slot */
|
uint8_t dataBuffer[(TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE) * 4]; /* 4 bytes per slot */
|
||||||
|
|
||||||
} UserEventBuffer;
|
} UserEventBuffer;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1182,7 +1273,7 @@ typedef struct
|
||||||
int32_t debugMarker3;
|
int32_t debugMarker3;
|
||||||
|
|
||||||
/* The event data, in 4-byte records */
|
/* The event data, in 4-byte records */
|
||||||
uint8_t eventData[ TRC_CFG_EVENT_BUFFER_SIZE * 4 ];
|
uint8_t eventData[ (TRC_CFG_EVENT_BUFFER_SIZE) * 4 ];
|
||||||
|
|
||||||
#if (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)
|
#if (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)
|
||||||
UserEventBuffer userEventBuffer;
|
UserEventBuffer userEventBuffer;
|
||||||
|
@ -1249,14 +1340,6 @@ RecorderDataPtr->ObjectPropertyTable.objbytes[uiIndexOfObject(handle, objectclas
|
||||||
RecorderDataPtr->ObjectPropertyTable.objbytes[uiIndexOfObject(handle, objectclass) \
|
RecorderDataPtr->ObjectPropertyTable.objbytes[uiIndexOfObject(handle, objectclass) \
|
||||||
+ RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[objectclass] + 1]
|
+ RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[objectclass] + 1]
|
||||||
|
|
||||||
#define TRACE_SET_FLAG_ISEXCLUDED(flags, bitIndex) flags[(bitIndex) >> 3] |= (1 << ((bitIndex) & 7))
|
|
||||||
#define TRACE_CLEAR_FLAG_ISEXCLUDED(flags, bitIndex) flags[(bitIndex) >> 3] &= (uint8_t)(~(1 << ((bitIndex) & 7)))
|
|
||||||
#define TRACE_GET_FLAG_ISEXCLUDED(flags, bitIndex) (flags[(bitIndex) >> 3] & (1 << ((bitIndex) & 7)))
|
|
||||||
|
|
||||||
#define TRACE_SET_EVENT_CODE_FLAG_ISEXCLUDED(eventCode) TRACE_SET_FLAG_ISEXCLUDED(trcExcludedEventCodes, eventCode)
|
|
||||||
#define TRACE_CLEAR_EVENT_CODE_FLAG_ISEXCLUDED(eventCode) TRACE_CLEAR_FLAG_ISEXCLUDED(trcExcludedEventCodes, eventCode)
|
|
||||||
#define TRACE_GET_EVENT_CODE_FLAG_ISEXCLUDED(eventCode) TRACE_GET_FLAG_ISEXCLUDED(trcExcludedEventCodes, eventCode)
|
|
||||||
|
|
||||||
/* DEBUG ASSERTS */
|
/* DEBUG ASSERTS */
|
||||||
#if defined TRC_CFG_USE_TRACE_ASSERT && TRC_CFG_USE_TRACE_ASSERT != 0
|
#if defined TRC_CFG_USE_TRACE_ASSERT && TRC_CFG_USE_TRACE_ASSERT != 0
|
||||||
#define TRACE_ASSERT(eval, msg, defRetVal) \
|
#define TRACE_ASSERT(eval, msg, defRetVal) \
|
||||||
|
@ -1273,6 +1356,279 @@ if (!(eval)) \
|
||||||
|
|
||||||
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
|
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Default values for STREAM PORT macros
|
||||||
|
*
|
||||||
|
* As a normal user, this is nothing you don't need to bother about. This is
|
||||||
|
* only important if you want to define your own custom streaming interface.
|
||||||
|
*
|
||||||
|
* You may override these in your own trcStreamingPort.h to create a custom
|
||||||
|
* stream port, and thereby stream the trace on any host-target interface.
|
||||||
|
* These default values are suitable for most cases, except the J-Link port.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TRC_STREAM_PORT_USE_INTERNAL_BUFFER
|
||||||
|
*
|
||||||
|
* There are two kinds of stream ports, those that store the event to the
|
||||||
|
* internal buffer (with periodic flushing by the TzCtrl task) and those that
|
||||||
|
* write directly to the streaming interface. Most stream ports use the
|
||||||
|
* recorder's internal buffer, except for the SEGGER J-Link port (also uses a
|
||||||
|
* RAM buffer, but one defined in the SEGGER code).
|
||||||
|
*
|
||||||
|
* If the stream port (trcStreamingPort.h) defines this as zero (0), it is
|
||||||
|
* expected to transmit the data directly using TRC_STREAM_PORT_COMMIT_EVENT.
|
||||||
|
* Otherwise it is expected that the trace data is stored in the internal buffer
|
||||||
|
* and the TzCtrl task will then send the buffer pages when they become full.
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef TRC_STREAM_PORT_USE_INTERNAL_BUFFER
|
||||||
|
#define TRC_STREAM_PORT_USE_INTERNAL_BUFFER 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TRC_STREAM_PORT_ON_TRACE_BEGIN
|
||||||
|
*
|
||||||
|
* Defining any actions needed in the stream port when the recording is activated.
|
||||||
|
*******************************************************************************/
|
||||||
|
#ifndef TRC_STREAM_PORT_ON_TRACE_BEGIN
|
||||||
|
#define TRC_STREAM_PORT_ON_TRACE_BEGIN() /* Do nothing */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TRC_STREAM_PORT_ON_TRACE_BEGIN
|
||||||
|
*
|
||||||
|
* Defining any actions needed in the stream port when the tracing stops.
|
||||||
|
* Empty by default.
|
||||||
|
*******************************************************************************/
|
||||||
|
#ifndef TRC_STREAM_PORT_ON_TRACE_END
|
||||||
|
#define TRC_STREAM_PORT_ON_TRACE_END() /* Do nothing */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TRC_STREAM_PORT_ALLOCATE_EVENT
|
||||||
|
*
|
||||||
|
* This macro is used to allocate memory for each event record, just before
|
||||||
|
* assigning the record fields.
|
||||||
|
* Depending on "TRC_STREAM_PORT_USE_INTERNAL_BUFFER", this either allocates
|
||||||
|
* space in the paged event buffer, or on the local stack. In the latter case,
|
||||||
|
* the COMMIT event is used to write the data to the streaming interface.
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef TRC_STREAM_PORT_ALLOCATE_EVENT
|
||||||
|
#if (TRC_STREAM_PORT_USE_INTERNAL_BUFFER == 1)
|
||||||
|
#define TRC_STREAM_PORT_ALLOCATE_EVENT(_type, _ptrData, _size) _type* _ptrData; _ptrData = (_type*)prvPagedEventBufferGetWritePointer(_size);
|
||||||
|
#else
|
||||||
|
#define TRC_STREAM_PORT_ALLOCATE_EVENT(_type, _ptrData, _size) _type _tmpArray[_size / sizeof(_type)]; _type* _ptrData = _tmpArray;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TRC_STREAM_PORT_ALLOCATE_DYNAMIC_EVENT
|
||||||
|
*
|
||||||
|
* This macro is used to allocate memory for each event record, just before
|
||||||
|
* assigning the record fields.
|
||||||
|
* This has the same purpose as TRC_STREAM_PORT_ALLOCATE_EVENT and by default
|
||||||
|
* it has the same definition as TRC_STREAM_PORT_ALLOCATE_EVENT. This is used
|
||||||
|
* for events carrying variable-sized payload, such as strings.
|
||||||
|
* In the SEGGER RTT port, we need this in order to make a worst-case
|
||||||
|
* allocation on the stack.
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef TRC_STREAM_PORT_ALLOCATE_DYNAMIC_EVENT
|
||||||
|
#if (TRC_STREAM_PORT_USE_INTERNAL_BUFFER == 1)
|
||||||
|
#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 */
|
||||||
|
#else
|
||||||
|
#define TRC_STREAM_PORT_ALLOCATE_DYNAMIC_EVENT(_type, _ptrData, _size) _type _tmpArray[sizeof(largestEventType) / sizeof(_type)]; _type* _ptrData = _tmpArray;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TRC_STREAM_PORT_COMMIT_EVENT
|
||||||
|
*
|
||||||
|
* The COMMIT macro is used to write a single event record directly to the
|
||||||
|
* streaming inteface, without first storing the event in the internal buffer.
|
||||||
|
* This is currently only used in the SEGGER J-Link RTT port.
|
||||||
|
*
|
||||||
|
* This relies on the TRC_STREAM_PORT_WRITE_DATA macro, defined in by the
|
||||||
|
* stream port in trcStreamingPort.h. The COMMIT macro calls
|
||||||
|
* prvTraceWarning(TRC_STREAM_PORT_WRITE_DATA) if a non-zero value is returned
|
||||||
|
* from TRC_STREAM_PORT_WRITE_DATA. If zero (0) is returned, it is assumed
|
||||||
|
* that all data was successfully written.
|
||||||
|
*
|
||||||
|
* In ports using the internal buffer, this macro has no purpose as the events
|
||||||
|
* are written to the internal buffer instead. They are then flushed to the
|
||||||
|
* streaming interface in the TzCtrl task using TRC_STREAM_PORT_WRITE_DATA.
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef TRC_STREAM_PORT_COMMIT_EVENT
|
||||||
|
#if (TRC_STREAM_PORT_USE_INTERNAL_BUFFER == 1)
|
||||||
|
#define TRC_STREAM_PORT_COMMIT_EVENT(_ptrData, _size) /* Not used */
|
||||||
|
#else
|
||||||
|
#define TRC_STREAM_PORT_COMMIT_EVENT(_ptrData, _size) \
|
||||||
|
{ \
|
||||||
|
if (TRC_STREAM_PORT_WRITE_DATA(_ptrData, _size, 0) != 0)\
|
||||||
|
prvTraceWarning(PSF_WARNING_STREAM_PORT_WRITE); \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TRC_STREAM_PORT_READ_DATA (defined in trcStreamingPort.h)
|
||||||
|
*
|
||||||
|
* Defining how to read data from host (commands from Tracealyzer).
|
||||||
|
*
|
||||||
|
* If there is no direct interface to host (e.g., if streaming to a file
|
||||||
|
* system) this should be defined as 0. Instead use vTraceEnable(TRC_START) and
|
||||||
|
* vTraceStop() to control the recording from target.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* - _ptrData: a pointer to a data buffer, where the received data shall be
|
||||||
|
* stored (TracealyzerCommandType*).
|
||||||
|
*
|
||||||
|
* - _size: the number of bytes to read (int).
|
||||||
|
*
|
||||||
|
* - _ptrBytesRead: a pointer to an integer (int), that should be assigned
|
||||||
|
* with the number of bytes that was received.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
*
|
||||||
|
* int32_t myRead(void* ptrData, uint32_t size, int32_t* ptrBytesRead);
|
||||||
|
*
|
||||||
|
* #define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) \
|
||||||
|
* myRead(_ptrData, _size, _ptrBytesRead)
|
||||||
|
*
|
||||||
|
* Your "myRead" function should return 0 if successful, i.e. if at least some
|
||||||
|
* bytes were received. A non-zero value should be returned if the streaming
|
||||||
|
* interface returned an error (e.g. a closed socket), which results in the
|
||||||
|
* recorder calling prvTraceWarning with the error code
|
||||||
|
* PSF_WARNING_STREAM_PORT_WRITE.
|
||||||
|
*
|
||||||
|
* If developing your own custom stream port and using the default internal
|
||||||
|
* buffer, it is important that the _ptrBytesRead parameter is assigned
|
||||||
|
* correctly by "myRead", i.e. with the number of bytes actually written.
|
||||||
|
* Otherwise the data stream may get out of sync in case the streaming interface
|
||||||
|
* can't swallow all data at once.
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef TRC_STREAM_PORT_READ_DATA
|
||||||
|
#error "No definition for TRC_STREAM_PORT_READ_DATA (should be in trcStreamingPort.h)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TRC_STREAM_PORT_WRITE_DATA (defined in trcStreamingPort.h)
|
||||||
|
*
|
||||||
|
* Defining how to write trace data to the streaming interface.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* - _ptrData: a pointer (void*) to the data to write.
|
||||||
|
*
|
||||||
|
* - _size: the number of bytes to write (uint32_t).
|
||||||
|
*
|
||||||
|
* - _ptrBytesWritten: a pointer to an integer (int32_t), that should be
|
||||||
|
* assigned with the number of bytes actually written.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
*
|
||||||
|
* int32_t myWrite(void* ptrData, uint32_t size, int32_t* ptrBytesWritten);
|
||||||
|
*
|
||||||
|
* #define TRC_STREAM_PORT_WRITE_DATA(_ptrData, _size, _ptrBytesWritten) \
|
||||||
|
* myWrite(_ptrData, _size, _ptrBytesWritten)
|
||||||
|
*
|
||||||
|
* Your "myWrite" function should return 0 if successful, i.e. if at least some
|
||||||
|
* bytes were sent. A non-zero value should be returned if the streaming interface
|
||||||
|
* returned an error (e.g. a closed socket), which results in the recorder calling
|
||||||
|
* prvTraceWarning with the error code PSF_WARNING_STREAM_PORT_WRITE.
|
||||||
|
*
|
||||||
|
* If developing your own custom stream port and using the default internal
|
||||||
|
* buffer, it is important that the _ptrBytesWritten parameter is assigned
|
||||||
|
* correctly by "myWrite", i.e. with the number of bytes actually written.
|
||||||
|
* Otherwise the data stream may get out of sync in case the streaming interface
|
||||||
|
* can't swallow all data at once.
|
||||||
|
*
|
||||||
|
* Assuming TRC_STREAM_PORT_USE_INTERNAL_BUFFER is 1 (default), the TzCtrl task
|
||||||
|
* will use this macro to send one buffer page at a time. In case all data can't
|
||||||
|
* be written at once (if _ptrBytesWritten is less than _size), the TzCtrl task
|
||||||
|
* is smart enough to make repeated calls (with updated parameters) in order to
|
||||||
|
* send the remaining data.
|
||||||
|
*
|
||||||
|
* However, if TRC_STREAM_PORT_USE_INTERNAL_BUFFER is 0, this is used from the
|
||||||
|
* COMMIT macro, directly in the "event functions". In that case, the
|
||||||
|
* _ptrBytesWritten parameter will be NULL and should be ignored by the write
|
||||||
|
* function. In this case, it is assumed that all data can be sent in a single
|
||||||
|
* call, otherwise the write function should return a non-zero error code.
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef TRC_STREAM_PORT_WRITE_DATA
|
||||||
|
#error "No definition for TRC_STREAM_PORT_WRITE_DATA (should be in trcStreamingPort.h)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Data structure declaration, depending on TRC_CFG_RECORDER_BUFFER_ALLOCATION
|
||||||
|
*******************************************************************************/
|
||||||
|
#if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_STATIC)
|
||||||
|
|
||||||
|
/* Static allocation. */
|
||||||
|
|
||||||
|
/* If not defined in trcStreamingPort.h */
|
||||||
|
#ifndef TRC_STREAM_PORT_ALLOCATE_FIELDS
|
||||||
|
#define TRC_STREAM_PORT_ALLOCATE_FIELDS() \
|
||||||
|
char _TzTraceData[(TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT) * (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE)];
|
||||||
|
extern char _TzTraceData[(TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT) * (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE)];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If not defined in trcStreamingPort.h */
|
||||||
|
#ifndef TRC_STREAM_PORT_MALLOC
|
||||||
|
#define TRC_STREAM_PORT_MALLOC() /* Static allocation. Not used. */
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
/* For Dynamic or Custom Allocation mode */
|
||||||
|
|
||||||
|
/* If not defined in trcStreamingPort.h */
|
||||||
|
#ifndef TRC_STREAM_PORT_ALLOCATE_FIELDS
|
||||||
|
#define TRC_STREAM_PORT_ALLOCATE_FIELDS() char* _TzTraceData = NULL;
|
||||||
|
extern char* _TzTraceData;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If not defined in trcStreamingPort.h */
|
||||||
|
#ifndef TRC_STREAM_PORT_MALLOC
|
||||||
|
#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 allocation. Not used. */
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TRC_STREAM_PORT_INIT
|
||||||
|
#define TRC_STREAM_PORT_INIT() \
|
||||||
|
TRC_STREAM_PORT_MALLOC(); /* Empty if static allocation mode */ \
|
||||||
|
prvPagedEventBufferInit(_TzTraceData);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Signal an error. */
|
||||||
|
void prvTraceError(int errCode);
|
||||||
|
|
||||||
|
/* Signal an warning (does not stop the recorder). */
|
||||||
|
void prvTraceWarning(int errCode);
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*** ERROR AND WARNING CODES (check using xTraceGetLastError) *****************/
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
#define PSF_ERROR_NONE 0
|
||||||
|
#define PSF_ERROR_EVENT_CODE_TOO_LARGE 1
|
||||||
|
#define PSF_ERROR_ISR_NESTING_OVERFLOW 2
|
||||||
|
#define PSF_ERROR_DWT_NOT_SUPPORTED 3
|
||||||
|
#define PSF_ERROR_DWT_CYCCNT_NOT_SUPPORTED 4
|
||||||
|
#define PSF_ERROR_TZCTRLTASK_NOT_CREATED 5
|
||||||
|
|
||||||
|
#define PSF_WARNING_SYMBOL_TABLE_SLOTS 101
|
||||||
|
#define PSF_WARNING_SYMBOL_MAX_LENGTH 102
|
||||||
|
#define PSF_WARNING_OBJECT_DATA_SLOTS 103
|
||||||
|
#define PSF_WARNING_STRING_TOO_LONG 104
|
||||||
|
#define PSF_WARNING_STREAM_PORT_READ 105
|
||||||
|
#define PSF_WARNING_STREAM_PORT_WRITE 106
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/*** INTERNAL STREAMING FUNCTIONS *********************************************/
|
/*** INTERNAL STREAMING FUNCTIONS *********************************************/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -1320,10 +1676,7 @@ void prvPagedEventBufferInit(char* buffer);
|
||||||
void* prvPagedEventBufferGetWritePointer(int sizeOfEvent);
|
void* prvPagedEventBufferGetWritePointer(int sizeOfEvent);
|
||||||
|
|
||||||
/* Transfer a full buffer page */
|
/* Transfer a full buffer page */
|
||||||
int32_t prvPagedEventBufferTransfer(int32_t(*writeFunc)(void* data, uint32_t size, int32_t* ptrBytesWritten), int32_t* nofBytes);
|
uint32_t prvPagedEventBufferTransfer(void);
|
||||||
|
|
||||||
/* Resets the paged event buffer */
|
|
||||||
void prvPagedEventBufferReset(void);
|
|
||||||
|
|
||||||
/* The data structure for commands (a bit overkill) */
|
/* The data structure for commands (a bit overkill) */
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -1344,6 +1697,7 @@ int prvIsValidCommand(TracealyzerCommandType* cmd);
|
||||||
/* Executed the received command (Start or Stop) */
|
/* Executed the received command (Start or Stop) */
|
||||||
void prvProcessCommand(TracealyzerCommandType* cmd);
|
void prvProcessCommand(TracealyzerCommandType* cmd);
|
||||||
|
|
||||||
|
#define vTraceSetStopHook(x)
|
||||||
|
|
||||||
#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/
|
#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/
|
||||||
|
|
||||||
|
@ -1363,6 +1717,9 @@ void prvProcessCommand(TracealyzerCommandType* cmd);
|
||||||
#define vTraceChannelPrint(label)
|
#define vTraceChannelPrint(label)
|
||||||
#define vTraceUBData(label, ...)
|
#define vTraceUBData(label, ...)
|
||||||
|
|
||||||
|
#define vTraceSetFilterGroup(x)
|
||||||
|
#define vTraceSetFilterMask(x)
|
||||||
|
|
||||||
#define prvTraceSetReadyEventsEnabled(status)
|
#define prvTraceSetReadyEventsEnabled(status)
|
||||||
|
|
||||||
#define vTraceExcludeTask(handle)
|
#define vTraceExcludeTask(handle)
|
||||||
|
@ -1379,6 +1736,10 @@ void prvProcessCommand(TracealyzerCommandType* cmd);
|
||||||
#define TRC_ALLOC_CUSTOM_BUFFER(bufname)
|
#define TRC_ALLOC_CUSTOM_BUFFER(bufname)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define xTraceIsRecordingEnabled() (0)
|
||||||
|
|
||||||
|
#define vTraceSetStopHook(x)
|
||||||
|
|
||||||
#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/
|
#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -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
|
* Percepio AB, www.percepio.com
|
||||||
*
|
*
|
||||||
* trcConfig.h
|
* trcConfig.h
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
*
|
*
|
||||||
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
||||||
*
|
*
|
||||||
* Copyright Percepio AB, 2016.
|
* Copyright Percepio AB, 2018.
|
||||||
* www.percepio.com
|
* www.percepio.com
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
@ -99,6 +99,161 @@ extern "C" {
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#define TRC_CFG_RECORDER_MODE TRC_RECORDER_MODE_SNAPSHOT
|
#define TRC_CFG_RECORDER_MODE TRC_RECORDER_MODE_SNAPSHOT
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TRC_CFG_FREERTOS_VERSION
|
||||||
|
*
|
||||||
|
* Specify what version of FreeRTOS that is used (don't change unless using the
|
||||||
|
* trace recorder library with an older version of FreeRTOS).
|
||||||
|
*
|
||||||
|
* TRC_FREERTOS_VERSION_7_3 If using FreeRTOS v7.3.x
|
||||||
|
* TRC_FREERTOS_VERSION_7_4 If using FreeRTOS v7.4.x
|
||||||
|
* TRC_FREERTOS_VERSION_7_5_OR_7_6 If using FreeRTOS v7.5.0 - v7.6.0
|
||||||
|
* TRC_FREERTOS_VERSION_8_X If using FreeRTOS v8.X.X
|
||||||
|
* TRC_FREERTOS_VERSION_9_0_0 If using FreeRTOS v9.0.0
|
||||||
|
* TRC_FREERTOS_VERSION_9_0_1 If using FreeRTOS v9.0.1
|
||||||
|
* TRC_FREERTOS_VERSION_9_0_2 If using FreeRTOS v9.0.2
|
||||||
|
* TRC_FREERTOS_VERSION_10_0_0 If using FreeRTOS v10.0.0 or later
|
||||||
|
*****************************************************************************/
|
||||||
|
#define TRC_CFG_FREERTOS_VERSION TRC_FREERTOS_VERSION_10_0_0
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* TRC_CFG_SCHEDULING_ONLY
|
||||||
|
*
|
||||||
|
* Macro which should be defined as an integer value.
|
||||||
|
*
|
||||||
|
* If this setting is enabled (= 1), only scheduling events are recorded.
|
||||||
|
* If disabled (= 0), all events are recorded (unless filtered in other ways).
|
||||||
|
*
|
||||||
|
* Default value is 0 (= include additional events).
|
||||||
|
******************************************************************************/
|
||||||
|
#define TRC_CFG_SCHEDULING_ONLY 0
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TRC_CFG_INCLUDE_MEMMANG_EVENTS
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
|
*
|
||||||
|
* This controls if malloc and free calls should be traced. Set this to zero (0)
|
||||||
|
* to exclude malloc/free calls, or one (1) to include such events in the trace.
|
||||||
|
*
|
||||||
|
* Default value is 1.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define TRC_CFG_INCLUDE_MEMMANG_EVENTS 1
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TRC_CFG_INCLUDE_USER_EVENTS
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
|
*
|
||||||
|
* If this is zero (0), all code related to User Events is excluded in order
|
||||||
|
* to reduce code size. Any attempts of storing User Events are then silently
|
||||||
|
* ignored.
|
||||||
|
*
|
||||||
|
* User Events are application-generated events, like "printf" but for the
|
||||||
|
* trace log, generated using vTracePrint and vTracePrintF.
|
||||||
|
* The formatting is done on host-side, by Tracealyzer. User Events are
|
||||||
|
* therefore much faster than a console printf and can often be used
|
||||||
|
* in timing critical code without problems.
|
||||||
|
*
|
||||||
|
* Note: In streaming mode, User Events are used to provide error messages
|
||||||
|
* and warnings from the recorder (in case of incorrect configuration) for
|
||||||
|
* display in Tracealyzer. Disabling user events will also disable these
|
||||||
|
* warnings. You can however still catch them by calling xTraceGetLastError
|
||||||
|
* or by putting breakpoints in prvTraceError and prvTraceWarning.
|
||||||
|
*
|
||||||
|
* Default value is 1.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define TRC_CFG_INCLUDE_USER_EVENTS 1
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* TRC_CFG_INCLUDE_ISR_TRACING
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
|
*
|
||||||
|
* If this is zero (0), the code for recording Interrupt Service Routines is
|
||||||
|
* excluded, in order to reduce code size.
|
||||||
|
*
|
||||||
|
* Default value is 1.
|
||||||
|
*
|
||||||
|
* Note: tracing ISRs requires that you insert calls to vTraceStoreISRBegin
|
||||||
|
* and vTraceStoreISREnd in your interrupt handlers.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define TRC_CFG_INCLUDE_ISR_TRACING 1
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* TRC_CFG_INCLUDE_READY_EVENTS
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
|
*
|
||||||
|
* If one (1), events are recorded when tasks enter scheduling state "ready".
|
||||||
|
* This allows Tracealyzer to show the initial pending time before tasks enter
|
||||||
|
* the execution state, and present accurate response times.
|
||||||
|
* If zero (0), "ready events" are not created, which allows for recording
|
||||||
|
* longer traces in the same amount of RAM.
|
||||||
|
*
|
||||||
|
* Default value is 1.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define TRC_CFG_INCLUDE_READY_EVENTS 1
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* TRC_CFG_INCLUDE_OSTICK_EVENTS
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
|
*
|
||||||
|
* If this is one (1), events will be generated whenever the OS clock is
|
||||||
|
* increased. If zero (0), OS tick events are not generated, which allows for
|
||||||
|
* recording longer traces in the same amount of RAM.
|
||||||
|
*
|
||||||
|
* Default value is 1.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define TRC_CFG_INCLUDE_OSTICK_EVENTS 1
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
|
*
|
||||||
|
* If this is zero (0), the trace will exclude any "event group" events.
|
||||||
|
*
|
||||||
|
* Default value is 0 (excluded) since dependent on event_groups.c
|
||||||
|
*****************************************************************************/
|
||||||
|
#define TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS 0
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* TRC_CFG_INCLUDE_TIMER_EVENTS
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
|
*
|
||||||
|
* If this is zero (0), the trace will exclude any Timer events.
|
||||||
|
*
|
||||||
|
* Default value is 0 since dependent on timers.c
|
||||||
|
*****************************************************************************/
|
||||||
|
#define TRC_CFG_INCLUDE_TIMER_EVENTS 0
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
|
*
|
||||||
|
* If this is zero (0), the trace will exclude any "pending function call"
|
||||||
|
* events, such as xTimerPendFunctionCall().
|
||||||
|
*
|
||||||
|
* Default value is 0 since dependent on timers.c
|
||||||
|
*****************************************************************************/
|
||||||
|
#define TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS 0
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Configuration Macro: TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
|
*
|
||||||
|
* If this is zero (0), the trace will exclude any stream buffer or message
|
||||||
|
* buffer events.
|
||||||
|
*
|
||||||
|
* Default value is 0 since dependent on stream_buffer.c (new in FreeRTOS v10)
|
||||||
|
******************************************************************************/
|
||||||
|
#define TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS 0
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Configuration Macro: TRC_CFG_RECORDER_BUFFER_ALLOCATION
|
* Configuration Macro: TRC_CFG_RECORDER_BUFFER_ALLOCATION
|
||||||
*
|
*
|
||||||
|
@ -117,19 +272,6 @@ extern "C" {
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#define TRC_CFG_RECORDER_BUFFER_ALLOCATION TRC_RECORDER_BUFFER_ALLOCATION_STATIC
|
#define TRC_CFG_RECORDER_BUFFER_ALLOCATION TRC_RECORDER_BUFFER_ALLOCATION_STATIC
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* TRC_CFG_FREERTOS_VERSION
|
|
||||||
*
|
|
||||||
* Specify what version of FreeRTOS that is used (don't change unless using the
|
|
||||||
* trace recorder library with an older version of FreeRTOS).
|
|
||||||
*
|
|
||||||
* TRC_FREERTOS_VERSION_7_3_OR_7_4 If using FreeRTOS v7.3.0 - v7.4.2
|
|
||||||
* TRC_FREERTOS_VERSION_7_5_OR_7_6 If using FreeRTOS v7.5.0 - v7.6.0
|
|
||||||
* TRC_FREERTOS_VERSION_8_X If using FreeRTOS v8.X.X
|
|
||||||
* TRC_FREERTOS_VERSION_9_X If using FreeRTOS v9.X.X
|
|
||||||
*****************************************************************************/
|
|
||||||
#define TRC_CFG_FREERTOS_VERSION TRC_FREERTOS_VERSION_9_X
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* TRC_CFG_MAX_ISR_NESTING
|
* TRC_CFG_MAX_ISR_NESTING
|
||||||
*
|
*
|
||||||
|
|
|
@ -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
|
* Percepio AB, www.percepio.com
|
||||||
*
|
*
|
||||||
* trcSnapshotConfig.h
|
* trcSnapshotConfig.h
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
*
|
*
|
||||||
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
||||||
*
|
*
|
||||||
* Copyright Percepio AB, 2017.
|
* Copyright Percepio AB, 2018.
|
||||||
* www.percepio.com
|
* www.percepio.com
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
@ -69,22 +69,6 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
#define TRC_CFG_SNAPSHOT_MODE TRC_SNAPSHOT_MODE_RING_BUFFER
|
#define TRC_CFG_SNAPSHOT_MODE TRC_SNAPSHOT_MODE_RING_BUFFER
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* TRC_CFG_SCHEDULING_ONLY
|
|
||||||
*
|
|
||||||
* Macro which should be defined as an integer value.
|
|
||||||
*
|
|
||||||
* If this setting is enabled (= 1), only scheduling events are recorded.
|
|
||||||
* If disabled (= 0), all events are recorded.
|
|
||||||
*
|
|
||||||
* For users of Tracealyzer Free Edition, that only displays scheduling events, this
|
|
||||||
* option can be used to avoid storing other events.
|
|
||||||
*
|
|
||||||
* Default value is 0 (store all enabled events).
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
#define TRC_CFG_SCHEDULING_ONLY 0
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* TRC_CFG_EVENT_BUFFER_SIZE
|
* TRC_CFG_EVENT_BUFFER_SIZE
|
||||||
*
|
*
|
||||||
|
@ -122,83 +106,15 @@
|
||||||
* check the actual usage by selecting View menu -> Trace Details ->
|
* check the actual usage by selecting View menu -> Trace Details ->
|
||||||
* Resource Usage -> Object Table.
|
* Resource Usage -> Object Table.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#define TRC_CFG_NTASK 10
|
#define TRC_CFG_NTASK 15
|
||||||
#define TRC_CFG_NISR 5
|
#define TRC_CFG_NISR 5
|
||||||
#define TRC_CFG_NQUEUE 10
|
#define TRC_CFG_NQUEUE 10
|
||||||
#define TRC_CFG_NSEMAPHORE 10
|
#define TRC_CFG_NSEMAPHORE 10
|
||||||
#define TRC_CFG_NMUTEX 10
|
#define TRC_CFG_NMUTEX 10
|
||||||
#define TRC_CFG_NTIMER 5
|
#define TRC_CFG_NTIMER 5
|
||||||
#define TRC_CFG_NEVENTGROUP 5
|
#define TRC_CFG_NEVENTGROUP 5
|
||||||
|
#define TRC_CFG_NSTREAMBUFFER 5
|
||||||
/******************************************************************************
|
#define TRC_CFG_NMESSAGEBUFFER 5
|
||||||
* TRC_CFG_INCLUDE_MEMMANG_EVENTS
|
|
||||||
*
|
|
||||||
* Macro which should be defined as either zero (0) or one (1).
|
|
||||||
*
|
|
||||||
* This controls if malloc and free calls should be traced. Set this to zero (0)
|
|
||||||
* to exclude malloc/free calls, or one (1) to include such events in the trace.
|
|
||||||
*
|
|
||||||
* Default value is 1.
|
|
||||||
*****************************************************************************/
|
|
||||||
#define TRC_CFG_INCLUDE_MEMMANG_EVENTS 1
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* TRC_CFG_INCLUDE_USER_EVENTS
|
|
||||||
*
|
|
||||||
* Macro which should be defined as either zero (0) or one (1).
|
|
||||||
*
|
|
||||||
* If this is zero (0) the code for creating User Events is excluded to
|
|
||||||
* reduce code size. User Events are application-generated events, like
|
|
||||||
* "printf" but for the trace log and the formatting is done offline, by the
|
|
||||||
* Tracealyzer visualization tool. User Events are much faster than a printf
|
|
||||||
* and can therefore be used in timing critical code.
|
|
||||||
*
|
|
||||||
* Default value is 1.
|
|
||||||
*****************************************************************************/
|
|
||||||
#define TRC_CFG_INCLUDE_USER_EVENTS 1
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* TRC_CFG_INCLUDE_ISR_TRACING
|
|
||||||
*
|
|
||||||
* Macro which should be defined as either zero (0) or one (1).
|
|
||||||
*
|
|
||||||
* If this is zero (0), the code for recording Interrupt Service Routines is
|
|
||||||
* excluded, in order to reduce code size.
|
|
||||||
*
|
|
||||||
* Default value is 1.
|
|
||||||
*
|
|
||||||
* Note: tracing ISRs requires that you insert calls to vTraceStoreISRBegin
|
|
||||||
* and vTraceStoreISREnd in your interrupt handlers.
|
|
||||||
*****************************************************************************/
|
|
||||||
#define TRC_CFG_INCLUDE_ISR_TRACING 1
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* TRC_CFG_INCLUDE_READY_EVENTS
|
|
||||||
*
|
|
||||||
* Macro which should be defined as either zero (0) or one (1).
|
|
||||||
*
|
|
||||||
* If one (1), events are recorded when tasks enter scheduling state "ready".
|
|
||||||
* This allows Tracealyzer to show the initial pending time before tasks enter
|
|
||||||
* the execution state, and present accurate response times.
|
|
||||||
* If zero (0), "ready events" are not created, which allows for recording
|
|
||||||
* longer traces in the same amount of RAM.
|
|
||||||
*
|
|
||||||
* Default value is 1.
|
|
||||||
*****************************************************************************/
|
|
||||||
#define TRC_CFG_INCLUDE_READY_EVENTS 1
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* TRC_CFG_INCLUDE_OSTICK_EVENTS
|
|
||||||
*
|
|
||||||
* Macro which should be defined as either zero (0) or one (1).
|
|
||||||
*
|
|
||||||
* If this is one (1), events will be generated whenever the OS clock is
|
|
||||||
* increased. If zero (0), OS tick events are not generated, which allows for
|
|
||||||
* recording longer traces in the same amount of RAM.
|
|
||||||
*
|
|
||||||
* Default value is 0.
|
|
||||||
*****************************************************************************/
|
|
||||||
#define TRC_CFG_INCLUDE_OSTICK_EVENTS 0
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* TRC_CFG_INCLUDE_FLOAT_SUPPORT
|
* TRC_CFG_INCLUDE_FLOAT_SUPPORT
|
||||||
|
@ -218,19 +134,6 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
#define TRC_CFG_INCLUDE_FLOAT_SUPPORT 0
|
#define TRC_CFG_INCLUDE_FLOAT_SUPPORT 0
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* TRC_CFG_INCLUDE_OBJECT_DELETE
|
|
||||||
*
|
|
||||||
* Macro which should be defined as either zero (0) or one (1).
|
|
||||||
*
|
|
||||||
* This must be enabled (1) if tasks, queues or other
|
|
||||||
* traced kernel objects are deleted at runtime. If no deletes are made, this
|
|
||||||
* can be set to 0 in order to exclude the delete-handling code.
|
|
||||||
*
|
|
||||||
* Default value is 1.
|
|
||||||
*****************************************************************************/
|
|
||||||
#define TRC_CFG_INCLUDE_OBJECT_DELETE 1
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* TRC_CFG_SYMBOL_TABLE_SIZE
|
* TRC_CFG_SYMBOL_TABLE_SIZE
|
||||||
*
|
*
|
||||||
|
@ -265,6 +168,8 @@
|
||||||
#define TRC_CFG_NAME_LEN_MUTEX 15
|
#define TRC_CFG_NAME_LEN_MUTEX 15
|
||||||
#define TRC_CFG_NAME_LEN_TIMER 15
|
#define TRC_CFG_NAME_LEN_TIMER 15
|
||||||
#define TRC_CFG_NAME_LEN_EVENTGROUP 15
|
#define TRC_CFG_NAME_LEN_EVENTGROUP 15
|
||||||
|
#define TRC_CFG_NAME_LEN_STREAMBUFFER 15
|
||||||
|
#define TRC_CFG_NAME_LEN_MESSAGEBUFFER 15
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
*** ADVANCED SETTINGS ********************************************************
|
*** ADVANCED SETTINGS ********************************************************
|
||||||
|
|
|
@ -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
|
* Percepio AB, www.percepio.com
|
||||||
*
|
*
|
||||||
* trcStreamingConfig.h
|
* trcStreamingConfig.h
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
*
|
*
|
||||||
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
||||||
*
|
*
|
||||||
* Copyright Percepio AB, 2017.
|
* Copyright Percepio AB, 2018.
|
||||||
* www.percepio.com
|
* www.percepio.com
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ extern "C" {
|
||||||
* - Task names
|
* - Task names
|
||||||
* - Named ISRs (vTraceSetISRProperties)
|
* - Named ISRs (vTraceSetISRProperties)
|
||||||
* - Named kernel objects (vTraceStoreKernelObjectName)
|
* - Named kernel objects (vTraceStoreKernelObjectName)
|
||||||
* - User event channels (vTraceStoreUserEventChannelName)
|
* - User event channels (xTraceRegisterString)
|
||||||
*
|
*
|
||||||
* If this value is too small, not all symbol names will be stored and the
|
* If this value is too small, not all symbol names will be stored and the
|
||||||
* trace display will be affected. In that case, there will be warnings
|
* trace display will be affected. In that case, there will be warnings
|
||||||
|
@ -72,7 +72,7 @@ extern "C" {
|
||||||
* - Task names
|
* - Task names
|
||||||
* - Named ISRs (vTraceSetISRProperties)
|
* - Named ISRs (vTraceSetISRProperties)
|
||||||
* - Named kernel objects (vTraceStoreKernelObjectName)
|
* - Named kernel objects (vTraceStoreKernelObjectName)
|
||||||
* - User event channel names (vTraceStoreUserEventChannelName)
|
* - User event channel names (xTraceRegisterString)
|
||||||
*
|
*
|
||||||
* If longer symbol names are used, they will be truncated by the recorder,
|
* If longer symbol names are used, they will be truncated by the recorder,
|
||||||
* which will affect the trace display. In that case, there will be warnings
|
* which will affect the trace display. In that case, there will be warnings
|
||||||
|
@ -123,7 +123,7 @@ extern "C" {
|
||||||
* Specifies the number of pages used by the paged event buffer.
|
* Specifies the number of pages used by the paged event buffer.
|
||||||
* This may need to be increased if there are a lot of missed events.
|
* This may need to be increased if there are a lot of missed events.
|
||||||
*
|
*
|
||||||
* Note: not used by the J-Link RTT stream port (see SEGGER_RTT_Conf.h instead)
|
* Note: not used by the J-Link RTT stream port (see trcStreamingPort.h instead)
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#define TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT 2
|
#define TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT 2
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ extern "C" {
|
||||||
* to match any internal low-level buffers used by the streaming interface, like
|
* to match any internal low-level buffers used by the streaming interface, like
|
||||||
* the Ethernet MTU (Maximum Transmission Unit).
|
* the Ethernet MTU (Maximum Transmission Unit).
|
||||||
*
|
*
|
||||||
* Note: not used by the J-Link RTT stream port (see SEGGER_RTT_Conf.h instead)
|
* Note: not used by the J-Link RTT stream port (see trcStreamingPort.h instead)
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#define TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE 2500
|
#define TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE 2500
|
||||||
|
|
||||||
|
|
|
@ -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)";
|
|
@ -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
|
|
@ -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 */
|
|
@ -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
|
|
@ -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
|
|
@ -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 */
|
|
@ -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)*/
|
|
@ -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 ****************************/
|
|
|
@ -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
|
* Percepio AB, www.percepio.com
|
||||||
*
|
*
|
||||||
* trcStreamingPort.h
|
* trcStreamingPort.h
|
||||||
|
@ -7,6 +7,11 @@
|
||||||
* The interface definitions for trace streaming ("stream ports").
|
* The interface definitions for trace streaming ("stream ports").
|
||||||
* This "stream port" sets up the recorder to use SEGGER RTT as streaming channel.
|
* 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
|
* Terms of Use
|
||||||
* This file is part of the trace recorder library (RECORDER), which is the
|
* This file is part of the trace recorder library (RECORDER), which is the
|
||||||
* intellectual property of Percepio AB (PERCEPIO) and provided under a
|
* 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)
|
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
||||||
*
|
*
|
||||||
* Copyright Percepio AB, 2017.
|
* Copyright Percepio AB, 2018.
|
||||||
* www.percepio.com
|
* www.percepio.com
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
@ -113,17 +118,18 @@ extern "C" {
|
||||||
* internal RAM buffer read by the J-Link probes during execution.
|
* internal RAM buffer read by the J-Link probes during execution.
|
||||||
*
|
*
|
||||||
* Possible values:
|
* Possible values:
|
||||||
* - SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL (default)
|
* - SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL
|
||||||
* - SEGGER_RTT_MODE_NO_BLOCK_SKIP
|
* - 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
|
* complete and valid trace. This may however cause blocking if your streaming
|
||||||
* interface isn't fast enough, which may disturb the real-time behavior.
|
* 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".
|
* 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_Conf.h"
|
||||||
#include "SEGGER_RTT.h"
|
#include "SEGGER_RTT.h"
|
||||||
|
@ -140,22 +146,18 @@ extern "C" {
|
||||||
#if TRC_CFG_RTT_UP_BUFFER_INDEX == 0
|
#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_RTT_ALLOC_UP() static char* _TzTraceData = NULL; /* Not actually used. Ignore allocation method. */
|
||||||
#define TRC_STREAM_PORT_MALLOC() /* Static allocation. Not used. */
|
#define TRC_STREAM_PORT_MALLOC() /* Static allocation. Not used. */
|
||||||
#define TRC_ALLOC_CUSTOM_BUFFER(bufname) /* Only for custom allocation */
|
|
||||||
#else
|
#else
|
||||||
#if TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_STATIC
|
#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_RTT_ALLOC_UP() char _TzTraceData[TRC_CFG_RTT_BUFFER_SIZE_UP]; /* Static allocation */
|
||||||
#define TRC_STREAM_PORT_MALLOC() /* Static allocation. Not used. */
|
#define TRC_STREAM_PORT_MALLOC() /* Static allocation. Not used. */
|
||||||
#define TRC_ALLOC_CUSTOM_BUFFER(bufname) /* Only for custom allocation */
|
|
||||||
#endif
|
#endif
|
||||||
#if TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC
|
#if TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC
|
||||||
#define TRC_RTT_ALLOC_UP() char* _TzTraceData = NULL; /* Dynamic allocation */
|
#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_STREAM_PORT_MALLOC() _TzTraceData = TRC_PORT_MALLOC(TRC_CFG_RTT_BUFFER_SIZE_UP);
|
||||||
#define TRC_ALLOC_CUSTOM_BUFFER(bufname) /* Only for custom allocation */
|
|
||||||
#endif
|
#endif
|
||||||
#if TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM
|
#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_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_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
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -170,20 +172,22 @@ extern "C" {
|
||||||
TRC_RTT_ALLOC_UP() /* Macro that will result in proper UP buffer allocation */ \
|
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 */
|
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() \
|
#define TRC_STREAM_PORT_INIT() \
|
||||||
TRC_STREAM_PORT_MALLOC(); /*Dynamic allocation or empty if static */ \
|
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_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);
|
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;
|
/* Important for the J-Link port, in most other ports this can be skipped (default is 1) */
|
||||||
#define TRC_STREAM_PORT_ALLOCATE_DYNAMIC_EVENT(_type, _ptrData, _size) _type _tmpArray[sizeof(largestEventType) / sizeof(_type)]; _type* _ptrData = _tmpArray;
|
#define TRC_STREAM_PORT_USE_INTERNAL_BUFFER 0
|
||||||
#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)
|
|
||||||
|
|
||||||
#define TRC_STREAM_PORT_ON_TRACE_BEGIN() /* Do nothing */
|
#define TRC_STREAM_PORT_WRITE_DATA(_ptrData, _size, _ptrBytesWritten) writeToRTT(_ptrData, _size, _ptrBytesWritten)
|
||||||
#define TRC_STREAM_PORT_ON_TRACE_END() /* Do nothing */
|
|
||||||
|
|
||||||
|
#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) readFromRTT(_ptrData, _size, _ptrBytesRead)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
@ -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
|
* Percepio AB, www.percepio.com
|
||||||
*
|
*
|
||||||
* trcStreamingPort.h
|
* trcStreamingPort.h
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
*
|
*
|
||||||
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
||||||
*
|
*
|
||||||
* Copyright Percepio AB, 2017.
|
* Copyright Percepio AB, 2018.
|
||||||
* www.percepio.com
|
* www.percepio.com
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
@ -51,37 +51,13 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#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);
|
int32_t trcTcpRead(void* data, uint32_t size, int32_t *ptrBytesRead);
|
||||||
|
|
||||||
#if TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_STATIC
|
int32_t trcTcpWrite(void* data, uint32_t size, int32_t *ptrBytesWritten);
|
||||||
#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
|
|
||||||
|
|
||||||
#define TRC_STREAM_PORT_INIT() \
|
#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) trcTcpRead(_ptrData, _size, _ptrBytesRead)
|
||||||
TRC_STREAM_PORT_MALLOC(); /*Dynamic allocation or empty if static */ \
|
|
||||||
prvPagedEventBufferInit(_TzTraceData);
|
|
||||||
|
|
||||||
#define TRC_STREAM_PORT_ALLOCATE_EVENT(_type, _ptrData, _size) _type* _ptrData; _ptrData = (_type*)prvPagedEventBufferGetWritePointer(_size);
|
#define TRC_STREAM_PORT_WRITE_DATA(_ptrData, _size, _ptrBytesSent) trcTcpWrite(_ptrData, _size, _ptrBytesSent)
|
||||||
#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 */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
* Percepio AB, www.percepio.com
|
||||||
*
|
*
|
||||||
* trcStreamingPort.c
|
* trcStreamingPort.c
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
*
|
*
|
||||||
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
||||||
*
|
*
|
||||||
* Copyright Percepio AB, 2017.
|
* Copyright Percepio AB, 2018.
|
||||||
* www.percepio.com
|
* www.percepio.com
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@
|
||||||
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
|
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
|
||||||
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
|
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
|
||||||
|
|
||||||
/* TCP/IP includes */
|
/* TCP/IP includes - for lwIP in this case */
|
||||||
#include "lwip/tcpip.h"
|
#include "lwip/tcpip.h"
|
||||||
#include "lwip/sockets.h"
|
#include "lwip/sockets.h"
|
||||||
|
|
||||||
|
@ -68,11 +68,14 @@ int32_t trcSocketSend( void* data, int32_t size, int32_t* bytesWritten )
|
||||||
if (new_sd < 0)
|
if (new_sd < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (bytesWritten == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
*bytesWritten = send( new_sd, data, size, 0 );
|
*bytesWritten = send( new_sd, data, size, 0 );
|
||||||
if (*bytesWritten < 0)
|
if (*bytesWritten < 0)
|
||||||
{
|
{
|
||||||
/* EWOULDBLOCK may be expected when buffers are full */
|
/* EWOULDBLOCK may be expected when buffers are full */
|
||||||
if (errno != EWOULDBLOCK)
|
if (errno != 0 && errno != EWOULDBLOCK)
|
||||||
{
|
{
|
||||||
closesocket(new_sd);
|
closesocket(new_sd);
|
||||||
new_sd = -1;
|
new_sd = -1;
|
||||||
|
@ -94,7 +97,7 @@ int32_t trcSocketReceive( void* data, int32_t size, int32_t* bytesRead )
|
||||||
if ( *bytesRead < 0 )
|
if ( *bytesRead < 0 )
|
||||||
{
|
{
|
||||||
/* EWOULDBLOCK may be expected when there is no data to receive */
|
/* EWOULDBLOCK may be expected when there is no data to receive */
|
||||||
if (errno != EWOULDBLOCK)
|
if (errno != 0 && errno != EWOULDBLOCK)
|
||||||
{
|
{
|
||||||
closesocket(new_sd);
|
closesocket(new_sd);
|
||||||
new_sd = -1;
|
new_sd = -1;
|
||||||
|
|
|
@ -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
|
* Percepio AB, www.percepio.com
|
||||||
*
|
*
|
||||||
* trcStreamingPort.h
|
* trcStreamingPort.h
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
*
|
*
|
||||||
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
||||||
*
|
*
|
||||||
* Copyright Percepio AB, 2017.
|
* Copyright Percepio AB, 2018.
|
||||||
* www.percepio.com
|
* www.percepio.com
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
@ -51,16 +51,6 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#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 files as needed, in this case it is files from STM32Cube FW_F7 V1.4.1 */
|
||||||
#include "usb_device.h"
|
#include "usb_device.h"
|
||||||
#include "usbd_cdc.h"
|
#include "usbd_cdc.h"
|
||||||
|
@ -70,32 +60,21 @@ extern "C" {
|
||||||
/* Tested on STM32 devices using Keil/CMSIS USB stack */
|
/* Tested on STM32 devices using Keil/CMSIS USB stack */
|
||||||
|
|
||||||
extern USBD_CDC_ItfTypeDef USBD_Interface_fops_FS;
|
extern USBD_CDC_ItfTypeDef USBD_Interface_fops_FS;
|
||||||
|
|
||||||
uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len);
|
uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len);
|
||||||
|
|
||||||
int32_t trcCDCReceive(void *data, uint32_t size, int32_t* NumBytes);
|
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
|
int32_t trcCDCTransmit(void* data, uint32_t size, int32_t * noOfBytesSent );
|
||||||
#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
|
|
||||||
|
|
||||||
#define TRC_STREAM_PORT_INIT() \
|
#define TRC_STREAM_PORT_INIT() \
|
||||||
MX_USB_DEVICE_Init(); \
|
MX_USB_DEVICE_Init(); \
|
||||||
TRC_STREAM_PORT_MALLOC(); /*Dynamic allocation or empty if static */
|
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_WRITE_DATA(_ptrData, _size, _ptrBytesSent) trcCDCTransmit(_ptrData, _size, _ptrBytesSent)
|
||||||
#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_ON_TRACE_BEGIN() { prvPagedEventBufferInit(_TzTraceData); }
|
|
||||||
#define TRC_STREAM_PORT_ON_TRACE_END() /* Do nothing */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
|
|
||||||
#include "trcRecorder.h"
|
#include "trcRecorder.h"
|
||||||
|
|
||||||
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
|
#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"
|
#include "stdint.h"
|
||||||
|
|
||||||
|
@ -29,8 +30,8 @@ uint8_t UserRxBufferFS[APP_RX_DATA_SIZE];
|
||||||
uint8_t UserTxBufferFS[APP_TX_DATA_SIZE];
|
uint8_t UserTxBufferFS[APP_TX_DATA_SIZE];
|
||||||
|
|
||||||
extern USBD_HandleTypeDef hUsbDeviceFS;
|
extern USBD_HandleTypeDef hUsbDeviceFS;
|
||||||
extern PCD_HandleTypeDef hpcd_USB_OTG_FS;
|
|
||||||
|
|
||||||
|
extern PCD_HandleTypeDef hpcd_USB_OTG_FS;
|
||||||
|
|
||||||
recBuf commandBuffer;
|
recBuf commandBuffer;
|
||||||
|
|
||||||
|
@ -186,6 +187,7 @@ uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The READ function, used in trcStreamingPort.h */
|
||||||
int32_t trcCDCReceive(void *data, uint32_t size, int32_t* NumBytes)
|
int32_t trcCDCReceive(void *data, uint32_t size, int32_t* NumBytes)
|
||||||
{
|
{
|
||||||
uint32_t i,diff;
|
uint32_t i,diff;
|
||||||
|
@ -217,13 +219,18 @@ int32_t trcCDCReceive(void *data, uint32_t size, int32_t* NumBytes)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The WRITE function, used in trcStreamingPort.h */
|
||||||
int32_t trcCDCTransmit(void* data, uint32_t size, int32_t * noOfBytesSent )
|
int32_t trcCDCTransmit(void* data, uint32_t size, int32_t * noOfBytesSent )
|
||||||
{
|
{
|
||||||
int32_t result;
|
int32_t result;
|
||||||
result=CDC_Transmit_FS(data,size);
|
result=CDC_Transmit_FS(data, size);
|
||||||
*noOfBytesSent=size;
|
*noOfBytesSent = size;
|
||||||
|
|
||||||
return result;
|
/* 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
317
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/tracealyzer_readme.txt
Normal file
317
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/tracealyzer_readme.txt
Normal file
|
@ -0,0 +1,317 @@
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Tracealyzer Recorder Library v4.1.0 for FreeRTOS
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Tracealyzer is a sophisticated tool for tracing and visualization
|
||||||
|
of FreeRTOS-based software systems.
|
||||||
|
|
||||||
|
Tracealyzer gives an unprecedented insight into the runtime behavior, which
|
||||||
|
speeds up debugging, validation and optimization.
|
||||||
|
|
||||||
|
This, the Trace Recorder Library, is the target-side part of Tracealyzer, that
|
||||||
|
performs the actual tracing. The resulting data can then be viewed in the
|
||||||
|
Tracealyzer PC application, found at https://percepio.com/tracealyzer
|
||||||
|
|
||||||
|
To learn more, see these links.
|
||||||
|
|
||||||
|
- Getting Started (videos etc): https://percepio.com/gettingstarted
|
||||||
|
|
||||||
|
- FAQ: https://percepio.com/category/faq
|
||||||
|
|
||||||
|
In case you have any questions, don't hesitate to contact support@percepio.com
|
||||||
|
|
||||||
|
Tracealyzer supports FreeRTOS v7.3 and newer, including Amazon FreeRTOS.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Changes, v4.0.3 -> v4.1.0
|
||||||
|
|
||||||
|
- Improved performance of User Events
|
||||||
|
- Fixed handling of format strings ending with '%'
|
||||||
|
- Improved handling of creative user configuration macros
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Changes, v4.0.2 -> v4.0.3
|
||||||
|
|
||||||
|
- Minor fix for TCP/IP stream port.
|
||||||
|
- Corrected default RTT mode setting.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Changes, v4.0.1 -> v4.0.2
|
||||||
|
|
||||||
|
- Memory allocation trace events now ignore filters.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Changes, v4.0.0 -> v4.0.1
|
||||||
|
|
||||||
|
- Minor fixes to default values.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Changes, v3.3.0 -> v4.0.0
|
||||||
|
|
||||||
|
- Fixed some issues with filters.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Changes, v3.2.0 -> v3.3.0
|
||||||
|
|
||||||
|
- Added support for FreeRTOS v10, including the new object types Message Buffer
|
||||||
|
and Stream Buffer.
|
||||||
|
|
||||||
|
- Improved the object-level filtering to also support Timer, Event Group,
|
||||||
|
Message Buffer and Stream Buffer objects.
|
||||||
|
|
||||||
|
- Fixed a few remaining build problems with older FreeRTOS versions (v7.x).
|
||||||
|
|
||||||
|
- vTraceStoreISRBegin now reports an error on invalid handles, i.e., if the
|
||||||
|
initialization of the handle (xTraceSetISRProperties) had not been made.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Changes, v3.1.2 -> v3.2.0
|
||||||
|
|
||||||
|
- Added new filtering system - that works in both snapshot and streaming mode.
|
||||||
|
Filtering was previously not supported in streaming mode, but can be very
|
||||||
|
useful for slower streaming interfaces. By exluding irrelevant events, the
|
||||||
|
amount of data produced can be reduced a lot.
|
||||||
|
|
||||||
|
* New functions vTraceSetFilterGroup and vTraceSetFilterMask allows for
|
||||||
|
excluding all events from specific objects (like a semaphore or queue).
|
||||||
|
|
||||||
|
* Added new "generic" filters (preprocessor level) to trcConfig.h, that
|
||||||
|
exclude all events of a particular types.
|
||||||
|
- TRC_CFG_INCLUDE_NOTIFY_EVENTS
|
||||||
|
- TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS
|
||||||
|
- TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS
|
||||||
|
- TRC_CFG_INCLUDE_TIMER_EVENTS
|
||||||
|
|
||||||
|
* Upgraded some previous filters from "Snapshot only" to the Common API
|
||||||
|
and thereby moved them from trcSnapshotConfig.h to trcConfig.h.
|
||||||
|
- TRC_CFG_SCHEDULING_ONLY
|
||||||
|
- TRC_CFG_INCLUDE_MEMMANG_EVENTS
|
||||||
|
- TRC_CFG_INCLUDE_USER_EVENTS
|
||||||
|
- TRC_CFG_INCLUDE_ISR_TRACING
|
||||||
|
- TRC_CFG_INCLUDE_READY_EVENTS
|
||||||
|
- TRC_CFG_INCLUDE_OSTICK_EVENTS
|
||||||
|
|
||||||
|
* Removed the old filter system from trcSnapshotRecorder.c.
|
||||||
|
|
||||||
|
- Improved streaming interface - Now only two (2) macros are needed to be
|
||||||
|
defined in most cases, read and write. This makes it a lot easier to make
|
||||||
|
custom stream ports.
|
||||||
|
|
||||||
|
* Many definitions that were identical in most stream ports, have been
|
||||||
|
replaced by default definitions in the recorder core. If needed, they
|
||||||
|
can be overriden by custom definitions in trcStreamingPort.h.
|
||||||
|
|
||||||
|
* Stream ports are now assumed to use recorder's internal event buffer.
|
||||||
|
Other stream ports that writes directly to the streaming interface
|
||||||
|
(like J-Link) should define TRC_STREAM_PORT_USE_INTERNAL_BUFFER
|
||||||
|
as zero (0) to make it work correctly.
|
||||||
|
|
||||||
|
* Macro TRC_STREAM_PORT_PERIODIC_SEND_DATA has been replaced by
|
||||||
|
TRC_STREAM_PORT_WRITE_DATA. Together with TRC_STREAM_PORT_READ_DATA,
|
||||||
|
this is all that is necessary for a typical stream port.
|
||||||
|
|
||||||
|
* Return values from the stream port macros READ_DATA and WRITE_DATA are
|
||||||
|
now checked. Expects 0 on success, anything else produces a warning
|
||||||
|
that can be retrived using xTraceGetLastError() and also seen in
|
||||||
|
Tracealyzer if a trace was produced.
|
||||||
|
|
||||||
|
* Stream ports should no longer call prvPagedEventBufferInit explicitly
|
||||||
|
(e.g. in TRC_STREAM_PORT_ON_TRACE_BEGIN). This is now called
|
||||||
|
automatically if TRC_STREAM_PORT_USE_INTERNAL_BUFFER == 1.
|
||||||
|
|
||||||
|
* Macros TRC_STREAM_PORT_ON_TRACE_BEGIN and TRC_STREAM_PORT_ON_TRACE_END
|
||||||
|
are now unused by default and don't need to be defined.
|
||||||
|
You can however use them to hook in some own function at these events.
|
||||||
|
|
||||||
|
- Added two new stream ports
|
||||||
|
|
||||||
|
* TCPIP-Win32: allows for testing the streaming on Windows ports of your
|
||||||
|
RTOS, using Winsock.
|
||||||
|
|
||||||
|
* File: example of streaming to a local file system (tested on Windows,
|
||||||
|
but easy to modify).
|
||||||
|
|
||||||
|
- Added support for FreeRTOS v9.0.1
|
||||||
|
|
||||||
|
* Replaced FreeRTOS version code TRC_FREERTOS_VERSION_9_X with
|
||||||
|
- TRC_FREERTOS_VERSION_9_0_0
|
||||||
|
- TRC_FREERTOS_VERSION_9_0_1
|
||||||
|
|
||||||
|
* Using TRC_FREERTOS_VERSION_9_X is no longer allowed.
|
||||||
|
|
||||||
|
- Added additional events for xQueuePeek, for blocking and timeouts events.
|
||||||
|
|
||||||
|
- Added event for traceTIMER_EXPIRED, showing when the timer callback
|
||||||
|
function is called.
|
||||||
|
|
||||||
|
- Improved diagnostics in streaming mode, in case of errors in the recorder.
|
||||||
|
|
||||||
|
* Added prvTraceWarning() - registers a "warning" error code, without
|
||||||
|
stopping the recorder. Called if READ_DATA or WRITE_DATA returns a
|
||||||
|
non-zero value, and in several other cases where the recorder
|
||||||
|
configuration is incorrect (e.g., too small symbol table).
|
||||||
|
|
||||||
|
* Added several new warning codes (PSF_WARNING_XYZ), corresponding to the
|
||||||
|
issues detected by prvCheckRecorderStatus.
|
||||||
|
|
||||||
|
* Fixed duplicate definitions of warning messages, so the warnings reported
|
||||||
|
to Tracealyzer are the same as those provided in xTraceGetLastError().
|
||||||
|
|
||||||
|
* Added better explainations of warning/error messages in the body of
|
||||||
|
xTraceGetLastError (in streaming mode).
|
||||||
|
|
||||||
|
- Added xTraceIsRecordingEnabled() to Common API.
|
||||||
|
|
||||||
|
- Added "unofficial" hardware port for Altera Nios-II.
|
||||||
|
This is a user contribition, not yet verified by Percerpio.
|
||||||
|
|
||||||
|
- Fixed bug in vTraceEnable - option TRC_START_AWAIT_HOST was ignored if already initialized.
|
||||||
|
|
||||||
|
- Fixed a few remaining compiler warnings.
|
||||||
|
|
||||||
|
- Changed order of some settings in trcConfig.h - moved advanced stuff to the
|
||||||
|
bottom.
|
||||||
|
|
||||||
|
- Removed SEGGER_RTT_Printf.c from the J-Link stream port since not required
|
||||||
|
for Tracealyzer.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Changes, v3.1.1 -> v3.1.2
|
||||||
|
- Fixed two bugs related to User Events, one in vTracePrintF and other in vTracePrint.
|
||||||
|
|
||||||
|
- Fixed a build problem related to a single reference of the old FreeRTOS type "xTaskHandle", in trcKernelPort.c.
|
||||||
|
Changed to "TaskHandle_t", unless if using an older FreeRTOS kernel or the "compatibility mode".
|
||||||
|
|
||||||
|
- Removed traceCREATE_MUTEX hook for FreeRTOS v9 or later (no longer required)
|
||||||
|
|
||||||
|
- Updated the User Manual regarding snapshot trace via IAR Embedded Workbench.
|
||||||
|
|
||||||
|
- Renamed vTraceGetTraceBuffer to xTraceGetTraceBuffer, since returning a pointer.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Changes, v3.1.0 -> v3.1.1
|
||||||
|
|
||||||
|
After the major changes in the v3.1.0 trace recorder library, this update
|
||||||
|
corrects a number of minor issues. Only minor functional improvements.
|
||||||
|
|
||||||
|
- You can now use TRC_ALLOC_CUSTOM_BUFFER to declare a trace buffer on a custom
|
||||||
|
location (using linker directives).
|
||||||
|
The related function vTraceSetRecorderDataBuffer has been promoted to the
|
||||||
|
Common API (previously only supported in snapshot mode, but custom allocation
|
||||||
|
is now generally supported also in streaming mode).
|
||||||
|
|
||||||
|
- Removed TRC_CFG_USE_LINKER_PRAGMA. No longer necessary thanks to the custom
|
||||||
|
allocation mode.
|
||||||
|
|
||||||
|
- Added support for timestamping from custom periodic timers, required for
|
||||||
|
accurate timestamping on Cortex-M0/M0+ devices when using tickless idle.
|
||||||
|
Only for streaming mode so far. See TRC_CUSTOM_TIMER_INCR / DECR.
|
||||||
|
|
||||||
|
- ARM Cortex-M port: Made sure the DWT unit is initialized properly, in case
|
||||||
|
the debugger doesn't handle this.
|
||||||
|
|
||||||
|
- ARM Cortex-M port: Added possibility to use Systick timestamping also on
|
||||||
|
Cortex-M3/M4/M7 devices (that otherwise use DWT timestamping by default).
|
||||||
|
To use this option, define the macro TRC_CFG_ARM_CM_USE_SYSTICK.
|
||||||
|
|
||||||
|
- J-Link streaming: The default RTT buffer has been changed from 0 to 1.
|
||||||
|
|
||||||
|
- J-Link streaming: The RTT buffer settings for buffer 1 and higher, are now
|
||||||
|
found in trcStreamingPort.h. Note: These settings don't apply to buffer 0.
|
||||||
|
|
||||||
|
- vTracePrint has been optimized for better performance in string logging.
|
||||||
|
|
||||||
|
- Minor performance improvement related to symbol table transfer in streaming mode.
|
||||||
|
|
||||||
|
- Timer names now registered also in streaming mode.
|
||||||
|
|
||||||
|
- Timer start and stop event are now traced.
|
||||||
|
|
||||||
|
- Implemented support for queue registry (traceQUEUE_REGISTRY_ADD) also for streaming.
|
||||||
|
|
||||||
|
- Fixed a bug related to repeated calls of vTraceEnable.
|
||||||
|
|
||||||
|
- Fixed a bug where task-switches seemed to occur even though the scheduler was disabled.
|
||||||
|
|
||||||
|
- Renamed HARDWARE_PORT_TEXAS_INSTRUMENTS_TMS570_RM48, added prefix TRC.
|
||||||
|
|
||||||
|
- Fixed several language issues in the comments and documentation.
|
||||||
|
|
||||||
|
- Fixed several minor issues and warnings from different compilers
|
||||||
|
(including PowerPC/gcc) and configurations.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Changes, v3.0.9 -> v3.1.0
|
||||||
|
|
||||||
|
- Merge of previously separated snapshot and streaming recorders into a single
|
||||||
|
recorder supporting both streaming and snapshot as different modes.
|
||||||
|
|
||||||
|
- New common API for supporting both streaming and snapshot modes.
|
||||||
|
|
||||||
|
- New integration guide, see the User Manual.
|
||||||
|
|
||||||
|
- Major improvement of API documentation in source files and User Manual.
|
||||||
|
|
||||||
|
- New concept of "stream ports", giving a better structure defining streaming
|
||||||
|
interfaces, and restructured the J-Link and TCP/IP streaming as stream ports.
|
||||||
|
|
||||||
|
- Added a stream port for USB CDC connections, with STM32 as example.
|
||||||
|
Since Tracealyzer now can receive serial data on Windows COM ports, this is
|
||||||
|
really easy to use.
|
||||||
|
|
||||||
|
- Added a warning (#error) for cases where FreeRTOS tickless idle mode is used
|
||||||
|
together with timestamping using SysTick or other periodic interrupt timers,
|
||||||
|
Tracing with tickless idle requires an independent time source to correctly
|
||||||
|
capture the length of the idle periods.
|
||||||
|
|
||||||
|
- Major changes in the recorder API. Important examples are:
|
||||||
|
|
||||||
|
* Some configuration macros have changed names, e.g. for "hardware port".
|
||||||
|
Make sure to remove any old "trcConfig.h" files if upgrading from an
|
||||||
|
earlier version!
|
||||||
|
|
||||||
|
* Recorder configuration in trcConfig.h has been minimized and now only
|
||||||
|
includes the important settings that are independent of recorder mode.
|
||||||
|
Advanced settings for each mode are found in trcSnapshotConfig.h and
|
||||||
|
trcStreamingConfig.h.
|
||||||
|
|
||||||
|
* vTraceEnable replaces Trace_Init and vTraceInitTraceData, as well as
|
||||||
|
vTraceStart and uiTraceStart.
|
||||||
|
|
||||||
|
* vTraceStop now part of the common API and thereby available also in
|
||||||
|
streaming. And since vTraceEnable can start the streaming directly
|
||||||
|
you have the option control the tracing from target, e.g., for
|
||||||
|
streaming to a device file system.
|
||||||
|
|
||||||
|
* vTraceStoreKernelObjectName from old streaming recorder has been replaced
|
||||||
|
by vTraceSetQueueName, vTraceSetSemaphoreName, etc.
|
||||||
|
|
||||||
|
* vTraceSetISRProperties now returns a "traceHandle" that should be passed as
|
||||||
|
parameter to vTraceStoreISRBegin and vTraceStoreISREnd.
|
||||||
|
|
||||||
|
* xTraceRegisterString has replaced the old functions xTraceOpenLabel and
|
||||||
|
vTraceStoreUserEventChannelName. This now returns a "traceString" for use
|
||||||
|
as "channel" parameter in vTracePrintF, and in other places where strings
|
||||||
|
are stored.
|
||||||
|
|
||||||
|
* Removed vTraceStoreISREndManual and vTraceStoreISREndAuto, use
|
||||||
|
vTraceStoreISREnd instead.
|
||||||
|
|
||||||
|
* Renamed the functions for saving User Events in a separate buffer:
|
||||||
|
- xTraceRegisterChannelFormat -> xTraceRegisterUBChannel
|
||||||
|
- vTraceChannelPrintF -> vTraceUBData
|
||||||
|
- vTraceChannelUserEvent -> vTraceUBEvent
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright Percepio AB, 2018.
|
|
@ -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
|
* Percepio AB, www.percepio.com
|
||||||
*
|
*
|
||||||
* trcKernelPort.c
|
* trcKernelPort.c
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
*
|
*
|
||||||
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
||||||
*
|
*
|
||||||
* Copyright Percepio AB, 2017.
|
* Copyright Percepio AB, 2018.
|
||||||
* www.percepio.com
|
* www.percepio.com
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
@ -50,6 +50,26 @@
|
||||||
|
|
||||||
#if (defined(TRC_USE_TRACEALYZER_RECORDER) && TRC_USE_TRACEALYZER_RECORDER == 1)
|
#if (defined(TRC_USE_TRACEALYZER_RECORDER) && TRC_USE_TRACEALYZER_RECORDER == 1)
|
||||||
|
|
||||||
|
#ifndef TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS
|
||||||
|
/* TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS is missing in trcConfig.h. */
|
||||||
|
#error "TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS must be defined in trcConfig.h."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TRC_CFG_INCLUDE_TIMER_EVENTS
|
||||||
|
/* TRC_CFG_INCLUDE_TIMER_EVENTS is missing in trcConfig.h. */
|
||||||
|
#error "TRC_CFG_INCLUDE_TIMER_EVENTS must be defined in trcConfig.h."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS
|
||||||
|
/* TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS is missing in trcConfig.h. */
|
||||||
|
#error "TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS must be defined in trcConfig.h."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS
|
||||||
|
/* TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS is missing in trcConfig.h. Define this as 1 if using FreeRTOS v10 or later and like to trace stream buffer or message buffer events, otherwise 0. */
|
||||||
|
#error "TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS must be defined in trcConfig.h."
|
||||||
|
#endif
|
||||||
|
|
||||||
#if (configUSE_TICKLESS_IDLE != 0 && (TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR))
|
#if (configUSE_TICKLESS_IDLE != 0 && (TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR))
|
||||||
/*
|
/*
|
||||||
The below error message is to alert you on the following issue:
|
The below error message is to alert you on the following issue:
|
||||||
|
@ -57,8 +77,8 @@
|
||||||
The hardware port selected in trcConfig.h uses the operating system timer for the
|
The hardware port selected in trcConfig.h uses the operating system timer for the
|
||||||
timestamping, i.e., the periodic interrupt timer that drives the OS tick interrupt.
|
timestamping, i.e., the periodic interrupt timer that drives the OS tick interrupt.
|
||||||
|
|
||||||
When using tickless idle, the recorder needs an independent time source in order to
|
When using "tickless idle" mode, the recorder needs an independent time source in
|
||||||
correctly record the durations of the idle times. Otherwise, the trace may appear
|
order to correctly record the durations of the idle times. Otherwise, the trace may appear
|
||||||
to have a different length than in reality, and the reported CPU load is also affected.
|
to have a different length than in reality, and the reported CPU load is also affected.
|
||||||
|
|
||||||
You may override this warning by defining the TRC_CFG_ACKNOWLEDGE_TICKLESS_IDLE_WARNING
|
You may override this warning by defining the TRC_CFG_ACKNOWLEDGE_TICKLESS_IDLE_WARNING
|
||||||
|
@ -77,11 +97,161 @@
|
||||||
#ifndef TRC_CFG_ACKNOWLEDGE_TICKLESS_IDLE_WARNING
|
#ifndef TRC_CFG_ACKNOWLEDGE_TICKLESS_IDLE_WARNING
|
||||||
#error Trace Recorder: This timestamping mode is not recommended with Tickless Idle.
|
#error Trace Recorder: This timestamping mode is not recommended with Tickless Idle.
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif /* (configUSE_TICKLESS_IDLE != 0 && (TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR)) */
|
||||||
|
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
#include "queue.h"
|
#include "queue.h"
|
||||||
|
|
||||||
|
#if (TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X)
|
||||||
|
/* If the project does not include the FreeRTOS timers, TRC_CFG_INCLUDE_TIMER_EVENTS must be set to 0 */
|
||||||
|
#include "timers.h"
|
||||||
|
#endif /* (TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X) */
|
||||||
|
|
||||||
|
#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X)
|
||||||
|
/* If the project does not include the FreeRTOS event groups, TRC_CFG_INCLUDE_TIMER_EVENTS must be set to 0 */
|
||||||
|
#include "event_groups.h"
|
||||||
|
#endif /* (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X) */
|
||||||
|
|
||||||
|
#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
|
||||||
|
/* If the project does not include the FreeRTOS stream buffers, TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS must be set to 0 */
|
||||||
|
#include "stream_buffer.h"
|
||||||
|
#endif /* (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
|
||||||
|
|
||||||
|
uint32_t prvTraceGetQueueNumber(void* handle);
|
||||||
|
|
||||||
|
#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_8_X)
|
||||||
|
|
||||||
|
extern unsigned char ucQueueGetQueueNumber( xQueueHandle pxQueue );
|
||||||
|
extern void vQueueSetQueueNumber( xQueueHandle pxQueue, unsigned char ucQueueNumber );
|
||||||
|
extern unsigned char ucQueueGetQueueType( xQueueHandle pxQueue );
|
||||||
|
|
||||||
|
uint32_t prvTraceGetQueueNumber(void* handle)
|
||||||
|
{
|
||||||
|
return (uint32_t)ucQueueGetQueueNumber(handle);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
uint32_t prvTraceGetQueueNumber(void* handle)
|
||||||
|
{
|
||||||
|
return (uint32_t)uxQueueGetQueueNumber(handle);
|
||||||
|
}
|
||||||
|
#endif /* (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_8_X) */
|
||||||
|
|
||||||
|
uint8_t prvTraceGetQueueType(void* handle)
|
||||||
|
{
|
||||||
|
// This is either declared in header file in FreeRTOS 8 and later, or as extern above
|
||||||
|
return ucQueueGetQueueType(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tasks */
|
||||||
|
uint16_t prvTraceGetTaskNumberLow16(void* handle)
|
||||||
|
{
|
||||||
|
return TRACE_GET_LOW16(uxTaskGetTaskNumber(handle));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t prvTraceGetTaskNumberHigh16(void* handle)
|
||||||
|
{
|
||||||
|
return TRACE_GET_HIGH16(uxTaskGetTaskNumber(handle));
|
||||||
|
}
|
||||||
|
|
||||||
|
void prvTraceSetTaskNumberLow16(void* handle, uint16_t value)
|
||||||
|
{
|
||||||
|
vTaskSetTaskNumber(handle, TRACE_SET_LOW16(uxTaskGetTaskNumber(handle), value));
|
||||||
|
}
|
||||||
|
|
||||||
|
void prvTraceSetTaskNumberHigh16(void* handle, uint16_t value)
|
||||||
|
{
|
||||||
|
vTaskSetTaskNumber(handle, TRACE_SET_HIGH16(uxTaskGetTaskNumber(handle), value));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t prvTraceGetQueueNumberLow16(void* handle)
|
||||||
|
{
|
||||||
|
return TRACE_GET_LOW16(prvTraceGetQueueNumber(handle));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t prvTraceGetQueueNumberHigh16(void* handle)
|
||||||
|
{
|
||||||
|
return TRACE_GET_HIGH16(prvTraceGetQueueNumber(handle));
|
||||||
|
}
|
||||||
|
|
||||||
|
void prvTraceSetQueueNumberLow16(void* handle, uint16_t value)
|
||||||
|
{
|
||||||
|
vQueueSetQueueNumber(handle, TRACE_SET_LOW16(prvTraceGetQueueNumber(handle), value));
|
||||||
|
}
|
||||||
|
|
||||||
|
void prvTraceSetQueueNumberHigh16(void* handle, uint16_t value)
|
||||||
|
{
|
||||||
|
vQueueSetQueueNumber(handle, TRACE_SET_HIGH16(prvTraceGetQueueNumber(handle), value));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
|
||||||
|
|
||||||
|
uint16_t prvTraceGetTimerNumberLow16(void* handle)
|
||||||
|
{
|
||||||
|
return TRACE_GET_LOW16(uxTimerGetTimerNumber(handle));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t prvTraceGetTimerNumberHigh16(void* handle)
|
||||||
|
{
|
||||||
|
return TRACE_GET_HIGH16(uxTimerGetTimerNumber(handle));
|
||||||
|
}
|
||||||
|
|
||||||
|
void prvTraceSetTimerNumberLow16(void* handle, uint16_t value)
|
||||||
|
{
|
||||||
|
vTimerSetTimerNumber(handle, TRACE_SET_LOW16(uxTimerGetTimerNumber(handle), value));
|
||||||
|
}
|
||||||
|
|
||||||
|
void prvTraceSetTimerNumberHigh16(void* handle, uint16_t value)
|
||||||
|
{
|
||||||
|
vTimerSetTimerNumber(handle, TRACE_SET_HIGH16(uxTimerGetTimerNumber(handle), value));
|
||||||
|
}
|
||||||
|
#endif /* (TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
|
||||||
|
|
||||||
|
#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
|
||||||
|
|
||||||
|
uint16_t prvTraceGetEventGroupNumberLow16(void* handle)
|
||||||
|
{
|
||||||
|
return TRACE_GET_LOW16(uxEventGroupGetNumber(handle));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t prvTraceGetEventGroupNumberHigh16(void* handle)
|
||||||
|
{
|
||||||
|
return TRACE_GET_HIGH16(uxEventGroupGetNumber(handle));
|
||||||
|
}
|
||||||
|
|
||||||
|
void prvTraceSetEventGroupNumberLow16(void* handle, uint16_t value)
|
||||||
|
{
|
||||||
|
vEventGroupSetNumber(handle, TRACE_SET_LOW16(uxEventGroupGetNumber(handle), value));
|
||||||
|
}
|
||||||
|
|
||||||
|
void prvTraceSetEventGroupNumberHigh16(void* handle, uint16_t value)
|
||||||
|
{
|
||||||
|
vEventGroupSetNumber(handle, TRACE_SET_HIGH16(uxEventGroupGetNumber(handle), value));
|
||||||
|
}
|
||||||
|
#endif /* (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
|
||||||
|
|
||||||
|
#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
|
||||||
|
|
||||||
|
uint16_t prvTraceGetStreamBufferNumberLow16(void* handle)
|
||||||
|
{
|
||||||
|
return TRACE_GET_LOW16(uxStreamBufferGetStreamBufferNumber(handle));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t prvTraceGetStreamBufferNumberHigh16(void* handle)
|
||||||
|
{
|
||||||
|
return TRACE_GET_HIGH16(uxStreamBufferGetStreamBufferNumber(handle));
|
||||||
|
}
|
||||||
|
|
||||||
|
void prvTraceSetStreamBufferNumberLow16(void* handle, uint16_t value)
|
||||||
|
{
|
||||||
|
vStreamBufferSetStreamBufferNumber(handle, TRACE_SET_LOW16(uxStreamBufferGetStreamBufferNumber(handle), value));
|
||||||
|
}
|
||||||
|
|
||||||
|
void prvTraceSetStreamBufferNumberHigh16(void* handle, uint16_t value)
|
||||||
|
{
|
||||||
|
vStreamBufferSetStreamBufferNumber(handle, TRACE_SET_HIGH16(uxStreamBufferGetStreamBufferNumber(handle), value));
|
||||||
|
}
|
||||||
|
#endif /* (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
|
||||||
|
|
||||||
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
|
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
|
||||||
|
|
||||||
static void* pCurrentTCB = NULL;
|
static void* pCurrentTCB = NULL;
|
||||||
|
@ -93,10 +263,12 @@ static TaskHandle_t HandleTzCtrl = NULL; /* TzCtrl task TCB */
|
||||||
static xTaskHandle HandleTzCtrl = NULL; /* TzCtrl task TCB */
|
static xTaskHandle HandleTzCtrl = NULL; /* TzCtrl task TCB */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(configSUPPORT_STATIC_ALLOCATION)
|
||||||
#if (configSUPPORT_STATIC_ALLOCATION == 1)
|
#if (configSUPPORT_STATIC_ALLOCATION == 1)
|
||||||
static StackType_t stackTzCtrl[TRC_CFG_CTRL_TASK_STACK_SIZE];
|
static StackType_t stackTzCtrl[TRC_CFG_CTRL_TASK_STACK_SIZE];
|
||||||
static StaticTask_t tcbTzCtrl;
|
static StaticTask_t tcbTzCtrl;
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Monitored by TzCtrl task, that give warnings as User Events */
|
/* Monitored by TzCtrl task, that give warnings as User Events */
|
||||||
extern volatile uint32_t NoRoomForSymbol;
|
extern volatile uint32_t NoRoomForSymbol;
|
||||||
|
@ -120,6 +292,8 @@ TRC_STREAM_PORT_ALLOCATE_FIELDS()
|
||||||
/* Called by TzCtrl task periodically (Normally every 100 ms) */
|
/* Called by TzCtrl task periodically (Normally every 100 ms) */
|
||||||
static void prvCheckRecorderStatus(void);
|
static void prvCheckRecorderStatus(void);
|
||||||
|
|
||||||
|
extern void prvTraceWarning(int errCode);
|
||||||
|
|
||||||
/* The TzCtrl task - receives commands from Tracealyzer (start/stop) */
|
/* The TzCtrl task - receives commands from Tracealyzer (start/stop) */
|
||||||
static portTASK_FUNCTION( TzCtrl, pvParameters );
|
static portTASK_FUNCTION( TzCtrl, pvParameters );
|
||||||
|
|
||||||
|
@ -132,14 +306,31 @@ static portTASK_FUNCTION( TzCtrl, pvParameters );
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void vTraceEnable(int startOption)
|
void vTraceEnable(int startOption)
|
||||||
{
|
{
|
||||||
int bytes = 0;
|
int32_t bytes = 0;
|
||||||
|
int32_t status;
|
||||||
extern uint32_t RecorderEnabled;
|
extern uint32_t RecorderEnabled;
|
||||||
TracealyzerCommandType msg;
|
TracealyzerCommandType msg;
|
||||||
|
|
||||||
if (HandleTzCtrl != NULL)
|
/* Only do this first time...*/
|
||||||
return; /* Seems we already initiated */
|
if (HandleTzCtrl == NULL)
|
||||||
|
{
|
||||||
|
TRC_STREAM_PORT_INIT();
|
||||||
|
|
||||||
TRC_STREAM_PORT_INIT();
|
/* Note: Requires that TRC_CFG_INCLUDE_USER_EVENTS is 1. */
|
||||||
|
trcWarningChannel = xTraceRegisterString("Warnings from Recorder");
|
||||||
|
|
||||||
|
/* Creates the TzCtrl task - receives trace commands (start, stop, ...) */
|
||||||
|
#if defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION == 1)
|
||||||
|
HandleTzCtrl = xTaskCreateStatic(TzCtrl, STRING_CAST("TzCtrl"), TRC_CFG_CTRL_TASK_STACK_SIZE, NULL, TRC_CFG_CTRL_TASK_PRIORITY, stackTzCtrl, &tcbTzCtrl);
|
||||||
|
#else
|
||||||
|
xTaskCreate( TzCtrl, STRING_CAST("TzCtrl"), TRC_CFG_CTRL_TASK_STACK_SIZE, NULL, TRC_CFG_CTRL_TASK_PRIORITY, &HandleTzCtrl );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (HandleTzCtrl == NULL)
|
||||||
|
{
|
||||||
|
prvTraceError(PSF_ERROR_TZCTRLTASK_NOT_CREATED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (startOption == TRC_START_AWAIT_HOST)
|
if (startOption == TRC_START_AWAIT_HOST)
|
||||||
{
|
{
|
||||||
|
@ -147,9 +338,15 @@ void vTraceEnable(int startOption)
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
bytes = 0;
|
bytes = 0;
|
||||||
TRC_STREAM_PORT_READ_DATA(&msg, sizeof(TracealyzerCommandType), &bytes);
|
|
||||||
|
|
||||||
if (bytes == sizeof(TracealyzerCommandType))
|
status = TRC_STREAM_PORT_READ_DATA(&msg, sizeof(TracealyzerCommandType), (int32_t*)&bytes);
|
||||||
|
|
||||||
|
if (status != 0)
|
||||||
|
{
|
||||||
|
prvTraceWarning(PSF_WARNING_STREAM_PORT_READ);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((status == 0) && (bytes == sizeof(TracealyzerCommandType)))
|
||||||
{
|
{
|
||||||
if (prvIsValidCommand(&msg))
|
if (prvIsValidCommand(&msg))
|
||||||
{
|
{
|
||||||
|
@ -179,38 +376,9 @@ void vTraceEnable(int startOption)
|
||||||
/* On TRC_INIT */
|
/* On TRC_INIT */
|
||||||
TRC_PORT_SPECIFIC_INIT();
|
TRC_PORT_SPECIFIC_INIT();
|
||||||
}
|
}
|
||||||
|
|
||||||
trcWarningChannel = xTraceRegisterString("Warnings from Recorder");
|
|
||||||
|
|
||||||
/* Creates the TzCtrl task - receives trace commands (start, stop, ...) */
|
|
||||||
#if (configSUPPORT_STATIC_ALLOCATION == 1)
|
|
||||||
HandleTzCtrl = xTaskCreateStatic(TzCtrl, "TzCtrl", TRC_CFG_CTRL_TASK_STACK_SIZE, NULL, TRC_CFG_CTRL_TASK_PRIORITY, stackTzCtrl, &tcbTzCtrl);
|
|
||||||
(void)HandleTzCtrl;
|
|
||||||
#else
|
|
||||||
xTaskCreate( TzCtrl, "TzCtrl", TRC_CFG_CTRL_TASK_STACK_SIZE, NULL, TRC_CFG_CTRL_TASK_PRIORITY, &HandleTzCtrl );
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* prvTraceOnBegin
|
|
||||||
*
|
|
||||||
* Called on trace begin.
|
|
||||||
******************************************************************************/
|
|
||||||
void prvTraceOnBegin()
|
|
||||||
{
|
|
||||||
TRC_STREAM_PORT_ON_TRACE_BEGIN();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* prvTraceOnEnd
|
|
||||||
*
|
|
||||||
* Called on trace end.
|
|
||||||
******************************************************************************/
|
|
||||||
void prvTraceOnEnd()
|
|
||||||
{
|
|
||||||
TRC_STREAM_PORT_ON_TRACE_END();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (TRC_CFG_SCHEDULING_ONLY == 0)
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* vTraceSetQueueName(void* object, const char* name)
|
* vTraceSetQueueName(void* object, const char* name)
|
||||||
*
|
*
|
||||||
|
@ -243,13 +411,58 @@ void vTraceSetSemaphoreName(void* object, const char* name)
|
||||||
* Parameter object: pointer to the Mutex that shall be named
|
* Parameter object: pointer to the Mutex that shall be named
|
||||||
* Parameter name: the name to set (const string literal)
|
* Parameter name: the name to set (const string literal)
|
||||||
*
|
*
|
||||||
* Sets a name for Semaphore objects for display in Tracealyzer.
|
* Sets a name for Mutex objects for display in Tracealyzer.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void vTraceSetMutexName(void* object, const char* name)
|
void vTraceSetMutexName(void* object, const char* name)
|
||||||
{
|
{
|
||||||
vTraceStoreKernelObjectName(object, name);
|
vTraceStoreKernelObjectName(object, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X)
|
||||||
|
/*******************************************************************************
|
||||||
|
* vTraceSetEventGroupName(void* object, const char* name)
|
||||||
|
*
|
||||||
|
* Parameter object: pointer to the vTraceSetEventGroupName that shall be named
|
||||||
|
* Parameter name: the name to set (const string literal)
|
||||||
|
*
|
||||||
|
* Sets a name for EventGroup objects for display in Tracealyzer.
|
||||||
|
******************************************************************************/
|
||||||
|
void vTraceSetEventGroupName(void* object, const char* name)
|
||||||
|
{
|
||||||
|
vTraceStoreKernelObjectName(object, name);
|
||||||
|
}
|
||||||
|
#endif /* (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X) */
|
||||||
|
|
||||||
|
#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
|
||||||
|
/*******************************************************************************
|
||||||
|
* vTraceSetStreamBufferName(void* object, const char* name)
|
||||||
|
*
|
||||||
|
* Parameter object: pointer to the StreamBuffer that shall be named
|
||||||
|
* Parameter name: the name to set (const string literal)
|
||||||
|
*
|
||||||
|
* Sets a name for StreamBuffer objects for display in Tracealyzer.
|
||||||
|
******************************************************************************/
|
||||||
|
void vTraceSetStreamBufferName(void* object, const char* name)
|
||||||
|
{
|
||||||
|
vTraceStoreKernelObjectName(object, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* vTraceSetMessageBufferName(void* object, const char* name)
|
||||||
|
*
|
||||||
|
* Parameter object: pointer to the MessageBuffer that shall be named
|
||||||
|
* Parameter name: the name to set (const string literal)
|
||||||
|
*
|
||||||
|
* Sets a name for MessageBuffer objects for display in Tracealyzer.
|
||||||
|
******************************************************************************/
|
||||||
|
void vTraceSetMessageBufferName(void* object, const char* name)
|
||||||
|
{
|
||||||
|
vTraceStoreKernelObjectName(object, name);
|
||||||
|
}
|
||||||
|
#endif /* (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
|
||||||
|
|
||||||
|
#endif /* (TRC_CFG_SCHEDULING_ONLY == 0) */
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* prvGetCurrentTaskHandle
|
* prvGetCurrentTaskHandle
|
||||||
*
|
*
|
||||||
|
@ -283,7 +496,7 @@ uint32_t prvIsNewTCB(void* pNewTCB)
|
||||||
* Returns true if the RTOS scheduler currently is disabled, thus preventing any
|
* Returns true if the RTOS scheduler currently is disabled, thus preventing any
|
||||||
* task-switches from occurring. Only called from vTraceStoreISREnd.
|
* task-switches from occurring. Only called from vTraceStoreISREnd.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
unsigned char prvTraceIsSchedulerSuspended()
|
unsigned char prvTraceIsSchedulerSuspended(void)
|
||||||
{
|
{
|
||||||
/* Assumed to be available in FreeRTOS. According to the FreeRTOS docs,
|
/* Assumed to be available in FreeRTOS. According to the FreeRTOS docs,
|
||||||
INCLUDE_xTaskGetSchedulerState or configUSE_TIMERS must be set to 1 in
|
INCLUDE_xTaskGetSchedulerState or configUSE_TIMERS must be set to 1 in
|
||||||
|
@ -304,47 +517,37 @@ static void prvCheckRecorderStatus(void)
|
||||||
{
|
{
|
||||||
if (NoRoomForSymbol > NoRoomForSymbol_last)
|
if (NoRoomForSymbol > NoRoomForSymbol_last)
|
||||||
{
|
{
|
||||||
vTracePrintF(trcWarningChannel, "TRC_CFG_SYMBOL_TABLE_SLOTS too small. Add %d slots.",
|
if (NoRoomForSymbol > 0)
|
||||||
NoRoomForSymbol);
|
{
|
||||||
|
prvTraceWarning(PSF_WARNING_SYMBOL_TABLE_SLOTS);
|
||||||
|
}
|
||||||
NoRoomForSymbol_last = NoRoomForSymbol;
|
NoRoomForSymbol_last = NoRoomForSymbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NoRoomForObjectData > NoRoomForObjectData_last)
|
if (NoRoomForObjectData > NoRoomForObjectData_last)
|
||||||
{
|
{
|
||||||
vTracePrintF(trcWarningChannel, "TRC_CFG_OBJECT_DATA_SLOTS too small. Add %d slots.",
|
if (NoRoomForObjectData > 0)
|
||||||
NoRoomForObjectData);
|
{
|
||||||
|
prvTraceWarning(PSF_WARNING_OBJECT_DATA_SLOTS);
|
||||||
|
}
|
||||||
NoRoomForObjectData_last = NoRoomForObjectData;
|
NoRoomForObjectData_last = NoRoomForObjectData;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LongestSymbolName > LongestSymbolName_last)
|
if (LongestSymbolName > LongestSymbolName_last)
|
||||||
{
|
{
|
||||||
if (LongestSymbolName > TRC_CFG_SYMBOL_MAX_LENGTH)
|
if (LongestSymbolName > (TRC_CFG_SYMBOL_MAX_LENGTH))
|
||||||
{
|
{
|
||||||
vTracePrintF(trcWarningChannel, "TRC_CFG_SYMBOL_MAX_LENGTH too small. Add %d chars.",
|
prvTraceWarning(PSF_WARNING_SYMBOL_MAX_LENGTH);
|
||||||
LongestSymbolName);
|
|
||||||
}
|
}
|
||||||
LongestSymbolName_last = LongestSymbolName;
|
LongestSymbolName_last = LongestSymbolName;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MaxBytesTruncated > MaxBytesTruncated_last)
|
if (MaxBytesTruncated > MaxBytesTruncated_last)
|
||||||
{
|
{
|
||||||
/* Some string event generated a too long string that was truncated.
|
if (MaxBytesTruncated > 0)
|
||||||
This may happen for the following functions:
|
{
|
||||||
- vTracePrintF
|
prvTraceWarning(PSF_WARNING_STRING_TOO_LONG);
|
||||||
- vTracePrintF
|
}
|
||||||
- vTraceStoreKernelObjectName
|
|
||||||
- vTraceStoreUserEventChannelName
|
|
||||||
- vTraceSetISRProperties
|
|
||||||
|
|
||||||
A PSF event may store maximum 60 bytes payload, including data arguments
|
|
||||||
and string characters. For User Events, also the User Event Channel ptr
|
|
||||||
must be squeezed in, if a channel is specified. */
|
|
||||||
|
|
||||||
vTracePrintF(trcWarningChannel, "String event too long, up to %d bytes truncated.",
|
|
||||||
MaxBytesTruncated);
|
|
||||||
|
|
||||||
MaxBytesTruncated_last = MaxBytesTruncated;
|
MaxBytesTruncated_last = MaxBytesTruncated;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -352,14 +555,15 @@ static void prvCheckRecorderStatus(void)
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* TzCtrl
|
* TzCtrl
|
||||||
*
|
*
|
||||||
* Task for receiving commands from Tracealyzer and for recorder diagnostics.
|
* Task for sending the trace data from the internal buffer to the stream
|
||||||
*
|
* interface (assuming TRC_STREAM_PORT_USE_INTERNAL_BUFFER == 1) and for
|
||||||
|
* receiving commands from Tracealyzer. Also does some diagnostics.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
static portTASK_FUNCTION( TzCtrl, pvParameters )
|
static portTASK_FUNCTION( TzCtrl, pvParameters )
|
||||||
{
|
{
|
||||||
TracealyzerCommandType msg;
|
TracealyzerCommandType msg;
|
||||||
int bytes = 0;
|
int32_t bytes = 0;
|
||||||
|
int32_t status = 0;
|
||||||
(void)pvParameters;
|
(void)pvParameters;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
|
@ -368,8 +572,14 @@ static portTASK_FUNCTION( TzCtrl, pvParameters )
|
||||||
{
|
{
|
||||||
/* Listen for new commands */
|
/* Listen for new commands */
|
||||||
bytes = 0;
|
bytes = 0;
|
||||||
TRC_STREAM_PORT_READ_DATA(&msg, sizeof(TracealyzerCommandType), &bytes);
|
status = TRC_STREAM_PORT_READ_DATA(&msg, sizeof(TracealyzerCommandType), (int32_t*)&bytes);
|
||||||
if (bytes == sizeof(TracealyzerCommandType))
|
|
||||||
|
if (status != 0)
|
||||||
|
{
|
||||||
|
prvTraceWarning(PSF_WARNING_STREAM_PORT_READ);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((status == 0) && (bytes == sizeof(TracealyzerCommandType)))
|
||||||
{
|
{
|
||||||
if (prvIsValidCommand(&msg))
|
if (prvIsValidCommand(&msg))
|
||||||
{
|
{
|
||||||
|
@ -377,15 +587,21 @@ static portTASK_FUNCTION( TzCtrl, pvParameters )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send periodic data */
|
/* If the internal buffer is disabled, the COMMIT macro instead sends the data directly
|
||||||
bytes = 0;
|
from the "event functions" (using TRC_STREAM_PORT_WRITE_DATA). */
|
||||||
TRC_STREAM_PORT_PERIODIC_SEND_DATA(&bytes);
|
#if (TRC_STREAM_PORT_USE_INTERNAL_BUFFER == 1)
|
||||||
/* If there was data sent (bytes != 0), immediately loop around and do all this again. Otherwise, step out of this loop and sleep for a while. */
|
/* If there is a buffer page, this sends it to the streaming interface using TRC_STREAM_PORT_WRITE_DATA. */
|
||||||
}
|
bytes = prvPagedEventBufferTransfer();
|
||||||
while (bytes != 0);
|
#endif
|
||||||
|
|
||||||
|
/* If there was data sent or received (bytes != 0), loop around and repeat, if there is more data to send or receive.
|
||||||
|
Otherwise, step out of this loop and sleep for a while. */
|
||||||
|
|
||||||
|
} while (bytes != 0);
|
||||||
|
|
||||||
prvCheckRecorderStatus();
|
prvCheckRecorderStatus();
|
||||||
vTaskDelay(TRC_CFG_CTRL_TASK_DELAY); /* 10ms */
|
|
||||||
|
vTaskDelay(TRC_CFG_CTRL_TASK_DELAY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,11 +614,11 @@ static portTASK_FUNCTION( TzCtrl, pvParameters )
|
||||||
int uiInEventGroupSetBitsFromISR = 0;
|
int uiInEventGroupSetBitsFromISR = 0;
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* TraceObjectClassTable
|
* TraceQueueClassTable
|
||||||
* Translates a FreeRTOS QueueType into trace objects classes (TRACE_CLASS_).
|
* Translates a FreeRTOS QueueType into trace objects classes (TRACE_CLASS_).
|
||||||
* Has one entry for each QueueType, gives TRACE_CLASS ID.
|
* Has one entry for each QueueType, gives TRACE_CLASS ID.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
traceObjectClass TraceObjectClassTable[5] = {
|
traceObjectClass TraceQueueClassTable[5] = {
|
||||||
TRACE_CLASS_QUEUE,
|
TRACE_CLASS_QUEUE,
|
||||||
TRACE_CLASS_MUTEX,
|
TRACE_CLASS_MUTEX,
|
||||||
TRACE_CLASS_SEMAPHORE,
|
TRACE_CLASS_SEMAPHORE,
|
||||||
|
@ -410,6 +626,7 @@ traceObjectClass TraceObjectClassTable[5] = {
|
||||||
TRACE_CLASS_MUTEX
|
TRACE_CLASS_MUTEX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if (TRC_CFG_SCHEDULING_ONLY == 0)
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* vTraceSetQueueName(void* object, const char* name)
|
* vTraceSetQueueName(void* object, const char* name)
|
||||||
*
|
*
|
||||||
|
@ -420,7 +637,7 @@ traceObjectClass TraceObjectClassTable[5] = {
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void vTraceSetQueueName(void* object, const char* name)
|
void vTraceSetQueueName(void* object, const char* name)
|
||||||
{
|
{
|
||||||
prvTraceSetObjectName(TRACE_GET_OBJECT_TRACE_CLASS(TRC_UNUSED, object), TRACE_GET_OBJECT_NUMBER(TRC_UNUSED, object), name);
|
prvTraceSetObjectName(TRACE_CLASS_QUEUE, TRACE_GET_OBJECT_NUMBER(QUEUE, object), name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
@ -433,7 +650,7 @@ void vTraceSetQueueName(void* object, const char* name)
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void vTraceSetSemaphoreName(void* object, const char* name)
|
void vTraceSetSemaphoreName(void* object, const char* name)
|
||||||
{
|
{
|
||||||
prvTraceSetObjectName(TRACE_GET_OBJECT_TRACE_CLASS(TRC_UNUSED, object), TRACE_GET_OBJECT_NUMBER(TRC_UNUSED, object), name);
|
prvTraceSetObjectName(TRACE_CLASS_SEMAPHORE, TRACE_GET_OBJECT_NUMBER(QUEUE, object), name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
@ -446,36 +663,59 @@ void vTraceSetSemaphoreName(void* object, const char* name)
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void vTraceSetMutexName(void* object, const char* name)
|
void vTraceSetMutexName(void* object, const char* name)
|
||||||
{
|
{
|
||||||
prvTraceSetObjectName(TRACE_GET_OBJECT_TRACE_CLASS(TRC_UNUSED, object), TRACE_GET_OBJECT_NUMBER(TRC_UNUSED, object), name);
|
prvTraceSetObjectName(TRACE_CLASS_MUTEX, TRACE_GET_OBJECT_NUMBER(QUEUE, object), name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X)
|
||||||
|
/*******************************************************************************
|
||||||
|
* vTraceSetEventGroupName(void* object, const char* name)
|
||||||
|
*
|
||||||
|
* Parameter object: pointer to the EventGroup that shall be named
|
||||||
|
* Parameter name: the name to set (const string literal)
|
||||||
|
*
|
||||||
|
* Sets a name for EventGroup objects for display in Tracealyzer.
|
||||||
|
******************************************************************************/
|
||||||
|
void vTraceSetEventGroupName(void* object, const char* name)
|
||||||
|
{
|
||||||
|
prvTraceSetObjectName(TRACE_CLASS_EVENTGROUP, TRACE_GET_OBJECT_NUMBER(EVENTGROUP, object), name);
|
||||||
|
}
|
||||||
|
#endif /* (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X) */
|
||||||
|
|
||||||
|
#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0)
|
||||||
|
/*******************************************************************************
|
||||||
|
* vTraceSetStreamBufferName(void* object, const char* name)
|
||||||
|
*
|
||||||
|
* Parameter object: pointer to the StreamBuffer that shall be named
|
||||||
|
* Parameter name: the name to set (const string literal)
|
||||||
|
*
|
||||||
|
* Sets a name for StreamBuffer objects for display in Tracealyzer.
|
||||||
|
******************************************************************************/
|
||||||
|
void vTraceSetStreamBufferName(void* object, const char* name)
|
||||||
|
{
|
||||||
|
prvTraceSetObjectName(TRACE_CLASS_STREAMBUFFER, TRACE_GET_OBJECT_NUMBER(STREAMBUFFER, object), name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* vTraceSetMessageBufferName(void* object, const char* name)
|
||||||
|
*
|
||||||
|
* Parameter object: pointer to the MessageBuffer that shall be named
|
||||||
|
* Parameter name: the name to set (const string literal)
|
||||||
|
*
|
||||||
|
* Sets a name for MessageBuffer objects for display in Tracealyzer.
|
||||||
|
******************************************************************************/
|
||||||
|
void vTraceSetMessageBufferName(void* object, const char* name)
|
||||||
|
{
|
||||||
|
prvTraceSetObjectName(TRACE_CLASS_MESSAGEBUFFER, TRACE_GET_OBJECT_NUMBER(STREAMBUFFER, object), name);
|
||||||
|
}
|
||||||
|
#endif /* (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */
|
||||||
|
|
||||||
|
#endif /* (TRC_CFG_SCHEDULING_ONLY == 0) */
|
||||||
|
|
||||||
void* prvTraceGetCurrentTaskHandle()
|
void* prvTraceGetCurrentTaskHandle()
|
||||||
{
|
{
|
||||||
return xTaskGetCurrentTaskHandle();
|
return xTaskGetCurrentTaskHandle();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_8_X)
|
|
||||||
traceHandle prvTraceGetObjectNumber(void* handle)
|
|
||||||
{
|
|
||||||
return (traceHandle) ucQueueGetQueueNumber(handle);
|
|
||||||
}
|
|
||||||
#else /* For FreeRTOS v8 and later */
|
|
||||||
traceHandle prvTraceGetObjectNumber(void* handle)
|
|
||||||
{
|
|
||||||
return (traceHandle) uxQueueGetQueueNumber(handle);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint8_t prvTraceGetObjectType(void* handle)
|
|
||||||
{
|
|
||||||
return ucQueueGetQueueType(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
traceHandle prvTraceGetTaskNumber(void* handle)
|
|
||||||
{
|
|
||||||
return (traceHandle)uxTaskGetTaskNumber(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialization of the object property table */
|
/* Initialization of the object property table */
|
||||||
void vTraceInitObjectPropertyTable()
|
void vTraceInitObjectPropertyTable()
|
||||||
{
|
{
|
||||||
|
@ -487,6 +727,8 @@ void vTraceInitObjectPropertyTable()
|
||||||
RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[4] = TRC_CFG_NISR;
|
RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[4] = TRC_CFG_NISR;
|
||||||
RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[5] = TRC_CFG_NTIMER;
|
RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[5] = TRC_CFG_NTIMER;
|
||||||
RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[6] = TRC_CFG_NEVENTGROUP;
|
RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[6] = TRC_CFG_NEVENTGROUP;
|
||||||
|
RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[7] = TRC_CFG_NSTREAMBUFFER;
|
||||||
|
RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[8] = TRC_CFG_NMESSAGEBUFFER;
|
||||||
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[0] = TRC_CFG_NAME_LEN_QUEUE;
|
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[0] = TRC_CFG_NAME_LEN_QUEUE;
|
||||||
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[1] = TRC_CFG_NAME_LEN_SEMAPHORE;
|
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[1] = TRC_CFG_NAME_LEN_SEMAPHORE;
|
||||||
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[2] = TRC_CFG_NAME_LEN_MUTEX;
|
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[2] = TRC_CFG_NAME_LEN_MUTEX;
|
||||||
|
@ -494,6 +736,8 @@ void vTraceInitObjectPropertyTable()
|
||||||
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[4] = TRC_CFG_NAME_LEN_ISR;
|
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[4] = TRC_CFG_NAME_LEN_ISR;
|
||||||
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[5] = TRC_CFG_NAME_LEN_TIMER;
|
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[5] = TRC_CFG_NAME_LEN_TIMER;
|
||||||
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[6] = TRC_CFG_NAME_LEN_EVENTGROUP;
|
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[6] = TRC_CFG_NAME_LEN_EVENTGROUP;
|
||||||
|
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[7] = TRC_CFG_NAME_LEN_STREAMBUFFER;
|
||||||
|
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[8] = TRC_CFG_NAME_LEN_MESSAGEBUFFER;
|
||||||
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[0] = PropertyTableSizeQueue;
|
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[0] = PropertyTableSizeQueue;
|
||||||
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[1] = PropertyTableSizeSemaphore;
|
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[1] = PropertyTableSizeSemaphore;
|
||||||
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[2] = PropertyTableSizeMutex;
|
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[2] = PropertyTableSizeMutex;
|
||||||
|
@ -501,6 +745,8 @@ void vTraceInitObjectPropertyTable()
|
||||||
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[4] = PropertyTableSizeISR;
|
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[4] = PropertyTableSizeISR;
|
||||||
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[5] = PropertyTableSizeTimer;
|
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[5] = PropertyTableSizeTimer;
|
||||||
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[6] = PropertyTableSizeEventGroup;
|
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[6] = PropertyTableSizeEventGroup;
|
||||||
|
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[7] = PropertyTableSizeStreamBuffer;
|
||||||
|
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[8] = PropertyTableSizeMessageBuffer;
|
||||||
RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[0] = StartIndexQueue;
|
RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[0] = StartIndexQueue;
|
||||||
RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[1] = StartIndexSemaphore;
|
RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[1] = StartIndexSemaphore;
|
||||||
RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[2] = StartIndexMutex;
|
RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[2] = StartIndexMutex;
|
||||||
|
@ -508,6 +754,8 @@ void vTraceInitObjectPropertyTable()
|
||||||
RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[4] = StartIndexISR;
|
RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[4] = StartIndexISR;
|
||||||
RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[5] = StartIndexTimer;
|
RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[5] = StartIndexTimer;
|
||||||
RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[6] = StartIndexEventGroup;
|
RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[6] = StartIndexEventGroup;
|
||||||
|
RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[7] = StartIndexStreamBuffer;
|
||||||
|
RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[8] = StartIndexMessageBuffer;
|
||||||
RecorderDataPtr->ObjectPropertyTable.ObjectPropertyTableSizeInBytes = TRACE_OBJECT_TABLE_SIZE;
|
RecorderDataPtr->ObjectPropertyTable.ObjectPropertyTableSizeInBytes = TRACE_OBJECT_TABLE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -515,20 +763,24 @@ void vTraceInitObjectPropertyTable()
|
||||||
void vTraceInitObjectHandleStack()
|
void vTraceInitObjectHandleStack()
|
||||||
{
|
{
|
||||||
objectHandleStacks.indexOfNextAvailableHandle[0] = objectHandleStacks.lowestIndexOfClass[0] = 0;
|
objectHandleStacks.indexOfNextAvailableHandle[0] = objectHandleStacks.lowestIndexOfClass[0] = 0;
|
||||||
objectHandleStacks.indexOfNextAvailableHandle[1] = objectHandleStacks.lowestIndexOfClass[1] = TRC_CFG_NQUEUE;
|
objectHandleStacks.indexOfNextAvailableHandle[1] = objectHandleStacks.lowestIndexOfClass[1] = (TRC_CFG_NQUEUE);
|
||||||
objectHandleStacks.indexOfNextAvailableHandle[2] = objectHandleStacks.lowestIndexOfClass[2] = TRC_CFG_NQUEUE + TRC_CFG_NSEMAPHORE;
|
objectHandleStacks.indexOfNextAvailableHandle[2] = objectHandleStacks.lowestIndexOfClass[2] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE);
|
||||||
objectHandleStacks.indexOfNextAvailableHandle[3] = objectHandleStacks.lowestIndexOfClass[3] = TRC_CFG_NQUEUE + TRC_CFG_NSEMAPHORE + TRC_CFG_NMUTEX;
|
objectHandleStacks.indexOfNextAvailableHandle[3] = objectHandleStacks.lowestIndexOfClass[3] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX);
|
||||||
objectHandleStacks.indexOfNextAvailableHandle[4] = objectHandleStacks.lowestIndexOfClass[4] = TRC_CFG_NQUEUE + TRC_CFG_NSEMAPHORE + TRC_CFG_NMUTEX + TRC_CFG_NTASK;
|
objectHandleStacks.indexOfNextAvailableHandle[4] = objectHandleStacks.lowestIndexOfClass[4] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK);
|
||||||
objectHandleStacks.indexOfNextAvailableHandle[5] = objectHandleStacks.lowestIndexOfClass[5] = TRC_CFG_NQUEUE + TRC_CFG_NSEMAPHORE + TRC_CFG_NMUTEX + TRC_CFG_NTASK + TRC_CFG_NISR;
|
objectHandleStacks.indexOfNextAvailableHandle[5] = objectHandleStacks.lowestIndexOfClass[5] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR);
|
||||||
objectHandleStacks.indexOfNextAvailableHandle[6] = objectHandleStacks.lowestIndexOfClass[6] = TRC_CFG_NQUEUE + TRC_CFG_NSEMAPHORE + TRC_CFG_NMUTEX + TRC_CFG_NTASK + TRC_CFG_NISR + TRC_CFG_NTIMER;
|
objectHandleStacks.indexOfNextAvailableHandle[6] = objectHandleStacks.lowestIndexOfClass[6] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER);
|
||||||
|
objectHandleStacks.indexOfNextAvailableHandle[7] = objectHandleStacks.lowestIndexOfClass[7] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER) + (TRC_CFG_NEVENTGROUP);
|
||||||
|
objectHandleStacks.indexOfNextAvailableHandle[8] = objectHandleStacks.lowestIndexOfClass[8] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER) + (TRC_CFG_NEVENTGROUP) + (TRC_CFG_NSTREAMBUFFER);
|
||||||
|
|
||||||
objectHandleStacks.highestIndexOfClass[0] = TRC_CFG_NQUEUE - 1;
|
objectHandleStacks.highestIndexOfClass[0] = (TRC_CFG_NQUEUE) - 1;
|
||||||
objectHandleStacks.highestIndexOfClass[1] = TRC_CFG_NQUEUE + TRC_CFG_NSEMAPHORE - 1;
|
objectHandleStacks.highestIndexOfClass[1] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) - 1;
|
||||||
objectHandleStacks.highestIndexOfClass[2] = TRC_CFG_NQUEUE + TRC_CFG_NSEMAPHORE + TRC_CFG_NMUTEX - 1;
|
objectHandleStacks.highestIndexOfClass[2] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) - 1;
|
||||||
objectHandleStacks.highestIndexOfClass[3] = TRC_CFG_NQUEUE + TRC_CFG_NSEMAPHORE + TRC_CFG_NMUTEX + TRC_CFG_NTASK - 1;
|
objectHandleStacks.highestIndexOfClass[3] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) - 1;
|
||||||
objectHandleStacks.highestIndexOfClass[4] = TRC_CFG_NQUEUE + TRC_CFG_NSEMAPHORE + TRC_CFG_NMUTEX + TRC_CFG_NTASK + TRC_CFG_NISR - 1;
|
objectHandleStacks.highestIndexOfClass[4] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) - 1;
|
||||||
objectHandleStacks.highestIndexOfClass[5] = TRC_CFG_NQUEUE + TRC_CFG_NSEMAPHORE + TRC_CFG_NMUTEX + TRC_CFG_NTASK + TRC_CFG_NISR + TRC_CFG_NTIMER - 1;
|
objectHandleStacks.highestIndexOfClass[5] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER) - 1;
|
||||||
objectHandleStacks.highestIndexOfClass[6] = TRC_CFG_NQUEUE + TRC_CFG_NSEMAPHORE + TRC_CFG_NMUTEX + TRC_CFG_NTASK + TRC_CFG_NISR + TRC_CFG_NTIMER + TRC_CFG_NEVENTGROUP - 1;
|
objectHandleStacks.highestIndexOfClass[6] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER) + (TRC_CFG_NEVENTGROUP) - 1;
|
||||||
|
objectHandleStacks.highestIndexOfClass[7] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER) + (TRC_CFG_NEVENTGROUP) + (TRC_CFG_NSTREAMBUFFER) - 1;
|
||||||
|
objectHandleStacks.highestIndexOfClass[8] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER) + (TRC_CFG_NEVENTGROUP) + (TRC_CFG_NSTREAMBUFFER) + (TRC_CFG_NMESSAGEBUFFER) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns the "Not enough handles" error message for this object class */
|
/* Returns the "Not enough handles" error message for this object class */
|
||||||
|
@ -550,39 +802,15 @@ const char* pszTraceGetErrorNotEnoughHandles(traceObjectClass objectclass)
|
||||||
return "Not enough TIMER handles - increase TRC_CFG_NTIMER in trcSnapshotConfig.h";
|
return "Not enough TIMER handles - increase TRC_CFG_NTIMER in trcSnapshotConfig.h";
|
||||||
case TRACE_CLASS_EVENTGROUP:
|
case TRACE_CLASS_EVENTGROUP:
|
||||||
return "Not enough EVENTGROUP handles - increase TRC_CFG_NEVENTGROUP in trcSnapshotConfig.h";
|
return "Not enough EVENTGROUP handles - increase TRC_CFG_NEVENTGROUP in trcSnapshotConfig.h";
|
||||||
|
case TRACE_CLASS_STREAMBUFFER:
|
||||||
|
return "Not enough STREAMBUFFER handles - increase TRC_CFG_NSTREAMBUFFER in trcSnapshotConfig.h";
|
||||||
|
case TRACE_CLASS_MESSAGEBUFFER:
|
||||||
|
return "Not enough MESSAGEBUFFER handles - increase TRC_CFG_NMESSAGEBUFFER in trcSnapshotConfig.h";
|
||||||
default:
|
default:
|
||||||
return "pszTraceGetErrorHandles: Invalid objectclass!";
|
return "pszTraceGetErrorHandles: Invalid objectclass!";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns the exclude state of the object */
|
|
||||||
uint8_t uiTraceIsObjectExcluded(traceObjectClass objectclass, traceHandle handle)
|
|
||||||
{
|
|
||||||
TRACE_ASSERT(objectclass < TRACE_NCLASSES, "prvIsObjectExcluded: objectclass >= TRACE_NCLASSES", 1);
|
|
||||||
TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], "prvIsObjectExcluded: Invalid value for handle", 1);
|
|
||||||
|
|
||||||
switch(objectclass)
|
|
||||||
{
|
|
||||||
case TRACE_CLASS_TASK:
|
|
||||||
return (uint8_t) TRACE_GET_TASK_FLAG_ISEXCLUDED(handle);
|
|
||||||
case TRACE_CLASS_SEMAPHORE:
|
|
||||||
return (uint8_t) TRACE_GET_SEMAPHORE_FLAG_ISEXCLUDED(handle);
|
|
||||||
case TRACE_CLASS_MUTEX:
|
|
||||||
return (uint8_t) TRACE_GET_MUTEX_FLAG_ISEXCLUDED(handle);
|
|
||||||
case TRACE_CLASS_QUEUE:
|
|
||||||
return (uint8_t) TRACE_GET_QUEUE_FLAG_ISEXCLUDED(handle);
|
|
||||||
case TRACE_CLASS_TIMER:
|
|
||||||
return (uint8_t) TRACE_GET_TIMER_FLAG_ISEXCLUDED(handle);
|
|
||||||
case TRACE_CLASS_EVENTGROUP:
|
|
||||||
return (uint8_t) TRACE_GET_EVENTGROUP_FLAG_ISEXCLUDED(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
prvTraceError("Invalid object class ID in prvIsObjectExcluded!");
|
|
||||||
|
|
||||||
/* Must never reach */
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* prvTraceIsSchedulerSuspended
|
* prvTraceIsSchedulerSuspended
|
||||||
*
|
*
|
||||||
|
@ -590,7 +818,7 @@ uint8_t uiTraceIsObjectExcluded(traceObjectClass objectclass, traceHandle handle
|
||||||
* task-switches from occurring. Only called from vTraceStoreISREnd.
|
* task-switches from occurring. Only called from vTraceStoreISREnd.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
|
#if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
|
||||||
unsigned char prvTraceIsSchedulerSuspended()
|
unsigned char prvTraceIsSchedulerSuspended(void)
|
||||||
{
|
{
|
||||||
/* Assumed to be available in FreeRTOS. According to the FreeRTOS docs,
|
/* Assumed to be available in FreeRTOS. According to the FreeRTOS docs,
|
||||||
INCLUDE_xTaskGetSchedulerState or configUSE_TIMERS must be set to 1 in
|
INCLUDE_xTaskGetSchedulerState or configUSE_TIMERS must be set to 1 in
|
||||||
|
|
|
@ -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
|
* Percepio AB, www.percepio.com
|
||||||
*
|
*
|
||||||
* trcSnapshotRecorder.c
|
* trcSnapshotRecorder.c
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
*
|
*
|
||||||
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
||||||
*
|
*
|
||||||
* Copyright Percepio AB, 2017.
|
* Copyright Percepio AB, 2018.
|
||||||
* www.percepio.com
|
* www.percepio.com
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
@ -66,6 +66,7 @@ int32_t isPendingContextSwitch = 0;
|
||||||
#if !defined TRC_CFG_INCLUDE_READY_EVENTS || TRC_CFG_INCLUDE_READY_EVENTS == 1
|
#if !defined TRC_CFG_INCLUDE_READY_EVENTS || TRC_CFG_INCLUDE_READY_EVENTS == 1
|
||||||
static int readyEventsEnabled = 1;
|
static int readyEventsEnabled = 1;
|
||||||
#endif /*!defined TRC_CFG_INCLUDE_READY_EVENTS || TRC_CFG_INCLUDE_READY_EVENTS == 1*/
|
#endif /*!defined TRC_CFG_INCLUDE_READY_EVENTS || TRC_CFG_INCLUDE_READY_EVENTS == 1*/
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* uiTraceTickCount
|
* uiTraceTickCount
|
||||||
*
|
*
|
||||||
|
@ -77,7 +78,9 @@ static int readyEventsEnabled = 1;
|
||||||
uint32_t uiTraceTickCount = 0;
|
uint32_t uiTraceTickCount = 0;
|
||||||
|
|
||||||
uint32_t trace_disable_timestamp = 0;
|
uint32_t trace_disable_timestamp = 0;
|
||||||
|
|
||||||
static uint32_t last_timestamp = 0;
|
static uint32_t last_timestamp = 0;
|
||||||
|
|
||||||
/* Flag that shows if inside a critical section of the recorder */
|
/* Flag that shows if inside a critical section of the recorder */
|
||||||
volatile int recorder_busy = 0;
|
volatile int recorder_busy = 0;
|
||||||
|
|
||||||
|
@ -87,18 +90,21 @@ uint32_t timestampFrequency = 0;
|
||||||
/* The last error message of the recorder. NULL if no error message. */
|
/* The last error message of the recorder. NULL if no error message. */
|
||||||
const char* traceErrorMessage = NULL;
|
const char* traceErrorMessage = NULL;
|
||||||
|
|
||||||
|
|
||||||
int8_t nISRactive = 0;
|
int8_t nISRactive = 0;
|
||||||
traceHandle handle_of_last_logged_task = 0;
|
|
||||||
uint8_t inExcludedTask = 0;
|
|
||||||
|
|
||||||
extern uint8_t inExcludedTask;
|
traceHandle handle_of_last_logged_task = 0;
|
||||||
extern int8_t nISRactive;
|
|
||||||
extern traceHandle handle_of_last_logged_task;
|
|
||||||
|
|
||||||
/* Called when the recorder is stopped, set by vTraceSetStopHook. */
|
/* Called when the recorder is stopped, set by vTraceSetStopHook. */
|
||||||
TRACE_STOP_HOOK vTraceStopHookPtr = (TRACE_STOP_HOOK)0;
|
TRACE_STOP_HOOK vTraceStopHookPtr = (TRACE_STOP_HOOK)0;
|
||||||
|
|
||||||
|
uint16_t CurrentFilterMask = 0xFFFF;
|
||||||
|
|
||||||
|
uint16_t CurrentFilterGroup = FilterGroup0;
|
||||||
|
|
||||||
|
extern int8_t nISRactive;
|
||||||
|
|
||||||
|
extern traceHandle handle_of_last_logged_task;
|
||||||
|
|
||||||
/*************** Private Functions *******************************************/
|
/*************** Private Functions *******************************************/
|
||||||
static void prvStrncpy(char* dst, const char* src, uint32_t maxLength);
|
static void prvStrncpy(char* dst, const char* src, uint32_t maxLength);
|
||||||
static uint8_t prvTraceGetObjectState(uint8_t objectclass, traceHandle id);
|
static uint8_t prvTraceGetObjectState(uint8_t objectclass, traceHandle id);
|
||||||
|
@ -108,6 +114,8 @@ static uint16_t prvTraceGetDTS(uint16_t param_maxDTS);
|
||||||
static traceString prvTraceOpenSymbol(const char* name, traceString userEventChannel);
|
static traceString prvTraceOpenSymbol(const char* name, traceString userEventChannel);
|
||||||
static void prvTraceUpdateCounters(void);
|
static void prvTraceUpdateCounters(void);
|
||||||
|
|
||||||
|
void vTraceStoreMemMangEvent(uint32_t ecode, uint32_t address, int32_t signed_size);
|
||||||
|
|
||||||
#if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER)
|
#if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER)
|
||||||
static void prvCheckDataToBeOverwrittenForMultiEntryEvents(uint8_t nEntries);
|
static void prvCheckDataToBeOverwrittenForMultiEntryEvents(uint8_t nEntries);
|
||||||
#endif
|
#endif
|
||||||
|
@ -137,8 +145,7 @@ static uint8_t prvTraceGet8BitHandle(traceHandle handle);
|
||||||
|
|
||||||
|
|
||||||
#if (TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1) && (TRC_CFG_SCHEDULING_ONLY == 0)
|
#if (TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1) && (TRC_CFG_SCHEDULING_ONLY == 0)
|
||||||
/* Current heap usage. Always updated. */
|
static uint32_t heapMemUsage = 0;
|
||||||
static uint32_t heapMemUsage = 0;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (TRC_CFG_SCHEDULING_ONLY == 0)
|
#if (TRC_CFG_SCHEDULING_ONLY == 0)
|
||||||
|
@ -261,7 +268,8 @@ void vTraceSetRecorderDataBuffer(void* pRecorderData)
|
||||||
* vTraceSetStopHook
|
* vTraceSetStopHook
|
||||||
*
|
*
|
||||||
* Sets a function to be called when the recorder is stopped. This can be used
|
* Sets a function to be called when the recorder is stopped. This can be used
|
||||||
* to save the trace to a file system, if available.
|
* to save the trace to a file system, if available. This is only implemented
|
||||||
|
* for snapshot mode.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void vTraceSetStopHook(TRACE_STOP_HOOK stopHookFunction)
|
void vTraceSetStopHook(TRACE_STOP_HOOK stopHookFunction)
|
||||||
{
|
{
|
||||||
|
@ -314,7 +322,7 @@ uint32_t uiTraceStart(void)
|
||||||
|
|
||||||
if (RecorderDataPtr == NULL)
|
if (RecorderDataPtr == NULL)
|
||||||
{
|
{
|
||||||
prvTraceError("RecorderDataPtr is NULL. Call vTraceInitTraceData() before starting trace.");
|
TRACE_ASSERT(RecorderDataPtr != NULL, "Recorder not initialized. Use vTraceEnable() instead!", 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,7 +376,10 @@ void vTraceStart(void)
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void vTraceStop(void)
|
void vTraceStop(void)
|
||||||
{
|
{
|
||||||
RecorderDataPtr->recorderActive = 0;
|
if (RecorderDataPtr != NULL)
|
||||||
|
{
|
||||||
|
RecorderDataPtr->recorderActive = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (vTraceStopHookPtr != (TRACE_STOP_HOOK)0)
|
if (vTraceStopHookPtr != (TRACE_STOP_HOOK)0)
|
||||||
{
|
{
|
||||||
|
@ -376,6 +387,22 @@ void vTraceStop(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* xTraceIsRecordingEnabled
|
||||||
|
* Returns true (1) if the recorder is enabled (i.e. is recording), otherwise 0.
|
||||||
|
******************************************************************************/
|
||||||
|
int xTraceIsRecordingEnabled(void)
|
||||||
|
{
|
||||||
|
if (RecorderDataPtr != NULL)
|
||||||
|
{
|
||||||
|
return (int)RecorderDataPtr->recorderActive;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* xTraceGetLastError
|
* xTraceGetLastError
|
||||||
*
|
*
|
||||||
|
@ -433,7 +460,6 @@ uint32_t uiTraceGetTraceBufferSize(void)
|
||||||
* prvTraceTaskInstanceFinish
|
* prvTraceTaskInstanceFinish
|
||||||
*
|
*
|
||||||
* Private common function for the vTraceTaskInstanceFinishXXX functions.
|
* Private common function for the vTraceTaskInstanceFinishXXX functions.
|
||||||
*
|
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static void prvTraceTaskInstanceFinish(int8_t direct)
|
static void prvTraceTaskInstanceFinish(int8_t direct)
|
||||||
{
|
{
|
||||||
|
@ -443,7 +469,7 @@ static void prvTraceTaskInstanceFinish(int8_t direct)
|
||||||
TRACE_ALLOC_CRITICAL_SECTION();
|
TRACE_ALLOC_CRITICAL_SECTION();
|
||||||
|
|
||||||
trcCRITICAL_SECTION_BEGIN();
|
trcCRITICAL_SECTION_BEGIN();
|
||||||
if (RecorderDataPtr->recorderActive && (! inExcludedTask || nISRactive) && handle_of_last_logged_task)
|
if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)
|
||||||
{
|
{
|
||||||
dts45 = (uint8_t)prvTraceGetDTS(0xFF);
|
dts45 = (uint8_t)prvTraceGetDTS(0xFF);
|
||||||
tis = (TaskInstanceStatusEvent*) prvTraceNextFreeEventBufferSlot();
|
tis = (TaskInstanceStatusEvent*) prvTraceNextFreeEventBufferSlot();
|
||||||
|
@ -482,9 +508,6 @@ static void prvTraceTaskInstanceFinish(int8_t direct)
|
||||||
* processCommand(command);
|
* processCommand(command);
|
||||||
* vTraceInstanceFinishedNext();
|
* vTraceInstanceFinishedNext();
|
||||||
* }
|
* }
|
||||||
*
|
|
||||||
* Note: This is only supported in Tracealyzer tools v2.7 or later
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
void vTraceInstanceFinishedNext(void)
|
void vTraceInstanceFinishedNext(void)
|
||||||
{
|
{
|
||||||
|
@ -514,9 +537,6 @@ void vTraceInstanceFinishedNext(void)
|
||||||
* DoSometingElse();
|
* DoSometingElse();
|
||||||
* vTraceInstanceFinishedNext();
|
* vTraceInstanceFinishedNext();
|
||||||
* }
|
* }
|
||||||
*
|
|
||||||
* Note: This is only supported in Tracealyzer tools v2.7 or later
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
void vTraceInstanceFinishedNow(void)
|
void vTraceInstanceFinishedNow(void)
|
||||||
{
|
{
|
||||||
|
@ -546,15 +566,16 @@ void vTraceInstanceFinishedNow(void)
|
||||||
* ...
|
* ...
|
||||||
* vTraceStoreISREnd(0);
|
* vTraceStoreISREnd(0);
|
||||||
* }
|
* }
|
||||||
*
|
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
traceHandle xTraceSetISRProperties(const char* name, uint8_t priority)
|
traceHandle xTraceSetISRProperties(const char* name, uint8_t priority)
|
||||||
{
|
{
|
||||||
static traceHandle handle = 0;
|
static traceHandle handle = 0;
|
||||||
handle++;
|
TRACE_ASSERT(RecorderDataPtr != NULL, "Recorder not initialized, call vTraceEnable() first!", (traceHandle)0);
|
||||||
TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[TRACE_CLASS_ISR], "xTraceSetISRProperties: Invalid value for handle", 0);
|
TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[TRACE_CLASS_ISR], "xTraceSetISRProperties: Invalid value for handle", 0);
|
||||||
TRACE_ASSERT(name != NULL, "xTraceSetISRProperties: name == NULL", 0);
|
TRACE_ASSERT(name != NULL, "xTraceSetISRProperties: name == NULL", 0);
|
||||||
|
|
||||||
|
handle++;
|
||||||
|
|
||||||
prvTraceSetObjectName(TRACE_CLASS_ISR, handle, name);
|
prvTraceSetObjectName(TRACE_CLASS_ISR, handle, name);
|
||||||
prvTraceSetPriorityProperty(TRACE_CLASS_ISR, handle, priority);
|
prvTraceSetPriorityProperty(TRACE_CLASS_ISR, handle, priority);
|
||||||
|
|
||||||
|
@ -578,7 +599,6 @@ void vTraceInstanceFinishedNow(void)
|
||||||
* ...
|
* ...
|
||||||
* vTraceStoreISREnd(0);
|
* vTraceStoreISREnd(0);
|
||||||
* }
|
* }
|
||||||
*
|
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void vTraceStoreISRBegin(traceHandle handle)
|
void vTraceStoreISRBegin(traceHandle handle)
|
||||||
{
|
{
|
||||||
|
@ -605,7 +625,8 @@ void vTraceStoreISRBegin(traceHandle handle)
|
||||||
{
|
{
|
||||||
uint16_t dts4;
|
uint16_t dts4;
|
||||||
|
|
||||||
TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[TRACE_CLASS_ISR], "vTraceStoreISRBegin: Invalid value for handle", TRC_UNUSED);
|
TRACE_ASSERT(handle != 0, "vTraceStoreISRBegin: Invalid ISR handle (NULL)", TRC_UNUSED);
|
||||||
|
TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[TRACE_CLASS_ISR], "vTraceStoreISRBegin: Invalid ISR handle (> NISR)", TRC_UNUSED);
|
||||||
|
|
||||||
dts4 = (uint16_t)prvTraceGetDTS(0xFFFF);
|
dts4 = (uint16_t)prvTraceGetDTS(0xFFFF);
|
||||||
|
|
||||||
|
@ -657,7 +678,6 @@ void vTraceStoreISRBegin(traceHandle handle)
|
||||||
* ...
|
* ...
|
||||||
* vTraceStoreISREnd(0);
|
* vTraceStoreISREnd(0);
|
||||||
* }
|
* }
|
||||||
*
|
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void vTraceStoreISREnd(int pendingISR)
|
void vTraceStoreISREnd(int pendingISR)
|
||||||
{
|
{
|
||||||
|
@ -742,6 +762,7 @@ void prvTraceDecreaseISRActive(void)
|
||||||
}
|
}
|
||||||
#endif /* (TRC_CFG_INCLUDE_ISR_TRACING == 1)*/
|
#endif /* (TRC_CFG_INCLUDE_ISR_TRACING == 1)*/
|
||||||
|
|
||||||
|
|
||||||
/********************************************************************************/
|
/********************************************************************************/
|
||||||
/* User Event functions */
|
/* User Event functions */
|
||||||
/********************************************************************************/
|
/********************************************************************************/
|
||||||
|
@ -1036,13 +1057,13 @@ static void prvTraceClearChannelBuffer(uint32_t count)
|
||||||
{
|
{
|
||||||
uint32_t slots;
|
uint32_t slots;
|
||||||
|
|
||||||
TRACE_ASSERT(TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE >= count,
|
TRACE_ASSERT((TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE) >= count,
|
||||||
"prvTraceClearChannelBuffer: TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE is too small to handle this event.", TRC_UNUSED);
|
"prvTraceClearChannelBuffer: TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE is too small to handle this event.", TRC_UNUSED);
|
||||||
|
|
||||||
/* Check if we're close to the end of the buffer */
|
/* Check if we're close to the end of the buffer */
|
||||||
if (RecorderDataPtr->userEventBuffer.nextSlotToWrite + count > TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE)
|
if (RecorderDataPtr->userEventBuffer.nextSlotToWrite + count > (TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE))
|
||||||
{
|
{
|
||||||
slots = TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE - RecorderDataPtr->userEventBuffer.nextSlotToWrite; /* Number of slots before end of buffer */
|
slots = (TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE) - RecorderDataPtr->userEventBuffer.nextSlotToWrite; /* Number of slots before end of buffer */
|
||||||
(void)memset(&RecorderDataPtr->userEventBuffer.channelBuffer[RecorderDataPtr->userEventBuffer.nextSlotToWrite], 0, slots);
|
(void)memset(&RecorderDataPtr->userEventBuffer.channelBuffer[RecorderDataPtr->userEventBuffer.nextSlotToWrite], 0, slots);
|
||||||
(void)memset(&RecorderDataPtr->userEventBuffer.channelBuffer[0], 0, (count - slots));
|
(void)memset(&RecorderDataPtr->userEventBuffer.channelBuffer[0], 0, (count - slots));
|
||||||
}
|
}
|
||||||
|
@ -1063,12 +1084,12 @@ static void prvTraceCopyToDataBuffer(uint32_t* data, uint32_t count)
|
||||||
|
|
||||||
TRACE_ASSERT(data != NULL,
|
TRACE_ASSERT(data != NULL,
|
||||||
"prvTraceCopyToDataBuffer: data == NULL.", TRC_UNUSED);
|
"prvTraceCopyToDataBuffer: data == NULL.", TRC_UNUSED);
|
||||||
TRACE_ASSERT(count <= TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE,
|
TRACE_ASSERT(count <= (TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE),
|
||||||
"prvTraceCopyToDataBuffer: TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE is too small to handle this event.", TRC_UNUSED);
|
"prvTraceCopyToDataBuffer: TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE is too small to handle this event.", TRC_UNUSED);
|
||||||
/* Check if we're close to the end of the buffer */
|
/* Check if we're close to the end of the buffer */
|
||||||
if (RecorderDataPtr->userEventBuffer.nextSlotToWrite + count > TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE)
|
if (RecorderDataPtr->userEventBuffer.nextSlotToWrite + count > (TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE))
|
||||||
{
|
{
|
||||||
slots = TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE - RecorderDataPtr->userEventBuffer.nextSlotToWrite; /* Number of slots before end of buffer */
|
slots = (TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE) - RecorderDataPtr->userEventBuffer.nextSlotToWrite; /* Number of slots before end of buffer */
|
||||||
(void)memcpy(&RecorderDataPtr->userEventBuffer.dataBuffer[RecorderDataPtr->userEventBuffer.nextSlotToWrite * 4], data, slots * 4);
|
(void)memcpy(&RecorderDataPtr->userEventBuffer.dataBuffer[RecorderDataPtr->userEventBuffer.nextSlotToWrite * 4], data, slots * 4);
|
||||||
(void)memcpy(&RecorderDataPtr->userEventBuffer.dataBuffer[0], data + slots, (count - slots) * 4);
|
(void)memcpy(&RecorderDataPtr->userEventBuffer.dataBuffer[0], data + slots, (count - slots) * 4);
|
||||||
}
|
}
|
||||||
|
@ -1119,7 +1140,7 @@ static void prvTraceUBHelper2(traceUBChannel channel, uint32_t* data, uint32_t n
|
||||||
|
|
||||||
TRACE_ALLOC_CRITICAL_SECTION();
|
TRACE_ALLOC_CRITICAL_SECTION();
|
||||||
|
|
||||||
TRACE_ASSERT(TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE >= noOfSlots, "prvTraceUBHelper2: TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE is too small to handle this event.", TRC_UNUSED);
|
TRACE_ASSERT((TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE) >= noOfSlots, "prvTraceUBHelper2: TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE is too small to handle this event.", TRC_UNUSED);
|
||||||
|
|
||||||
trcCRITICAL_SECTION_BEGIN();
|
trcCRITICAL_SECTION_BEGIN();
|
||||||
/* Store the timestamp */
|
/* Store the timestamp */
|
||||||
|
@ -1138,7 +1159,7 @@ static void prvTraceUBHelper2(traceUBChannel channel, uint32_t* data, uint32_t n
|
||||||
prvTraceCopyToDataBuffer(data, noOfSlots); /* Will wrap around the data if necessary */
|
prvTraceCopyToDataBuffer(data, noOfSlots); /* Will wrap around the data if necessary */
|
||||||
|
|
||||||
old_nextSlotToWrite = RecorderDataPtr->userEventBuffer.nextSlotToWrite; /* Save the index that we want to write the channel data at when we're done */
|
old_nextSlotToWrite = RecorderDataPtr->userEventBuffer.nextSlotToWrite; /* Save the index that we want to write the channel data at when we're done */
|
||||||
RecorderDataPtr->userEventBuffer.nextSlotToWrite = (RecorderDataPtr->userEventBuffer.nextSlotToWrite + noOfSlots) % TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE; /* Make sure we never end up outside the buffer */
|
RecorderDataPtr->userEventBuffer.nextSlotToWrite = (RecorderDataPtr->userEventBuffer.nextSlotToWrite + noOfSlots) % (TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE); /* Make sure we never end up outside the buffer */
|
||||||
|
|
||||||
/* Write to the channel buffer to indicate that this user event is ready to be used */
|
/* Write to the channel buffer to indicate that this user event is ready to be used */
|
||||||
if (channel != 0)
|
if (channel != 0)
|
||||||
|
@ -1174,7 +1195,7 @@ traceUBChannel xTraceRegisterUBChannel(traceString channel, traceString formatSt
|
||||||
TRACE_ASSERT(formatStr != 0, "xTraceRegisterChannelFormat: formatStr == 0", (traceUBChannel)0);
|
TRACE_ASSERT(formatStr != 0, "xTraceRegisterChannelFormat: formatStr == 0", (traceUBChannel)0);
|
||||||
|
|
||||||
trcCRITICAL_SECTION_BEGIN();
|
trcCRITICAL_SECTION_BEGIN();
|
||||||
for (i = 1; i <= TRC_CFG_UB_CHANNELS; i++) /* Size of the channels buffer is TRC_CFG_UB_CHANNELS + 1. Index 0 is unused. */
|
for (i = 1; i <= (TRC_CFG_UB_CHANNELS); i++) /* Size of the channels buffer is TRC_CFG_UB_CHANNELS + 1. Index 0 is unused. */
|
||||||
{
|
{
|
||||||
if(RecorderDataPtr->userEventBuffer.channels[i].name == 0 && RecorderDataPtr->userEventBuffer.channels[i].defaultFormat == 0)
|
if(RecorderDataPtr->userEventBuffer.channels[i].name == 0 && RecorderDataPtr->userEventBuffer.channels[i].defaultFormat == 0)
|
||||||
{
|
{
|
||||||
|
@ -1203,9 +1224,8 @@ traceUBChannel xTraceRegisterUBChannel(traceString channel, traceString formatSt
|
||||||
*
|
*
|
||||||
* Slightly faster version of vTracePrintF() due to no lookups.
|
* Slightly faster version of vTracePrintF() due to no lookups.
|
||||||
*
|
*
|
||||||
* Note: This is only available if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is enabled in
|
* Note: This is only available if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is
|
||||||
* trcConfig.h
|
* enabled in trcSnapshotConfig.h
|
||||||
*
|
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1))
|
#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1))
|
||||||
void vTraceUBData(traceUBChannel channelPair, ...)
|
void vTraceUBData(traceUBChannel channelPair, ...)
|
||||||
|
@ -1228,7 +1248,7 @@ void vTraceUBData_Helper(traceUBChannel channelPair, va_list vl)
|
||||||
traceString formatStr;
|
traceString formatStr;
|
||||||
|
|
||||||
TRACE_ASSERT(channelPair != 0, "vTraceUBData_Helper: channelPair == 0", TRC_UNUSED);
|
TRACE_ASSERT(channelPair != 0, "vTraceUBData_Helper: channelPair == 0", TRC_UNUSED);
|
||||||
TRACE_ASSERT(channelPair <= TRC_CFG_UB_CHANNELS, "vTraceUBData_Helper: ", TRC_UNUSED);
|
TRACE_ASSERT(channelPair <= (TRC_CFG_UB_CHANNELS), "vTraceUBData_Helper: ", TRC_UNUSED);
|
||||||
|
|
||||||
channel = RecorderDataPtr->userEventBuffer.channels[channelPair].name;
|
channel = RecorderDataPtr->userEventBuffer.channels[channelPair].name;
|
||||||
formatStr = RecorderDataPtr->userEventBuffer.channels[channelPair].defaultFormat;
|
formatStr = RecorderDataPtr->userEventBuffer.channels[channelPair].defaultFormat;
|
||||||
|
@ -1248,7 +1268,7 @@ void vTraceUBEvent(traceUBChannel channelPair)
|
||||||
uint32_t data[(3 + MAX_ARG_SIZE) / 4];
|
uint32_t data[(3 + MAX_ARG_SIZE) / 4];
|
||||||
|
|
||||||
TRACE_ASSERT(channelPair != 0, "vTraceUBEvent: channelPair == 0", TRC_UNUSED);
|
TRACE_ASSERT(channelPair != 0, "vTraceUBEvent: channelPair == 0", TRC_UNUSED);
|
||||||
TRACE_ASSERT(channelPair <= TRC_CFG_UB_CHANNELS, "vTraceUBEvent: ", TRC_UNUSED);
|
TRACE_ASSERT(channelPair <= (TRC_CFG_UB_CHANNELS), "vTraceUBEvent: ", TRC_UNUSED);
|
||||||
|
|
||||||
prvTraceUBHelper2(channelPair, data, 1); /* Only need one slot for timestamp */
|
prvTraceUBHelper2(channelPair, data, 1); /* Only need one slot for timestamp */
|
||||||
}
|
}
|
||||||
|
@ -1331,7 +1351,7 @@ void vTracePrintF_Helper(traceString eventLabel, const char* formatStr, va_list
|
||||||
|
|
||||||
trcCRITICAL_SECTION_BEGIN();
|
trcCRITICAL_SECTION_BEGIN();
|
||||||
|
|
||||||
if (RecorderDataPtr->recorderActive && (! inExcludedTask || nISRactive) && handle_of_last_logged_task)
|
if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)
|
||||||
{
|
{
|
||||||
/* First, write the "primary" user event entry in the local buffer, but
|
/* First, write the "primary" user event entry in the local buffer, but
|
||||||
let the event type be "EVENT_BEING_WRITTEN" for now...*/
|
let the event type be "EVENT_BEING_WRITTEN" for now...*/
|
||||||
|
@ -1396,7 +1416,7 @@ void vTracePrintF_Helper(traceString eventLabel, const char* formatStr, va_list
|
||||||
RecorderDataPtr->nextFreeIndex += noOfSlots;
|
RecorderDataPtr->nextFreeIndex += noOfSlots;
|
||||||
RecorderDataPtr->numEvents += noOfSlots;
|
RecorderDataPtr->numEvents += noOfSlots;
|
||||||
|
|
||||||
if (RecorderDataPtr->nextFreeIndex >= TRC_CFG_EVENT_BUFFER_SIZE)
|
if (RecorderDataPtr->nextFreeIndex >= (TRC_CFG_EVENT_BUFFER_SIZE))
|
||||||
{
|
{
|
||||||
#if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER)
|
#if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER)
|
||||||
/* We have reached the end, but this is a ring buffer. Start from the beginning again. */
|
/* We have reached the end, but this is a ring buffer. Start from the beginning again. */
|
||||||
|
@ -1423,7 +1443,7 @@ void vTracePrintF_Helper(traceString eventLabel, const char* formatStr, va_list
|
||||||
traceString formatLabel;
|
traceString formatLabel;
|
||||||
traceUBChannel channel;
|
traceUBChannel channel;
|
||||||
|
|
||||||
if (RecorderDataPtr->recorderActive && (! inExcludedTask || nISRactive) && handle_of_last_logged_task)
|
if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)
|
||||||
{
|
{
|
||||||
formatLabel = xTraceRegisterString(formatStr);
|
formatLabel = xTraceRegisterString(formatStr);
|
||||||
|
|
||||||
|
@ -1452,7 +1472,7 @@ void vTracePrint(traceString chn, const char* str)
|
||||||
TRACE_ALLOC_CRITICAL_SECTION();
|
TRACE_ALLOC_CRITICAL_SECTION();
|
||||||
|
|
||||||
trcCRITICAL_SECTION_BEGIN();
|
trcCRITICAL_SECTION_BEGIN();
|
||||||
if (RecorderDataPtr->recorderActive && (! inExcludedTask || nISRactive) && handle_of_last_logged_task)
|
if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)
|
||||||
{
|
{
|
||||||
dts1 = (uint8_t)prvTraceGetDTS(0xFF);
|
dts1 = (uint8_t)prvTraceGetDTS(0xFF);
|
||||||
ue = (UserEvent*) prvTraceNextFreeEventBufferSlot();
|
ue = (UserEvent*) prvTraceNextFreeEventBufferSlot();
|
||||||
|
@ -1470,7 +1490,7 @@ void vTracePrint(traceString chn, const char* str)
|
||||||
traceUBChannel channel;
|
traceUBChannel channel;
|
||||||
uint32_t noOfSlots = 1;
|
uint32_t noOfSlots = 1;
|
||||||
uint32_t tempDataBuffer[(3 + MAX_ARG_SIZE) / 4];
|
uint32_t tempDataBuffer[(3 + MAX_ARG_SIZE) / 4];
|
||||||
if (RecorderDataPtr->recorderActive && (! inExcludedTask || nISRactive) && handle_of_last_logged_task)
|
if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)
|
||||||
{
|
{
|
||||||
traceString trcStr = prvTraceOpenSymbol(str, chn);
|
traceString trcStr = prvTraceOpenSymbol(str, chn);
|
||||||
channel = xTraceRegisterUBChannel(chn, trcStr);
|
channel = xTraceRegisterUBChannel(chn, trcStr);
|
||||||
|
@ -1498,13 +1518,12 @@ void vTracePrint(traceString chn, const char* str)
|
||||||
* myEventHandle = xTraceRegisterString("MyUserEvent");
|
* myEventHandle = xTraceRegisterString("MyUserEvent");
|
||||||
* ...
|
* ...
|
||||||
* vTracePrintF(myEventHandle, "My value is: %d", myValue);
|
* vTracePrintF(myEventHandle, "My value is: %d", myValue);
|
||||||
*
|
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1))
|
#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1))
|
||||||
traceString xTraceRegisterString(const char* label)
|
traceString xTraceRegisterString(const char* label)
|
||||||
{
|
{
|
||||||
TRACE_ASSERT(label != NULL, "xTraceRegisterString: label == NULL", (traceString)0);
|
TRACE_ASSERT(label != NULL, "xTraceRegisterString: label == NULL", (traceString)0);
|
||||||
|
TRACE_ASSERT(RecorderDataPtr != NULL, "Recorder not initialized, call vTraceEnable() first!", (traceHandle)0);
|
||||||
return prvTraceOpenSymbol(label, 0);
|
return prvTraceOpenSymbol(label, 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1545,7 +1564,7 @@ void prvTraceStoreTaskReady(traceHandle handle)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE_ASSERT(handle <= TRC_CFG_NTASK, "prvTraceStoreTaskReady: Invalid value for handle", TRC_UNUSED);
|
TRACE_ASSERT(handle <= (TRC_CFG_NTASK), "prvTraceStoreTaskReady: Invalid value for handle", TRC_UNUSED);
|
||||||
|
|
||||||
if (recorder_busy)
|
if (recorder_busy)
|
||||||
{
|
{
|
||||||
|
@ -1566,18 +1585,15 @@ void prvTraceStoreTaskReady(traceHandle handle)
|
||||||
trcCRITICAL_SECTION_BEGIN();
|
trcCRITICAL_SECTION_BEGIN();
|
||||||
if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */
|
if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */
|
||||||
{
|
{
|
||||||
if (!TRACE_GET_TASK_FLAG_ISEXCLUDED(handle))
|
dts3 = (uint16_t)prvTraceGetDTS(0xFFFF);
|
||||||
|
hnd8 = prvTraceGet8BitHandle(handle);
|
||||||
|
tr = (TREvent*)prvTraceNextFreeEventBufferSlot();
|
||||||
|
if (tr != NULL)
|
||||||
{
|
{
|
||||||
dts3 = (uint16_t)prvTraceGetDTS(0xFFFF);
|
tr->type = DIV_TASK_READY;
|
||||||
hnd8 = prvTraceGet8BitHandle(handle);
|
tr->dts = dts3;
|
||||||
tr = (TREvent*)prvTraceNextFreeEventBufferSlot();
|
tr->objHandle = hnd8;
|
||||||
if (tr != NULL)
|
prvTraceUpdateCounters();
|
||||||
{
|
|
||||||
tr->type = DIV_TASK_READY;
|
|
||||||
tr->dts = dts3;
|
|
||||||
tr->objHandle = hnd8;
|
|
||||||
prvTraceUpdateCounters();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
trcCRITICAL_SECTION_END();
|
trcCRITICAL_SECTION_END();
|
||||||
|
@ -1667,44 +1683,40 @@ void vTraceStoreMemMangEvent(uint32_t ecode, uint32_t address, int32_t signed_si
|
||||||
|
|
||||||
if (RecorderDataPtr->recorderActive)
|
if (RecorderDataPtr->recorderActive)
|
||||||
{
|
{
|
||||||
/* If it is an ISR or NOT an excluded task, this kernel call will be stored in the trace */
|
dts1 = (uint8_t)prvTraceGetDTS(0xFF);
|
||||||
if (nISRactive || !inExcludedTask)
|
size_low = (uint16_t)prvTraceGetParam(0xFFFF, size);
|
||||||
|
ms = (MemEventSize *)prvTraceNextFreeEventBufferSlot();
|
||||||
|
|
||||||
|
if (ms != NULL)
|
||||||
{
|
{
|
||||||
dts1 = (uint8_t)prvTraceGetDTS(0xFF);
|
ms->dts = dts1;
|
||||||
size_low = (uint16_t)prvTraceGetParam(0xFFFF, size);
|
ms->type = NULL_EVENT; /* Updated when all events are written */
|
||||||
ms = (MemEventSize *)prvTraceNextFreeEventBufferSlot();
|
ms->size = size_low;
|
||||||
|
prvTraceUpdateCounters();
|
||||||
|
|
||||||
if (ms != NULL)
|
/* Storing a second record with address (signals "failed" if null) */
|
||||||
|
#if (TRC_CFG_HEAP_SIZE_BELOW_16M)
|
||||||
|
/* If the heap address range is within 16 MB, i.e., the upper 8 bits
|
||||||
|
of addresses are constant, this optimization avoids storing an extra
|
||||||
|
event record by ignoring the upper 8 bit of the address */
|
||||||
|
addr_low = address & 0xFFFF;
|
||||||
|
addr_high = (address >> 16) & 0xFF;
|
||||||
|
#else
|
||||||
|
/* The whole 32 bit address is stored using a second event record
|
||||||
|
for the upper 16 bit */
|
||||||
|
addr_low = (uint16_t)prvTraceGetParam(0xFFFF, address);
|
||||||
|
addr_high = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ma = (MemEventAddr *) prvTraceNextFreeEventBufferSlot();
|
||||||
|
if (ma != NULL)
|
||||||
{
|
{
|
||||||
ms->dts = dts1;
|
ma->addr_low = addr_low;
|
||||||
ms->type = NULL_EVENT; /* Updated when all events are written */
|
ma->addr_high = addr_high;
|
||||||
ms->size = size_low;
|
ma->type = (uint8_t) (ecode + 1); /* Note this! */
|
||||||
|
ms->type = (uint8_t) ecode;
|
||||||
prvTraceUpdateCounters();
|
prvTraceUpdateCounters();
|
||||||
|
RecorderDataPtr->heapMemUsage = heapMemUsage;
|
||||||
/* Storing a second record with address (signals "failed" if null) */
|
|
||||||
#if (TRC_CFG_HEAP_SIZE_BELOW_16M)
|
|
||||||
/* If the heap address range is within 16 MB, i.e., the upper 8 bits
|
|
||||||
of addresses are constant, this optimization avoids storing an extra
|
|
||||||
event record by ignoring the upper 8 bit of the address */
|
|
||||||
addr_low = address & 0xFFFF;
|
|
||||||
addr_high = (address >> 16) & 0xFF;
|
|
||||||
#else
|
|
||||||
/* The whole 32 bit address is stored using a second event record
|
|
||||||
for the upper 16 bit */
|
|
||||||
addr_low = (uint16_t)prvTraceGetParam(0xFFFF, address);
|
|
||||||
addr_high = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ma = (MemEventAddr *) prvTraceNextFreeEventBufferSlot();
|
|
||||||
if (ma != NULL)
|
|
||||||
{
|
|
||||||
ma->addr_low = addr_low;
|
|
||||||
ma->addr_high = addr_high;
|
|
||||||
ma->type = (uint8_t) (ecode + 1); /* Note this! */
|
|
||||||
ms->type = (uint8_t) ecode;
|
|
||||||
prvTraceUpdateCounters();
|
|
||||||
RecorderDataPtr->heapMemUsage = heapMemUsage;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1755,23 +1767,15 @@ void prvTraceStoreKernelCall(uint32_t ecode, traceObjectClass objectClass, uint3
|
||||||
trcCRITICAL_SECTION_BEGIN();
|
trcCRITICAL_SECTION_BEGIN();
|
||||||
if (RecorderDataPtr->recorderActive)
|
if (RecorderDataPtr->recorderActive)
|
||||||
{
|
{
|
||||||
/* If it is an ISR or NOT an excluded task, this kernel call will be stored in the trace */
|
dts1 = (uint16_t)prvTraceGetDTS(0xFFFF);
|
||||||
if (nISRactive || !inExcludedTask)
|
hnd8 = prvTraceGet8BitHandle((traceHandle)objectNumber);
|
||||||
|
kse = (KernelCall*) prvTraceNextFreeEventBufferSlot();
|
||||||
|
if (kse != NULL)
|
||||||
{
|
{
|
||||||
/* Check if the referenced object or the event code is excluded */
|
kse->dts = dts1;
|
||||||
if (!uiTraceIsObjectExcluded(objectClass, (traceHandle)objectNumber) && !TRACE_GET_EVENT_CODE_FLAG_ISEXCLUDED(ecode))
|
kse->type = (uint8_t)ecode;
|
||||||
{
|
kse->objHandle = hnd8;
|
||||||
dts1 = (uint16_t)prvTraceGetDTS(0xFFFF);
|
prvTraceUpdateCounters();
|
||||||
hnd8 = prvTraceGet8BitHandle((traceHandle)objectNumber);
|
|
||||||
kse = (KernelCall*) prvTraceNextFreeEventBufferSlot();
|
|
||||||
if (kse != NULL)
|
|
||||||
{
|
|
||||||
kse->dts = dts1;
|
|
||||||
kse->type = (uint8_t)ecode;
|
|
||||||
kse->objHandle = hnd8;
|
|
||||||
prvTraceUpdateCounters();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
trcCRITICAL_SECTION_END();
|
trcCRITICAL_SECTION_END();
|
||||||
|
@ -1818,24 +1822,19 @@ void prvTraceStoreKernelCallWithParam(uint32_t evtcode,
|
||||||
}
|
}
|
||||||
|
|
||||||
trcCRITICAL_SECTION_BEGIN();
|
trcCRITICAL_SECTION_BEGIN();
|
||||||
if (RecorderDataPtr->recorderActive && handle_of_last_logged_task && (! inExcludedTask || nISRactive))
|
if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)
|
||||||
{
|
{
|
||||||
/* Check if the referenced object or the event code is excluded */
|
dts2 = (uint8_t)prvTraceGetDTS(0xFF);
|
||||||
if (!uiTraceIsObjectExcluded(objectClass, (traceHandle)objectNumber) &&
|
p8 = (uint8_t) prvTraceGetParam(0xFF, param);
|
||||||
!TRACE_GET_EVENT_CODE_FLAG_ISEXCLUDED(evtcode))
|
hnd8 = prvTraceGet8BitHandle((traceHandle)objectNumber);
|
||||||
|
kse = (KernelCallWithParamAndHandle*) prvTraceNextFreeEventBufferSlot();
|
||||||
|
if (kse != NULL)
|
||||||
{
|
{
|
||||||
dts2 = (uint8_t)prvTraceGetDTS(0xFF);
|
kse->dts = dts2;
|
||||||
p8 = (uint8_t) prvTraceGetParam(0xFF, param);
|
kse->type = (uint8_t)evtcode;
|
||||||
hnd8 = prvTraceGet8BitHandle((traceHandle)objectNumber);
|
kse->objHandle = hnd8;
|
||||||
kse = (KernelCallWithParamAndHandle*) prvTraceNextFreeEventBufferSlot();
|
kse->param = p8;
|
||||||
if (kse != NULL)
|
prvTraceUpdateCounters();
|
||||||
{
|
|
||||||
kse->dts = dts2;
|
|
||||||
kse->type = (uint8_t)evtcode;
|
|
||||||
kse->objHandle = hnd8;
|
|
||||||
kse->param = p8;
|
|
||||||
prvTraceUpdateCounters();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
trcCRITICAL_SECTION_END();
|
trcCRITICAL_SECTION_END();
|
||||||
|
@ -1913,22 +1912,17 @@ void prvTraceStoreKernelCallWithNumericParamOnly(uint32_t evtcode, uint32_t para
|
||||||
}
|
}
|
||||||
|
|
||||||
trcCRITICAL_SECTION_BEGIN();
|
trcCRITICAL_SECTION_BEGIN();
|
||||||
if (RecorderDataPtr->recorderActive && handle_of_last_logged_task
|
if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)
|
||||||
&& (! inExcludedTask || nISRactive))
|
|
||||||
{
|
{
|
||||||
/* Check if the event code is excluded */
|
dts6 = (uint8_t)prvTraceGetDTS(0xFF);
|
||||||
if (!TRACE_GET_EVENT_CODE_FLAG_ISEXCLUDED(evtcode))
|
restParam = (uint16_t)prvTraceGetParam(0xFFFF, param);
|
||||||
|
kse = (KernelCallWithParam16*) prvTraceNextFreeEventBufferSlot();
|
||||||
|
if (kse != NULL)
|
||||||
{
|
{
|
||||||
dts6 = (uint8_t)prvTraceGetDTS(0xFF);
|
kse->dts = dts6;
|
||||||
restParam = (uint16_t)prvTraceGetParam(0xFFFF, param);
|
kse->type = (uint8_t)evtcode;
|
||||||
kse = (KernelCallWithParam16*) prvTraceNextFreeEventBufferSlot();
|
kse->param = restParam;
|
||||||
if (kse != NULL)
|
prvTraceUpdateCounters();
|
||||||
{
|
|
||||||
kse->dts = dts6;
|
|
||||||
kse->type = (uint8_t)evtcode;
|
|
||||||
kse->param = restParam;
|
|
||||||
prvTraceUpdateCounters();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
trcCRITICAL_SECTION_END();
|
trcCRITICAL_SECTION_END();
|
||||||
|
@ -1944,44 +1938,18 @@ void prvTraceStoreTaskswitch(traceHandle task_handle)
|
||||||
{
|
{
|
||||||
uint16_t dts3;
|
uint16_t dts3;
|
||||||
TSEvent* ts;
|
TSEvent* ts;
|
||||||
int8_t skipEvent;
|
|
||||||
uint8_t hnd8;
|
uint8_t hnd8;
|
||||||
#if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
|
#if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
|
||||||
extern int32_t isPendingContextSwitch;
|
extern int32_t isPendingContextSwitch;
|
||||||
#endif
|
#endif
|
||||||
trcSR_ALLOC_CRITICAL_SECTION_ON_CORTEX_M_ONLY();
|
trcSR_ALLOC_CRITICAL_SECTION_ON_CORTEX_M_ONLY();
|
||||||
|
|
||||||
skipEvent = 0;
|
TRACE_ASSERT(task_handle <= (TRC_CFG_NTASK),
|
||||||
|
|
||||||
TRACE_ASSERT(task_handle <= TRC_CFG_NTASK,
|
|
||||||
"prvTraceStoreTaskswitch: Invalid value for task_handle", TRC_UNUSED);
|
"prvTraceStoreTaskswitch: Invalid value for task_handle", TRC_UNUSED);
|
||||||
|
|
||||||
/* Skip the event if the task has been excluded, using vTraceExcludeTask */
|
|
||||||
if (TRACE_GET_TASK_FLAG_ISEXCLUDED(task_handle))
|
|
||||||
{
|
|
||||||
skipEvent = 1;
|
|
||||||
inExcludedTask = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
inExcludedTask = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
trcCRITICAL_SECTION_BEGIN_ON_CORTEX_M_ONLY();
|
trcCRITICAL_SECTION_BEGIN_ON_CORTEX_M_ONLY();
|
||||||
|
|
||||||
/* Skip the event if the same task is scheduled */
|
if ((task_handle != handle_of_last_logged_task) && (RecorderDataPtr->recorderActive))
|
||||||
if (task_handle == handle_of_last_logged_task)
|
|
||||||
{
|
|
||||||
skipEvent = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!RecorderDataPtr->recorderActive)
|
|
||||||
{
|
|
||||||
skipEvent = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If this event should be logged, log it! */
|
|
||||||
if (skipEvent == 0)
|
|
||||||
{
|
{
|
||||||
#if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
|
#if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
|
||||||
isPendingContextSwitch = 0;
|
isPendingContextSwitch = 0;
|
||||||
|
@ -2026,8 +1994,7 @@ void prvTraceStoreTaskswitch(traceHandle task_handle)
|
||||||
* and name (a symbol table handle). The stored name-handle mapping is thus the
|
* and name (a symbol table handle). The stored name-handle mapping is thus the
|
||||||
* "old" one, valid up until this point.
|
* "old" one, valid up until this point.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#if (TRC_CFG_INCLUDE_OBJECT_DELETE == 1)
|
void prvTraceStoreObjectNameOnCloseEvent(uint8_t evtcode, traceHandle handle,
|
||||||
void prvTraceStoreObjectNameOnCloseEvent(traceHandle handle,
|
|
||||||
traceObjectClass objectclass)
|
traceObjectClass objectclass)
|
||||||
{
|
{
|
||||||
ObjCloseNameEvent * ce;
|
ObjCloseNameEvent * ce;
|
||||||
|
@ -2049,7 +2016,7 @@ void prvTraceStoreObjectNameOnCloseEvent(traceHandle handle,
|
||||||
ce = (ObjCloseNameEvent*) prvTraceNextFreeEventBufferSlot();
|
ce = (ObjCloseNameEvent*) prvTraceNextFreeEventBufferSlot();
|
||||||
if (ce != NULL)
|
if (ce != NULL)
|
||||||
{
|
{
|
||||||
ce->type = (uint8_t) (EVENTGROUP_OBJCLOSE_NAME + objectclass);
|
ce->type = (uint8_t) evtcode;
|
||||||
ce->objHandle = hnd8;
|
ce->objHandle = hnd8;
|
||||||
ce->symbolIndex = idx;
|
ce->symbolIndex = idx;
|
||||||
prvTraceUpdateCounters();
|
prvTraceUpdateCounters();
|
||||||
|
@ -2057,7 +2024,7 @@ void prvTraceStoreObjectNameOnCloseEvent(traceHandle handle,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void prvTraceStoreObjectPropertiesOnCloseEvent(traceHandle handle,
|
void prvTraceStoreObjectPropertiesOnCloseEvent(uint8_t evtcode, traceHandle handle,
|
||||||
traceObjectClass objectclass)
|
traceObjectClass objectclass)
|
||||||
{
|
{
|
||||||
ObjClosePropEvent * pe;
|
ObjClosePropEvent * pe;
|
||||||
|
@ -2081,12 +2048,11 @@ void prvTraceStoreObjectPropertiesOnCloseEvent(traceHandle handle,
|
||||||
{
|
{
|
||||||
pe->arg1 = TRACE_PROPERTY_OBJECT_STATE(objectclass, handle);
|
pe->arg1 = TRACE_PROPERTY_OBJECT_STATE(objectclass, handle);
|
||||||
}
|
}
|
||||||
pe->type = (uint8_t) (EVENTGROUP_OBJCLOSE_PROP + objectclass);
|
pe->type = evtcode;
|
||||||
prvTraceUpdateCounters();
|
prvTraceUpdateCounters();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void prvTraceSetPriorityProperty(uint8_t objectclass, traceHandle id, uint8_t value)
|
void prvTraceSetPriorityProperty(uint8_t objectclass, traceHandle id, uint8_t value)
|
||||||
{
|
{
|
||||||
|
@ -2142,16 +2108,6 @@ void prvTraceSetTaskInstanceFinished(traceHandle handle)
|
||||||
* Static data initializations
|
* Static data initializations
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
/* Tasks and kernel objects can be explicitly excluded from the trace to reduce
|
|
||||||
buffer usage. This structure handles the exclude flags for all objects and tasks.
|
|
||||||
Note that slot 0 is not used, since not a valid handle. */
|
|
||||||
uint8_t trcExcludedObjects[(TRACE_KERNEL_OBJECT_COUNT + TRACE_NCLASSES) / 8 + 1] = { 0 };
|
|
||||||
|
|
||||||
/* Specific events can also be excluded, i.e., by the event code. This can be
|
|
||||||
used to exclude kernel calls that don't refer to a kernel object, like a delay.
|
|
||||||
This structure handle the exclude flags for all event codes */
|
|
||||||
uint8_t trcExcludedEventCodes[NEventCodes / 8 + 1] = { 0 };
|
|
||||||
|
|
||||||
/* A set of stacks that keeps track of available object handles for each class.
|
/* A set of stacks that keeps track of available object handles for each class.
|
||||||
The stacks are empty initially, meaning that allocation of new handles will be
|
The stacks are empty initially, meaning that allocation of new handles will be
|
||||||
based on a counter (for each object class). Any delete operation will
|
based on a counter (for each object class). Any delete operation will
|
||||||
|
@ -2222,7 +2178,7 @@ void prvTraceInitTraceData()
|
||||||
RecorderDataPtr->minor_version = TRACE_MINOR_VERSION;
|
RecorderDataPtr->minor_version = TRACE_MINOR_VERSION;
|
||||||
RecorderDataPtr->irq_priority_order = TRC_IRQ_PRIORITY_ORDER;
|
RecorderDataPtr->irq_priority_order = TRC_IRQ_PRIORITY_ORDER;
|
||||||
RecorderDataPtr->filesize = sizeof(RecorderDataType);
|
RecorderDataPtr->filesize = sizeof(RecorderDataType);
|
||||||
RecorderDataPtr->maxEvents = TRC_CFG_EVENT_BUFFER_SIZE;
|
RecorderDataPtr->maxEvents = (TRC_CFG_EVENT_BUFFER_SIZE);
|
||||||
RecorderDataPtr->debugMarker0 = (int32_t) 0xF0F0F0F0;
|
RecorderDataPtr->debugMarker0 = (int32_t) 0xF0F0F0F0;
|
||||||
RecorderDataPtr->isUsing16bitHandles = TRC_CFG_USE_16BIT_OBJECT_HANDLES;
|
RecorderDataPtr->isUsing16bitHandles = TRC_CFG_USE_16BIT_OBJECT_HANDLES;
|
||||||
RecorderDataPtr->isrTailchainingThreshold = TRC_CFG_ISR_TAILCHAINING_THRESHOLD;
|
RecorderDataPtr->isrTailchainingThreshold = TRC_CFG_ISR_TAILCHAINING_THRESHOLD;
|
||||||
|
@ -2231,7 +2187,7 @@ void prvTraceInitTraceData()
|
||||||
vTraceInitObjectPropertyTable();
|
vTraceInitObjectPropertyTable();
|
||||||
|
|
||||||
RecorderDataPtr->debugMarker1 = (int32_t)0xF1F1F1F1;
|
RecorderDataPtr->debugMarker1 = (int32_t)0xF1F1F1F1;
|
||||||
RecorderDataPtr->SymbolTable.symTableSize = TRC_CFG_SYMBOL_TABLE_SIZE;
|
RecorderDataPtr->SymbolTable.symTableSize = (TRC_CFG_SYMBOL_TABLE_SIZE);
|
||||||
RecorderDataPtr->SymbolTable.nextFreeSymbolIndex = 1;
|
RecorderDataPtr->SymbolTable.nextFreeSymbolIndex = 1;
|
||||||
#if (TRC_CFG_INCLUDE_FLOAT_SUPPORT == 1)
|
#if (TRC_CFG_INCLUDE_FLOAT_SUPPORT == 1)
|
||||||
RecorderDataPtr->exampleFloatEncoding = 1.0f; /* otherwise already zero */
|
RecorderDataPtr->exampleFloatEncoding = 1.0f; /* otherwise already zero */
|
||||||
|
@ -2255,8 +2211,8 @@ void prvTraceInitTraceData()
|
||||||
#if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER
|
#if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER
|
||||||
RecorderDataPtr->userEventBuffer.bufferID = 1;
|
RecorderDataPtr->userEventBuffer.bufferID = 1;
|
||||||
RecorderDataPtr->userEventBuffer.version = 0;
|
RecorderDataPtr->userEventBuffer.version = 0;
|
||||||
RecorderDataPtr->userEventBuffer.numberOfSlots = TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE;
|
RecorderDataPtr->userEventBuffer.numberOfSlots = (TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE);
|
||||||
RecorderDataPtr->userEventBuffer.numberOfChannels = TRC_CFG_UB_CHANNELS + 1;
|
RecorderDataPtr->userEventBuffer.numberOfChannels = (TRC_CFG_UB_CHANNELS) + 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Kernel specific initialization of the objectHandleStacks variable */
|
/* Kernel specific initialization of the objectHandleStacks variable */
|
||||||
|
@ -2289,6 +2245,15 @@ void prvTraceInitTraceData()
|
||||||
RecorderDataPtr->startmarker1 = 0x02;
|
RecorderDataPtr->startmarker1 = 0x02;
|
||||||
RecorderDataPtr->startmarker0 = 0x01;
|
RecorderDataPtr->startmarker0 = 0x01;
|
||||||
|
|
||||||
|
if (traceErrorMessage != NULL)
|
||||||
|
{
|
||||||
|
// An error was detected before vTraceEnable was called, make sure this is stored in the trace data.
|
||||||
|
prvStrncpy(RecorderDataPtr->systemInfo, traceErrorMessage, 80);
|
||||||
|
RecorderDataPtr->internalErrorOccured = 1;
|
||||||
|
vTraceStop();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef TRC_PORT_SPECIFIC_INIT
|
#ifdef TRC_PORT_SPECIFIC_INIT
|
||||||
TRC_PORT_SPECIFIC_INIT();
|
TRC_PORT_SPECIFIC_INIT();
|
||||||
|
@ -2305,7 +2270,7 @@ void* prvTraceNextFreeEventBufferSlot(void)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RecorderDataPtr->nextFreeIndex >= TRC_CFG_EVENT_BUFFER_SIZE)
|
if (RecorderDataPtr->nextFreeIndex >= (TRC_CFG_EVENT_BUFFER_SIZE))
|
||||||
{
|
{
|
||||||
prvTraceError("Attempt to index outside event buffer!");
|
prvTraceError("Attempt to index outside event buffer!");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -2336,9 +2301,14 @@ traceHandle prvTraceGetObjectHandle(traceObjectClass objectclass)
|
||||||
traceHandle handle;
|
traceHandle handle;
|
||||||
static int indexOfHandle;
|
static int indexOfHandle;
|
||||||
|
|
||||||
|
TRACE_ALLOC_CRITICAL_SECTION();
|
||||||
|
|
||||||
|
TRACE_ASSERT(RecorderDataPtr != NULL, "Recorder not initialized, call vTraceEnable() first!", (traceHandle)0);
|
||||||
|
|
||||||
TRACE_ASSERT(objectclass < TRACE_NCLASSES,
|
TRACE_ASSERT(objectclass < TRACE_NCLASSES,
|
||||||
"prvTraceGetObjectHandle: Invalid value for objectclass", (traceHandle)0);
|
"prvTraceGetObjectHandle: Invalid value for objectclass", (traceHandle)0);
|
||||||
|
|
||||||
|
trcCRITICAL_SECTION_BEGIN();
|
||||||
indexOfHandle = objectHandleStacks.indexOfNextAvailableHandle[objectclass];
|
indexOfHandle = objectHandleStacks.indexOfNextAvailableHandle[objectclass];
|
||||||
if (objectHandleStacks.objectHandles[indexOfHandle] == 0)
|
if (objectHandleStacks.objectHandles[indexOfHandle] == 0)
|
||||||
{
|
{
|
||||||
|
@ -2372,8 +2342,9 @@ traceHandle prvTraceGetObjectHandle(traceObjectClass objectclass)
|
||||||
objectHandleStacks.handleCountWaterMarksOfClass[objectclass] =
|
objectHandleStacks.handleCountWaterMarksOfClass[objectclass] =
|
||||||
(traceHandle)hndCount;
|
(traceHandle)hndCount;
|
||||||
}
|
}
|
||||||
TRACE_CLEAR_OBJECT_FLAG_ISEXCLUDED(objectclass, handle);
|
|
||||||
}
|
}
|
||||||
|
trcCRITICAL_SECTION_END();
|
||||||
|
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2537,7 +2508,10 @@ void vTraceSetFrequency(uint32_t frequency)
|
||||||
void prvTraceError(const char* msg)
|
void prvTraceError(const char* msg)
|
||||||
{
|
{
|
||||||
/* Stop the recorder */
|
/* Stop the recorder */
|
||||||
vTraceStop();
|
if (RecorderDataPtr != NULL)
|
||||||
|
{
|
||||||
|
vTraceStop();
|
||||||
|
}
|
||||||
|
|
||||||
/* If first error only... */
|
/* If first error only... */
|
||||||
if (traceErrorMessage == NULL)
|
if (traceErrorMessage == NULL)
|
||||||
|
@ -2551,6 +2525,16 @@ void prvTraceError(const char* msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vTraceSetFilterMask(uint16_t filterMask)
|
||||||
|
{
|
||||||
|
CurrentFilterMask = filterMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vTraceSetFilterGroup(uint16_t filterGroup)
|
||||||
|
{
|
||||||
|
CurrentFilterGroup = filterGroup;
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* prvCheckDataToBeOverwrittenForMultiEntryEvents
|
* prvCheckDataToBeOverwrittenForMultiEntryEvents
|
||||||
*
|
*
|
||||||
|
@ -2623,7 +2607,7 @@ void prvTraceUpdateCounters(void)
|
||||||
|
|
||||||
RecorderDataPtr->nextFreeIndex++;
|
RecorderDataPtr->nextFreeIndex++;
|
||||||
|
|
||||||
if (RecorderDataPtr->nextFreeIndex >= TRC_CFG_EVENT_BUFFER_SIZE)
|
if (RecorderDataPtr->nextFreeIndex >= (TRC_CFG_EVENT_BUFFER_SIZE))
|
||||||
{
|
{
|
||||||
#if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER)
|
#if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER)
|
||||||
RecorderDataPtr->bufferIsFull = 1;
|
RecorderDataPtr->bufferIsFull = 1;
|
||||||
|
@ -2663,16 +2647,16 @@ uint16_t prvTraceGetDTS(uint16_t param_maxDTS)
|
||||||
if (timestampFrequency != 0)
|
if (timestampFrequency != 0)
|
||||||
{
|
{
|
||||||
/* If to override default TRC_HWTC_FREQ_HZ value with value set by vTraceSetFrequency */
|
/* If to override default TRC_HWTC_FREQ_HZ value with value set by vTraceSetFrequency */
|
||||||
RecorderDataPtr->frequency = timestampFrequency / TRC_HWTC_DIVISOR;
|
RecorderDataPtr->frequency = timestampFrequency / (TRC_HWTC_DIVISOR);
|
||||||
}
|
}
|
||||||
else if (init_hwtc_count != TRC_HWTC_COUNT)
|
else if (init_hwtc_count != (TRC_HWTC_COUNT))
|
||||||
{
|
{
|
||||||
/* If using default value and timer has been started.
|
/* If using default value and timer has been started.
|
||||||
Note: If the default frequency value set here would be incorrect, e.g.,
|
Note: If the default frequency value set here would be incorrect, e.g.,
|
||||||
if the timer has actually not been configured yet, override this
|
if the timer has actually not been configured yet, override this
|
||||||
with vTraceSetFrequency.
|
with vTraceSetFrequency.
|
||||||
*/
|
*/
|
||||||
RecorderDataPtr->frequency = TRC_HWTC_FREQ_HZ / TRC_HWTC_DIVISOR;
|
RecorderDataPtr->frequency = (TRC_HWTC_FREQ_HZ) / (TRC_HWTC_DIVISOR);
|
||||||
}
|
}
|
||||||
/* If no override (vTraceSetFrequency) and timer inactive -> no action */
|
/* If no override (vTraceSetFrequency) and timer inactive -> no action */
|
||||||
}
|
}
|
||||||
|
@ -2819,7 +2803,7 @@ uint16_t prvTraceCreateSymbolTableEntry(const char* name,
|
||||||
TRACE_ASSERT(name != NULL, "prvTraceCreateSymbolTableEntry: name == NULL", 0);
|
TRACE_ASSERT(name != NULL, "prvTraceCreateSymbolTableEntry: name == NULL", 0);
|
||||||
TRACE_ASSERT(len != 0, "prvTraceCreateSymbolTableEntry: len == 0", 0);
|
TRACE_ASSERT(len != 0, "prvTraceCreateSymbolTableEntry: len == 0", 0);
|
||||||
|
|
||||||
if (RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + len + 4 >= TRC_CFG_SYMBOL_TABLE_SIZE)
|
if (RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + len + 4 >= (TRC_CFG_SYMBOL_TABLE_SIZE))
|
||||||
{
|
{
|
||||||
prvTraceError("Symbol table full. Increase TRC_CFG_SYMBOL_TABLE_SIZE in trcConfig.h");
|
prvTraceError("Symbol table full. Increase TRC_CFG_SYMBOL_TABLE_SIZE in trcConfig.h");
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
@ -3033,10 +3017,10 @@ void prvTracePortGetTimeStamp(uint32_t *pTimestamp)
|
||||||
/* Retrieve TRC_HWTC_COUNT only once since the same value should be used all throughout this function. */
|
/* Retrieve TRC_HWTC_COUNT only once since the same value should be used all throughout this function. */
|
||||||
#if (TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_INCR)
|
#if (TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_INCR)
|
||||||
/* Get the increasing tick count */
|
/* Get the increasing tick count */
|
||||||
hwtc_count = TRC_HWTC_COUNT;
|
hwtc_count = (TRC_HWTC_COUNT);
|
||||||
#elif (TRC_HWTC_TYPE == TRC_OS_TIMER_DECR || TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_DECR)
|
#elif (TRC_HWTC_TYPE == TRC_OS_TIMER_DECR || TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_DECR)
|
||||||
/* Convert decreasing tick count into increasing tick count */
|
/* Convert decreasing tick count into increasing tick count */
|
||||||
hwtc_count = TRC_HWTC_PERIOD - TRC_HWTC_COUNT;
|
hwtc_count = (TRC_HWTC_PERIOD) - (TRC_HWTC_COUNT);
|
||||||
#else
|
#else
|
||||||
#error "TRC_HWTC_TYPE has unexpected value"
|
#error "TRC_HWTC_TYPE has unexpected value"
|
||||||
#endif
|
#endif
|
||||||
|
@ -3081,9 +3065,9 @@ void prvTracePortGetTimeStamp(uint32_t *pTimestamp)
|
||||||
if (pTimestamp)
|
if (pTimestamp)
|
||||||
{
|
{
|
||||||
/* Get timestamp from trace ticks. Scale down the period to avoid unwanted overflows. */
|
/* Get timestamp from trace ticks. Scale down the period to avoid unwanted overflows. */
|
||||||
last_timestamp = traceTickCount * (TRC_HWTC_PERIOD / TRC_HWTC_DIVISOR);
|
last_timestamp = traceTickCount * ((TRC_HWTC_PERIOD) / (TRC_HWTC_DIVISOR));
|
||||||
/* Increase timestamp by (hwtc_count + "lost hardware ticks from scaling down period") / TRC_HWTC_DIVISOR. */
|
/* Increase timestamp by (hwtc_count + "lost hardware ticks from scaling down period") / TRC_HWTC_DIVISOR. */
|
||||||
last_timestamp += (hwtc_count + traceTickCount * (TRC_HWTC_PERIOD % TRC_HWTC_DIVISOR)) / TRC_HWTC_DIVISOR;
|
last_timestamp += (hwtc_count + traceTickCount * ((TRC_HWTC_PERIOD) % (TRC_HWTC_DIVISOR))) / (TRC_HWTC_DIVISOR);
|
||||||
}
|
}
|
||||||
/* Store the previous value */
|
/* Store the previous value */
|
||||||
last_traceTickCount = traceTickCount;
|
last_traceTickCount = traceTickCount;
|
||||||
|
@ -3099,10 +3083,10 @@ void prvTracePortGetTimeStamp(uint32_t *pTimestamp)
|
||||||
diff = (hwtc_count - last_hwtc_count) + last_hwtc_rest;
|
diff = (hwtc_count - last_hwtc_count) + last_hwtc_rest;
|
||||||
|
|
||||||
/* Scale down the diff */
|
/* Scale down the diff */
|
||||||
diff_scaled = diff / TRC_HWTC_DIVISOR;
|
diff_scaled = diff / (TRC_HWTC_DIVISOR);
|
||||||
|
|
||||||
/* Find out how many ticks were lost when scaling down, so we can add them the next time */
|
/* Find out how many ticks were lost when scaling down, so we can add them the next time */
|
||||||
last_hwtc_rest = diff % TRC_HWTC_DIVISOR;
|
last_hwtc_rest = diff % (TRC_HWTC_DIVISOR);
|
||||||
|
|
||||||
/* We increase the scaled timestamp by the scaled amount */
|
/* We increase the scaled timestamp by the scaled amount */
|
||||||
last_timestamp += diff_scaled;
|
last_timestamp += diff_scaled;
|
||||||
|
|
|
@ -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
|
* Percepio AB, www.percepio.com
|
||||||
*
|
*
|
||||||
* trcStreamingRecorder.c
|
* trcStreamingRecorder.c
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
*
|
*
|
||||||
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
||||||
*
|
*
|
||||||
* Copyright Percepio AB, 2017.
|
* Copyright Percepio AB, 2018.
|
||||||
* www.percepio.com
|
* www.percepio.com
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ typedef struct{
|
||||||
} ObjectDataTable;
|
} ObjectDataTable;
|
||||||
|
|
||||||
typedef struct{
|
typedef struct{
|
||||||
uint8_t Status;
|
uint16_t Status; /* 16 bit to avoid implicit padding (warnings) */
|
||||||
uint16_t BytesRemaining;
|
uint16_t BytesRemaining;
|
||||||
char* WritePointer;
|
char* WritePointer;
|
||||||
} PageType;
|
} PageType;
|
||||||
|
@ -135,13 +135,6 @@ typedef struct{
|
||||||
|
|
||||||
#define PSF_ASSERT(_assert, _err) if (! (_assert)){ prvTraceError(_err); return; }
|
#define PSF_ASSERT(_assert, _err) if (! (_assert)){ prvTraceError(_err); return; }
|
||||||
|
|
||||||
#define PSF_ERROR_NONE 0
|
|
||||||
#define PSF_ERROR_EVENT_CODE_TOO_LARGE 1
|
|
||||||
#define PSF_ERROR_ISR_NESTING_OVERFLOW 2
|
|
||||||
#define PSF_ERROR_DWT_NOT_SUPPORTED 3
|
|
||||||
#define PSF_ERROR_DWT_CYCCNT_NOT_SUPPORTED 4
|
|
||||||
#define PSF_ERROR_AUTO_ISR_END 5
|
|
||||||
|
|
||||||
/* Part of the PSF format - encodes the number of 32-bit params in an event */
|
/* Part of the PSF format - encodes the number of 32-bit params in an event */
|
||||||
#define PARAM_COUNT(n) ((n & 0xF) << 12)
|
#define PARAM_COUNT(n) ((n & 0xF) << 12)
|
||||||
|
|
||||||
|
@ -190,9 +183,9 @@ int32_t isPendingContextSwitch = 0;
|
||||||
|
|
||||||
uint32_t uiTraceTickCount = 0;
|
uint32_t uiTraceTickCount = 0;
|
||||||
uint32_t timestampFrequency = 0;
|
uint32_t timestampFrequency = 0;
|
||||||
uint32_t DroppedEventCounter = 0; // Total number of dropped events (failed allocations)
|
uint32_t DroppedEventCounter = 0;
|
||||||
uint32_t TotalBytesRemaining_LowWaterMark = TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT * TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE;
|
uint32_t TotalBytesRemaining_LowWaterMark = (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT) * (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE);
|
||||||
uint32_t TotalBytesRemaining = TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT * TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE;
|
uint32_t TotalBytesRemaining = (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT) * (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE);
|
||||||
|
|
||||||
PageType PageInfo[TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT];
|
PageType PageInfo[TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT];
|
||||||
|
|
||||||
|
@ -228,9 +221,9 @@ volatile uint32_t NoRoomForObjectData = 0;
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* LongestSymbolName
|
* LongestSymbolName
|
||||||
*
|
*
|
||||||
* Updated in prvTraceSaveSymbol. Should not exceed SYMBOL_MAX_LENGTH, otherwise
|
* Updated in prvTraceSaveSymbol. Should not exceed TRC_CFG_SYMBOL_MAX_LENGTH,
|
||||||
* symbol names will be truncated. In that case, set SYMBOL_MAX_LENGTH to (at
|
* otherwise symbol names will be truncated. In that case, set
|
||||||
* least) this value.
|
* TRC_CFG_SYMBOL_MAX_LENGTH to (at least) this value.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
volatile uint32_t LongestSymbolName = 0;
|
volatile uint32_t LongestSymbolName = 0;
|
||||||
|
|
||||||
|
@ -245,14 +238,22 @@ volatile uint32_t LongestSymbolName = 0;
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
volatile uint32_t MaxBytesTruncated = 0;
|
volatile uint32_t MaxBytesTruncated = 0;
|
||||||
|
|
||||||
|
uint16_t CurrentFilterMask = 0xFFFF;
|
||||||
|
|
||||||
|
uint16_t CurrentFilterGroup = FilterGroup0;
|
||||||
|
|
||||||
/* Internal common function for storing string events */
|
/* Internal common function for storing string events */
|
||||||
static void prvTraceStoreStringEventHelper( int nArgs,
|
static void prvTraceStoreStringEventHelper( int nArgs,
|
||||||
uint16_t eventID,
|
uint16_t eventID,
|
||||||
traceString userEvtChannel,
|
traceString userEvtChannel,
|
||||||
|
int len,
|
||||||
const char* str,
|
const char* str,
|
||||||
va_list* vl);
|
va_list* vl);
|
||||||
static void prvTraceStoreSimpleStringEventHelper( traceString userEvtChannel,
|
|
||||||
const char* str);
|
/* Not static to avoid warnings from SysGCC/PPC */
|
||||||
|
void prvTraceStoreSimpleStringEventHelper(traceString userEvtChannel,
|
||||||
|
const char* str);
|
||||||
|
|
||||||
|
|
||||||
/* Stores the header information on Start */
|
/* Stores the header information on Start */
|
||||||
static void prvTraceStoreHeader(void);
|
static void prvTraceStoreHeader(void);
|
||||||
|
@ -278,7 +279,8 @@ static void prvPageReadComplete(int pageIndex);
|
||||||
/* Retrieve a buffer page to write to. */
|
/* Retrieve a buffer page to write to. */
|
||||||
static int prvAllocateBufferPage(int prevPage);
|
static int prvAllocateBufferPage(int prevPage);
|
||||||
|
|
||||||
/* Get the current buffer page index and remaining number of bytes. */
|
/* Get the current buffer page index (return value) and the number
|
||||||
|
of valid bytes in the buffer page (bytesUsed). */
|
||||||
static int prvGetBufferPage(int32_t* bytesUsed);
|
static int prvGetBufferPage(int32_t* bytesUsed);
|
||||||
|
|
||||||
/* Performs timestamping using definitions in trcHardwarePort.h */
|
/* Performs timestamping using definitions in trcHardwarePort.h */
|
||||||
|
@ -287,6 +289,9 @@ static uint32_t prvGetTimestamp32(void);
|
||||||
/* Signal an error. */
|
/* Signal an error. */
|
||||||
void prvTraceError(int errCode);
|
void prvTraceError(int errCode);
|
||||||
|
|
||||||
|
/* Signal an warning (does not stop the recorder). */
|
||||||
|
void prvTraceWarning(int errCode);
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* vTraceInstanceFinishedNow
|
* vTraceInstanceFinishedNow
|
||||||
*
|
*
|
||||||
|
@ -315,21 +320,6 @@ void vTraceInstanceFinishedNext(void)
|
||||||
prvTraceStoreEvent0(PSF_EVENT_IFE_NEXT);
|
prvTraceStoreEvent0(PSF_EVENT_IFE_NEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* xTraceRegisterString
|
|
||||||
*
|
|
||||||
* Stores a name for a user event channel, returns the handle.
|
|
||||||
******************************************************************************/
|
|
||||||
traceString xTraceRegisterString(const char* name)
|
|
||||||
{
|
|
||||||
prvTraceSaveSymbol((const void*)name, name);
|
|
||||||
|
|
||||||
/* Always save in symbol table, if the recording has not yet started */
|
|
||||||
prvTraceStoreStringEvent(1, PSF_EVENT_OBJ_NAME, (const char*)name, (uint32_t)name);
|
|
||||||
|
|
||||||
return (traceString)name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* vTraceStoreKernelObjectName
|
* vTraceStoreKernelObjectName
|
||||||
*
|
*
|
||||||
|
@ -362,6 +352,23 @@ void vTraceSetFrequency(uint32_t frequency)
|
||||||
timestampFrequency = frequency;
|
timestampFrequency = frequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* xTraceRegisterString
|
||||||
|
*
|
||||||
|
* Stores a name for a user event channel, returns the handle.
|
||||||
|
******************************************************************************/
|
||||||
|
traceString xTraceRegisterString(const char* name)
|
||||||
|
{
|
||||||
|
prvTraceSaveSymbol((const void*)name, name);
|
||||||
|
|
||||||
|
/* Always save in symbol table, if the recording has not yet started */
|
||||||
|
prvTraceStoreStringEvent(1, PSF_EVENT_OBJ_NAME, (const char*)name, (uint32_t)name);
|
||||||
|
|
||||||
|
return (traceString)name;
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* vTracePrint
|
* vTracePrint
|
||||||
*
|
*
|
||||||
|
@ -450,7 +457,7 @@ void vTracePrintF(traceString chn, const char* fmt, ...)
|
||||||
{
|
{
|
||||||
if (fmt[i] == '%')
|
if (fmt[i] == '%')
|
||||||
{
|
{
|
||||||
if (fmt[i + 1] != '%')
|
if (fmt[i + 1] != 0 && fmt[i + 1] != '%')
|
||||||
{
|
{
|
||||||
nArgs++; /* Found an argument */
|
nArgs++; /* Found an argument */
|
||||||
}
|
}
|
||||||
|
@ -463,15 +470,15 @@ void vTracePrintF(traceString chn, const char* fmt, ...)
|
||||||
|
|
||||||
if (chn != NULL)
|
if (chn != NULL)
|
||||||
{
|
{
|
||||||
prvTraceStoreStringEventHelper(nArgs, (uint16_t)(PSF_EVENT_USER_EVENT + nArgs + 1), chn, fmt, &vl);
|
prvTraceStoreStringEventHelper(nArgs, (uint16_t)(PSF_EVENT_USER_EVENT + nArgs + 1), chn, i, fmt, &vl);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
prvTraceStoreStringEventHelper(nArgs, (uint16_t)(PSF_EVENT_USER_EVENT + nArgs), chn, fmt, &vl);
|
prvTraceStoreStringEventHelper(nArgs, (uint16_t)(PSF_EVENT_USER_EVENT + nArgs), chn, i, fmt, &vl);
|
||||||
}
|
}
|
||||||
|
|
||||||
va_end(vl);
|
va_end(vl);
|
||||||
}
|
}
|
||||||
|
#endif /* (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) */
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* xTraceSetISRProperties
|
* xTraceSetISRProperties
|
||||||
|
@ -536,11 +543,13 @@ void vTraceStoreISRBegin(traceHandle handle)
|
||||||
if (ISR_stack_index == -1)
|
if (ISR_stack_index == -1)
|
||||||
isPendingContextSwitch = 0;
|
isPendingContextSwitch = 0;
|
||||||
|
|
||||||
if (ISR_stack_index < TRC_CFG_MAX_ISR_NESTING - 1)
|
if (ISR_stack_index < (TRC_CFG_MAX_ISR_NESTING) - 1)
|
||||||
{
|
{
|
||||||
ISR_stack_index++;
|
ISR_stack_index++;
|
||||||
ISR_stack[ISR_stack_index] = (uint32_t)handle;
|
ISR_stack[ISR_stack_index] = (uint32_t)handle;
|
||||||
|
#if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
|
||||||
prvTraceStoreEvent1(PSF_EVENT_ISR_BEGIN, (uint32_t)handle);
|
prvTraceStoreEvent1(PSF_EVENT_ISR_BEGIN, (uint32_t)handle);
|
||||||
|
#endif
|
||||||
TRACE_EXIT_CRITICAL_SECTION();
|
TRACE_EXIT_CRITICAL_SECTION();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -579,6 +588,8 @@ void vTraceStoreISREnd(int isTaskSwitchRequired)
|
||||||
|
|
||||||
TRACE_ENTER_CRITICAL_SECTION();
|
TRACE_ENTER_CRITICAL_SECTION();
|
||||||
|
|
||||||
|
(void)ISR_stack;
|
||||||
|
|
||||||
/* Is there a pending task-switch? (perhaps from an earlier ISR) */
|
/* Is there a pending task-switch? (perhaps from an earlier ISR) */
|
||||||
isPendingContextSwitch |= isTaskSwitchRequired;
|
isPendingContextSwitch |= isTaskSwitchRequired;
|
||||||
|
|
||||||
|
@ -586,8 +597,10 @@ void vTraceStoreISREnd(int isTaskSwitchRequired)
|
||||||
{
|
{
|
||||||
ISR_stack_index--;
|
ISR_stack_index--;
|
||||||
|
|
||||||
|
#if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
|
||||||
/* Store return to interrupted ISR (if nested ISRs)*/
|
/* Store return to interrupted ISR (if nested ISRs)*/
|
||||||
prvTraceStoreEvent1(PSF_EVENT_ISR_RESUME, (uint32_t)ISR_stack[ISR_stack_index]);
|
prvTraceStoreEvent1(PSF_EVENT_ISR_RESUME, (uint32_t)ISR_stack[ISR_stack_index]);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -596,7 +609,9 @@ void vTraceStoreISREnd(int isTaskSwitchRequired)
|
||||||
/* Store return to interrupted task, if no context switch will occur in between. */
|
/* Store return to interrupted task, if no context switch will occur in between. */
|
||||||
if ((isPendingContextSwitch == 0) || (prvTraceIsSchedulerSuspended()))
|
if ((isPendingContextSwitch == 0) || (prvTraceIsSchedulerSuspended()))
|
||||||
{
|
{
|
||||||
|
#if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
|
||||||
prvTraceStoreEvent1(PSF_EVENT_TS_RESUME, (uint32_t)TRACE_GET_CURRENT_TASK());
|
prvTraceStoreEvent1(PSF_EVENT_TS_RESUME, (uint32_t)TRACE_GET_CURRENT_TASK());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -607,43 +622,106 @@ void vTraceStoreISREnd(int isTaskSwitchRequired)
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* xTraceGetLastError
|
* xTraceGetLastError
|
||||||
*
|
*
|
||||||
* Returns the last error, if any.
|
* Returns the last error or warning, as a string, or NULL if none.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
const char* xTraceGetLastError(void)
|
const char* xTraceGetLastError(void)
|
||||||
{
|
{
|
||||||
if (NoRoomForSymbol > 0)
|
/* Note: the error messages are short, in order to fit in a User Event.
|
||||||
{
|
Instead, the users can read more in the below comments.*/
|
||||||
return "TRC_CFG_SYMBOL_TABLE_SLOTS too small.";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (LongestSymbolName > (TRC_CFG_SYMBOL_MAX_LENGTH))
|
|
||||||
{
|
|
||||||
return "TRC_CFG_SYMBOL_MAX_LENGTH too small.";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NoRoomForObjectData > 0)
|
|
||||||
{
|
|
||||||
return "TRC_CFG_OBJECT_DATA_SLOTS too small.";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (MaxBytesTruncated > 0)
|
|
||||||
{
|
|
||||||
return "String or User Event too long.";
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (errorCode)
|
switch (errorCode)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
case PSF_WARNING_SYMBOL_TABLE_SLOTS:
|
||||||
|
/* There was not enough symbol table slots for storing symbol names.
|
||||||
|
The number of missing slots is counted by NoRoomForSymbol. Inspect this
|
||||||
|
variable and increase TRC_CFG_SYMBOL_TABLE_SLOTS by at least that value. */
|
||||||
|
|
||||||
|
return "Exceeded SYMBOL_TABLE_SLOTS (see xTraceGetLastError)";
|
||||||
|
|
||||||
|
case PSF_WARNING_SYMBOL_MAX_LENGTH:
|
||||||
|
/* A symbol name exceeded TRC_CFG_SYMBOL_MAX_LENGTH in length.
|
||||||
|
Make sure the symbol names are at most TRC_CFG_SYMBOL_MAX_LENGTH,
|
||||||
|
or inspect LongestSymbolName and increase TRC_CFG_SYMBOL_MAX_LENGTH
|
||||||
|
to at least this value. */
|
||||||
|
|
||||||
|
return "Exceeded SYMBOL_MAX_LENGTH (see xTraceGetLastError)";
|
||||||
|
|
||||||
|
case PSF_WARNING_OBJECT_DATA_SLOTS:
|
||||||
|
/* There was not enough symbol object table slots for storing object
|
||||||
|
properties, such as task priorites. The number of missing slots is
|
||||||
|
counted by NoRoomForObjectData. Inspect this variable and increase
|
||||||
|
TRC_CFG_OBJECT_DATA_SLOTS by at least that value. */
|
||||||
|
|
||||||
|
return "Exceeded OBJECT_DATA_SLOTS (see xTraceGetLastError)";
|
||||||
|
|
||||||
|
case PSF_WARNING_STRING_TOO_LONG:
|
||||||
|
/* Some string argument was longer than the maximum payload size
|
||||||
|
and has been truncated by "MaxBytesTruncated" bytes.
|
||||||
|
|
||||||
|
This may happen for the following functions:
|
||||||
|
- vTracePrint
|
||||||
|
- vTracePrintF
|
||||||
|
- vTraceStoreKernelObjectName
|
||||||
|
- xTraceRegisterString
|
||||||
|
- vTraceSetISRProperties
|
||||||
|
|
||||||
|
A PSF event may store maximum 60 bytes payload, including data
|
||||||
|
arguments and string characters. For User Events, also the User
|
||||||
|
Event Channel (4 bytes) must be squeezed in, if a channel is
|
||||||
|
specified (can be NULL). */
|
||||||
|
|
||||||
|
return "String too long (see xTraceGetLastError)";
|
||||||
|
|
||||||
|
case PSF_WARNING_STREAM_PORT_READ:
|
||||||
|
/* TRC_STREAM_PORT_READ_DATA is expected to return 0 when completed successfully.
|
||||||
|
This means there is an error in the communication with host/Tracealyzer. */
|
||||||
|
|
||||||
|
return "TRC_STREAM_PORT_READ_DATA returned error (!= 0).";
|
||||||
|
|
||||||
|
case PSF_WARNING_STREAM_PORT_WRITE:
|
||||||
|
/* TRC_STREAM_PORT_WRITE_DATA is expected to return 0 when completed successfully.
|
||||||
|
This means there is an error in the communication with host/Tracealyzer. */
|
||||||
|
|
||||||
|
return "TRC_STREAM_PORT_WRITE_DATA returned error (!= 0).";
|
||||||
|
|
||||||
case PSF_ERROR_EVENT_CODE_TOO_LARGE:
|
case PSF_ERROR_EVENT_CODE_TOO_LARGE:
|
||||||
return "An invalid event code was used.";
|
/* The highest allowed event code is 4095, anything higher is an unexpected error.
|
||||||
|
Please contact support@percepio.com for assistance.*/
|
||||||
|
|
||||||
|
return "Invalid event code (see xTraceGetLastError)";
|
||||||
|
|
||||||
case PSF_ERROR_ISR_NESTING_OVERFLOW:
|
case PSF_ERROR_ISR_NESTING_OVERFLOW:
|
||||||
return "Too much ISR nesting.";
|
/* Nesting of ISR trace calls exceeded the limit (TRC_CFG_MAX_ISR_NESTING).
|
||||||
|
If this is unlikely, make sure that you call vTraceStoreISRExit in the end
|
||||||
|
of all ISR handlers. Or increase TRC_CFG_MAX_ISR_NESTING. */
|
||||||
|
|
||||||
|
return "Exceeded ISR nesting (see xTraceGetLastError)";
|
||||||
|
|
||||||
case PSF_ERROR_DWT_NOT_SUPPORTED:
|
case PSF_ERROR_DWT_NOT_SUPPORTED:
|
||||||
return "DWT not supported by this chip.";
|
/* On ARM Cortex-M only - failed to initialize DWT Cycle Counter since not supported by this chip.
|
||||||
|
DWT timestamping is selected automatically for ART Cortex-M3, M4 and higher, based on the __CORTEX_M
|
||||||
|
macro normally set by ARM's CMSIS library, since typically available. You can however select
|
||||||
|
SysTick timestamping instead by defining adding "#define TRC_CFG_ARM_CM_USE_SYSTICK".*/
|
||||||
|
|
||||||
|
return "DWT not supported (see xTraceGetLastError)";
|
||||||
|
|
||||||
case PSF_ERROR_DWT_CYCCNT_NOT_SUPPORTED:
|
case PSF_ERROR_DWT_CYCCNT_NOT_SUPPORTED:
|
||||||
return "DWT_CYCCNT not supported by this chip.";
|
/* On ARM Cortex-M only - failed to initialize DWT Cycle Counter since not supported by this chip.
|
||||||
|
DWT timestamping is selected automatically for ART Cortex-M3, M4 and higher, based on the __CORTEX_M
|
||||||
|
macro normally set by ARM's CMSIS library, since typically available. You can however select
|
||||||
|
SysTick timestamping instead by defining adding "#define TRC_CFG_ARM_CM_USE_SYSTICK".*/
|
||||||
|
|
||||||
|
return "DWT_CYCCNT not supported (see xTraceGetLastError)";
|
||||||
|
|
||||||
|
case PSF_ERROR_TZCTRLTASK_NOT_CREATED:
|
||||||
|
/* vTraceEnable failed creating the trace control task (TzCtrl) - incorrect parameters (priority?)
|
||||||
|
or insufficient heap size? */
|
||||||
|
return "Could not create TzCtrl (see xTraceGetLastError)";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return "";
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
@ -686,6 +764,27 @@ void vTraceSetRecorderDataBuffer(void* pRecorderData)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* xTraceIsRecordingEnabled
|
||||||
|
* Returns true (1) if the recorder is enabled (i.e. is recording), otherwise 0.
|
||||||
|
******************************************************************************/
|
||||||
|
int xTraceIsRecordingEnabled(void)
|
||||||
|
{
|
||||||
|
return (int)RecorderEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vTraceSetFilterMask(uint16_t filterMask)
|
||||||
|
{
|
||||||
|
CurrentFilterMask = filterMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vTraceSetFilterGroup(uint16_t filterGroup)
|
||||||
|
{
|
||||||
|
CurrentFilterGroup = filterGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/*** INTERNAL FUNCTIONS *******************************************************/
|
/*** INTERNAL FUNCTIONS *******************************************************/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -697,6 +796,11 @@ static void prvSetRecorderEnabled(uint32_t isEnabled)
|
||||||
|
|
||||||
TRACE_ALLOC_CRITICAL_SECTION();
|
TRACE_ALLOC_CRITICAL_SECTION();
|
||||||
|
|
||||||
|
if (RecorderEnabled == isEnabled)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
currentTask = TRACE_GET_CURRENT_TASK();
|
currentTask = TRACE_GET_CURRENT_TASK();
|
||||||
|
|
||||||
TRACE_ENTER_CRITICAL_SECTION();
|
TRACE_ENTER_CRITICAL_SECTION();
|
||||||
|
@ -710,7 +814,11 @@ static void prvSetRecorderEnabled(uint32_t isEnabled)
|
||||||
|
|
||||||
if (RecorderEnabled)
|
if (RecorderEnabled)
|
||||||
{
|
{
|
||||||
prvTraceOnBegin();
|
TRC_STREAM_PORT_ON_TRACE_BEGIN();
|
||||||
|
|
||||||
|
#if (TRC_STREAM_PORT_USE_INTERNAL_BUFFER == 1)
|
||||||
|
prvPagedEventBufferInit(_TzTraceData);
|
||||||
|
#endif
|
||||||
|
|
||||||
eventCounter = 0;
|
eventCounter = 0;
|
||||||
ISR_stack_index = -1;
|
ISR_stack_index = -1;
|
||||||
|
@ -726,14 +834,14 @@ static void prvSetRecorderEnabled(uint32_t isEnabled)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
prvTraceOnEnd();
|
TRC_STREAM_PORT_ON_TRACE_END();
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE_EXIT_CRITICAL_SECTION();
|
TRACE_EXIT_CRITICAL_SECTION();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stores the symbol table on Start */
|
/* Stores the symbol table on Start */
|
||||||
static void prvTraceStoreSymbolTable()
|
static void prvTraceStoreSymbolTable(void)
|
||||||
{
|
{
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
uint32_t j = 0;
|
uint32_t j = 0;
|
||||||
|
@ -760,7 +868,7 @@ static void prvTraceStoreSymbolTable()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stores the object table on Start */
|
/* Stores the object table on Start */
|
||||||
static void prvTraceStoreObjectDataTable()
|
static void prvTraceStoreObjectDataTable(void)
|
||||||
{
|
{
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
uint32_t j = 0;
|
uint32_t j = 0;
|
||||||
|
@ -787,7 +895,7 @@ static void prvTraceStoreObjectDataTable()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stores the header information on Start */
|
/* Stores the header information on Start */
|
||||||
static void prvTraceStoreHeader()
|
static void prvTraceStoreHeader(void)
|
||||||
{
|
{
|
||||||
TRACE_ALLOC_CRITICAL_SECTION();
|
TRACE_ALLOC_CRITICAL_SECTION();
|
||||||
|
|
||||||
|
@ -807,7 +915,7 @@ static void prvTraceStoreHeader()
|
||||||
header->symbolSize = SYMBOL_TABLE_SLOT_SIZE;
|
header->symbolSize = SYMBOL_TABLE_SLOT_SIZE;
|
||||||
header->symbolCount = (TRC_CFG_SYMBOL_TABLE_SLOTS);
|
header->symbolCount = (TRC_CFG_SYMBOL_TABLE_SLOTS);
|
||||||
header->objectDataSize = 8;
|
header->objectDataSize = 8;
|
||||||
header->objectDataCount = TRC_CFG_OBJECT_DATA_SLOTS;
|
header->objectDataCount = (TRC_CFG_OBJECT_DATA_SLOTS);
|
||||||
TRC_STREAM_PORT_COMMIT_EVENT(header, sizeof(PSFHeaderInfo));
|
TRC_STREAM_PORT_COMMIT_EVENT(header, sizeof(PSFHeaderInfo));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -815,64 +923,17 @@ static void prvTraceStoreHeader()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store the current warnings */
|
/* Store the current warnings */
|
||||||
static void prvTraceStoreWarnings()
|
static void prvTraceStoreWarnings(void)
|
||||||
{
|
{
|
||||||
TRACE_ALLOC_CRITICAL_SECTION();
|
|
||||||
|
|
||||||
TRACE_ENTER_CRITICAL_SECTION();
|
|
||||||
|
|
||||||
if (RecorderEnabled)
|
if (RecorderEnabled)
|
||||||
{
|
{
|
||||||
if (NoRoomForSymbol > 0)
|
const char* errStr = xTraceGetLastError();
|
||||||
|
|
||||||
|
if (errStr != NULL)
|
||||||
{
|
{
|
||||||
vTracePrintF(trcWarningChannel, "TRC_CFG_SYMBOL_TABLE_SLOTS too small. Add %d slots.", NoRoomForSymbol);
|
vTracePrint(trcWarningChannel, errStr);
|
||||||
}
|
|
||||||
|
|
||||||
if (LongestSymbolName > 0)
|
|
||||||
{
|
|
||||||
if (LongestSymbolName > (TRC_CFG_SYMBOL_MAX_LENGTH))
|
|
||||||
{
|
|
||||||
vTracePrintF(trcWarningChannel, "TRC_CFG_SYMBOL_MAX_LENGTH too small. Add %d chars.", LongestSymbolName - (TRC_CFG_SYMBOL_MAX_LENGTH));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NoRoomForObjectData > 0)
|
|
||||||
{
|
|
||||||
/* We don't know how many objects we actually need to make room for since NoRoomForObjectData can be increased multiple times for the same object! */
|
|
||||||
vTracePrintF(trcWarningChannel, "TRC_CFG_OBJECT_DATA_SLOTS too small. Add more slots.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (MaxBytesTruncated > 0)
|
|
||||||
{
|
|
||||||
/* Some string event generated a too long string that was truncated.
|
|
||||||
This may happen for the following functions:
|
|
||||||
- vTracePrintF
|
|
||||||
- vTraceStoreKernelObjectName
|
|
||||||
- vTraceStoreUserEventChannelName
|
|
||||||
- vTraceSetISRProperties
|
|
||||||
|
|
||||||
A PSF event may store maximum 60 bytes payload, including data arguments
|
|
||||||
and string characters. For User Events, also the User Event Channel ptr
|
|
||||||
must be squeezed in, if a channel is specified. */
|
|
||||||
|
|
||||||
vTracePrintF(trcWarningChannel, "String event too long, up to %d bytes truncated.", MaxBytesTruncated);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (errorCode)
|
|
||||||
{
|
|
||||||
case PSF_ERROR_EVENT_CODE_TOO_LARGE:
|
|
||||||
break;
|
|
||||||
case PSF_ERROR_ISR_NESTING_OVERFLOW:
|
|
||||||
break;
|
|
||||||
case PSF_ERROR_DWT_NOT_SUPPORTED:
|
|
||||||
vTracePrintF(trcWarningChannel, "DWT not supported, see prvTraceInitCortexM.");
|
|
||||||
break;
|
|
||||||
case PSF_ERROR_DWT_CYCCNT_NOT_SUPPORTED:
|
|
||||||
vTracePrintF(trcWarningChannel, "DWT_CYCCNT not supported, see prvTraceInitCortexM.");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TRACE_EXIT_CRITICAL_SECTION();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store an event with zero parameters (event ID only) */
|
/* Store an event with zero parameters (event ID only) */
|
||||||
|
@ -1035,20 +1096,24 @@ void prvTraceStoreEvent(int nParam, uint16_t eventID, ...)
|
||||||
/* Stories an event with a string and <nParam> 32-bit integer parameters */
|
/* Stories an event with a string and <nParam> 32-bit integer parameters */
|
||||||
void prvTraceStoreStringEvent(int nArgs, uint16_t eventID, const char* str, ...)
|
void prvTraceStoreStringEvent(int nArgs, uint16_t eventID, const char* str, ...)
|
||||||
{
|
{
|
||||||
|
int len;
|
||||||
va_list vl;
|
va_list vl;
|
||||||
|
|
||||||
|
for (len = 0; (str[len] != 0) && (len < 52); len++); /* empty loop */
|
||||||
|
|
||||||
va_start(vl, str);
|
va_start(vl, str);
|
||||||
prvTraceStoreStringEventHelper(nArgs, eventID, NULL, str, &vl);
|
prvTraceStoreStringEventHelper(nArgs, eventID, NULL, len, str, &vl);
|
||||||
va_end(vl);
|
va_end(vl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Internal common function for storing string events */
|
/* Internal common function for storing string events */
|
||||||
static void prvTraceStoreStringEventHelper( int nArgs,
|
static void prvTraceStoreStringEventHelper(int nArgs,
|
||||||
uint16_t eventID,
|
uint16_t eventID,
|
||||||
traceString userEvtChannel,
|
traceString userEvtChannel,
|
||||||
const char* str, va_list* vl)
|
int len,
|
||||||
|
const char* str,
|
||||||
|
va_list* vl)
|
||||||
{
|
{
|
||||||
int len;
|
|
||||||
int nWords;
|
int nWords;
|
||||||
int nStrWords;
|
int nStrWords;
|
||||||
int i;
|
int i;
|
||||||
|
@ -1057,8 +1122,6 @@ static void prvTraceStoreStringEventHelper( int nArgs,
|
||||||
|
|
||||||
PSF_ASSERT(eventID < 4096, PSF_ERROR_EVENT_CODE_TOO_LARGE);
|
PSF_ASSERT(eventID < 4096, PSF_ERROR_EVENT_CODE_TOO_LARGE);
|
||||||
|
|
||||||
for (len = 0; (str[len] != 0) && (len < 52); len++); /* empty loop */
|
|
||||||
|
|
||||||
/* The string length in multiples of 32 bit words (+1 for null character) */
|
/* The string length in multiples of 32 bit words (+1 for null character) */
|
||||||
nStrWords = (len+1+3)/4;
|
nStrWords = (len+1+3)/4;
|
||||||
|
|
||||||
|
@ -1140,8 +1203,8 @@ static void prvTraceStoreStringEventHelper( int nArgs,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Internal common function for storing string events without additional arguments */
|
/* Internal common function for storing string events without additional arguments */
|
||||||
static void prvTraceStoreSimpleStringEventHelper( traceString userEvtChannel,
|
void prvTraceStoreSimpleStringEventHelper(traceString userEvtChannel,
|
||||||
const char* str)
|
const char* str)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
int nWords;
|
int nWords;
|
||||||
|
@ -1465,6 +1528,16 @@ void prvProcessCommand(TracealyzerCommandType* cmd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Called on warnings, when the recording can continue. */
|
||||||
|
void prvTraceWarning(int errCode)
|
||||||
|
{
|
||||||
|
if (!errorCode)
|
||||||
|
{
|
||||||
|
errorCode = errCode;
|
||||||
|
prvTraceStoreWarnings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Called on critical errors in the recorder. Stops the recorder! */
|
/* Called on critical errors in the recorder. Stops the recorder! */
|
||||||
void prvTraceError(int errCode)
|
void prvTraceError(int errCode)
|
||||||
{
|
{
|
||||||
|
@ -1472,7 +1545,7 @@ void prvTraceError(int errCode)
|
||||||
{
|
{
|
||||||
errorCode = errCode;
|
errorCode = errCode;
|
||||||
prvTraceStoreWarnings();
|
prvTraceStoreWarnings();
|
||||||
vTracePrintF(trcWarningChannel, "Error detected. Stopped recorder.");
|
vTracePrintF(trcWarningChannel, "Recorder stopped in prvTraceError()");
|
||||||
|
|
||||||
prvSetRecorderEnabled(0);
|
prvSetRecorderEnabled(0);
|
||||||
}
|
}
|
||||||
|
@ -1550,7 +1623,7 @@ static uint32_t prvGetTimestamp32(void)
|
||||||
|
|
||||||
#if ((TRC_HWTC_TYPE == TRC_OS_TIMER_INCR) || (TRC_HWTC_TYPE == TRC_OS_TIMER_DECR))
|
#if ((TRC_HWTC_TYPE == TRC_OS_TIMER_INCR) || (TRC_HWTC_TYPE == TRC_OS_TIMER_DECR))
|
||||||
uint32_t ticks = TRACE_GET_OS_TICKS();
|
uint32_t ticks = TRACE_GET_OS_TICKS();
|
||||||
return (TRC_HWTC_COUNT & 0x00FFFFFFU) + ((ticks & 0x000000FFU) << 24);
|
return ((TRC_HWTC_COUNT) & 0x00FFFFFFU) + ((ticks & 0x000000FFU) << 24);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1563,25 +1636,25 @@ static void prvTraceStoreTSConfig(void)
|
||||||
timestampFrequency = TRC_HWTC_FREQ_HZ;
|
timestampFrequency = TRC_HWTC_FREQ_HZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_INCR || TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_DECR)
|
#if (TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_INCR || TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_DECR)
|
||||||
{
|
|
||||||
prvTraceStoreEvent(5,
|
prvTraceStoreEvent(5,
|
||||||
PSF_EVENT_TS_CONFIG,
|
PSF_EVENT_TS_CONFIG,
|
||||||
(uint32_t)timestampFrequency,
|
(uint32_t)timestampFrequency,
|
||||||
(uint32_t)TRACE_TICK_RATE_HZ,
|
(uint32_t)(TRACE_TICK_RATE_HZ),
|
||||||
(uint32_t)TRC_HWTC_TYPE,
|
(uint32_t)(TRC_HWTC_TYPE),
|
||||||
(uint32_t)TRC_CFG_ISR_TAILCHAINING_THRESHOLD,
|
(uint32_t)(TRC_CFG_ISR_TAILCHAINING_THRESHOLD),
|
||||||
(uint32_t)TRC_HWTC_PERIOD);
|
(uint32_t)(TRC_HWTC_PERIOD));
|
||||||
}
|
|
||||||
else
|
#else
|
||||||
{
|
|
||||||
prvTraceStoreEvent(4,
|
prvTraceStoreEvent(4,
|
||||||
PSF_EVENT_TS_CONFIG,
|
PSF_EVENT_TS_CONFIG,
|
||||||
(uint32_t)timestampFrequency,
|
(uint32_t)timestampFrequency,
|
||||||
(uint32_t)TRACE_TICK_RATE_HZ,
|
(uint32_t)(TRACE_TICK_RATE_HZ),
|
||||||
(uint32_t)TRC_HWTC_TYPE,
|
(uint32_t)(TRC_HWTC_TYPE),
|
||||||
(uint32_t)TRC_CFG_ISR_TAILCHAINING_THRESHOLD);
|
(uint32_t)(TRC_CFG_ISR_TAILCHAINING_THRESHOLD));
|
||||||
}
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Retrieve a buffer page to write to. */
|
/* Retrieve a buffer page to write to. */
|
||||||
|
@ -1590,11 +1663,11 @@ static int prvAllocateBufferPage(int prevPage)
|
||||||
int index;
|
int index;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
index = (prevPage + 1) % TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT;
|
index = (prevPage + 1) % (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT);
|
||||||
|
|
||||||
while((PageInfo[index].Status != PAGE_STATUS_FREE) && (count ++ < TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT))
|
while((PageInfo[index].Status != PAGE_STATUS_FREE) && (count ++ < (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT)))
|
||||||
{
|
{
|
||||||
index = (index + 1) % TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT;
|
index = (index + 1) % (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PageInfo[index].Status == PAGE_STATUS_FREE)
|
if (PageInfo[index].Status == PAGE_STATUS_FREE)
|
||||||
|
@ -1611,11 +1684,11 @@ static void prvPageReadComplete(int pageIndex)
|
||||||
TRACE_ALLOC_CRITICAL_SECTION();
|
TRACE_ALLOC_CRITICAL_SECTION();
|
||||||
|
|
||||||
TRACE_ENTER_CRITICAL_SECTION();
|
TRACE_ENTER_CRITICAL_SECTION();
|
||||||
PageInfo[pageIndex].BytesRemaining = TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE;
|
PageInfo[pageIndex].BytesRemaining = (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE);
|
||||||
PageInfo[pageIndex].WritePointer = &EventBuffer[pageIndex * TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE];
|
PageInfo[pageIndex].WritePointer = &EventBuffer[pageIndex * (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE)];
|
||||||
PageInfo[pageIndex].Status = PAGE_STATUS_FREE;
|
PageInfo[pageIndex].Status = PAGE_STATUS_FREE;
|
||||||
|
|
||||||
TotalBytesRemaining += TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE;
|
TotalBytesRemaining += (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE);
|
||||||
|
|
||||||
TRACE_EXIT_CRITICAL_SECTION();
|
TRACE_EXIT_CRITICAL_SECTION();
|
||||||
}
|
}
|
||||||
|
@ -1625,16 +1698,16 @@ static int prvGetBufferPage(int32_t* bytesUsed)
|
||||||
{
|
{
|
||||||
static int8_t lastPage = -1;
|
static int8_t lastPage = -1;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int8_t index = (int8_t) ((lastPage + 1) % TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT);
|
int8_t index = (int8_t) ((lastPage + 1) % (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT));
|
||||||
|
|
||||||
while((PageInfo[index].Status != PAGE_STATUS_READ) && (count++ < TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT))
|
while((PageInfo[index].Status != PAGE_STATUS_READ) && (count++ < (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT)))
|
||||||
{
|
{
|
||||||
index = (int8_t)((index + 1) % TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT);
|
index = (int8_t)((index + 1) % (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PageInfo[index].Status == PAGE_STATUS_READ)
|
if (PageInfo[index].Status == PAGE_STATUS_READ)
|
||||||
{
|
{
|
||||||
*bytesUsed = TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE - PageInfo[index].BytesRemaining;
|
*bytesUsed = (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE) - PageInfo[index].BytesRemaining;
|
||||||
lastPage = index;
|
lastPage = index;
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
@ -1645,63 +1718,58 @@ static int prvGetBufferPage(int32_t* bytesUsed)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
* uint32_t prvPagedEventBufferTransfer(void)
|
||||||
int32_t prvPagedEventBufferTransfer(int32_t (*writeFunc)(void* data,
|
*
|
||||||
uint32_t size),
|
* Transfers one buffer page of trace data, if a full page is available, using
|
||||||
int32_t* nofBytes)
|
* the macro TRC_STREAM_PORT_WRITE_DATA as defined in trcStreamingPort.h.
|
||||||
|
*
|
||||||
Transfers one block of trace data, if available for reading. Returns the number
|
* This function is intended to be called the periodic TzCtrl task with a suitable
|
||||||
of bytes transfered, or a negative error code. If data was transferred (return
|
* delay (e.g. 10-100 ms).
|
||||||
value > 0), it can be good to call this function again until all data available
|
*
|
||||||
has been transfered.
|
* Returns the number of bytes sent. If non-zero, it is good to call this
|
||||||
|
* again, in order to send any additional data waiting in the buffer.
|
||||||
This function is intended to be called by a periodic task with a suitable
|
* If zero, wait a while before calling again.
|
||||||
delay (e.g. 10-100 ms).
|
*
|
||||||
|
* In case of errors from the streaming interface, it registers a warning
|
||||||
Return value: as returned from writeFunc (0 == OK)
|
* (PSF_WARNING_STREAM_PORT_WRITE) provided by xTraceGetLastError().
|
||||||
|
*
|
||||||
Parameters:
|
*******************************************************************************/
|
||||||
|
uint32_t prvPagedEventBufferTransfer(void)
|
||||||
- writeFunc
|
|
||||||
Function pointer (example: int32_t write(void* data, uint32_t size))
|
|
||||||
The function passed as writeFunc should write "size" bytes from "data" to the
|
|
||||||
socket/file/channel, and return a status code where 0 means OK,
|
|
||||||
and any other non-zero value means an error.
|
|
||||||
|
|
||||||
- int32_t* nofBytes
|
|
||||||
Pointer to an integer assigned the number of bytes that was transfered.
|
|
||||||
|
|
||||||
*******************************************************************************/
|
|
||||||
int32_t prvPagedEventBufferTransfer(int32_t (*writeFunc)(void* data, uint32_t size, int32_t* ptrBytesWritten), int32_t* nofBytes)
|
|
||||||
{
|
{
|
||||||
int8_t pageToTransfer = -1;
|
int8_t pageToTransfer = -1;
|
||||||
int32_t transferred = 0;
|
int32_t bytesTransferredTotal = 0;
|
||||||
int32_t size = 0;
|
int32_t bytesTransferredNow = 0;
|
||||||
|
int32_t bytesToTransfer;
|
||||||
|
|
||||||
pageToTransfer = (int8_t)prvGetBufferPage(nofBytes);
|
pageToTransfer = (int8_t)prvGetBufferPage(&bytesToTransfer);
|
||||||
size = *nofBytes; // The number of bytes we want to transfer
|
|
||||||
transferred = 0; // The number of bytes we have transferred so far
|
/* bytesToTransfer now contains the number of "valid" bytes in the buffer page, that should be transmitted.
|
||||||
|
There might be some unused junk bytes in the end, that must be ignored. */
|
||||||
|
|
||||||
if (pageToTransfer > -1)
|
if (pageToTransfer > -1)
|
||||||
{
|
{
|
||||||
while (1) // Keep going until we have transferred all that we intended to
|
while (1) /* Keep going until we have transferred all that we intended to */
|
||||||
{
|
{
|
||||||
if (writeFunc(&EventBuffer[pageToTransfer * TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE + transferred], (uint32_t)(size - transferred), nofBytes) == 0)
|
if (TRC_STREAM_PORT_WRITE_DATA(
|
||||||
|
&EventBuffer[pageToTransfer * (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE) + bytesTransferredTotal],
|
||||||
|
(uint32_t)(bytesToTransfer - bytesTransferredTotal),
|
||||||
|
&bytesTransferredNow) == 0)
|
||||||
{
|
{
|
||||||
// Write was successful. Update the number of transferred bytes.
|
/* Write was successful. Update the number of transferred bytes. */
|
||||||
transferred += *nofBytes;
|
bytesTransferredTotal += bytesTransferredNow;
|
||||||
if (size == transferred)
|
|
||||||
|
if (bytesTransferredTotal == bytesToTransfer)
|
||||||
{
|
{
|
||||||
// All bytes have been transferred. Mark as Complete and return.
|
/* All bytes have been transferred. Mark the buffer page as "Read Complete" (so it can be written to) and return OK. */
|
||||||
*nofBytes = transferred;
|
|
||||||
prvPageReadComplete(pageToTransfer);
|
prvPageReadComplete(pageToTransfer);
|
||||||
return 0;
|
return (uint32_t)bytesTransferredTotal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*nofBytes = 0;
|
/* Some error from the streaming interface... */
|
||||||
return 1;
|
prvTraceWarning(PSF_WARNING_STREAM_PORT_WRITE);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1709,19 +1777,16 @@ int32_t prvPagedEventBufferTransfer(int32_t (*writeFunc)(void* data, uint32_t si
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
* void* prvPagedEventBufferGetWritePointer(int sizeOfEvent)
|
||||||
void* prvPagedEventBufferGetWritePointer(int sizeOfEvent)
|
*
|
||||||
|
* Returns a pointer to an available location in the buffer able to store the
|
||||||
Returns a pointer to an available location in the buffer able to store the
|
* requested size.
|
||||||
requested size.
|
*
|
||||||
|
* Return value: The pointer.
|
||||||
Return value: The pointer.
|
*
|
||||||
|
* Parameters:
|
||||||
Parameters:
|
* - sizeOfEvent: The size of the event that is to be placed in the buffer.
|
||||||
|
*
|
||||||
- sizeOfEvent
|
|
||||||
The size of the event that is to be placed in the buffer.
|
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
void* prvPagedEventBufferGetWritePointer(int sizeOfEvent)
|
void* prvPagedEventBufferGetWritePointer(int sizeOfEvent)
|
||||||
{
|
{
|
||||||
|
@ -1767,19 +1832,15 @@ void* prvPagedEventBufferGetWritePointer(int sizeOfEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
* void prvPagedEventBufferInit(char* buffer)
|
||||||
void prvPagedEventBufferInit(char* buffer)
|
*
|
||||||
|
* Assigns the buffer to use and initializes the PageInfo structure.
|
||||||
Assigns the buffer to use and initializes the PageInfo structure.
|
*
|
||||||
|
* Return value: void
|
||||||
Return value: void
|
*
|
||||||
|
* Parameters:
|
||||||
Parameters:
|
* - char* buffer: pointer to the trace data buffer, allocated by the caller.
|
||||||
|
*
|
||||||
- buffer
|
|
||||||
Pointer to the buffer location that is dynamically or statically allocated by
|
|
||||||
the caller.
|
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
void prvPagedEventBufferInit(char* buffer)
|
void prvPagedEventBufferInit(char* buffer)
|
||||||
{
|
{
|
||||||
|
@ -1789,13 +1850,14 @@ void prvPagedEventBufferInit(char* buffer)
|
||||||
EventBuffer = buffer;
|
EventBuffer = buffer;
|
||||||
|
|
||||||
TRACE_ENTER_CRITICAL_SECTION();
|
TRACE_ENTER_CRITICAL_SECTION();
|
||||||
for (i = 0; i < TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT; i++)
|
for (i = 0; i < (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT); i++)
|
||||||
{
|
{
|
||||||
PageInfo[i].BytesRemaining = TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE;
|
PageInfo[i].BytesRemaining = (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE);
|
||||||
PageInfo[i].WritePointer = &EventBuffer[i * TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE];
|
PageInfo[i].WritePointer = &EventBuffer[i * (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE)];
|
||||||
PageInfo[i].Status = PAGE_STATUS_FREE;
|
PageInfo[i].Status = PAGE_STATUS_FREE;
|
||||||
}
|
}
|
||||||
TRACE_EXIT_CRITICAL_SECTION();
|
TRACE_EXIT_CRITICAL_SECTION();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/
|
#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
Directories:
|
|
||||||
|
|
||||||
+ The FreeRTOS-Plus/Source contains the source code of each FreeRTOS+ product.
|
|
||||||
|
|
||||||
+ See http://www.FreeRTOS.org for FreeRTOS documentation. See
|
|
||||||
http://www.freertos.org/plus for FreeRTOS+ documentation.
|
|
||||||
|
|
Loading…
Reference in a new issue