From 55a8e5b24614d5c0b82eef208cd0297e2c1bfb29 Mon Sep 17 00:00:00 2001 From: rtel Date: Mon, 2 Jul 2018 22:29:02 +0000 Subject: [PATCH] Update trace recorder code. Add TCP Echo server to the FreeR_Plus_TCP_Minimal_Window_Simulator project. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2556 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- .../DemoTasks/SimpleTCPEchoServer.c | 288 +++ .../DemoTasks/include/SimpleTCPEchoServer.h | 76 + .../FreeRTOSConfig.h | 14 +- .../WIN32.vcxproj | 1 + .../WIN32.vcxproj.filters | 3 + .../main.c | 17 +- .../Source/FreeRTOS-Plus-TCP/FreeRTOS_DHCP.c | 45 +- .../FreeRTOS-Plus-TCP/FreeRTOS_TCP_WIN.c | 12 +- .../include/FreeRTOSIPConfigDefaults.h | 4 +- .../Include/trcHardwarePort.h | 19 +- .../Include/trcKernelPort.h | 2266 +++++++++++------ .../Include/trcPortDefines.h | 23 +- .../FreeRTOS-Plus-Trace/Include/trcRecorder.h | 645 +++-- .../FreeRTOS-Plus-Trace/config/trcConfig.h | 208 +- .../config/trcSnapshotConfig.h | 235 +- .../config/trcStreamingConfig.h | 12 +- .../Keil-uVision-Tracealyzer-ITM-Exporter.ini | 52 + .../streamports/ARM_ITM/Readme-ARM_ITM.txt | 28 + .../ARM_ITM/include/trcStreamingPort.h | 91 + .../streamports/ARM_ITM/trcStreamingPort.c | 71 + .../streamports/File/Readme-Streamport.txt | 19 + .../File/include/trcStreamingPort.h | 87 + .../streamports/File/trcStreamingPort.c | 103 + .../streamports/Jlink_RTT/SEGGER_RTT_Printf.c | 505 ---- .../Jlink_RTT/include/trcStreamingPort.h | 44 +- .../streamports/Jlink_RTT/trcStreamingPort.c | 44 + .../TCPIP/include/trcStreamingPort.h | 34 +- .../streamports/TCPIP/trcStreamingPort.c | 13 +- .../USB_CDC/include/trcStreamingPort.h | 33 +- .../streamports/USB_CDC/trcStreamingPort.c | 19 +- .../tracealyzer_readme.txt | 317 +++ .../FreeRTOS-Plus-Trace/trcKernelPort.c | 556 ++-- .../FreeRTOS-Plus-Trace/trcSnapshotRecorder.c | 392 ++- .../trcStreamingRecorder.c | 514 ++-- FreeRTOS-Plus/Source/readme.txt | 7 - 35 files changed, 4396 insertions(+), 2401 deletions(-) create mode 100644 FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/SimpleTCPEchoServer.c create mode 100644 FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/include/SimpleTCPEchoServer.h create mode 100644 FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/Keil-uVision-Tracealyzer-ITM-Exporter.ini create mode 100644 FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/Readme-ARM_ITM.txt create mode 100644 FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/include/trcStreamingPort.h create mode 100644 FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/trcStreamingPort.c create mode 100644 FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/Readme-Streamport.txt create mode 100644 FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/include/trcStreamingPort.h create mode 100644 FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/trcStreamingPort.c delete mode 100644 FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/SEGGER_RTT_Printf.c create mode 100644 FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/trcStreamingPort.c create mode 100644 FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/tracealyzer_readme.txt delete mode 100644 FreeRTOS-Plus/Source/readme.txt diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/SimpleTCPEchoServer.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/SimpleTCPEchoServer.c new file mode 100644 index 000000000..2a2c704d7 --- /dev/null +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/SimpleTCPEchoServer.c @@ -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 +#include + +/* 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 */ + diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/include/SimpleTCPEchoServer.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/include/SimpleTCPEchoServer.h new file mode 100644 index 000000000..7409e6777 --- /dev/null +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/include/SimpleTCPEchoServer.h @@ -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 */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/FreeRTOSConfig.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/FreeRTOSConfig.h index c51c7f9a1..1c4f496e9 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/FreeRTOSConfig.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/FreeRTOSConfig.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 ipconfigUSE_DNS is set to 1 but a DNS server cannot be contacted. */ -#define configIP_ADDR0 172 -#define configIP_ADDR1 25 -#define configIP_ADDR2 218 +#define configIP_ADDR0 10 +#define configIP_ADDR1 10 +#define configIP_ADDR2 10 #define configIP_ADDR3 200 /* 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. */ -#define configGATEWAY_ADDR0 172 -#define configGATEWAY_ADDR1 25 -#define configGATEWAY_ADDR2 218 +#define configGATEWAY_ADDR0 10 +#define configGATEWAY_ADDR1 10 +#define configGATEWAY_ADDR2 10 #define configGATEWAY_ADDR3 1 /* 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 ipconfigUSE_DNS is set to 1 but a DNS server cannot be contacted. */ #define configNET_MASK0 255 -#define configNET_MASK1 255 +#define configNET_MASK1 0 #define configNET_MASK2 0 #define configNET_MASK3 0 diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/WIN32.vcxproj b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/WIN32.vcxproj index 14a8d8aa9..a550436f7 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/WIN32.vcxproj +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/WIN32.vcxproj @@ -154,6 +154,7 @@ + diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/WIN32.vcxproj.filters b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/WIN32.vcxproj.filters index 48849714c..de00fc84a 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/WIN32.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/WIN32.vcxproj.filters @@ -97,6 +97,9 @@ FreeRTOS+\FreeRTOS+TCP + + DemoTasks + diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/main.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/main.c index 7be6b5e91..bd9b45bc5 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/main.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/main.c @@ -44,6 +44,7 @@ #include "FreeRTOS_IP.h" #include "FreeRTOS_Sockets.h" #include "SimpleUDPClientAndServer.h" +#include "SimpleTCPEchoServer.h" #include "TCPEchoClient_SingleTasks.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_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 mainHOST_NAME "RTOSDemo" #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 configECHO_SERVER_ADDR0 to configECHO_SERVER_ADDR3 constants in 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_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 */ + #if( mainCREATE_TCP_ECHO_SERVER_TASK == 1 ) + { + vStartSimpleTCPServerTasks( mainECHO_SERVER_TASK_STACK_SIZE, mainECHO_SERVER_TASK_PRIORITY ); + } + #endif + xTasksAlreadyCreated = pdTRUE; } diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DHCP.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DHCP.c index 6fb30226b..8ce9e8e92 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DHCP.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DHCP.c @@ -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. * * 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 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * http://www.FreeRTOS.org * http://aws.amazon.com/freertos - * - * 1 tab == 4 spaces! + * http://www.FreeRTOS.org */ /* Standard includes. */ @@ -597,15 +595,19 @@ static void prvInitialiseDHCP( void ) xDHCPData.ulTransactionId++; } - 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. */ - prvCreateDHCPSocket(); - FreeRTOS_debug_printf( ( "prvInitialiseDHCP: start after %lu ticks\n", dhcpINITIAL_TIMER_PERIOD ) ); - vIPReloadDHCPTimer( dhcpINITIAL_TIMER_PERIOD ); + /* Check for random number generator API failure. */ + if( 0 != xDHCPData.ulTransactionId ) + { + 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. */ + prvCreateDHCPSocket(); + FreeRTOS_debug_printf( ( "prvInitialiseDHCP: start after %lu ticks\n", 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. */ ulProcessed++; } - else + else if( *pucByte == ( uint8_t ) dhcpMESSAGE_TYPE_NACK ) { - if( *pucByte == ( uint8_t ) dhcpMESSAGE_TYPE_NACK ) + if( xExpectedMessageType == ( BaseType_t ) dhcpMESSAGE_TYPE_ACK ) { - if( xExpectedMessageType == ( BaseType_t ) dhcpMESSAGE_TYPE_ACK ) - { - /* Start again. */ - xDHCPData.eDHCPState = eWaitingSendFirstDiscover; - } + /* Start again. */ + xDHCPData.eDHCPState = eWaitingSendFirstDiscover; } - /* Stop processing further options. */ - ucLength = 0; + } + else + { + /* Don't process other message types. */ } break; diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_WIN.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_WIN.c index e1d6c8db5..556482a82 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_WIN.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_WIN.c @@ -292,7 +292,7 @@ void vListInsertGeneric( List_t * const pxList, ListItem_t * const pxNewListItem pxWhere->pxPrevious = pxNewListItem; /* Remember which list the item is in. */ - pxNewListItem->pvContainer = ( void * ) pxList; + pxNewListItem->pxContainer = pxList; ( pxList->uxNumberOfItems )++; } @@ -788,12 +788,12 @@ const int32_t l500ms = 500; { ulSavedSequenceNumber = ulCurrentSequenceNumber; - /* Clean up all sequence received between ulSequenceNumber + /* Clean up all sequence received between ulSequenceNumber and ulSequenceNumber + ulLength since they are duplicated. - If the server is forced to retransmit packets several time - in a row it might send a batch of concatenated packet for - speed. So we cannot rely on the packets between - ulSequenceNumber and ulSequenceNumber + ulLength to be + If the server is forced to retransmit packets several time + in a row it might send a batch of concatenated packet for + speed. So we cannot rely on the packets between + ulSequenceNumber and ulSequenceNumber + ulLength to be sequential and it is better to just clean them out. */ do { diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOSIPConfigDefaults.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOSIPConfigDefaults.h index 1ebb5c1c0..36781cca5 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOSIPConfigDefaults.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOSIPConfigDefaults.h @@ -510,7 +510,7 @@ from the FreeRTOSIPConfig.h configuration header file. */ #endif #ifndef ipconfigTCP_KEEP_ALIVE - #define ipconfigTCP_KEEP_ALIVE 0 + #define ipconfigTCP_KEEP_ALIVE 1 #endif #ifndef ipconfigDNS_USE_CALLBACKS @@ -526,7 +526,7 @@ from the FreeRTOSIPConfig.h configuration header file. */ #endif #ifndef ipconfigTCP_HANG_PROTECTION - #define ipconfigTCP_HANG_PROTECTION 0 + #define ipconfigTCP_HANG_PROTECTION 1 #endif #ifndef ipconfigTCP_IP_SANITY diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcHardwarePort.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcHardwarePort.h index 4be605eaa..da31e9364 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcHardwarePort.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcHardwarePort.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 * * trcHardwarePort.h @@ -38,7 +38,7 @@ * * Tabs are used for indent in this file (1 tab = 4 spaces) * - * Copyright Percepio AB, 2017. + * Copyright Percepio AB, 2018. * www.percepio.com ******************************************************************************/ @@ -344,7 +344,22 @@ #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD) #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) + /* INPUT YOUR PERIPHERAL BASE ADDRESS HERE */ #define TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS 0xSOMETHING diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcKernelPort.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcKernelPort.h index 3458b0a8b..59d57f80f 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcKernelPort.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcKernelPort.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 * * Terms of Use @@ -38,7 +38,7 @@ * * Tabs are used for indent in this file (1 tab = 4 spaces) * - * Copyright Percepio AB, 2017. + * Copyright Percepio AB, 2018. * www.percepio.com ******************************************************************************/ @@ -56,12 +56,41 @@ extern "C" { /*** FreeRTOS version codes **************************************************/ #define FREERTOS_VERSION_NOT_SET 0 -#define TRC_FREERTOS_VERSION_7_3_OR_7_4 1 -#define TRC_FREERTOS_VERSION_7_5_OR_7_6 2 -#define TRC_FREERTOS_VERSION_8_X 3 -#define TRC_FREERTOS_VERSION_9_X 4 +#define TRC_FREERTOS_VERSION_7_3 1 /* v7.3 is earliest supported.*/ +#define TRC_FREERTOS_VERSION_7_4 2 +#define TRC_FREERTOS_VERSION_7_5_OR_7_6 3 +#define TRC_FREERTOS_VERSION_8_X 4 /* Any v8.x.x*/ +#define TRC_FREERTOS_VERSION_9_0_0 5 +#define TRC_FREERTOS_VERSION_9_0_1 6 +#define TRC_FREERTOS_VERSION_9_0_2 7 +#define TRC_FREERTOS_VERSION_10_0_0 8 /* If using FreeRTOS v10.0.0 or later version */ -#if (TRC_USE_TRACEALYZER_RECORDER == 1) +#define TRC_FREERTOS_VERSION_9_X 42 /* Not allowed anymore */ + +#if (TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_X) +/* This setting for TRC_CFG_FREERTOS_VERSION is no longer allowed as v9.0.1 needs special handling. */ +#error "Please specify your exact FreeRTOS version in trcConfig.h, from the options listed above." +#endif + +#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) +#define prvGetStreamBufferType(x) ((( StreamBuffer_t * )x )->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER) +#else +#define prvGetStreamBufferType(x) 0 +#endif + +/* Added mainly for our internal testing. This makes it easier to create test applications that + runs on multiple FreeRTOS versions. */ +#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_8_X) + /* FreeRTOS v7.0 and later */ + #define STRING_CAST(x) ( (signed char*) x ) + #define TickType portTickType +#else + /* FreeRTOS v8.0 and later */ + #define STRING_CAST(x) x + #define TickType TickType_t +#endif + +#if (defined(TRC_USE_TRACEALYZER_RECORDER)) && (TRC_USE_TRACEALYZER_RECORDER == 1) /******************************************************************************* * INCLUDE_xTaskGetCurrentTaskHandle must be set to 1 for tracing to work properly @@ -69,6 +98,7 @@ extern "C" { #undef INCLUDE_xTaskGetCurrentTaskHandle #define INCLUDE_xTaskGetCurrentTaskHandle 1 +#if (TRC_CFG_SCHEDULING_ONLY == 0) /******************************************************************************* * vTraceSetQueueName(void* object, const char* name) * @@ -99,6 +129,59 @@ void vTraceSetSemaphoreName(void* object, const char* name); ******************************************************************************/ void vTraceSetMutexName(void* object, const char* name); +#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1) +/******************************************************************************* +* 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); +#else /* (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1) */ +#define vTraceSetEventGroupName(object, name) /* Do nothing */ +#endif /* (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1) */ + +#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1) +/******************************************************************************* +* 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); +#else /* (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1) */ +#define vTraceSetStreamBufferName(object, name) /* Do nothing */ +#endif /* (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1) */ + +#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1) +/******************************************************************************* + * 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); +#else /* (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1) */ +#define vTraceSetMessageBufferName(object, name) /* Do nothing */ +#endif /* (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1) */ + +#else /* (TRC_CFG_SCHEDULING_ONLY == 0) */ + +#define vTraceSetQueueName(object, name) /* Do nothing */ +#define vTraceSetSemaphoreName(object, name) /* Do nothing */ +#define vTraceSetMutexName(object, name) /* Do nothing */ +#define vTraceSetEventGroupName(object, name) /* Do nothing */ +#define vTraceSetStreamBufferName(object, name) /* Do nothing */ +#define vTraceSetMessageBufferName(object, name) /* Do nothing */ + +#endif /* (TRC_CFG_SCHEDULING_ONLY == 0) */ + /******************************************************************************* * Note: Setting names for event groups is difficult to support, this has been * excluded intentionally. This since we don't know if event_groups.c is @@ -130,7 +213,7 @@ unsigned char prvTraceIsSchedulerSuspended(void); /* If using dynamic allocation of snapshot trace buffer... */ #define TRACE_MALLOC(size) pvPortMalloc(size) -#ifdef configUSE_TIMERS +#if defined(configUSE_TIMERS) #if (configUSE_TIMERS == 1) #undef INCLUDE_xTimerGetTimerDaemonTaskHandle #define INCLUDE_xTimerGetTimerDaemonTaskHandle 1 @@ -144,7 +227,7 @@ unsigned char prvTraceIsSchedulerSuspended(void); #define TRACE_EXIT_CRITICAL_SECTION() {__set_PRIMASK(__irq_status);} #endif -#if ((TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_CORTEX_A9) || (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Renesas_RX600) || (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_MICROCHIP_PIC24_PIC32)) +#if ((TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_CORTEX_A9) || (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Renesas_RX600) || (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_MICROCHIP_PIC24_PIC32) || (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Altera_NiosII)) #define TRACE_ALLOC_CRITICAL_SECTION() int __irq_status; #define TRACE_ENTER_CRITICAL_SECTION() {__irq_status = portSET_INTERRUPT_MASK_FROM_ISR();} #define TRACE_EXIT_CRITICAL_SECTION() {portCLEAR_INTERRUPT_MASK_FROM_ISR(__irq_status);} @@ -175,6 +258,108 @@ unsigned char prvTraceIsSchedulerSuspended(void); #error "This hardware port has no definition for critical sections! See http://percepio.com/2014/10/27/how-to-define-critical-sections-for-the-recorder/" #endif + +#if (TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_0_1) + /****************************************************************************** + * Fix for FreeRTOS v9.0.1 to correctly identify xQueuePeek events. + * + * In FreeRTOS v9.0.1, the below trace hooks are incorrectly used from three + * different functions. This as the earlier function xQueueGenericReceive + * has been replaced by xQueuePeek, xQueueSemaphoreTake and xQueueReceive. + * + * xQueueGenericReceive had a parameter "xJustPeeking", used by the trace hooks + * to tell between xQueuePeek events and others. This is no longer present, so + * we need another way to correctly identify peek events. Since all three + * functions call the same trace macros, the context of these macro is unknown. + * + * We therefore check the __LINE__ macro inside of the trace macros. This gives + * the line number of queue.c, where the macros are used. This can be used to + * tell if the context is xQueuePeek or another function. + * __LINE__ is a standard compiler feature since ancient times, so it should + * work on all common compilers. + * + * This might seem as a quite brittle and unusual solution, but works in this + * particular case and is only for FreeRTOS v9.0.1. + * Future versions of FreeRTOS should not need this fix, as we have submitted + * a correction of queue.c with individual trace macros for each function. + ******************************************************************************/ +#define isQueueReceiveHookActuallyPeek (__LINE__ > 1674) /* Half way between the closes trace points */ + +#elif (TRC_CFG_FREERTOS_VERSION <= TRC_FREERTOS_VERSION_9_0_0) +#define isQueueReceiveHookActuallyPeek xJustPeeking + +#elif (TRC_CFG_FREERTOS_VERSION > TRC_FREERTOS_VERSION_9_0_1) +#define isQueueReceiveHookActuallyPeek (__LINE__ < 0) /* instead of pdFALSE to fix a warning of "constant condition" */ + +#endif + +extern uint16_t CurrentFilterMask; + +extern uint16_t CurrentFilterGroup; + +uint8_t prvTraceGetQueueType(void* handle); + +uint16_t prvTraceGetTaskNumberLow16(void* handle); +uint16_t prvTraceGetTaskNumberHigh16(void* handle); +void prvTraceSetTaskNumberLow16(void* handle, uint16_t value); +void prvTraceSetTaskNumberHigh16(void* handle, uint16_t value); + +uint16_t prvTraceGetQueueNumberLow16(void* handle); +uint16_t prvTraceGetQueueNumberHigh16(void* handle); +void prvTraceSetQueueNumberLow16(void* handle, uint16_t value); +void prvTraceSetQueueNumberHigh16(void* handle, uint16_t value); + +#if (TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) +uint16_t prvTraceGetTimerNumberLow16(void* handle); +uint16_t prvTraceGetTimerNumberHigh16(void* handle); +void prvTraceSetTimerNumberLow16(void* handle, uint16_t value); +void prvTraceSetTimerNumberHigh16(void* handle, uint16_t 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); +uint16_t prvTraceGetEventGroupNumberHigh16(void* handle); +void prvTraceSetEventGroupNumberLow16(void* handle, uint16_t value); +void prvTraceSetEventGroupNumberHigh16(void* handle, uint16_t 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); +uint16_t prvTraceGetStreamBufferNumberHigh16(void* handle); +void prvTraceSetStreamBufferNumberLow16(void* handle, uint16_t value); +void prvTraceSetStreamBufferNumberHigh16(void* handle, uint16_t value); +#endif /* (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */ + +#define TRACE_GET_TASK_FILTER(pxTask) prvTraceGetTaskNumberHigh16((void*)pxTask) +#define TRACE_SET_TASK_FILTER(pxTask, group) prvTraceSetTaskNumberHigh16((void*)pxTask, group) + +#define TRACE_GET_QUEUE_FILTER(pxObject) prvTraceGetQueueNumberHigh16((void*)pxObject) +#define TRACE_SET_QUEUE_FILTER(pxObject, group) prvTraceSetQueueNumberHigh16((void*)pxObject, group) + +#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) +#define TRACE_GET_EVENTGROUP_FILTER(pxObject) prvTraceGetEventGroupNumberHigh16((void*)pxObject) +#define TRACE_SET_EVENTGROUP_FILTER(pxObject, group) prvTraceSetEventGroupNumberHigh16((void*)pxObject, group) +#else /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */ +/* FreeRTOS versions before v10.0 does not support filtering for event groups */ +#define TRACE_GET_EVENTGROUP_FILTER(pxObject) 1 +#define TRACE_SET_EVENTGROUP_FILTER(pxObject, group) +#endif /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */ + +#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) +#define TRACE_GET_TIMER_FILTER(pxObject) prvTraceGetTimerNumberHigh16((void*)pxObject) +#define TRACE_SET_TIMER_FILTER(pxObject, group) prvTraceSetTimerNumberHigh16((void*)pxObject, group) +#else /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */ +/* FreeRTOS versions before v10.0 does not support filtering for timers */ +#define TRACE_GET_TIMER_FILTER(pxObject) 1 +#define TRACE_SET_TIMER_FILTER(pxObject, group) +#endif /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */ + +#define TRACE_GET_STREAMBUFFER_FILTER(pxObject) prvTraceGetStreamBufferNumberHigh16((void*)pxObject) +#define TRACE_SET_STREAMBUFFER_FILTER(pxObject, group) prvTraceSetStreamBufferNumberHigh16((void*)pxObject, group) + +#define TRACE_GET_OBJECT_FILTER(CLASS, pxObject) TRACE_GET_##CLASS##_FILTER(pxObject) +#define TRACE_SET_OBJECT_FILTER(CLASS, pxObject, group) TRACE_SET_##CLASS##_FILTER(pxObject, group) + /******************************************************************************/ /*** Definitions for Snapshot mode ********************************************/ /******************************************************************************/ @@ -182,7 +367,7 @@ unsigned char prvTraceIsSchedulerSuspended(void); /*** The object classes *******************************************************/ -#define TRACE_NCLASSES 7 +#define TRACE_NCLASSES 9 #define TRACE_CLASS_QUEUE ((traceObjectClass)0) #define TRACE_CLASS_SEMAPHORE ((traceObjectClass)1) #define TRACE_CLASS_MUTEX ((traceObjectClass)2) @@ -190,55 +375,57 @@ unsigned char prvTraceIsSchedulerSuspended(void); #define TRACE_CLASS_ISR ((traceObjectClass)4) #define TRACE_CLASS_TIMER ((traceObjectClass)5) #define TRACE_CLASS_EVENTGROUP ((traceObjectClass)6) +#define TRACE_CLASS_STREAMBUFFER ((traceObjectClass)7) +#define TRACE_CLASS_MESSAGEBUFFER ((traceObjectClass)8) /*** Definitions for Object Table ********************************************/ -#define TRACE_KERNEL_OBJECT_COUNT (TRC_CFG_NQUEUE + TRC_CFG_NSEMAPHORE + TRC_CFG_NMUTEX + TRC_CFG_NTASK + TRC_CFG_NISR + TRC_CFG_NTIMER + TRC_CFG_NEVENTGROUP) +#define TRACE_KERNEL_OBJECT_COUNT ((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)) /* Queue properties (except name): current number of message in queue */ -#define PropertyTableSizeQueue (TRC_CFG_NAME_LEN_QUEUE + 1) +#define PropertyTableSizeQueue ((TRC_CFG_NAME_LEN_QUEUE) + 1) /* Semaphore properties (except name): state (signaled = 1, cleared = 0) */ -#define PropertyTableSizeSemaphore (TRC_CFG_NAME_LEN_SEMAPHORE + 1) +#define PropertyTableSizeSemaphore ((TRC_CFG_NAME_LEN_SEMAPHORE) + 1) /* Mutex properties (except name): owner (task handle, 0 = free) */ -#define PropertyTableSizeMutex (TRC_CFG_NAME_LEN_MUTEX + 1) +#define PropertyTableSizeMutex ((TRC_CFG_NAME_LEN_MUTEX) + 1) /* Task properties (except name): Byte 0: Current priority Byte 1: state (if already active) Byte 2: legacy, not used Byte 3: legacy, not used */ -#define PropertyTableSizeTask (TRC_CFG_NAME_LEN_TASK + 4) +#define PropertyTableSizeTask ((TRC_CFG_NAME_LEN_TASK) + 4) /* ISR properties: Byte 0: priority Byte 1: state (if already active) */ -#define PropertyTableSizeISR (TRC_CFG_NAME_LEN_ISR + 2) +#define PropertyTableSizeISR ((TRC_CFG_NAME_LEN_ISR) + 2) /* TRC_CFG_NTIMER properties: Byte 0: state (unused for now) */ -#define PropertyTableSizeTimer (TRC_CFG_NAME_LEN_TIMER + 1) +#define PropertyTableSizeTimer ((TRC_CFG_NAME_LEN_TIMER) + 1) /* TRC_CFG_NEVENTGROUP properties: Byte 0-3: state (unused for now)*/ -#define PropertyTableSizeEventGroup (TRC_CFG_NAME_LEN_EVENTGROUP + 4) +#define PropertyTableSizeEventGroup ((TRC_CFG_NAME_LEN_EVENTGROUP) + 4) +/* TRC_CFG_NSTREAMBUFFER properties: Byte 0-3: state (unused for now)*/ +#define PropertyTableSizeStreamBuffer ((TRC_CFG_NAME_LEN_STREAMBUFFER) + 4) -/* The layout of the byte array representing the Object Property Table */ -#define StartIndexQueue 0 -#define StartIndexSemaphore StartIndexQueue + TRC_CFG_NQUEUE * PropertyTableSizeQueue -#define StartIndexMutex StartIndexSemaphore + TRC_CFG_NSEMAPHORE * PropertyTableSizeSemaphore -#define StartIndexTask StartIndexMutex + TRC_CFG_NMUTEX * PropertyTableSizeMutex -#define StartIndexISR StartIndexTask + TRC_CFG_NTASK * PropertyTableSizeTask -#define StartIndexTimer StartIndexISR + TRC_CFG_NISR * PropertyTableSizeISR -#define StartIndexEventGroup StartIndexTimer + TRC_CFG_NTIMER * PropertyTableSizeTimer +/* TRC_CFG_NMESSAGEBUFFER properties: Byte 0-3: state (unused for now)*/ +#define PropertyTableSizeMessageBuffer ((TRC_CFG_NAME_LEN_MESSAGEBUFFER) + 4) -/* Number of bytes used by the object table */ -#define TRACE_OBJECT_TABLE_SIZE StartIndexEventGroup + TRC_CFG_NEVENTGROUP * PropertyTableSizeEventGroup -///*** FreeRTOS version codes **************************************************/ -//#define FREERTOS_VERSION_NOT_SET 0 -//#define TRC_FREERTOS_VERSION_7_3_OR_7_4 1 -//#define TRC_FREERTOS_VERSION_7_5_OR_7_6 2 -//#define TRC_FREERTOS_VERSION_8_X 3 -//#define TRC_FREERTOS_VERSION_9_X 4 +/* The layout of the byte array representing the Object Property Table */ +#define StartIndexQueue (0) +#define StartIndexSemaphore (StartIndexQueue + (TRC_CFG_NQUEUE) * PropertyTableSizeQueue) +#define StartIndexMutex (StartIndexSemaphore + (TRC_CFG_NSEMAPHORE) * PropertyTableSizeSemaphore) +#define StartIndexTask (StartIndexMutex + (TRC_CFG_NMUTEX) * PropertyTableSizeMutex) +#define StartIndexISR (StartIndexTask + (TRC_CFG_NTASK) * PropertyTableSizeTask) +#define StartIndexTimer (StartIndexISR + (TRC_CFG_NISR) * PropertyTableSizeISR) +#define StartIndexEventGroup (StartIndexTimer + (TRC_CFG_NTIMER) * PropertyTableSizeTimer) +#define StartIndexStreamBuffer (StartIndexEventGroup + (TRC_CFG_NEVENTGROUP) * PropertyTableSizeEventGroup) +#define StartIndexMessageBuffer (StartIndexStreamBuffer + (TRC_CFG_NSTREAMBUFFER) * PropertyTableSizeStreamBuffer) +/* Number of bytes used by the object table */ +#define TRACE_OBJECT_TABLE_SIZE (StartIndexMessageBuffer + (TRC_CFG_NMESSAGEBUFFER) * PropertyTableSizeMessageBuffer) /* Flag to tell the context of tracePEND_FUNC_CALL_FROM_ISR */ extern int uiInEventGroupSetBitsFromISR; @@ -252,26 +439,14 @@ void vTraceInitObjectHandleStack(void); /* Returns the "Not enough handles" error message for the specified object class */ const char* pszTraceGetErrorNotEnoughHandles(traceObjectClass objectclass); -traceHandle prvTraceGetObjectNumber(void* handle); - -uint8_t prvTraceGetObjectType(void* handle); - -traceHandle prvTraceGetTaskNumber(void* handle); - void* prvTraceGetCurrentTaskHandle(void); -uint8_t uiTraceIsObjectExcluded(traceObjectClass objectclass, traceHandle handle); - -#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X) -traceHandle prvTraceGetEventGroupNumber(void* handle); -#endif - /****************************************************************************** - * TraceObjectClassTable + * TraceQueueClassTable * Translates a FreeRTOS QueueType into trace objects classes (TRACE_CLASS_). * Has one entry for each QueueType, gives TRACE_CLASS ID. ******************************************************************************/ -extern traceObjectClass TraceObjectClassTable[5]; +extern traceObjectClass TraceQueueClassTable[5]; /*** Event codes for snapshot mode - must match Tracealyzer config files ******/ @@ -309,7 +484,7 @@ extern traceObjectClass TraceObjectClassTable[5]; * EVENTGROUP_OBJCLOSE_PROP), containing the handle-name mapping and object * properties valid up to this point. ******************************************************************************/ -#define EVENTGROUP_OBJCLOSE_NAME (EVENTGROUP_TS + 4UL) /*0x08*/ +#define EVENTGROUP_OBJCLOSE_NAME_TRCSUCCESS (EVENTGROUP_TS + 4UL) /*0x08*/ /******************************************************************************* * EVENTGROUP_OBJCLOSE_PROP @@ -326,7 +501,7 @@ extern traceObjectClass TraceObjectClassTable[5]; * handle. The lower three bits are not used (always zero) when queues are * closed since the queue type is given in the previous OBJCLOSE_NAME event. ******************************************************************************/ -#define EVENTGROUP_OBJCLOSE_PROP (EVENTGROUP_OBJCLOSE_NAME + 8UL) /*0x10*/ +#define EVENTGROUP_OBJCLOSE_PROP_TRCSUCCESS (EVENTGROUP_OBJCLOSE_NAME_TRCSUCCESS + 8UL) /*0x10*/ /******************************************************************************* * EVENTGROUP_CREATE @@ -335,7 +510,7 @@ extern traceObjectClass TraceObjectClassTable[5]; * The lower three bits in the event code gives the object class, i.e., type of * create operation (task, queue, semaphore, etc). ******************************************************************************/ -#define EVENTGROUP_CREATE_OBJ_SUCCESS (EVENTGROUP_OBJCLOSE_PROP + 8UL) /*0x18*/ +#define EVENTGROUP_CREATE_OBJ_TRCSUCCESS (EVENTGROUP_OBJCLOSE_PROP_TRCSUCCESS + 8UL) /*0x18*/ /******************************************************************************* * EVENTGROUP_SEND @@ -345,7 +520,7 @@ extern traceObjectClass TraceObjectClassTable[5]; * object class, i.e., what type of object that is operated on (queue, semaphore * or mutex). ******************************************************************************/ -#define EVENTGROUP_SEND_SUCCESS (EVENTGROUP_CREATE_OBJ_SUCCESS + 8UL) /*0x20*/ +#define EVENTGROUP_SEND_TRCSUCCESS (EVENTGROUP_CREATE_OBJ_TRCSUCCESS + 8UL) /*0x20*/ /******************************************************************************* * EVENTGROUP_RECEIVE @@ -355,51 +530,51 @@ extern traceObjectClass TraceObjectClassTable[5]; * object class, i.e., what type of object that is operated on (queue, semaphore * or mutex). ******************************************************************************/ -#define EVENTGROUP_RECEIVE_SUCCESS (EVENTGROUP_SEND_SUCCESS + 8UL) /*0x28*/ +#define EVENTGROUP_RECEIVE_TRCSUCCESS (EVENTGROUP_SEND_TRCSUCCESS + 8UL) /*0x28*/ /* Send/Give operations, from ISR */ -#define EVENTGROUP_SEND_FROM_ISR_SUCCESS \ - (EVENTGROUP_RECEIVE_SUCCESS + 8UL) /*0x30*/ +#define EVENTGROUP_SEND_FROM_ISR_TRCSUCCESS \ + (EVENTGROUP_RECEIVE_TRCSUCCESS + 8UL) /*0x30*/ /* Receive/Take operations, from ISR */ -#define EVENTGROUP_RECEIVE_FROM_ISR_SUCCESS \ - (EVENTGROUP_SEND_FROM_ISR_SUCCESS + 8UL) /*0x38*/ +#define EVENTGROUP_RECEIVE_FROM_ISR_TRCSUCCESS \ + (EVENTGROUP_SEND_FROM_ISR_TRCSUCCESS + 8UL) /*0x38*/ /* "Failed" event type versions of above (timeout, failed allocation, etc) */ -#define EVENTGROUP_KSE_FAILED \ - (EVENTGROUP_RECEIVE_FROM_ISR_SUCCESS + 8UL) /*0x40*/ +#define EVENTGROUP_KSE_TRCFAILED \ + (EVENTGROUP_RECEIVE_FROM_ISR_TRCSUCCESS + 8UL) /*0x40*/ /* Failed create calls - memory allocation failed */ -#define EVENTGROUP_CREATE_OBJ_FAILED (EVENTGROUP_KSE_FAILED) /*0x40*/ +#define EVENTGROUP_CREATE_OBJ_TRCFAILED (EVENTGROUP_KSE_TRCFAILED) /*0x40*/ /* Failed send/give - timeout! */ -#define EVENTGROUP_SEND_FAILED (EVENTGROUP_CREATE_OBJ_FAILED + 8UL) /*0x48*/ +#define EVENTGROUP_SEND_TRCFAILED (EVENTGROUP_CREATE_OBJ_TRCFAILED + 8UL) /*0x48*/ /* Failed receive/take - timeout! */ -#define EVENTGROUP_RECEIVE_FAILED (EVENTGROUP_SEND_FAILED + 8UL) /*0x50*/ +#define EVENTGROUP_RECEIVE_TRCFAILED (EVENTGROUP_SEND_TRCFAILED + 8UL) /*0x50*/ /* Failed non-blocking send/give - queue full */ -#define EVENTGROUP_SEND_FROM_ISR_FAILED (EVENTGROUP_RECEIVE_FAILED + 8UL) /*0x58*/ +#define EVENTGROUP_SEND_FROM_ISR_TRCFAILED (EVENTGROUP_RECEIVE_TRCFAILED + 8UL) /*0x58*/ /* Failed non-blocking receive/take - queue empty */ -#define EVENTGROUP_RECEIVE_FROM_ISR_FAILED \ - (EVENTGROUP_SEND_FROM_ISR_FAILED + 8UL) /*0x60*/ +#define EVENTGROUP_RECEIVE_FROM_ISR_TRCFAILED \ + (EVENTGROUP_SEND_FROM_ISR_TRCFAILED + 8UL) /*0x60*/ /* Events when blocking on receive/take */ -#define EVENTGROUP_RECEIVE_BLOCK \ - (EVENTGROUP_RECEIVE_FROM_ISR_FAILED + 8UL) /*0x68*/ +#define EVENTGROUP_RECEIVE_TRCBLOCK \ + (EVENTGROUP_RECEIVE_FROM_ISR_TRCFAILED + 8UL) /*0x68*/ /* Events when blocking on send/give */ -#define EVENTGROUP_SEND_BLOCK (EVENTGROUP_RECEIVE_BLOCK + 8UL) /*0x70*/ +#define EVENTGROUP_SEND_TRCBLOCK (EVENTGROUP_RECEIVE_TRCBLOCK + 8UL) /*0x70*/ /* Events on queue peek (receive) */ -#define EVENTGROUP_PEEK_SUCCESS (EVENTGROUP_SEND_BLOCK + 8UL) /*0x78*/ +#define EVENTGROUP_PEEK_TRCSUCCESS (EVENTGROUP_SEND_TRCBLOCK + 8UL) /*0x78*/ /* Events on object delete (vTaskDelete or vQueueDelete) */ -#define EVENTGROUP_DELETE_OBJ_SUCCESS (EVENTGROUP_PEEK_SUCCESS + 8UL) /*0x80*/ +#define EVENTGROUP_DELETE_OBJ_TRCSUCCESS (EVENTGROUP_PEEK_TRCSUCCESS + 8UL) /*0x80*/ /* Other events - object class is implied: TASK */ -#define EVENTGROUP_OTHERS (EVENTGROUP_DELETE_OBJ_SUCCESS + 8UL) /*0x88*/ +#define EVENTGROUP_OTHERS (EVENTGROUP_DELETE_OBJ_TRCSUCCESS + 8UL) /*0x88*/ #define TASK_DELAY_UNTIL (EVENTGROUP_OTHERS + 0UL) /*0x88*/ #define TASK_DELAY (EVENTGROUP_OTHERS + 1UL) /*0x89*/ #define TASK_SUSPEND (EVENTGROUP_OTHERS + 2UL) /*0x8A*/ @@ -412,8 +587,8 @@ extern traceObjectClass TraceObjectClassTable[5]; #define EVENTGROUP_MISC_PLACEHOLDER (EVENTGROUP_OTHERS + 8UL) /*0x90*/ #define PEND_FUNC_CALL (EVENTGROUP_MISC_PLACEHOLDER+0UL) /*0x90*/ #define PEND_FUNC_CALL_FROM_ISR (EVENTGROUP_MISC_PLACEHOLDER+1UL) /*0x91*/ -#define PEND_FUNC_CALL_FAILED (EVENTGROUP_MISC_PLACEHOLDER+2UL) /*0x92*/ -#define PEND_FUNC_CALL_FROM_ISR_FAILED (EVENTGROUP_MISC_PLACEHOLDER+3UL) /*0x93*/ +#define PEND_FUNC_CALL_TRCFAILED (EVENTGROUP_MISC_PLACEHOLDER+2UL) /*0x92*/ +#define PEND_FUNC_CALL_FROM_ISR_TRCFAILED (EVENTGROUP_MISC_PLACEHOLDER+3UL) /*0x93*/ #define MEM_MALLOC_SIZE (EVENTGROUP_MISC_PLACEHOLDER+4UL) /*0x94*/ #define MEM_MALLOC_ADDR (EVENTGROUP_MISC_PLACEHOLDER+5UL) /*0x95*/ #define MEM_FREE_SIZE (EVENTGROUP_MISC_PLACEHOLDER+6UL) /*0x96*/ @@ -463,36 +638,36 @@ extern traceObjectClass TraceObjectClassTable[5]; #define TIMER_RST (EVENTGROUP_TIMER + 2UL) /*0xB2*/ #define TIMER_STOP (EVENTGROUP_TIMER + 3UL) /*0xB3*/ #define TIMER_CHANGE_PERIOD (EVENTGROUP_TIMER + 4UL) /*0xB4*/ -#define TIMER_DELETE (EVENTGROUP_TIMER + 5UL) /*0xB5*/ +#define TIMER_DELETE_OBJ (EVENTGROUP_TIMER + 5UL) /*0xB5*/ #define TIMER_START_FROM_ISR (EVENTGROUP_TIMER + 6UL) /*0xB6*/ #define TIMER_RESET_FROM_ISR (EVENTGROUP_TIMER + 7UL) /*0xB7*/ #define TIMER_STOP_FROM_ISR (EVENTGROUP_TIMER + 8UL) /*0xB8*/ -#define TIMER_CREATE_FAILED (EVENTGROUP_TIMER + 9UL) /*0xB9*/ -#define TIMER_START_FAILED (EVENTGROUP_TIMER + 10UL) /*0xBA*/ -#define TIMER_RESET_FAILED (EVENTGROUP_TIMER + 11UL) /*0xBB*/ -#define TIMER_STOP_FAILED (EVENTGROUP_TIMER + 12UL) /*0xBC*/ -#define TIMER_CHANGE_PERIOD_FAILED (EVENTGROUP_TIMER + 13UL) /*0xBD*/ -#define TIMER_DELETE_FAILED (EVENTGROUP_TIMER + 14UL) /*0xBE*/ -#define TIMER_START_FROM_ISR_FAILED (EVENTGROUP_TIMER + 15UL) /*0xBF*/ -#define TIMER_RESET_FROM_ISR_FAILED (EVENTGROUP_TIMER + 16UL) /*0xC0*/ -#define TIMER_STOP_FROM_ISR_FAILED (EVENTGROUP_TIMER + 17UL) /*0xC1*/ +#define TIMER_CREATE_TRCFAILED (EVENTGROUP_TIMER + 9UL) /*0xB9*/ +#define TIMER_START_TRCFAILED (EVENTGROUP_TIMER + 10UL) /*0xBA*/ +#define TIMER_RESET_TRCFAILED (EVENTGROUP_TIMER + 11UL) /*0xBB*/ +#define TIMER_STOP_TRCFAILED (EVENTGROUP_TIMER + 12UL) /*0xBC*/ +#define TIMER_CHANGE_PERIOD_TRCFAILED (EVENTGROUP_TIMER + 13UL) /*0xBD*/ +#define TIMER_DELETE_TRCFAILED (EVENTGROUP_TIMER + 14UL) /*0xBE*/ +#define TIMER_START_FROM_ISR_TRCFAILED (EVENTGROUP_TIMER + 15UL) /*0xBF*/ +#define TIMER_RESET_FROM_ISR_TRCFAILED (EVENTGROUP_TIMER + 16UL) /*0xC0*/ +#define TIMER_STOP_FROM_ISR_TRCFAILED (EVENTGROUP_TIMER + 17UL) /*0xC1*/ #define EVENTGROUP_EG (EVENTGROUP_TIMER + 18UL) /*0xC2*/ #define EVENT_GROUP_CREATE (EVENTGROUP_EG + 0UL) /*0xC2*/ -#define EVENT_GROUP_CREATE_FAILED (EVENTGROUP_EG + 1UL) /*0xC3*/ -#define EVENT_GROUP_SYNC_BLOCK (EVENTGROUP_EG + 2UL) /*0xC4*/ +#define EVENT_GROUP_CREATE_TRCFAILED (EVENTGROUP_EG + 1UL) /*0xC3*/ +#define EVENT_GROUP_SYNC_TRCBLOCK (EVENTGROUP_EG + 2UL) /*0xC4*/ #define EVENT_GROUP_SYNC_END (EVENTGROUP_EG + 3UL) /*0xC5*/ -#define EVENT_GROUP_WAIT_BITS_BLOCK (EVENTGROUP_EG + 4UL) /*0xC6*/ +#define EVENT_GROUP_WAIT_BITS_TRCBLOCK (EVENTGROUP_EG + 4UL) /*0xC6*/ #define EVENT_GROUP_WAIT_BITS_END (EVENTGROUP_EG + 5UL) /*0xC7*/ #define EVENT_GROUP_CLEAR_BITS (EVENTGROUP_EG + 6UL) /*0xC8*/ #define EVENT_GROUP_CLEAR_BITS_FROM_ISR (EVENTGROUP_EG + 7UL) /*0xC9*/ #define EVENT_GROUP_SET_BITS (EVENTGROUP_EG + 8UL) /*0xCA*/ -#define EVENT_GROUP_DELETE (EVENTGROUP_EG + 9UL) /*0xCB*/ -#define EVENT_GROUP_SYNC_END_FAILED (EVENTGROUP_EG + 10UL) /*0xCC*/ -#define EVENT_GROUP_WAIT_BITS_END_FAILED (EVENTGROUP_EG + 11UL) /*0xCD*/ +#define EVENT_GROUP_DELETE_OBJ (EVENTGROUP_EG + 9UL) /*0xCB*/ +#define EVENT_GROUP_SYNC_END_TRCFAILED (EVENTGROUP_EG + 10UL) /*0xCC*/ +#define EVENT_GROUP_WAIT_BITS_END_TRCFAILED (EVENTGROUP_EG + 11UL) /*0xCD*/ #define EVENT_GROUP_SET_BITS_FROM_ISR (EVENTGROUP_EG + 12UL) /*0xCE*/ -#define EVENT_GROUP_SET_BITS_FROM_ISR_FAILED (EVENTGROUP_EG + 13UL) /*0xCF*/ +#define EVENT_GROUP_SET_BITS_FROM_ISR_TRCFAILED (EVENTGROUP_EG + 13UL) /*0xCF*/ #define TASK_INSTANCE_FINISHED_NEXT_KSE (EVENTGROUP_EG + 14UL) /*0xD0*/ #define TASK_INSTANCE_FINISHED_DIRECT (EVENTGROUP_EG + 15UL) /*0xD1*/ @@ -500,67 +675,150 @@ extern traceObjectClass TraceObjectClassTable[5]; #define TRACE_TASK_NOTIFY_GROUP (EVENTGROUP_EG + 16UL) /*0xD2*/ #define TRACE_TASK_NOTIFY (TRACE_TASK_NOTIFY_GROUP + 0UL) /*0xD2*/ #define TRACE_TASK_NOTIFY_TAKE (TRACE_TASK_NOTIFY_GROUP + 1UL) /*0xD3*/ -#define TRACE_TASK_NOTIFY_TAKE_BLOCK (TRACE_TASK_NOTIFY_GROUP + 2UL) /*0xD4*/ -#define TRACE_TASK_NOTIFY_TAKE_FAILED (TRACE_TASK_NOTIFY_GROUP + 3UL) /*0xD5*/ +#define TRACE_TASK_NOTIFY_TAKE_TRCBLOCK (TRACE_TASK_NOTIFY_GROUP + 2UL) /*0xD4*/ +#define TRACE_TASK_NOTIFY_TAKE_TRCFAILED (TRACE_TASK_NOTIFY_GROUP + 3UL) /*0xD5*/ #define TRACE_TASK_NOTIFY_WAIT (TRACE_TASK_NOTIFY_GROUP + 4UL) /*0xD6*/ -#define TRACE_TASK_NOTIFY_WAIT_BLOCK (TRACE_TASK_NOTIFY_GROUP + 5UL) /*0xD7*/ -#define TRACE_TASK_NOTIFY_WAIT_FAILED (TRACE_TASK_NOTIFY_GROUP + 6UL) /*0xD8*/ +#define TRACE_TASK_NOTIFY_WAIT_TRCBLOCK (TRACE_TASK_NOTIFY_GROUP + 5UL) /*0xD7*/ +#define TRACE_TASK_NOTIFY_WAIT_TRCFAILED (TRACE_TASK_NOTIFY_GROUP + 6UL) /*0xD8*/ #define TRACE_TASK_NOTIFY_FROM_ISR (TRACE_TASK_NOTIFY_GROUP + 7UL) /*0xD9*/ #define TRACE_TASK_NOTIFY_GIVE_FROM_ISR (TRACE_TASK_NOTIFY_GROUP + 8UL) /*0xDA*/ +#define TIMER_EXPIRED (TRACE_TASK_NOTIFY_GROUP + 9UL) /* 0xDB */ -#define TRACE_GET_TASK_PRIORITY(pxTCB) ((uint8_t)pxTCB->uxPriority) -#define TRACE_GET_TASK_NAME(pxTCB) ((char*)pxTCB->pcTaskName) -#define TRACE_GET_TASK_NUMBER(pxTCB) (prvTraceGetTaskNumber(pxTCB)) -#define TRACE_SET_TASK_NUMBER(pxTCB) pxTCB->uxTaskNumber = prvTraceGetObjectHandle(TRACE_CLASS_TASK); - -#define TRACE_GET_CLASS_TRACE_CLASS(CLASS, kernelClass) TraceObjectClassTable[kernelClass] -#define TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject) TRACE_GET_CLASS_TRACE_CLASS(CLASS, prvTraceGetObjectType(pxObject)) - -#define TRACE_GET_TIMER_NUMBER(tmr) (((uint32_t)tmr) != 0 ? ( ( traceHandle ) ((Timer_t*)tmr)->uxTimerNumber ) : 0) -#define TRACE_SET_TIMER_NUMBER(tmr) ((Timer_t*)tmr)->uxTimerNumber = prvTraceGetObjectHandle(TRACE_CLASS_TIMER); -#define TRACE_GET_TIMER_NAME(pxTimer) pxTimer->pcTimerName -#define TRACE_GET_TIMER_PERIOD(pxTimer) pxTimer->xTimerPeriodInTicks + /* Events on queue peek (receive) */ +#define EVENTGROUP_PEEK_TRCBLOCK (TRACE_TASK_NOTIFY_GROUP + 10UL) /*0xDC*/ +/* peek block on queue: 0xDC */ +/* peek block on semaphore: 0xDD */ +/* peek block on mutex: 0xDE */ +/* Events on queue peek (receive) */ +#define EVENTGROUP_PEEK_TRCFAILED (EVENTGROUP_PEEK_TRCBLOCK + 3UL) /*0xDF*/ +/* peek failed on queue: 0xDF */ +/* peek failed on semaphore: 0xE0 */ +/* peek failed on mutex: 0xE1 */ + +#define EVENTGROUP_STREAMBUFFER_DIV (EVENTGROUP_PEEK_TRCFAILED + 3UL) /*0xE2*/ +#define TRACE_STREAMBUFFER_RESET (EVENTGROUP_STREAMBUFFER_DIV + 0) /*0xE2*/ +#define TRACE_MESSAGEBUFFER_RESET (EVENTGROUP_STREAMBUFFER_DIV + 1UL) /*0xE3*/ +#define TRACE_STREAMBUFFER_OBJCLOSE_NAME_TRCSUCCESS (EVENTGROUP_STREAMBUFFER_DIV + 2UL) /*0xE4*/ +#define TRACE_MESSAGEBUFFER_OBJCLOSE_NAME_TRCSUCCESS (EVENTGROUP_STREAMBUFFER_DIV + 3UL) /*0xE5*/ +#define TRACE_STREAMBUFFER_OBJCLOSE_PROP_TRCSUCCESS (EVENTGROUP_STREAMBUFFER_DIV + 4UL) /*0xE6*/ +#define TRACE_MESSAGEBUFFER_OBJCLOSE_PROP_TRCSUCCESS (EVENTGROUP_STREAMBUFFER_DIV + 5UL) /*0xE7*/ + +/* The following are using previously "lost" event codes */ +#define TRACE_STREAMBUFFER_CREATE_OBJ_TRCSUCCESS (EVENTGROUP_CREATE_OBJ_TRCSUCCESS + 4UL) /*0x1C*/ +#define TRACE_STREAMBUFFER_CREATE_OBJ_TRCFAILED (EVENTGROUP_CREATE_OBJ_TRCFAILED + 4UL) /*0x44*/ +#define TRACE_STREAMBUFFER_DELETE_OBJ_TRCSUCCESS (EVENTGROUP_DELETE_OBJ_TRCSUCCESS + 4UL) /*0x84*/ +#define TRACE_STREAMBUFFER_SEND_TRCSUCCESS (EVENTGROUP_SEND_TRCSUCCESS + 3UL) /*0x23*/ +#define TRACE_STREAMBUFFER_SEND_TRCBLOCK (EVENTGROUP_SEND_TRCBLOCK + 3UL) /*0x73*/ +#define TRACE_STREAMBUFFER_SEND_TRCFAILED (EVENTGROUP_SEND_TRCFAILED + 3UL) /*0x4B*/ +#define TRACE_STREAMBUFFER_RECEIVE_TRCSUCCESS (EVENTGROUP_RECEIVE_TRCSUCCESS + 3UL) /*0x2B*/ +#define TRACE_STREAMBUFFER_RECEIVE_TRCBLOCK (EVENTGROUP_RECEIVE_TRCBLOCK + 3UL) /*0x6B*/ +#define TRACE_STREAMBUFFER_RECEIVE_TRCFAILED (EVENTGROUP_RECEIVE_TRCFAILED + 3UL) /*0x53*/ +#define TRACE_STREAMBUFFER_SEND_FROM_ISR_TRCSUCCESS (EVENTGROUP_SEND_FROM_ISR_TRCSUCCESS + 3UL) /*0x33*/ +#define TRACE_STREAMBUFFER_SEND_FROM_ISR_TRCFAILED (EVENTGROUP_SEND_FROM_ISR_TRCFAILED + 3UL) /*0x5B*/ +#define TRACE_STREAMBUFFER_RECEIVE_FROM_ISR_TRCSUCCESS (EVENTGROUP_RECEIVE_FROM_ISR_TRCSUCCESS + 3UL) /*0x3B*/ +#define TRACE_STREAMBUFFER_RECEIVE_FROM_ISR_TRCFAILED (EVENTGROUP_RECEIVE_FROM_ISR_TRCFAILED + 3UL) /*0x63*/ + +/* The following are using previously "lost" event codes. These macros aren't even directly referenced, instead we do (equivalent STREAMBUFFER code) + 1. */ +#define TRACE_MESSAGEBUFFER_CREATE_OBJ_TRCSUCCESS (EVENTGROUP_CREATE_OBJ_TRCSUCCESS + 5UL) /*0x1D*/ +#define TRACE_MESSAGEBUFFER_CREATE_OBJ_TRCFAILED (EVENTGROUP_CREATE_OBJ_TRCFAILED + 5UL) /*0x45*/ +#define TRACE_MESSAGEBUFFER_DELETE_OBJ_TRCSUCCESS (EVENTGROUP_DELETE_OBJ_TRCSUCCESS + 5UL) /*0x85*/ +#define TRACE_MESSAGEBUFFER_SEND_TRCSUCCESS (EVENTGROUP_SEND_TRCSUCCESS + 4UL) /*0x24*/ +#define TRACE_MESSAGEBUFFER_SEND_TRCBLOCK (EVENTGROUP_SEND_TRCBLOCK + 4UL) /*0x74*/ +#define TRACE_MESSAGEBUFFER_SEND_TRCFAILED (EVENTGROUP_SEND_TRCFAILED + 4UL) /*0x4C*/ +#define TRACE_MESSAGEBUFFER_RECEIVE_TRCSUCCESS (EVENTGROUP_RECEIVE_TRCSUCCESS + 4UL) /*0x2C*/ +#define TRACE_MESSAGEBUFFER_RECEIVE_TRCBLOCK (EVENTGROUP_RECEIVE_TRCBLOCK + 4UL) /*0x6C*/ +#define TRACE_MESSAGEBUFFER_RECEIVE_TRCFAILED (EVENTGROUP_RECEIVE_TRCFAILED + 4UL) /*0x54*/ +#define TRACE_MESSAGEBUFFER_SEND_FROM_ISR_TRCSUCCESS (EVENTGROUP_SEND_FROM_ISR_TRCSUCCESS + 4UL) /*0x34*/ +#define TRACE_MESSAGEBUFFER_SEND_FROM_ISR_TRCFAILED (EVENTGROUP_SEND_FROM_ISR_TRCFAILED + 4UL) /*0x5C*/ +#define TRACE_MESSAGEBUFFER_RECEIVE_FROM_ISR_TRCSUCCESS (EVENTGROUP_RECEIVE_FROM_ISR_TRCSUCCESS + 4UL) /*0x3C*/ +#define TRACE_MESSAGEBUFFER_RECEIVE_FROM_ISR_TRCFAILED (EVENTGROUP_RECEIVE_FROM_ISR_TRCFAILED + 4UL) /*0x64*/ + +/* LAST EVENT (0xE7) */ + +/**************************** +* MACROS TO GET TRACE CLASS * +****************************/ +#define TRACE_GET_TRACE_CLASS_FROM_TASK_CLASS(kernelClass) (TRACE_CLASS_TASK) +#define TRACE_GET_TRACE_CLASS_FROM_TASK_OBJECT(pxObject) (TRACE_CLASS_TASK) + +#define TRACE_GET_TRACE_CLASS_FROM_QUEUE_CLASS(kernelClass) TraceQueueClassTable[kernelClass] +#define TRACE_GET_TRACE_CLASS_FROM_QUEUE_OBJECT(pxObject) TRACE_GET_TRACE_CLASS_FROM_QUEUE_CLASS(prvTraceGetQueueType(pxObject)) + +#define TRACE_GET_TRACE_CLASS_FROM_TIMER_CLASS(kernelClass) (TRACE_CLASS_TIMER) +#define TRACE_GET_TRACE_CLASS_FROM_TIMER_OBJECT(pxObject) (TRACE_CLASS_TIMER) + +#define TRACE_GET_TRACE_CLASS_FROM_EVENTGROUP_CLASS(kernelClass) (TRACE_CLASS_EVENTGROUP) +#define TRACE_GET_TRACE_CLASS_FROM_EVENTGROUP_OBJECT(pxObject) (TRACE_CLASS_EVENTGROUP) + +/* TRACE_GET_TRACE_CLASS_FROM_STREAMBUFFER_CLASS can only be accessed with a parameter indicating if it is a MessageBuffer */ +#define TRACE_GET_TRACE_CLASS_FROM_STREAMBUFFER_CLASS(xIsMessageBuffer) (xIsMessageBuffer == 1 ? TRACE_CLASS_MESSAGEBUFFER : TRACE_CLASS_STREAMBUFFER) +#define TRACE_GET_TRACE_CLASS_FROM_STREAMBUFFER_OBJECT(pxObject) (prvGetStreamBufferType(pxObject) == 1 ? TRACE_CLASS_MESSAGEBUFFER : TRACE_CLASS_STREAMBUFFER) + +/* Generic versions */ +#define TRACE_GET_CLASS_TRACE_CLASS(CLASS, kernelClass) TRACE_GET_TRACE_CLASS_FROM_##CLASS##_CLASS(kernelClass) +#define TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject) TRACE_GET_TRACE_CLASS_FROM_##CLASS##_OBJECT(pxObject) + +/****************************** +* MACROS TO GET OBJECT NUMBER * +******************************/ +#define TRACE_GET_TASK_NUMBER(pxTCB) (traceHandle)(prvTraceGetTaskNumberLow16(pxTCB)) +#define TRACE_SET_TASK_NUMBER(pxTCB) prvTraceSetTaskNumberLow16(pxTCB, prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(TASK, pxTCB))); + +#define TRACE_GET_QUEUE_NUMBER(queue) ( ( traceHandle ) prvTraceGetQueueNumberLow16(queue) ) +#define TRACE_SET_QUEUE_NUMBER(queue) prvTraceSetQueueNumberLow16(queue, (uint16_t)prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, queue))); + +#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) +#define TRACE_GET_TIMER_NUMBER(tmr) ( ( traceHandle ) prvTraceGetTimerNumberLow16(tmr) ) +#define TRACE_SET_TIMER_NUMBER(tmr) prvTraceSetTimerNumberLow16(tmr, (uint16_t)prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(TIMER, tmr))); +#else /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */ +#define TRACE_GET_TIMER_NUMBER(tmr) ( ( traceHandle ) ((Timer_t*)tmr)->uxTimerNumber ) +#define TRACE_SET_TIMER_NUMBER(tmr) ((Timer_t*)tmr)->uxTimerNumber = prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(TIMER, tmr)); +#endif /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */ + +#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) +#define TRACE_GET_EVENTGROUP_NUMBER(eg) ( ( traceHandle ) prvTraceGetEventGroupNumberLow16(eg) ) +#define TRACE_SET_EVENTGROUP_NUMBER(eg) prvTraceSetEventGroupNumberLow16(eg, (uint16_t)prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(EVENTGROUP, eg))); +#else /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */ #define TRACE_GET_EVENTGROUP_NUMBER(eg) ( ( traceHandle ) uxEventGroupGetNumber(eg) ) +#define TRACE_SET_EVENTGROUP_NUMBER(eg) ((EventGroup_t*)eg)->uxEventGroupNumber = prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(EVENTGROUP, eg)); +#endif /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */ + + +#define TRACE_GET_STREAMBUFFER_NUMBER(sb) ( ( traceHandle ) prvTraceGetStreamBufferNumberLow16(sb) ) +#define TRACE_SET_STREAMBUFFER_NUMBER(sb) prvTraceSetStreamBufferNumberLow16(sb, (uint16_t)prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(STREAMBUFFER, sb))); + +/* Generic versions */ +#define TRACE_GET_OBJECT_NUMBER(CLASS, pxObject) TRACE_GET_##CLASS##_NUMBER(pxObject) +#define TRACE_SET_OBJECT_NUMBER(CLASS, pxObject) TRACE_SET_##CLASS##_NUMBER(pxObject) + +/****************************** +* MACROS TO GET EVENT CODES * +******************************/ +#define TRACE_GET_TASK_CLASS_EVENT_CODE(SERVICE, RESULT, kernelClass) (uint8_t)(EVENTGROUP_##SERVICE##_##RESULT + TRACE_GET_CLASS_TRACE_CLASS(TASK, kernelClass)) +#define TRACE_GET_QUEUE_CLASS_EVENT_CODE(SERVICE, RESULT, kernelClass) (uint8_t)(EVENTGROUP_##SERVICE##_##RESULT + TRACE_GET_CLASS_TRACE_CLASS(QUEUE, kernelClass)) +#define TRACE_GET_TIMER_CLASS_EVENT_CODE(SERVICE, RESULT, kernelClass) -- THIS IS NOT USED -- +#define TRACE_GET_EVENTGROUP_CLASS_EVENT_CODE(SERVICE, RESULT, kernelClass) -- THIS IS NOT USED -- +#define TRACE_GET_STREAMBUFFER_CLASS_EVENT_CODE(SERVICE, RESULT, isMessageBuffer) (uint8_t)(TRACE_STREAMBUFFER_##SERVICE##_##RESULT + (uint8_t)isMessageBuffer) + +#define TRACE_GET_TASK_OBJECT_EVENT_CODE(SERVICE, RESULT, pxTCB) (uint8_t)(EVENTGROUP_##SERVICE##_##RESULT + TRACE_CLASS_TASK) +#define TRACE_GET_QUEUE_OBJECT_EVENT_CODE(SERVICE, RESULT, pxObject) (uint8_t)(EVENTGROUP_##SERVICE##_##RESULT + TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, pxObject)) +#define TRACE_GET_TIMER_OBJECT_EVENT_CODE(SERVICE, RESULT, UNUSED) -- THIS IS NOT USED -- +#define TRACE_GET_EVENTGROUP_OBJECT_EVENT_CODE(SERVICE, RESULT, UNUSED) -- THIS IS NOT USED -- +#define TRACE_GET_STREAMBUFFER_OBJECT_EVENT_CODE(SERVICE, RESULT, pxObject) (uint8_t)(TRACE_STREAMBUFFER_##SERVICE##_##RESULT + prvGetStreamBufferType(pxObject)) + +/* Generic versions */ +#define TRACE_GET_CLASS_EVENT_CODE(SERVICE, RESULT, CLASS, kernelClass) TRACE_GET_##CLASS##_CLASS_EVENT_CODE(SERVICE, RESULT, kernelClass) +#define TRACE_GET_OBJECT_EVENT_CODE(SERVICE, RESULT, CLASS, pxObject) TRACE_GET_##CLASS##_OBJECT_EVENT_CODE(SERVICE, RESULT, pxObject) + +/****************************** +* SPECIAL MACROS FOR TASKS * +******************************/ +#define TRACE_GET_TASK_PRIORITY(pxTCB) ((uint8_t)pxTCB->uxPriority) +#define TRACE_GET_TASK_NAME(pxTCB) ((char*)pxTCB->pcTaskName) -#define TRACE_SET_EVENTGROUP_NUMBER(eg) ((EventGroup_t*)eg)->uxEventGroupNumber = prvTraceGetObjectHandle(TRACE_CLASS_EVENTGROUP); - -#define TRACE_GET_OBJECT_NUMBER(CLASS, pxObject) (prvTraceGetObjectNumber(pxObject)) - -#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_8_X) - #define TRACE_SET_OBJECT_NUMBER(CLASS, pxObject) pxObject->ucQueueNumber = prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject)); -#else - #define TRACE_SET_OBJECT_NUMBER(CLASS, pxObject) pxObject->uxQueueNumber = prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject)); -#endif - -#define TRACE_GET_CLASS_EVENT_CODE(SERVICE, RESULT, CLASS, kernelClass) (uint8_t)(EVENTGROUP_##SERVICE##_##RESULT + TRACE_GET_CLASS_TRACE_CLASS(CLASS, kernelClass)) -#define TRACE_GET_OBJECT_EVENT_CODE(SERVICE, RESULT, CLASS, pxObject) (uint8_t)(EVENTGROUP_##SERVICE##_##RESULT + TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject)) -#define TRACE_GET_TASK_EVENT_CODE(SERVICE, RESULT, CLASS, pxTCB) (uint8_t)(EVENTGROUP_##SERVICE##_##RESULT + TRACE_CLASS_TASK) - -/*** The trace macros for snapshot mode **************************************/ - -#ifdef configUSE_TICKLESS_IDLE -#if (configUSE_TICKLESS_IDLE != 0) - -#undef traceLOW_POWER_IDLE_BEGIN -#define traceLOW_POWER_IDLE_BEGIN() \ - { \ - extern uint32_t trace_disable_timestamp; \ - prvTraceStoreLowPower(0); \ - trace_disable_timestamp = 1; \ - } - -#undef traceLOW_POWER_IDLE_END -#define traceLOW_POWER_IDLE_END() \ - { \ - extern uint32_t trace_disable_timestamp; \ - trace_disable_timestamp = 0; \ - prvTraceStoreLowPower(1); \ - } - -#endif /* configUSE_TICKLESS_IDLE != 0 */ -#endif /* configUSE_TICKLESS_IDLE */ +/*** The trace macros for snapshot mode **************************************/ /* A macro that will update the tick count when returning from tickless idle */ #undef traceINCREASE_TICK_COUNT @@ -574,7 +832,7 @@ extern traceObjectClass TraceObjectClassTable[5]; /* Called on each OS tick. Will call uiPortGetTimestamp to make sure it is called at least once every OS tick. */ #undef traceTASK_INCREMENT_TICK -#if (TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_7_3_OR_7_4) +#if (TRC_CFG_FREERTOS_VERSION <= TRC_FREERTOS_VERSION_7_4) #define traceTASK_INCREMENT_TICK( xTickCount ) \ if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || uxMissedTicks == 0) { trcKERNEL_HOOKS_INCREMENT_TICK(); } \ @@ -591,7 +849,52 @@ extern traceObjectClass TraceObjectClassTable[5]; /* Called on each task-switch */ #undef traceTASK_SWITCHED_IN #define traceTASK_SWITCHED_IN() \ - trcKERNEL_HOOKS_TASK_SWITCH(TRACE_GET_CURRENT_TASK()); + trcKERNEL_HOOKS_TASK_SWITCH(TRACE_GET_CURRENT_TASK()); + +/* Called on vTaskCreate */ +#undef traceTASK_CREATE +#define traceTASK_CREATE(pxNewTCB) \ + if (pxNewTCB != NULL) \ + { \ + trcKERNEL_HOOKS_TASK_CREATE(TRACE_GET_OBJECT_EVENT_CODE(CREATE_OBJ, TRCSUCCESS, TASK, pxNewTCB), TASK, pxNewTCB); \ + } + +/* Called in vTaskCreate, if it fails (typically if the stack can not be allocated) */ +#undef traceTASK_CREATE_FAILED +#define traceTASK_CREATE_FAILED() \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY(TRACE_GET_CLASS_EVENT_CODE(CREATE_OBJ, TRCFAILED, TASK, NOT_USED), 0); + +/* Called on vTaskDelete */ +#undef traceTASK_DELETE +#define traceTASK_DELETE( pxTaskToDelete ) \ + { TRACE_ALLOC_CRITICAL_SECTION(); \ + TRACE_ENTER_CRITICAL_SECTION(); \ + trcKERNEL_HOOKS_TASK_DELETE(TRACE_GET_OBJECT_EVENT_CODE(DELETE_OBJ, TRCSUCCESS, TASK, pxTaskToDelete), TRACE_GET_OBJECT_EVENT_CODE(OBJCLOSE_NAME, TRCSUCCESS, TASK, pxTaskToDelete), TRACE_GET_OBJECT_EVENT_CODE(OBJCLOSE_PROP, TRCSUCCESS, TASK, pxTaskToDelete), pxTaskToDelete); \ + TRACE_EXIT_CRITICAL_SECTION(); } + +#if (TRC_CFG_SCHEDULING_ONLY == 0) + +#if defined(configUSE_TICKLESS_IDLE) +#if (configUSE_TICKLESS_IDLE != 0) + +#undef traceLOW_POWER_IDLE_BEGIN +#define traceLOW_POWER_IDLE_BEGIN() \ + { \ + extern uint32_t trace_disable_timestamp; \ + prvTraceStoreLowPower(0); \ + trace_disable_timestamp = 1; \ + } + +#undef traceLOW_POWER_IDLE_END +#define traceLOW_POWER_IDLE_END() \ + { \ + extern uint32_t trace_disable_timestamp; \ + trace_disable_timestamp = 0; \ + prvTraceStoreLowPower(1); \ + } + +#endif /* (configUSE_TICKLESS_IDLE != 0) */ +#endif /* defined(configUSE_TICKLESS_IDLE) */ /* Called on vTaskSuspend */ #undef traceTASK_SUSPEND @@ -612,135 +915,152 @@ extern traceObjectClass TraceObjectClassTable[5]; /* Called on vTaskDelayUntil - note the use of FreeRTOS variable xTimeToWake */ #undef traceTASK_DELAY_UNTIL -#if TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_X +#if TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 #define traceTASK_DELAY_UNTIL(xTimeToWake) \ trcKERNEL_HOOKS_TASK_DELAY(TASK_DELAY_UNTIL, pxCurrentTCB, xTimeToWake); \ trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); -#else /* TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_X */ +#else /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */ #define traceTASK_DELAY_UNTIL() \ trcKERNEL_HOOKS_TASK_DELAY(TASK_DELAY_UNTIL, pxCurrentTCB, xTimeToWake); \ trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); -#endif /* TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_X */ +#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */ -#if (TRC_CFG_INCLUDE_OBJECT_DELETE == 1) -/* Called on vTaskDelete */ -#undef traceTASK_DELETE -#define traceTASK_DELETE( pxTaskToDelete ) \ - { TRACE_ALLOC_CRITICAL_SECTION(); \ - TRACE_ENTER_CRITICAL_SECTION(); \ - trcKERNEL_HOOKS_TASK_DELETE(DELETE_OBJ, pxTaskToDelete); \ - TRACE_EXIT_CRITICAL_SECTION(); } +/* Called in xQueueCreate, and thereby for all other object based on queues, such as semaphores. */ +#undef traceQUEUE_CREATE +#define traceQUEUE_CREATE( pxNewQueue ) \ + trcKERNEL_HOOKS_OBJECT_CREATE(TRACE_GET_OBJECT_EVENT_CODE(CREATE_OBJ, TRCSUCCESS, QUEUE, pxNewQueue), QUEUE, pxNewQueue); + +/* Called in xQueueCreate, if the queue creation fails */ +#undef traceQUEUE_CREATE_FAILED +#define traceQUEUE_CREATE_FAILED( queueType ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY(TRACE_GET_CLASS_EVENT_CODE(CREATE_OBJ, TRCFAILED, QUEUE, queueType), 0); /* Called on vQueueDelete */ #undef traceQUEUE_DELETE #define traceQUEUE_DELETE( pxQueue ) \ { TRACE_ALLOC_CRITICAL_SECTION(); \ TRACE_ENTER_CRITICAL_SECTION(); \ - trcKERNEL_HOOKS_OBJECT_DELETE(DELETE_OBJ, TRC_UNUSED, pxQueue); \ + trcKERNEL_HOOKS_OBJECT_DELETE(TRACE_GET_OBJECT_EVENT_CODE(DELETE_OBJ, TRCSUCCESS, QUEUE, pxQueue), TRACE_GET_OBJECT_EVENT_CODE(OBJCLOSE_NAME, TRCSUCCESS, QUEUE, pxQueue), TRACE_GET_OBJECT_EVENT_CODE(OBJCLOSE_PROP, TRCSUCCESS, QUEUE, pxQueue), QUEUE, pxQueue); \ TRACE_EXIT_CRITICAL_SECTION(); } -#endif - -/* Called on vTaskCreate */ -#undef traceTASK_CREATE -#define traceTASK_CREATE(pxNewTCB) \ - if (pxNewTCB != NULL) \ - { \ - trcKERNEL_HOOKS_TASK_CREATE(CREATE_OBJ, TRC_UNUSED, pxNewTCB); \ - } - -/* Called in vTaskCreate, if it fails (typically if the stack can not be allocated) */ -#undef traceTASK_CREATE_FAILED -#define traceTASK_CREATE_FAILED() \ - trcKERNEL_HOOKS_TASK_CREATE_FAILED(CREATE_OBJ, TRC_UNUSED); - -/* Called in xQueueCreate, and thereby for all other object based on queues, such as semaphores. */ -#undef traceQUEUE_CREATE -#define traceQUEUE_CREATE( pxNewQueue )\ - trcKERNEL_HOOKS_OBJECT_CREATE(CREATE_OBJ, TRC_UNUSED, pxNewQueue); - -/* Called in xQueueCreate, if the queue creation fails */ -#undef traceQUEUE_CREATE_FAILED -#define traceQUEUE_CREATE_FAILED( queueType ) \ - trcKERNEL_HOOKS_OBJECT_CREATE_FAILED(CREATE_OBJ, TRC_UNUSED, queueType); /* This macro is not necessary as of FreeRTOS v9.0.0 */ -#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_X) +#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0) /* Called in xQueueCreateMutex, and thereby also from xSemaphoreCreateMutex and xSemaphoreCreateRecursiveMutex */ #undef traceCREATE_MUTEX #define traceCREATE_MUTEX( pxNewQueue ) \ - trcKERNEL_HOOKS_OBJECT_CREATE(CREATE_OBJ, TRC_UNUSED, pxNewQueue); + trcKERNEL_HOOKS_OBJECT_CREATE(TRACE_GET_OBJECT_EVENT_CODE(CREATE_OBJ, TRCSUCCESS, QUEUE, pxNewQueue), QUEUE, pxNewQueue); /* Called in xQueueCreateMutex when the operation fails (when memory allocation fails) */ #undef traceCREATE_MUTEX_FAILED #define traceCREATE_MUTEX_FAILED() \ - trcKERNEL_HOOKS_OBJECT_CREATE_FAILED(CREATE_OBJ, TRC_UNUSED, queueQUEUE_TYPE_MUTEX); -#endif /* (TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_X) */ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY(TRACE_GET_CLASS_EVENT_CODE(CREATE_OBJ, TRCFAILED, QUEUE, queueQUEUE_TYPE_MUTEX), 0); +#endif /* (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0) */ /* Called when the Mutex can not be given, since not holder */ #undef traceGIVE_MUTEX_RECURSIVE_FAILED #define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ) \ - trcKERNEL_HOOKS_KERNEL_SERVICE(SEND, FAILED, TRC_UNUSED, pxMutex); + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND, TRCFAILED, QUEUE, pxMutex), QUEUE, pxMutex); /* Called when a message is sent to a queue */ /* CS IS NEW ! */ #undef traceQUEUE_SEND #define traceQUEUE_SEND( pxQueue ) \ - trcKERNEL_HOOKS_KERNEL_SERVICE(SEND, SUCCESS, TRC_UNUSED, pxQueue); \ - trcKERNEL_HOOKS_SET_OBJECT_STATE(TRC_UNUSED, pxQueue, TRACE_GET_OBJECT_TRACE_CLASS(TRC_UNUSED, pxQueue) == TRACE_CLASS_MUTEX ? (uint8_t)0 : (uint8_t)(pxQueue->uxMessagesWaiting + 1)); + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND, TRCSUCCESS, QUEUE, pxQueue), QUEUE, pxQueue); \ + trcKERNEL_HOOKS_SET_OBJECT_STATE(QUEUE, pxQueue, TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, pxQueue) == TRACE_CLASS_MUTEX ? (uint8_t)0 : (uint8_t)(pxQueue->uxMessagesWaiting + 1)); /* Called when a message failed to be sent to a queue (timeout) */ #undef traceQUEUE_SEND_FAILED #define traceQUEUE_SEND_FAILED( pxQueue ) \ - trcKERNEL_HOOKS_KERNEL_SERVICE(SEND, FAILED, TRC_UNUSED, pxQueue); + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND, TRCFAILED, QUEUE, pxQueue), QUEUE, pxQueue); /* Called when the task is blocked due to a send operation on a full queue */ #undef traceBLOCKING_ON_QUEUE_SEND #define traceBLOCKING_ON_QUEUE_SEND( pxQueue ) \ - trcKERNEL_HOOKS_KERNEL_SERVICE(SEND, BLOCK, TRC_UNUSED, pxQueue); + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND, TRCBLOCK, QUEUE, pxQueue), QUEUE, pxQueue); /* Called when a message is received from a queue */ #undef traceQUEUE_RECEIVE #define traceQUEUE_RECEIVE( pxQueue ) \ - trcKERNEL_HOOKS_KERNEL_SERVICE(RECEIVE, SUCCESS, TRC_UNUSED, pxQueue); \ - trcKERNEL_HOOKS_SET_OBJECT_STATE(TRC_UNUSED, pxQueue, TRACE_GET_OBJECT_TRACE_CLASS(TRC_UNUSED, pxQueue) == TRACE_CLASS_MUTEX ? (uint8_t)TRACE_GET_TASK_NUMBER(TRACE_GET_CURRENT_TASK()) : (uint8_t)(pxQueue->uxMessagesWaiting - 1)); + if (isQueueReceiveHookActuallyPeek) \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(PEEK, TRCSUCCESS, QUEUE, pxQueue), QUEUE, pxQueue); \ + } \ + else \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE, TRCSUCCESS, QUEUE, pxQueue), QUEUE, pxQueue); \ + } \ + trcKERNEL_HOOKS_SET_OBJECT_STATE(QUEUE, pxQueue, TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, pxQueue) == TRACE_CLASS_MUTEX ? (uint8_t)TRACE_GET_TASK_NUMBER(TRACE_GET_CURRENT_TASK()) : (uint8_t)(pxQueue->uxMessagesWaiting - 1)); /* Called when a receive operation on a queue fails (timeout) */ #undef traceQUEUE_RECEIVE_FAILED #define traceQUEUE_RECEIVE_FAILED( pxQueue ) \ - trcKERNEL_HOOKS_KERNEL_SERVICE(RECEIVE, FAILED, TRC_UNUSED, pxQueue); + if (isQueueReceiveHookActuallyPeek) \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(PEEK, TRCFAILED, QUEUE, pxQueue), QUEUE, pxQueue); \ + } \ + else \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE, TRCFAILED, QUEUE, pxQueue), QUEUE, pxQueue); \ + } /* Called when the task is blocked due to a receive operation on an empty queue */ #undef traceBLOCKING_ON_QUEUE_RECEIVE #define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ) \ - trcKERNEL_HOOKS_KERNEL_SERVICE(RECEIVE, BLOCK, TRC_UNUSED, pxQueue); \ - if (TRACE_GET_OBJECT_TRACE_CLASS(TRC_UNUSED, pxQueue) != TRACE_CLASS_MUTEX) \ - {trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED();} + if (isQueueReceiveHookActuallyPeek) \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(PEEK, TRCBLOCK, QUEUE, pxQueue), QUEUE, pxQueue); \ + } \ + else \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE, TRCBLOCK, QUEUE, pxQueue), QUEUE, pxQueue); \ + } \ + if (TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, pxQueue) != TRACE_CLASS_MUTEX) \ + { \ + trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); \ + } /* Called on xQueuePeek */ #undef traceQUEUE_PEEK #define traceQUEUE_PEEK( pxQueue ) \ - trcKERNEL_HOOKS_KERNEL_SERVICE(PEEK, SUCCESS, TRC_UNUSED, pxQueue); + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(PEEK, TRCSUCCESS, QUEUE, pxQueue), QUEUE, pxQueue); + +/* Called on xQueuePeek fail/timeout (added in FreeRTOS v9.0.2) */ +#undef traceQUEUE_PEEK_FAILED +#define traceQUEUE_PEEK_FAILED( pxQueue ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(PEEK, TRCFAILED, QUEUE, pxQueue), QUEUE, pxQueue); + +/* Called on xQueuePeek blocking (added in FreeRTOS v9.0.2) */ +#undef traceBLOCKING_ON_QUEUE_PEEK +#define traceBLOCKING_ON_QUEUE_PEEK( pxQueue ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(PEEK, TRCBLOCK, QUEUE, pxQueue), QUEUE, pxQueue); \ + if (TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, pxQueue) != TRACE_CLASS_MUTEX) \ + { \ + trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); \ + } /* Called when a message is sent from interrupt context, e.g., using xQueueSendFromISR */ #undef traceQUEUE_SEND_FROM_ISR #define traceQUEUE_SEND_FROM_ISR( pxQueue ) \ - trcKERNEL_HOOKS_KERNEL_SERVICE(SEND_FROM_ISR, SUCCESS, TRC_UNUSED, pxQueue); \ - trcKERNEL_HOOKS_SET_OBJECT_STATE(TRC_UNUSED, pxQueue, (uint8_t)(pxQueue->uxMessagesWaiting + 1)); + trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(TRACE_GET_OBJECT_EVENT_CODE(SEND_FROM_ISR, TRCSUCCESS, QUEUE, pxQueue), QUEUE, pxQueue); \ + trcKERNEL_HOOKS_SET_OBJECT_STATE(QUEUE, pxQueue, (uint8_t)(pxQueue->uxMessagesWaiting + 1)); /* Called when a message send from interrupt context fails (since the queue was full) */ #undef traceQUEUE_SEND_FROM_ISR_FAILED #define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ) \ - trcKERNEL_HOOKS_KERNEL_SERVICE(SEND_FROM_ISR, FAILED, TRC_UNUSED, pxQueue); + trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(TRACE_GET_OBJECT_EVENT_CODE(SEND_FROM_ISR, TRCFAILED, QUEUE, pxQueue), QUEUE, pxQueue); /* Called when a message is received in interrupt context, e.g., using xQueueReceiveFromISR */ #undef traceQUEUE_RECEIVE_FROM_ISR #define traceQUEUE_RECEIVE_FROM_ISR( pxQueue ) \ - trcKERNEL_HOOKS_KERNEL_SERVICE(RECEIVE_FROM_ISR, SUCCESS, TRC_UNUSED, pxQueue); \ - trcKERNEL_HOOKS_SET_OBJECT_STATE(TRC_UNUSED, pxQueue, (uint8_t)(pxQueue->uxMessagesWaiting - 1)); + trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE_FROM_ISR, TRCSUCCESS, QUEUE, pxQueue), QUEUE, pxQueue); \ + trcKERNEL_HOOKS_SET_OBJECT_STATE(QUEUE, pxQueue, (uint8_t)(pxQueue->uxMessagesWaiting - 1)); /* Called when a message receive from interrupt context fails (since the queue was empty) */ #undef traceQUEUE_RECEIVE_FROM_ISR_FAILED #define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ) \ - trcKERNEL_HOOKS_KERNEL_SERVICE(RECEIVE_FROM_ISR, FAILED, TRC_UNUSED, pxQueue); + trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE_FROM_ISR, TRCFAILED, QUEUE, pxQueue), QUEUE, pxQueue); + +#undef traceQUEUE_REGISTRY_ADD +#define traceQUEUE_REGISTRY_ADD(object, name) prvTraceSetObjectName(TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, object), TRACE_GET_OBJECT_NUMBER(QUEUE, object), name); /* Called in vTaskPrioritySet */ #undef traceTASK_PRIORITY_SET @@ -765,332 +1085,302 @@ extern traceObjectClass TraceObjectClassTable[5]; /* Called in vTaskResumeFromISR */ #undef traceTASK_RESUME_FROM_ISR #define traceTASK_RESUME_FROM_ISR( pxTaskToResume ) \ - trcKERNEL_HOOKS_TASK_RESUME(TASK_RESUME_FROM_ISR, pxTaskToResume); + trcKERNEL_HOOKS_TASK_RESUME_FROM_ISR(TASK_RESUME_FROM_ISR, pxTaskToResume); #if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X) -#if (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1) +#if (TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1) extern void vTraceStoreMemMangEvent(uint32_t ecode, uint32_t address, int32_t size); +/* MALLOC and FREE are always stored, no matter if they happen inside filtered task */ #undef traceMALLOC -#define traceMALLOC( pvAddress, uiSize ) {if (pvAddress != 0) vTraceStoreMemMangEvent(MEM_MALLOC_SIZE, ( uint32_t ) pvAddress, (int32_t)uiSize); } +#define traceMALLOC( pvAddress, uiSize ) \ + if (pvAddress != 0) \ + vTraceStoreMemMangEvent(MEM_MALLOC_SIZE, ( uint32_t ) pvAddress, (int32_t)uiSize); #undef traceFREE -#define traceFREE( pvAddress, uiSize ) {vTraceStoreMemMangEvent(MEM_FREE_SIZE, ( uint32_t ) pvAddress, -((int32_t)uiSize)); } +#define traceFREE( pvAddress, uiSize ) \ + vTraceStoreMemMangEvent(MEM_FREE_SIZE, ( uint32_t ) pvAddress, -((int32_t)uiSize)); + +#endif /* (TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1) */ -#endif /* (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1) */ +#if (TRC_CFG_INCLUDE_TIMER_EVENTS == 1) /* Called in timer.c - xTimerCreate */ #undef traceTIMER_CREATE #define traceTIMER_CREATE(tmr) \ - trcKERNEL_HOOKS_TIMER_CREATE(TIMER_CREATE, tmr); + trcKERNEL_HOOKS_OBJECT_CREATE(TIMER_CREATE, TIMER, tmr); #undef traceTIMER_CREATE_FAILED #define traceTIMER_CREATE_FAILED() \ - trcKERNEL_HOOKS_TIMER_EVENT(TIMER_CREATE_FAILED, 0); + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY(TIMER_CREATE_TRCFAILED, 0); /* Note that xCommandID can never be tmrCOMMAND_EXECUTE_CALLBACK (-1) since the trace macro is not called in that case */ #undef traceTIMER_COMMAND_SEND #define traceTIMER_COMMAND_SEND(tmr, xCommandID, xOptionalValue, xReturn) \ -if (xCommandID > tmrCOMMAND_START_DONT_TRACE){\ - if (xCommandID == tmrCOMMAND_CHANGE_PERIOD){ prvTraceStoreKernelCallWithParam((xReturn == pdPASS) ? TIMER_CHANGE_PERIOD : TIMER_CHANGE_PERIOD_FAILED, TRACE_CLASS_TIMER, TRACE_GET_TIMER_NUMBER(tmr), xOptionalValue);}\ - else if ((xCommandID == tmrCOMMAND_DELETE) && (xReturn == pdPASS)){ trcKERNEL_HOOKS_TIMER_DELETE(TIMER_DELETE, tmr); } \ - else {trcKERNEL_HOOKS_TIMER_EVENT(EVENTGROUP_TIMER + (uint32_t)xCommandID + ((xReturn == pdPASS)?0:(TIMER_CREATE_FAILED - TIMER_CREATE)), tmr); }\ -} + if (xCommandID > tmrCOMMAND_START_DONT_TRACE) \ + { \ + if (xCommandID == tmrCOMMAND_CHANGE_PERIOD) \ + { \ + if (xReturn == pdPASS) { \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TIMER_CHANGE_PERIOD, TIMER, tmr, xOptionalValue); \ + } \ + else \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TIMER_CHANGE_PERIOD_TRCFAILED, TIMER, tmr, xOptionalValue); \ + } \ + } \ + else if ((xCommandID == tmrCOMMAND_DELETE) && (xReturn == pdPASS)) \ + { \ + trcKERNEL_HOOKS_OBJECT_DELETE(TIMER_DELETE_OBJ, EVENTGROUP_OBJCLOSE_NAME_TRCSUCCESS + TRACE_GET_OBJECT_TRACE_CLASS(TIMER, tmr), EVENTGROUP_OBJCLOSE_PROP_TRCSUCCESS + TRACE_GET_OBJECT_TRACE_CLASS(TIMER, tmr), TIMER, tmr); \ + } \ + else \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENTGROUP_TIMER + (uint32_t)xCommandID + ((xReturn == pdPASS) ? 0 : (TIMER_CREATE_TRCFAILED - TIMER_CREATE)), TIMER, tmr, xOptionalValue); \ + }\ + } + +#undef traceTIMER_EXPIRED +#define traceTIMER_EXPIRED(tmr) \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TIMER_EXPIRED, TIMER, tmr); + +#endif /* (TRC_CFG_INCLUDE_TIMER_EVENTS == 1) */ + +#if (TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS == 1) #undef tracePEND_FUNC_CALL #define tracePEND_FUNC_CALL(func, arg1, arg2, ret) \ -if (ret == pdPASS){ \ - prvTraceStoreKernelCall(PEND_FUNC_CALL, TRACE_CLASS_TASK, uxTaskGetTaskNumber(xTimerGetTimerDaemonTaskHandle()) ); \ -}else{ \ - prvTraceStoreKernelCall(PEND_FUNC_CALL_FAILED, TRACE_CLASS_TASK, uxTaskGetTaskNumber(xTimerGetTimerDaemonTaskHandle()) );} + if (ret == pdPASS){ \ + trcKERNEL_HOOKS_KERNEL_SERVICE(PEND_FUNC_CALL, TASK, xTimerGetTimerDaemonTaskHandle() ); \ + } \ + else \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE(PEND_FUNC_CALL_TRCFAILED, TASK, xTimerGetTimerDaemonTaskHandle() ); \ + } #undef tracePEND_FUNC_CALL_FROM_ISR #define tracePEND_FUNC_CALL_FROM_ISR(func, arg1, arg2, ret) \ - if (! uiInEventGroupSetBitsFromISR){ prvTraceStoreKernelCall(PEND_FUNC_CALL_FROM_ISR, TRACE_CLASS_TASK, uxTaskGetTaskNumber(xTimerGetTimerDaemonTaskHandle()) ); } \ + if (! uiInEventGroupSetBitsFromISR) \ + prvTraceStoreKernelCall(PEND_FUNC_CALL_FROM_ISR, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(xTimerGetTimerDaemonTaskHandle()) ); \ uiInEventGroupSetBitsFromISR = 0; +#endif /* (TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS == 1) */ + #endif /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X) */ +#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1) + #undef traceEVENT_GROUP_CREATE #define traceEVENT_GROUP_CREATE(eg) \ - TRACE_SET_EVENTGROUP_NUMBER(eg); \ - prvTraceStoreKernelCall(EVENT_GROUP_CREATE, TRACE_CLASS_EVENTGROUP, TRACE_GET_EVENTGROUP_NUMBER(eg)); - -#undef traceEVENT_GROUP_DELETE -#define traceEVENT_GROUP_DELETE(eg) \ - prvTraceStoreKernelCall(EVENT_GROUP_DELETE, TRACE_CLASS_EVENTGROUP, TRACE_GET_EVENTGROUP_NUMBER(eg)); \ - prvTraceStoreObjectNameOnCloseEvent(TRACE_GET_EVENTGROUP_NUMBER(eg), TRACE_CLASS_EVENTGROUP); \ - prvTraceStoreObjectPropertiesOnCloseEvent(TRACE_GET_EVENTGROUP_NUMBER(eg), TRACE_CLASS_EVENTGROUP); \ - prvTraceFreeObjectHandle(TRACE_CLASS_EVENTGROUP, TRACE_GET_EVENTGROUP_NUMBER(eg)); + trcKERNEL_HOOKS_OBJECT_CREATE(EVENT_GROUP_CREATE, EVENTGROUP, eg); #undef traceEVENT_GROUP_CREATE_FAILED #define traceEVENT_GROUP_CREATE_FAILED() \ - prvTraceStoreKernelCall(EVENT_GROUP_CREATE_FAILED, TRACE_CLASS_EVENTGROUP, 0); + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY(EVENT_GROUP_CREATE_TRCFAILED, 0); + +#undef traceEVENT_GROUP_DELETE +#define traceEVENT_GROUP_DELETE(eg) \ + { TRACE_ALLOC_CRITICAL_SECTION(); \ + TRACE_ENTER_CRITICAL_SECTION(); \ + trcKERNEL_HOOKS_OBJECT_DELETE(EVENT_GROUP_DELETE_OBJ, EVENTGROUP_OBJCLOSE_NAME_TRCSUCCESS + TRACE_GET_OBJECT_TRACE_CLASS(EVENTGROUP, eg), EVENTGROUP_OBJCLOSE_NAME_TRCSUCCESS + TRACE_GET_OBJECT_TRACE_CLASS(EVENTGROUP, eg), EVENTGROUP, eg); \ + TRACE_EXIT_CRITICAL_SECTION(); } #undef traceEVENT_GROUP_SYNC_BLOCK #define traceEVENT_GROUP_SYNC_BLOCK(eg, bitsToSet, bitsToWaitFor) \ - prvTraceStoreKernelCallWithParam(EVENT_GROUP_SYNC_BLOCK, TRACE_CLASS_EVENTGROUP, TRACE_GET_EVENTGROUP_NUMBER(eg), bitsToWaitFor); + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_SYNC_TRCBLOCK, EVENTGROUP, eg, bitsToWaitFor); #undef traceEVENT_GROUP_SYNC_END #define traceEVENT_GROUP_SYNC_END(eg, bitsToSet, bitsToWaitFor, wasTimeout) \ - if (wasTimeout){ prvTraceStoreKernelCallWithParam(EVENT_GROUP_SYNC_END_FAILED, TRACE_CLASS_EVENTGROUP, TRACE_GET_EVENTGROUP_NUMBER(eg), bitsToWaitFor);} \ - else{ prvTraceStoreKernelCallWithParam(EVENT_GROUP_SYNC_END, TRACE_CLASS_EVENTGROUP, TRACE_GET_EVENTGROUP_NUMBER(eg), bitsToWaitFor); } + if (wasTimeout) \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_SYNC_END_TRCFAILED, EVENTGROUP, eg, bitsToWaitFor); \ + } \ + else \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_SYNC_END, EVENTGROUP, eg, bitsToWaitFor); \ + } #undef traceEVENT_GROUP_WAIT_BITS_BLOCK #define traceEVENT_GROUP_WAIT_BITS_BLOCK(eg, bitsToWaitFor) \ - prvTraceStoreKernelCallWithParam(EVENT_GROUP_WAIT_BITS_BLOCK, TRACE_CLASS_EVENTGROUP, TRACE_GET_EVENTGROUP_NUMBER(eg), bitsToWaitFor); \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_WAIT_BITS_TRCBLOCK, EVENTGROUP, eg, bitsToWaitFor); \ trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); #undef traceEVENT_GROUP_WAIT_BITS_END #define traceEVENT_GROUP_WAIT_BITS_END(eg, bitsToWaitFor, wasTimeout) \ - if (wasTimeout){ prvTraceStoreKernelCallWithParam(EVENT_GROUP_WAIT_BITS_END_FAILED, TRACE_CLASS_EVENTGROUP, TRACE_GET_EVENTGROUP_NUMBER(eg), bitsToWaitFor); } \ - else{ prvTraceStoreKernelCallWithParam(EVENT_GROUP_WAIT_BITS_END, TRACE_CLASS_EVENTGROUP, TRACE_GET_EVENTGROUP_NUMBER(eg), bitsToWaitFor); } + if (wasTimeout) \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_WAIT_BITS_END_TRCFAILED, EVENTGROUP, eg, bitsToWaitFor); \ + } \ + else \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_WAIT_BITS_END, EVENTGROUP, eg, bitsToWaitFor); \ + } #undef traceEVENT_GROUP_CLEAR_BITS #define traceEVENT_GROUP_CLEAR_BITS(eg, bitsToClear) \ - if (bitsToClear) prvTraceStoreKernelCallWithParam(EVENT_GROUP_CLEAR_BITS, TRACE_CLASS_EVENTGROUP, TRACE_GET_EVENTGROUP_NUMBER(eg), bitsToClear); + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_CLEAR_BITS, EVENTGROUP, eg, bitsToClear); #undef traceEVENT_GROUP_CLEAR_BITS_FROM_ISR #define traceEVENT_GROUP_CLEAR_BITS_FROM_ISR(eg, bitsToClear) \ - if (bitsToClear) prvTraceStoreKernelCallWithParam(EVENT_GROUP_CLEAR_BITS_FROM_ISR, TRACE_CLASS_EVENTGROUP, TRACE_GET_EVENTGROUP_NUMBER(eg), bitsToClear); + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM_FROM_ISR(EVENT_GROUP_CLEAR_BITS_FROM_ISR, EVENTGROUP, eg, bitsToClear); #undef traceEVENT_GROUP_SET_BITS #define traceEVENT_GROUP_SET_BITS(eg, bitsToSet) \ - prvTraceStoreKernelCallWithParam(EVENT_GROUP_SET_BITS, TRACE_CLASS_EVENTGROUP, TRACE_GET_EVENTGROUP_NUMBER(eg), bitsToSet); + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_SET_BITS, EVENTGROUP, eg, bitsToSet); #undef traceEVENT_GROUP_SET_BITS_FROM_ISR #define traceEVENT_GROUP_SET_BITS_FROM_ISR(eg, bitsToSet) \ - prvTraceStoreKernelCallWithParam(EVENT_GROUP_SET_BITS_FROM_ISR, TRACE_CLASS_EVENTGROUP, TRACE_GET_EVENTGROUP_NUMBER(eg), bitsToSet); \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM_FROM_ISR(EVENT_GROUP_SET_BITS_FROM_ISR, EVENTGROUP, eg, bitsToSet); \ uiInEventGroupSetBitsFromISR = 1; +#endif /* (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1) */ + #undef traceTASK_NOTIFY_TAKE -#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_X) +#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0) #define traceTASK_NOTIFY_TAKE() \ if (pxCurrentTCB->eNotifyState == eNotified){ \ - prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_TAKE, TRACE_CLASS_TASK, uxTaskGetTaskNumber(pxCurrentTCB), xTicksToWait); \ - }else{ \ - prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_TAKE_FAILED, TRACE_CLASS_TASK, uxTaskGetTaskNumber(pxCurrentTCB), xTicksToWait);} -#else /* TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_X */ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TRACE_TASK_NOTIFY_TAKE, TASK, pxCurrentTCB, xTicksToWait); \ + } \ + else{ \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TRACE_TASK_NOTIFY_TAKE_TRCFAILED, TASK, pxCurrentTCB, xTicksToWait); \ + } +#else /* TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0 */ #define traceTASK_NOTIFY_TAKE() \ if (pxCurrentTCB->ucNotifyState == taskNOTIFICATION_RECEIVED){ \ - prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_TAKE, TRACE_CLASS_TASK, uxTaskGetTaskNumber(pxCurrentTCB), xTicksToWait); \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TRACE_TASK_NOTIFY_TAKE, TASK, pxCurrentTCB, xTicksToWait); \ }else{ \ - prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_TAKE_FAILED, TRACE_CLASS_TASK, uxTaskGetTaskNumber(pxCurrentTCB), xTicksToWait);} -#endif /* TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_X */ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TRACE_TASK_NOTIFY_TAKE_TRCFAILED, TASK, pxCurrentTCB, xTicksToWait);} +#endif /* TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0 */ #undef traceTASK_NOTIFY_TAKE_BLOCK #define traceTASK_NOTIFY_TAKE_BLOCK() \ - prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_TAKE_BLOCK, TRACE_CLASS_TASK, uxTaskGetTaskNumber(pxCurrentTCB), xTicksToWait); \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TRACE_TASK_NOTIFY_TAKE_TRCBLOCK, TASK, pxCurrentTCB, xTicksToWait); \ trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); #undef traceTASK_NOTIFY_WAIT -#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_X) +#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0) #define traceTASK_NOTIFY_WAIT() \ - if (pxCurrentTCB->eNotifyState == eNotified){ \ - prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT, TRACE_CLASS_TASK, uxTaskGetTaskNumber(pxCurrentTCB), xTicksToWait); \ - }else{ \ - prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT_FAILED, TRACE_CLASS_TASK, uxTaskGetTaskNumber(pxCurrentTCB), xTicksToWait);} -#else /* TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_X */ + if (TRACE_GET_TASK_FILTER(pxCurrentTCB) & CurrentFilterMask) \ + { \ + if (pxCurrentTCB->eNotifyState == eNotified) \ + prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxCurrentTCB), xTicksToWait); \ + else \ + prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT_TRCFAILED, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxCurrentTCB), xTicksToWait); \ + } +#else /* TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0 */ #define traceTASK_NOTIFY_WAIT() \ - if (pxCurrentTCB->ucNotifyState == taskNOTIFICATION_RECEIVED){ \ - prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT, TRACE_CLASS_TASK, uxTaskGetTaskNumber(pxCurrentTCB), xTicksToWait); \ - }else{ \ - prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT_FAILED, TRACE_CLASS_TASK, uxTaskGetTaskNumber(pxCurrentTCB), xTicksToWait); } -#endif /* TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_X */ + if (TRACE_GET_TASK_FILTER(pxCurrentTCB) & CurrentFilterMask) \ + { \ + if (pxCurrentTCB->ucNotifyState == taskNOTIFICATION_RECEIVED) \ + prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxCurrentTCB), xTicksToWait); \ + else \ + prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT_TRCFAILED, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxCurrentTCB), xTicksToWait); \ + } +#endif /* TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0 */ #undef traceTASK_NOTIFY_WAIT_BLOCK #define traceTASK_NOTIFY_WAIT_BLOCK() \ - prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT_BLOCK, TRACE_CLASS_TASK, uxTaskGetTaskNumber(pxCurrentTCB), xTicksToWait); \ + if (TRACE_GET_TASK_FILTER(pxCurrentTCB) & CurrentFilterMask) \ + prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT_TRCBLOCK, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxCurrentTCB), xTicksToWait); \ trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); #undef traceTASK_NOTIFY #define traceTASK_NOTIFY() \ - prvTraceStoreKernelCall(TRACE_TASK_NOTIFY, TRACE_CLASS_TASK, uxTaskGetTaskNumber(xTaskToNotify)); + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_TASK_FILTER(xTaskToNotify) & CurrentFilterMask) \ + prvTraceStoreKernelCall(TRACE_TASK_NOTIFY, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(xTaskToNotify)); #undef traceTASK_NOTIFY_FROM_ISR #define traceTASK_NOTIFY_FROM_ISR() \ - prvTraceStoreKernelCall(TRACE_TASK_NOTIFY_FROM_ISR, TRACE_CLASS_TASK, uxTaskGetTaskNumber(xTaskToNotify)); + if (TRACE_GET_TASK_FILTER(xTaskToNotify) & CurrentFilterMask) \ + prvTraceStoreKernelCall(TRACE_TASK_NOTIFY_FROM_ISR, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(xTaskToNotify)); #undef traceTASK_NOTIFY_GIVE_FROM_ISR #define traceTASK_NOTIFY_GIVE_FROM_ISR() \ - prvTraceStoreKernelCall(TRACE_TASK_NOTIFY_GIVE_FROM_ISR, TRACE_CLASS_TASK, uxTaskGetTaskNumber(xTaskToNotify)); + if (TRACE_GET_TASK_FILTER(xTaskToNotify) & CurrentFilterMask) \ + prvTraceStoreKernelCall(TRACE_TASK_NOTIFY_GIVE_FROM_ISR, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(xTaskToNotify)); -#undef traceQUEUE_REGISTRY_ADD -#define traceQUEUE_REGISTRY_ADD(object, name) prvTraceSetObjectName(TRACE_GET_OBJECT_TRACE_CLASS(TRC_UNUSED, object), TRACE_GET_OBJECT_NUMBER(TRC_UNUSED, object), name); +#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1) -/******************************************************************************* - * (macro) vTraceExcludeQueue(object) - * - * Parameter object: pointer to the Queue object that shall be excluded. - * - * Excludes all operations on this object from the trace. Allows for capturing - * longer traces the snapshot RAM buffer by filtering out irrelevant events. - ******************************************************************************/ -#define vTraceExcludeQueue(object) \ -TRACE_SET_QUEUE_FLAG_ISEXCLUDED(TRACE_GET_OBJECT_NUMBER(TRC_UNUSED, object)); +#undef traceSTREAM_BUFFER_CREATE +#define traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer ) \ + trcKERNEL_HOOKS_OBJECT_CREATE(TRACE_GET_OBJECT_EVENT_CODE(CREATE_OBJ, TRCSUCCESS, STREAMBUFFER, pxStreamBuffer), STREAMBUFFER, pxStreamBuffer); -/******************************************************************************* - * (macro) vTraceExcludeSemaphore(object) - * - * Parameter object: pointer to the Semaphore object that shall be excluded. - * - * Excludes all operations on this object from the trace. Allows for capturing - * longer traces the snapshot RAM buffer by filtering out irrelevant events. - * - * Note: Only for snapshot mode. - ******************************************************************************/ -#define vTraceExcludeSemaphore(object) \ -TRACE_SET_SEMAPHORE_FLAG_ISEXCLUDED(TRACE_GET_OBJECT_NUMBER(TRC_UNUSED, object)); +#undef traceSTREAM_BUFFER_CREATE_FAILED +#define traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY(TRACE_GET_CLASS_EVENT_CODE(CREATE_OBJ, TRCFAILED, STREAMBUFFER, xIsMessageBuffer), 0); -/******************************************************************************* - * (macro) vTraceExcludeMutex(object) - * - * Parameter object: pointer to the Mutex object that shall be excluded. - * - * Excludes all operations on this object from the trace. Allows for capturing - * longer traces the snapshot RAM buffer by filtering out irrelevant events. - * - * Note: Only for snapshot mode. - ******************************************************************************/ -#define vTraceExcludeMutex(object) \ -TRACE_SET_MUTEX_FLAG_ISEXCLUDED(TRACE_GET_OBJECT_NUMBER(TRC_UNUSED, object)); +#if 0 /*_RB_ Not defined anywhere*/ +#undef traceSTREAM_BUFFER_CREATE_STATIC_FAILED +#define traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer ) \ + traceSTREAM_BUFFER_CREATE_TRCFAILED( xIsMessageBuffer ) +#endif -/******************************************************************************* - * (macro) vTraceExcludeTimer(object) - * - * Parameter object: pointer to the Timer object that shall be excluded. - * - * Excludes all operations on this object from the trace. Allows for capturing - * longer traces the snapshot RAM buffer by filtering out irrelevant events. - * - * Note: Only for snapshot mode. - ******************************************************************************/ -#define vTraceExcludeTimer(object) \ -TRACE_SET_TIMER_FLAG_ISEXCLUDED(TRACE_GET_TIMER_NUMBER(object)); +#undef traceSTREAM_BUFFER_DELETE +#define traceSTREAM_BUFFER_DELETE( xStreamBuffer ) \ + trcKERNEL_HOOKS_OBJECT_DELETE(TRACE_GET_OBJECT_EVENT_CODE(DELETE_OBJ, TRCSUCCESS, STREAMBUFFER, xStreamBuffer), TRACE_GET_OBJECT_EVENT_CODE(OBJCLOSE_NAME, TRCSUCCESS, STREAMBUFFER, xStreamBuffer), TRACE_GET_OBJECT_EVENT_CODE(OBJCLOSE_PROP, TRCSUCCESS, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); -/******************************************************************************* - * (macro) vTraceExcludeEventGroup(object) - * - * Parameter object: pointer to the Event Group object that shall be excluded. - * - * Excludes all operations on this object from the trace. Allows for capturing - * longer traces the snapshot RAM buffer by filtering out irrelevant events. - * - * Note: Only for snapshot mode. - ******************************************************************************/ -#define vTraceExcludeEventGroup(object) \ -TRACE_SET_EVENTGROUP_FLAG_ISEXCLUDED(TRACE_GET_EVENTGROUP_NUMBER(object)); +#undef traceSTREAM_BUFFER_RESET +#define traceSTREAM_BUFFER_RESET( xStreamBuffer ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE(prvGetStreamBufferType(xStreamBuffer) > 0 ? TRACE_MESSAGEBUFFER_RESET : TRACE_STREAMBUFFER_RESET, STREAMBUFFER, xStreamBuffer); \ + trcKERNEL_HOOKS_SET_OBJECT_STATE(STREAMBUFFER, xStreamBuffer, 0); -/******************************************************************************* - * (macro) vTraceExcludeTask(object) - * - * Parameter object: pointer to the Task object that shall be excluded. - * - * Excludes all events from the specified task. Allows for capturing - * longer traces the snapshot RAM buffer by filtering out irrelevant events. - * - * Excluding tasks is problematic as the previous task will appear to continue - * executing while the excluded task is in fact executing. This therefore affects - * the timing statistics in an unpredictable way. - * Moreover, any operations on queues, semaphores, etc. made by an excluded task - * will also be excludes, so Tracealyzer will give an incorrect display regarding - * the states of these objects (number of messages in a queue, etc.). - * - * This should only be used on short tasks that don't affect other kernel objects - * of interest. - * - * Note: Only for snapshot mode. - ******************************************************************************/ -#define vTraceExcludeTask(object) \ -TRACE_SET_TASK_FLAG_ISEXCLUDED(TRACE_GET_TASK_NUMBER(object)); +#undef traceSTREAM_BUFFER_SEND +#define traceSTREAM_BUFFER_SEND( xStreamBuffer, xReturn ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND, TRCSUCCESS, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); \ + trcKERNEL_HOOKS_SET_OBJECT_STATE(STREAMBUFFER, xStreamBuffer, prvBytesInBuffer(xStreamBuffer)); + +#undef traceBLOCKING_ON_STREAM_BUFFER_SEND +#define traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND, TRCBLOCK, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); -/****************************************************************************** - * (macro) vTraceExcludeDelays() - * - * Excludes all Delay operations from the trace. Allows for capturing - * longer traces the snapshot RAM buffer. - * - * Note: Only for snapshot mode. - *****************************************************************************/ -#define vTraceExcludeDelays() \ -TRACE_SET_EVENT_CODE_FLAG_ISEXCLUDED(TASK_DELAY); \ -TRACE_SET_EVENT_CODE_FLAG_ISEXCLUDED(TASK_DELAY_UNTIL); - -/*** Private helper macros for exclude functionality ************************/ - -#define TRACE_SET_QUEUE_FLAG_ISEXCLUDED(queueIndex) TRACE_SET_FLAG_ISEXCLUDED(trcExcludedObjects, queueIndex) -#define TRACE_CLEAR_QUEUE_FLAG_ISEXCLUDED(queueIndex) TRACE_CLEAR_FLAG_ISEXCLUDED(trcExcludedObjects, queueIndex) -#define TRACE_GET_QUEUE_FLAG_ISEXCLUDED(queueIndex) TRACE_GET_FLAG_ISEXCLUDED(trcExcludedObjects, queueIndex) - -#define TRACE_SET_SEMAPHORE_FLAG_ISEXCLUDED(semaphoreIndex) TRACE_SET_FLAG_ISEXCLUDED(trcExcludedObjects, TRC_CFG_NQUEUE+1+semaphoreIndex) -#define TRACE_CLEAR_SEMAPHORE_FLAG_ISEXCLUDED(semaphoreIndex) TRACE_CLEAR_FLAG_ISEXCLUDED(trcExcludedObjects, TRC_CFG_NQUEUE+1+semaphoreIndex) -#define TRACE_GET_SEMAPHORE_FLAG_ISEXCLUDED(semaphoreIndex) TRACE_GET_FLAG_ISEXCLUDED(trcExcludedObjects, TRC_CFG_NQUEUE+1+semaphoreIndex) - -#define TRACE_SET_MUTEX_FLAG_ISEXCLUDED(mutexIndex) TRACE_SET_FLAG_ISEXCLUDED(trcExcludedObjects, TRC_CFG_NQUEUE+1+TRC_CFG_NSEMAPHORE+1+mutexIndex) -#define TRACE_CLEAR_MUTEX_FLAG_ISEXCLUDED(mutexIndex) TRACE_CLEAR_FLAG_ISEXCLUDED(trcExcludedObjects, TRC_CFG_NQUEUE+1+TRC_CFG_NSEMAPHORE+1+mutexIndex) -#define TRACE_GET_MUTEX_FLAG_ISEXCLUDED(mutexIndex) TRACE_GET_FLAG_ISEXCLUDED(trcExcludedObjects, TRC_CFG_NQUEUE+1+TRC_CFG_NSEMAPHORE+1+mutexIndex) - -#define TRACE_SET_TASK_FLAG_ISEXCLUDED(taskIndex) TRACE_SET_FLAG_ISEXCLUDED(trcExcludedObjects, TRC_CFG_NQUEUE+1+TRC_CFG_NSEMAPHORE+1+TRC_CFG_NMUTEX+1+taskIndex) -#define TRACE_CLEAR_TASK_FLAG_ISEXCLUDED(taskIndex) TRACE_CLEAR_FLAG_ISEXCLUDED(trcExcludedObjects, TRC_CFG_NQUEUE+1+TRC_CFG_NSEMAPHORE+1+TRC_CFG_NMUTEX+1+taskIndex) -#define TRACE_GET_TASK_FLAG_ISEXCLUDED(taskIndex) TRACE_GET_FLAG_ISEXCLUDED(trcExcludedObjects, TRC_CFG_NQUEUE+1+TRC_CFG_NSEMAPHORE+1+TRC_CFG_NMUTEX+1+taskIndex) - -#define TRACE_SET_TIMER_FLAG_ISEXCLUDED(timerIndex) TRACE_SET_FLAG_ISEXCLUDED(trcExcludedObjects, TRC_CFG_NQUEUE+1+TRC_CFG_NSEMAPHORE+1+TRC_CFG_NMUTEX+1+TRC_CFG_NTASK+1+timerIndex) -#define TRACE_CLEAR_TIMER_FLAG_ISEXCLUDED(timerIndex) TRACE_CLEAR_FLAG_ISEXCLUDED(trcExcludedObjects, TRC_CFG_NQUEUE+1+TRC_CFG_NSEMAPHORE+1+TRC_CFG_NMUTEX+1+TRC_CFG_NTASK+1+timerIndex) -#define TRACE_GET_TIMER_FLAG_ISEXCLUDED(timerIndex) TRACE_GET_FLAG_ISEXCLUDED(trcExcludedObjects, TRC_CFG_NQUEUE+1+TRC_CFG_NSEMAPHORE+1+TRC_CFG_NMUTEX+1+TRC_CFG_NTASK+1+timerIndex) - -#define TRACE_SET_EVENTGROUP_FLAG_ISEXCLUDED(egIndex) TRACE_SET_FLAG_ISEXCLUDED(trcExcludedObjects, TRC_CFG_NQUEUE+1+TRC_CFG_NSEMAPHORE+1+TRC_CFG_NMUTEX+1+TRC_CFG_NTASK+1+TRC_CFG_NTIMER+1+egIndex) -#define TRACE_CLEAR_EVENTGROUP_FLAG_ISEXCLUDED(egIndex) TRACE_CLEAR_FLAG_ISEXCLUDED(trcExcludedObjects, TRC_CFG_NQUEUE+1+TRC_CFG_NSEMAPHORE+1+TRC_CFG_NMUTEX+1+TRC_CFG_NTASK+1+TRC_CFG_NTIMER+1+egIndex) -#define TRACE_GET_EVENTGROUP_FLAG_ISEXCLUDED(egIndex) TRACE_GET_FLAG_ISEXCLUDED(trcExcludedObjects, TRC_CFG_NQUEUE+1+TRC_CFG_NSEMAPHORE+1+TRC_CFG_NMUTEX+1+TRC_CFG_NTASK+1+TRC_CFG_NTIMER+1+egIndex) - - -#define TRACE_CLEAR_OBJECT_FLAG_ISEXCLUDED(objectclass, handle) \ -switch (objectclass) \ -{ \ -case TRACE_CLASS_QUEUE: \ - TRACE_CLEAR_QUEUE_FLAG_ISEXCLUDED(handle); \ - break; \ -case TRACE_CLASS_SEMAPHORE: \ - TRACE_CLEAR_SEMAPHORE_FLAG_ISEXCLUDED(handle); \ - break; \ -case TRACE_CLASS_MUTEX: \ - TRACE_CLEAR_MUTEX_FLAG_ISEXCLUDED(handle); \ - break; \ -case TRACE_CLASS_TASK: \ - TRACE_CLEAR_TASK_FLAG_ISEXCLUDED(handle); \ - break; \ -case TRACE_CLASS_TIMER: \ - TRACE_CLEAR_TIMER_FLAG_ISEXCLUDED(handle); \ - break; \ -case TRACE_CLASS_EVENTGROUP: \ - TRACE_CLEAR_EVENTGROUP_FLAG_ISEXCLUDED(handle); \ - break; \ -} +#undef traceSTREAM_BUFFER_SEND_FAILED +#define traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND, TRCFAILED, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); -#define TRACE_SET_OBJECT_FLAG_ISEXCLUDED(objectclass, handle) \ -switch (objectclass) \ -{ \ -case TRACE_CLASS_QUEUE: \ - TRACE_SET_QUEUE_FLAG_ISEXCLUDED(handle); \ - break; \ -case TRACE_CLASS_SEMAPHORE: \ - TRACE_SET_SEMAPHORE_FLAG_ISEXCLUDED(handle); \ - break; \ -case TRACE_CLASS_MUTEX: \ - TRACE_SET_MUTEX_FLAG_ISEXCLUDED(handle); \ - break; \ -case TRACE_CLASS_TASK: \ - TRACE_SET_TASK_FLAG_ISEXCLUDED(handle); \ - break; \ -case TRACE_CLASS_TIMER: \ - TRACE_SET_TIMER_FLAG_ISEXCLUDED(handle); \ - break; \ -case TRACE_CLASS_EVENTGROUP: \ - TRACE_SET_EVENTGROUP_FLAG_ISEXCLUDED(handle); \ - break; \ -} +#undef traceSTREAM_BUFFER_RECEIVE +#define traceSTREAM_BUFFER_RECEIVE( xStreamBuffer, xReceivedLength ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE, TRCSUCCESS, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); \ + trcKERNEL_HOOKS_SET_OBJECT_STATE(STREAMBUFFER, xStreamBuffer, prvBytesInBuffer(xStreamBuffer)); + + +#undef traceBLOCKING_ON_STREAM_BUFFER_RECEIVE +#define traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE, TRCBLOCK, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); + +#undef traceSTREAM_BUFFER_RECEIVE_FAILED +#define traceSTREAM_BUFFER_RECEIVE_FAILED( xStreamBuffer ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE, TRCFAILED, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); + +#undef traceSTREAM_BUFFER_SEND_FROM_ISR +#define traceSTREAM_BUFFER_SEND_FROM_ISR( xStreamBuffer, xReturn ) \ + if( xReturn > ( size_t ) 0 ) \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(TRACE_GET_OBJECT_EVENT_CODE(SEND_FROM_ISR, TRCSUCCESS, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); \ + trcKERNEL_HOOKS_SET_OBJECT_STATE(STREAMBUFFER, xStreamBuffer, prvBytesInBuffer(xStreamBuffer)); \ + } \ + else \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(TRACE_GET_OBJECT_EVENT_CODE(SEND_FROM_ISR, TRCFAILED, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); \ + } + +#undef traceSTREAM_BUFFER_RECEIVE_FROM_ISR +#define traceSTREAM_BUFFER_RECEIVE_FROM_ISR( xStreamBuffer, xReceivedLength ) \ + if( xReceivedLength > ( size_t ) 0 ) \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE_FROM_ISR, TRCSUCCESS, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); \ + trcKERNEL_HOOKS_SET_OBJECT_STATE(STREAMBUFFER, xStreamBuffer, prvBytesInBuffer(xStreamBuffer)); \ + } \ + else \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE_FROM_ISR, TRCFAILED, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); \ + } + +#endif /* (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1) */ + +#endif /* (TRC_CFG_SCHEDULING_ONLY == 0) */ #endif /*#if TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT */ @@ -1106,20 +1396,6 @@ case TRACE_CLASS_EVENTGROUP: \ ******************************************************************************/ void vTraceStoreKernelObjectName(void* object, const char* name); -/******************************************************************************* - * prvTraceOnBegin - * - * Called on trace begin. - ******************************************************************************/ -void prvTraceOnBegin(void); - -/******************************************************************************* - * prvTraceOnEnd - * - * Called on trace end. - ******************************************************************************/ -void prvTraceOnEnd(void); - /******************************************************************************* * prvIsNewTCB * @@ -1157,6 +1433,8 @@ uint32_t prvIsNewTCB(void* pNewTCB); #define PSF_EVENT_EVENTGROUP_CREATE 0x15 #define PSF_EVENT_SEMAPHORE_COUNTING_CREATE 0x16 #define PSF_EVENT_MUTEX_RECURSIVE_CREATE 0x17 +#define PSF_EVENT_STREAMBUFFER_CREATE 0x18 +#define PSF_EVENT_MESSAGEBUFFER_CREATE 0x19 #define PSF_EVENT_TASK_DELETE 0x20 #define PSF_EVENT_QUEUE_DELETE 0x21 @@ -1164,6 +1442,8 @@ uint32_t prvIsNewTCB(void* pNewTCB); #define PSF_EVENT_MUTEX_DELETE 0x23 #define PSF_EVENT_TIMER_DELETE 0x24 #define PSF_EVENT_EVENTGROUP_DELETE 0x25 +#define PSF_EVENT_STREAMBUFFER_DELETE 0x28 +#define PSF_EVENT_MESSAGEBUFFER_DELETE 0x29 #define PSF_EVENT_TASK_READY 0x30 #define PSF_EVENT_NEW_TIME 0x31 @@ -1191,6 +1471,8 @@ uint32_t prvIsNewTCB(void* pNewTCB); #define PSF_EVENT_EVENTGROUP_CREATE_FAILED 0x45 #define PSF_EVENT_SEMAPHORE_COUNTING_CREATE_FAILED 0x46 #define PSF_EVENT_MUTEX_RECURSIVE_CREATE_FAILED 0x47 +#define PSF_EVENT_STREAMBUFFER_CREATE_FAILED 0x49 +#define PSF_EVENT_MESSAGEBUFFER_CREATE_FAILED 0x4A #define PSF_EVENT_TIMER_DELETE_FAILED 0x48 @@ -1231,16 +1513,16 @@ uint32_t prvIsNewTCB(void* pNewTCB); #define PSF_EVENT_SEMAPHORE_TAKE_FROMISR_FAILED 0x6D #define PSF_EVENT_QUEUE_PEEK 0x70 -#define PSF_EVENT_SEMAPHORE_PEEK 0x71 /* Will never be used */ -#define PSF_EVENT_MUTEX_PEEK 0x72 /* Will never be used */ +#define PSF_EVENT_SEMAPHORE_PEEK 0x71 +#define PSF_EVENT_MUTEX_PEEK 0x72 #define PSF_EVENT_QUEUE_PEEK_FAILED 0x73 -#define PSF_EVENT_SEMAPHORE_PEEK_FAILED 0x74 /* Will never be used */ -#define PSF_EVENT_MUTEX_PEEK_FAILED 0x75 /* Will never be used */ +#define PSF_EVENT_SEMAPHORE_PEEK_FAILED 0x74 +#define PSF_EVENT_MUTEX_PEEK_FAILED 0x75 #define PSF_EVENT_QUEUE_PEEK_BLOCK 0x76 -#define PSF_EVENT_SEMAPHORE_PEEK_BLOCK 0x77 /* Will never be used */ -#define PSF_EVENT_MUTEX_PEEK_BLOCK 0x78 /* Will never be used */ +#define PSF_EVENT_SEMAPHORE_PEEK_BLOCK 0x77 +#define PSF_EVENT_MUTEX_PEEK_BLOCK 0x78 #define PSF_EVENT_TASK_DELAY_UNTIL 0x79 #define PSF_EVENT_TASK_DELAY 0x7A @@ -1303,248 +1585,383 @@ uint32_t prvIsNewTCB(void* pNewTCB); #define PSF_EVENT_TASK_NOTIFY_FROM_ISR 0xD0 #define PSF_EVENT_TASK_NOTIFY_GIVE_FROM_ISR 0xD1 -/*** The trace macros for streaming ******************************************/ - -#if (defined(configUSE_TICKLESS_IDLE) && configUSE_TICKLESS_IDLE != 0) - -#undef traceLOW_POWER_IDLE_BEGIN -#define traceLOW_POWER_IDLE_BEGIN() \ - { \ - prvTraceStoreEvent1(PSF_EVENT_LOWPOWER_BEGIN, xExpectedIdleTime); \ - } - -#undef traceLOW_POWER_IDLE_END -#define traceLOW_POWER_IDLE_END() \ - { \ - prvTraceStoreEvent0(PSF_EVENT_LOWPOWER_END); \ - } +#define PSF_EVENT_TIMER_EXPIRED 0xD2 + +#define PSF_EVENT_STREAMBUFFER_SEND 0xD3 +#define PSF_EVENT_STREAMBUFFER_SEND_BLOCK 0xD4 +#define PSF_EVENT_STREAMBUFFER_SEND_FAILED 0xD5 +#define PSF_EVENT_STREAMBUFFER_RECEIVE 0xD6 +#define PSF_EVENT_STREAMBUFFER_RECEIVE_BLOCK 0xD7 +#define PSF_EVENT_STREAMBUFFER_RECEIVE_FAILED 0xD8 +#define PSF_EVENT_STREAMBUFFER_SEND_FROM_ISR 0xD9 +#define PSF_EVENT_STREAMBUFFER_SEND_FROM_ISR_FAILED 0xDA +#define PSF_EVENT_STREAMBUFFER_RECEIVE_FROM_ISR 0xDB +#define PSF_EVENT_STREAMBUFFER_RECEIVE_FROM_ISR_FAILED 0xDC +#define PSF_EVENT_STREAMBUFFER_RESET 0xDD + +#define PSF_EVENT_MESSAGEBUFFER_SEND 0xDE +#define PSF_EVENT_MESSAGEBUFFER_SEND_BLOCK 0xDF +#define PSF_EVENT_MESSAGEBUFFER_SEND_FAILED 0xE0 +#define PSF_EVENT_MESSAGEBUFFER_RECEIVE 0xE1 +#define PSF_EVENT_MESSAGEBUFFER_RECEIVE_BLOCK 0xE2 +#define PSF_EVENT_MESSAGEBUFFER_RECEIVE_FAILED 0xE3 +#define PSF_EVENT_MESSAGEBUFFER_SEND_FROM_ISR 0xE4 +#define PSF_EVENT_MESSAGEBUFFER_SEND_FROM_ISR_FAILED 0xE5 +#define PSF_EVENT_MESSAGEBUFFER_RECEIVE_FROM_ISR 0xE6 +#define PSF_EVENT_MESSAGEBUFFER_RECEIVE_FROM_ISR_FAILED 0xE7 +#define PSF_EVENT_MESSAGEBUFFER_RESET 0xE8 -#endif +/*** The trace macros for streaming ******************************************/ /* A macro that will update the tick count when returning from tickless idle */ #undef traceINCREASE_TICK_COUNT /* Note: This can handle time adjustments of max 2^32 ticks, i.e., 35 seconds at 120 MHz. Thus, tick-less idle periods longer than 2^32 ticks will appear "compressed" on the time line.*/ #define traceINCREASE_TICK_COUNT( xCount ) { extern uint32_t uiTraceTickCount; uiTraceTickCount += xCount; } -/* Called for each task that becomes ready */ -#undef traceMOVED_TASK_TO_READY_STATE -#define traceMOVED_TASK_TO_READY_STATE( pxTCB ) \ - prvTraceStoreEvent1(PSF_EVENT_TASK_READY, (uint32_t)pxTCB); +#if (TRC_CFG_INCLUDE_OSTICK_EVENTS == 1) +#define OS_TICK_EVENT(uxSchedulerSuspended, xTickCount) if (uxSchedulerSuspended == (unsigned portBASE_TYPE) pdFALSE) { prvTraceStoreEvent1(PSF_EVENT_NEW_TIME, (uint32_t)(xTickCount + 1)); } +#else +#define OS_TICK_EVENT(uxSchedulerSuspended, xTickCount) +#endif /* Called on each OS tick. Will call uiPortGetTimestamp to make sure it is called at least once every OS tick. */ #undef traceTASK_INCREMENT_TICK -#if TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_7_3_OR_7_4 +#if TRC_CFG_FREERTOS_VERSION <= TRC_FREERTOS_VERSION_7_4 #define traceTASK_INCREMENT_TICK( xTickCount ) \ if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || uxMissedTicks == 0) { extern uint32_t uiTraceTickCount; uiTraceTickCount++; } \ - if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE) { prvTraceStoreEvent1(PSF_EVENT_NEW_TIME, (uint32_t)(xTickCount + 1)); } -#else /* TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_7_3_OR_7_4 */ + OS_TICK_EVENT(uxSchedulerSuspended, xTickCount) +#else #define traceTASK_INCREMENT_TICK( xTickCount ) \ if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || uxPendedTicks == 0) { extern uint32_t uiTraceTickCount; uiTraceTickCount++; } \ - if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE) { prvTraceStoreEvent1(PSF_EVENT_NEW_TIME, (uint32_t)(xTickCount + 1)); } -#endif /* TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_7_3_OR_7_4 */ + OS_TICK_EVENT(uxSchedulerSuspended, xTickCount) +#endif /* TRC_CFG_FREERTOS_VERSION <= TRC_FREERTOS_VERSION_7_4 */ /* Called on each task-switch */ #undef traceTASK_SWITCHED_IN #define traceTASK_SWITCHED_IN() \ - if (prvIsNewTCB(pxCurrentTCB)) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ { \ - prvTraceStoreEvent2(PSF_EVENT_TASK_ACTIVATE, (uint32_t)pxCurrentTCB, pxCurrentTCB->uxPriority); \ + if (prvIsNewTCB(pxCurrentTCB)) \ + { \ + prvTraceStoreEvent2(PSF_EVENT_TASK_ACTIVATE, (uint32_t)pxCurrentTCB, pxCurrentTCB->uxPriority); \ + } \ } -/* Called on vTaskSuspend */ -#undef traceTASK_SUSPEND -#define traceTASK_SUSPEND( pxTaskToSuspend ) \ - prvTraceStoreEvent1(PSF_EVENT_TASK_SUSPEND, (uint32_t)pxTaskToSuspend); - -/* Called on vTaskDelay - note the use of FreeRTOS variable xTicksToDelay */ -#undef traceTASK_DELAY -#define traceTASK_DELAY() \ - prvTraceStoreEvent1(PSF_EVENT_TASK_DELAY, xTicksToDelay); - -/* Called on vTaskDelayUntil - note the use of FreeRTOS variable xTimeToWake */ -#undef traceTASK_DELAY_UNTIL -#if TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_X -#define traceTASK_DELAY_UNTIL(xTimeToWake) \ - prvTraceStoreEvent1(PSF_EVENT_TASK_DELAY_UNTIL, (uint32_t)xTimeToWake); -#else /* TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_X */ -#define traceTASK_DELAY_UNTIL() \ - prvTraceStoreEvent1(PSF_EVENT_TASK_DELAY_UNTIL, (uint32_t)xTimeToWake); -#endif /* TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_X */ - -/* Called on vTaskDelete */ -#undef traceTASK_DELETE -#define traceTASK_DELETE( pxTaskToDelete ) \ - prvTraceStoreEvent2(PSF_EVENT_TASK_DELETE, (uint32_t)pxTaskToDelete, (pxTaskToDelete != NULL) ? (pxTaskToDelete->uxPriority) : 0); \ - prvTraceDeleteSymbol(pxTaskToDelete); \ - prvTraceDeleteObjectData(pxTaskToDelete); - -/* Called on vQueueDelete */ -#undef traceQUEUE_DELETE -#define traceQUEUE_DELETE( pxQueue ) \ - switch (pxQueue->ucQueueType) \ - { \ - case queueQUEUE_TYPE_BASE: \ - prvTraceStoreEvent2(PSF_EVENT_QUEUE_DELETE, (uint32_t)pxQueue, (pxQueue != NULL) ? (pxQueue->uxMessagesWaiting) : 0); \ - break; \ - case queueQUEUE_TYPE_MUTEX: \ - case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ - prvTraceStoreEvent2(PSF_EVENT_MUTEX_DELETE, (uint32_t)pxQueue, (pxQueue != NULL) ? (pxQueue->uxMessagesWaiting) : 0); \ - break; \ - case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ - case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ - prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_DELETE, (uint32_t)pxQueue, (pxQueue != NULL) ? (pxQueue->uxMessagesWaiting) : 0); \ - break; \ - } \ - prvTraceDeleteSymbol(pxQueue); +/* Called for each task that becomes ready */ +#if (TRC_CFG_INCLUDE_READY_EVENTS == 1) +#undef traceMOVED_TASK_TO_READY_STATE +#define traceMOVED_TASK_TO_READY_STATE( pxTCB ) \ + if (TRACE_GET_TASK_FILTER(pxTCB) & CurrentFilterMask) \ + prvTraceStoreEvent1(PSF_EVENT_TASK_READY, (uint32_t)pxTCB); +#endif -/* Called on vTaskCreate */ #undef traceTASK_CREATE -#if TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_X +#if TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 #define traceTASK_CREATE(pxNewTCB) \ if (pxNewTCB != NULL) \ { \ prvTraceSaveSymbol(pxNewTCB, pxNewTCB->pcTaskName); \ prvTraceSaveObjectData(pxNewTCB, pxNewTCB->uxPriority); \ prvTraceStoreStringEvent(1, PSF_EVENT_OBJ_NAME, pxNewTCB->pcTaskName, pxNewTCB); \ - prvTraceStoreEvent2(PSF_EVENT_TASK_CREATE, (uint32_t)pxNewTCB, pxNewTCB->uxPriority); \ + TRACE_SET_TASK_FILTER(pxNewTCB, CurrentFilterGroup); \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_TASK_FILTER(pxNewTCB) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_TASK_CREATE, (uint32_t)pxNewTCB, pxNewTCB->uxPriority); \ } -#else /* TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_X */ +#else /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */ #define traceTASK_CREATE(pxNewTCB) \ if (pxNewTCB != NULL) \ { \ prvTraceSaveSymbol(pxNewTCB, (const char*)pcName); \ prvTraceSaveObjectData(pxNewTCB, uxPriority); \ - prvTraceStoreStringEvent(1, PSF_EVENT_OBJ_NAME, pcName, pxNewTCB); \ - prvTraceStoreEvent2(PSF_EVENT_TASK_CREATE, (uint32_t)pxNewTCB, uxPriority); \ + prvTraceStoreStringEvent(1, PSF_EVENT_OBJ_NAME, (const char*)pcName, pxNewTCB); \ + TRACE_SET_TASK_FILTER(pxNewTCB, CurrentFilterGroup); \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_TASK_FILTER(pxNewTCB) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_TASK_CREATE, (uint32_t)pxNewTCB, uxPriority); \ } -#endif /* TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_X */ +#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */ /* Called in vTaskCreate, if it fails (typically if the stack can not be allocated) */ #undef traceTASK_CREATE_FAILED #define traceTASK_CREATE_FAILED() \ - prvTraceStoreEvent0(PSF_EVENT_TASK_CREATE_FAILED); + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + prvTraceStoreEvent0(PSF_EVENT_TASK_CREATE_FAILED); + +/* Called on vTaskDelete */ +#undef traceTASK_DELETE // We don't allow for filtering out "delete" events. They are important and not very frequent. Moreover, we can't exclude create events, so this should be symmetrical. +#define traceTASK_DELETE( pxTaskToDelete ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_TASK_FILTER(pxTaskToDelete) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_TASK_DELETE, (uint32_t)pxTaskToDelete, (pxTaskToDelete != NULL) ? (pxTaskToDelete->uxPriority) : 0); \ + prvTraceDeleteSymbol(pxTaskToDelete); \ + prvTraceDeleteObjectData(pxTaskToDelete); + +#if (TRC_CFG_SCHEDULING_ONLY == 0) + +#if (defined(configUSE_TICKLESS_IDLE) && configUSE_TICKLESS_IDLE != 0) + +#undef traceLOW_POWER_IDLE_BEGIN +#define traceLOW_POWER_IDLE_BEGIN() \ + { \ + prvTraceStoreEvent1(PSF_EVENT_LOWPOWER_BEGIN, xExpectedIdleTime); \ + } + +#undef traceLOW_POWER_IDLE_END +#define traceLOW_POWER_IDLE_END() \ + { \ + prvTraceStoreEvent0(PSF_EVENT_LOWPOWER_END); \ + } + +#endif /* (defined(configUSE_TICKLESS_IDLE) && configUSE_TICKLESS_IDLE != 0) */ + +/* Called on vTaskSuspend */ +#undef traceTASK_SUSPEND +#define traceTASK_SUSPEND( pxTaskToSuspend ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_TASK_FILTER(pxTaskToSuspend) & CurrentFilterMask) \ + prvTraceStoreEvent1(PSF_EVENT_TASK_SUSPEND, (uint32_t)pxTaskToSuspend); + +/* Called on vTaskDelay - note the use of FreeRTOS variable xTicksToDelay */ +#undef traceTASK_DELAY +#define traceTASK_DELAY() \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + prvTraceStoreEvent1(PSF_EVENT_TASK_DELAY, xTicksToDelay); + +/* Called on vTaskDelayUntil - note the use of FreeRTOS variable xTimeToWake */ +#undef traceTASK_DELAY_UNTIL +#if TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 +#define traceTASK_DELAY_UNTIL(xTimeToWake) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + prvTraceStoreEvent1(PSF_EVENT_TASK_DELAY_UNTIL, (uint32_t)xTimeToWake); +#else /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */ +#define traceTASK_DELAY_UNTIL() \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + prvTraceStoreEvent1(PSF_EVENT_TASK_DELAY_UNTIL, (uint32_t)xTimeToWake); +#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */ + +#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0) +#define traceQUEUE_CREATE_HELPER() \ + case queueQUEUE_TYPE_MUTEX: \ + prvTraceStoreEvent1(PSF_EVENT_MUTEX_CREATE, (uint32_t)pxNewQueue); \ + break; \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + prvTraceStoreEvent1(PSF_EVENT_MUTEX_RECURSIVE_CREATE, (uint32_t)pxNewQueue); \ + break; +#else +#define traceQUEUE_CREATE_HELPER() +#endif /* (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0) */ /* Called in xQueueCreate, and thereby for all other object based on queues, such as semaphores. */ #undef traceQUEUE_CREATE #define traceQUEUE_CREATE( pxNewQueue )\ - switch (pxNewQueue->ucQueueType) \ + TRACE_SET_OBJECT_FILTER(QUEUE, pxNewQueue, CurrentFilterGroup); \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ { \ - case queueQUEUE_TYPE_BASE: \ - prvTraceStoreEvent2(PSF_EVENT_QUEUE_CREATE, (uint32_t)pxNewQueue, pxNewQueue->uxLength); \ - break; \ - case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ - prvTraceStoreEvent1(PSF_EVENT_SEMAPHORE_BINARY_CREATE, (uint32_t)pxNewQueue); \ - break; \ + if (TRACE_GET_OBJECT_FILTER(QUEUE, pxNewQueue) & CurrentFilterMask) \ + { \ + switch (pxNewQueue->ucQueueType) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent2(PSF_EVENT_QUEUE_CREATE, (uint32_t)pxNewQueue, uxQueueLength); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + prvTraceStoreEvent1(PSF_EVENT_SEMAPHORE_BINARY_CREATE, (uint32_t)pxNewQueue); \ + break; \ + traceQUEUE_CREATE_HELPER() \ + } \ + } \ } +#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0) +#define traceQUEUE_CREATE_FAILED_HELPER() \ + case queueQUEUE_TYPE_MUTEX: \ + prvTraceStoreEvent1(PSF_EVENT_MUTEX_CREATE_FAILED, 0); \ + break; \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + prvTraceStoreEvent1(PSF_EVENT_MUTEX_RECURSIVE_CREATE_FAILED, 0); \ + break; +#else +#define traceQUEUE_CREATE_FAILED_HELPER() +#endif /* (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0) */ + /* Called in xQueueCreate, if the queue creation fails */ #undef traceQUEUE_CREATE_FAILED #define traceQUEUE_CREATE_FAILED( queueType ) \ - switch (queueType) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ { \ - case queueQUEUE_TYPE_BASE: \ - prvTraceStoreEvent0(PSF_EVENT_QUEUE_CREATE_FAILED); \ - break; \ - case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ - prvTraceStoreEvent0(PSF_EVENT_SEMAPHORE_BINARY_CREATE_FAILED); \ - break; \ + switch (queueType) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent2(PSF_EVENT_QUEUE_CREATE_FAILED, 0, uxQueueLength); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + prvTraceStoreEvent1(PSF_EVENT_SEMAPHORE_BINARY_CREATE_FAILED, 0); \ + break; \ + traceQUEUE_CREATE_FAILED_HELPER() \ + } \ } +#undef traceQUEUE_DELETE // We don't allow for filtering out "delete" events. They are important and not very frequent. Moreover, we can't exclude create events, so this should be symmetrical. +#define traceQUEUE_DELETE( pxQueue ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + { \ + if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \ + { \ + switch (pxQueue->ucQueueType) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent2(PSF_EVENT_QUEUE_DELETE, (uint32_t)pxQueue, (pxQueue != NULL) ? (pxQueue->uxMessagesWaiting) : 0); \ + break; \ + case queueQUEUE_TYPE_MUTEX: \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + prvTraceStoreEvent2(PSF_EVENT_MUTEX_DELETE, (uint32_t)pxQueue, (pxQueue != NULL) ? (pxQueue->uxMessagesWaiting) : 0); \ + break; \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_DELETE, (uint32_t)pxQueue, (pxQueue != NULL) ? (pxQueue->uxMessagesWaiting) : 0); \ + break; \ + } \ + } \ + } \ + prvTraceDeleteSymbol(pxQueue); + /* Called in xQueueCreateCountingSemaphore, if the queue creation fails */ #undef traceCREATE_COUNTING_SEMAPHORE -#if TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_8_X || TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_X +#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X) +#define traceCREATE_COUNTING_SEMAPHORE() \ + TRACE_SET_OBJECT_FILTER(QUEUE, xHandle, CurrentFilterGroup); \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(QUEUE, xHandle) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE, (uint32_t)xHandle, uxMaxCount) +#elif (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_7_5_OR_7_6) #define traceCREATE_COUNTING_SEMAPHORE() \ - prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE, (uint32_t)xHandle, ((Queue_t *) xHandle)->uxMessagesWaiting); -#else /* TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_8_X || TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_X */ + TRACE_SET_OBJECT_FILTER(QUEUE, xHandle, CurrentFilterGroup); \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(QUEUE, xHandle) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE, (uint32_t)xHandle, uxInitialCount); +#elif (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_7_4) #define traceCREATE_COUNTING_SEMAPHORE() \ - prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE, (uint32_t)pxHandle, pxHandle->uxMessagesWaiting); -#endif /* TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_8_X || TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_X */ + TRACE_SET_OBJECT_FILTER(QUEUE, xHandle, CurrentFilterGroup); \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(QUEUE, xHandle) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE, (uint32_t)xHandle, uxCountValue); +#else +#define traceCREATE_COUNTING_SEMAPHORE() \ + TRACE_SET_OBJECT_FILTER(QUEUE, pxHandle, CurrentFilterGroup); \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(QUEUE, pxHandle) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE, (uint32_t)pxHandle, uxCountValue); +#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X */ #undef traceCREATE_COUNTING_SEMAPHORE_FAILED +#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X) +#define traceCREATE_COUNTING_SEMAPHORE_FAILED() \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE_FAILED, 0, uxMaxCount); +#elif (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_7_5_OR_7_6) #define traceCREATE_COUNTING_SEMAPHORE_FAILED() \ - prvTraceStoreEvent0(PSF_EVENT_SEMAPHORE_COUNTING_CREATE_FAILED); + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE_FAILED, 0, uxInitialCount); +#elif (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_7_4) +#define traceCREATE_COUNTING_SEMAPHORE_FAILED() \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE_FAILED, 0, uxCountValue); +#else +#define traceCREATE_COUNTING_SEMAPHORE_FAILED() \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE_FAILED, 0, uxCountValue); +#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X */ + +/* This macro is not necessary as of FreeRTOS v9.0.0 */ +#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0) /* Called in xQueueCreateMutex, and thereby also from xSemaphoreCreateMutex and xSemaphoreCreateRecursiveMutex */ #undef traceCREATE_MUTEX #define traceCREATE_MUTEX( pxNewQueue ) \ - switch (pxNewQueue->ucQueueType) \ + TRACE_SET_OBJECT_FILTER(QUEUE, pxNewQueue, CurrentFilterGroup); \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ { \ - case queueQUEUE_TYPE_MUTEX: \ - prvTraceStoreEvent1(PSF_EVENT_MUTEX_CREATE, (uint32_t)pxNewQueue); \ - break; \ - case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ - prvTraceStoreEvent1(PSF_EVENT_MUTEX_RECURSIVE_CREATE, (uint32_t)pxNewQueue); \ - break; \ + if (TRACE_GET_OBJECT_FILTER(QUEUE, pxNewQueue) & CurrentFilterMask) \ + { \ + switch (pxNewQueue->ucQueueType) \ + { \ + case queueQUEUE_TYPE_MUTEX: \ + prvTraceStoreEvent1(PSF_EVENT_MUTEX_CREATE, (uint32_t)pxNewQueue); \ + break; \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + prvTraceStoreEvent1(PSF_EVENT_MUTEX_RECURSIVE_CREATE, (uint32_t)pxNewQueue); \ + break; \ + } \ + }\ } /* Called in xQueueCreateMutex when the operation fails (when memory allocation fails) */ #undef traceCREATE_MUTEX_FAILED #define traceCREATE_MUTEX_FAILED() \ - prvTraceStoreEvent0(PSF_EVENT_MUTEX_CREATE_FAILED); + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + prvTraceStoreEvent1(PSF_EVENT_MUTEX_CREATE_FAILED, 0); +#endif /* (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0) */ /* Called when a message is sent to a queue */ /* CS IS NEW ! */ #undef traceQUEUE_SEND #define traceQUEUE_SEND( pxQueue ) \ - switch (pxQueue->ucQueueType) \ - { \ - case queueQUEUE_TYPE_BASE: \ - prvTraceStoreEvent2(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND : PSF_EVENT_QUEUE_SEND_FRONT, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting + 1); \ - break; \ - case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ - case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ - prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_GIVE, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting + 1); \ - break; \ - case queueQUEUE_TYPE_MUTEX: \ - case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ - prvTraceStoreEvent1(PSF_EVENT_MUTEX_GIVE, (uint32_t)pxQueue); \ - break; \ - } + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \ + switch (pxQueue->ucQueueType) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent2(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND : PSF_EVENT_QUEUE_SEND_FRONT, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting + 1); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_GIVE, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting + 1); \ + break; \ + case queueQUEUE_TYPE_MUTEX: \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + prvTraceStoreEvent1(PSF_EVENT_MUTEX_GIVE, (uint32_t)pxQueue); \ + break; \ + } /* Called when a message failed to be sent to a queue (timeout) */ #undef traceQUEUE_SEND_FAILED #define traceQUEUE_SEND_FAILED( pxQueue ) \ - switch (pxQueue->ucQueueType) \ - { \ - case queueQUEUE_TYPE_BASE: \ - prvTraceStoreEvent2(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND_FAILED : PSF_EVENT_QUEUE_SEND_FRONT_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \ - break; \ - case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ - case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ - prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_GIVE_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \ - break; \ - case queueQUEUE_TYPE_MUTEX: \ - case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ - prvTraceStoreEvent1(PSF_EVENT_MUTEX_GIVE_FAILED, (uint32_t)pxQueue); \ - break; \ - } + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \ + switch (pxQueue->ucQueueType) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent2(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND_FAILED : PSF_EVENT_QUEUE_SEND_FRONT_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_GIVE_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \ + break; \ + case queueQUEUE_TYPE_MUTEX: \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + prvTraceStoreEvent1(PSF_EVENT_MUTEX_GIVE_FAILED, (uint32_t)pxQueue); \ + break; \ + } /* Called when the task is blocked due to a send operation on a full queue */ #undef traceBLOCKING_ON_QUEUE_SEND #define traceBLOCKING_ON_QUEUE_SEND( pxQueue ) \ - switch (pxQueue->ucQueueType) \ - { \ - case queueQUEUE_TYPE_BASE: \ - prvTraceStoreEvent2(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND_BLOCK : PSF_EVENT_QUEUE_SEND_FRONT_BLOCK, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \ - break; \ - case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ - case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ - prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_GIVE_BLOCK, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \ - break; \ - case queueQUEUE_TYPE_MUTEX: \ - case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ - prvTraceStoreEvent1(PSF_EVENT_MUTEX_GIVE_BLOCK, (uint32_t)pxQueue); \ - break; \ - } - -/* Called for Recursive Mutex */ -#undef traceGIVE_MUTEX_RECURSIVE -#define traceGIVE_MUTEX_RECURSIVE( pxMutex ) \ - prvTraceStoreEvent1(PSF_EVENT_MUTEX_GIVE_RECURSIVE, (uint32_t)pxMutex); - -/* Called for Recursive Mutex */ -#undef traceGIVE_MUTEX_RECURSIVE_FAILED -#define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ) \ - prvTraceStoreEvent1(PSF_EVENT_MUTEX_GIVE_RECURSIVE_FAILED, (uint32_t)pxMutex); + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \ + switch (pxQueue->ucQueueType) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent2(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND_BLOCK : PSF_EVENT_QUEUE_SEND_FRONT_BLOCK, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_GIVE_BLOCK, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \ + break; \ + case queueQUEUE_TYPE_MUTEX: \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + prvTraceStoreEvent1(PSF_EVENT_MUTEX_GIVE_BLOCK, (uint32_t)pxQueue); \ + break; \ + } /**************************************************************************/ /* Makes sure xQueueGiveFromISR also has a xCopyPosition parameter */ @@ -1571,234 +1988,314 @@ BaseType_t MyWrapper(__a, __b, const BaseType_t xCopyPosition) /* Called when a message is sent from interrupt context, e.g., using xQueueSendFromISR */ #undef traceQUEUE_SEND_FROM_ISR #define traceQUEUE_SEND_FROM_ISR( pxQueue ) \ - switch (pxQueue->ucQueueType) \ - { \ - case queueQUEUE_TYPE_BASE: \ - prvTraceStoreEvent2(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND_FROMISR : PSF_EVENT_QUEUE_SEND_FRONT_FROMISR, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting + 1); \ - break; \ - case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ - case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ - prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_GIVE_FROMISR, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting + 1); \ - break; \ - } + if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \ + switch (pxQueue->ucQueueType) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent2(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND_FROMISR : PSF_EVENT_QUEUE_SEND_FRONT_FROMISR, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting + 1); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_GIVE_FROMISR, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting + 1); \ + break; \ + } /* Called when a message send from interrupt context fails (since the queue was full) */ #undef traceQUEUE_SEND_FROM_ISR_FAILED #define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ) \ - switch (pxQueue->ucQueueType) \ - { \ - case queueQUEUE_TYPE_BASE: \ - prvTraceStoreEvent2(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND_FROMISR_FAILED : PSF_EVENT_QUEUE_SEND_FRONT_FROMISR_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \ - break; \ - case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ - case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ - prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_GIVE_FROMISR_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \ - break; \ - } + if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \ + switch (pxQueue->ucQueueType) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent2(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND_FROMISR_FAILED : PSF_EVENT_QUEUE_SEND_FRONT_FROMISR_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_GIVE_FROMISR_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \ + break; \ + } /* Called when a message is received from a queue */ #undef traceQUEUE_RECEIVE #define traceQUEUE_RECEIVE( pxQueue ) \ - switch (pxQueue->ucQueueType) \ - { \ - case queueQUEUE_TYPE_BASE: \ - prvTraceStoreEvent3(PSF_EVENT_QUEUE_RECEIVE, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting - 1); \ - break; \ - case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ - case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ - prvTraceStoreEvent3(PSF_EVENT_SEMAPHORE_TAKE, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting - 1); \ - break; \ - case queueQUEUE_TYPE_MUTEX: \ - case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ - prvTraceStoreEvent2(PSF_EVENT_MUTEX_TAKE, (uint32_t)pxQueue, xTicksToWait); \ - break; \ - } + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \ + switch (pxQueue->ucQueueType) \ + { \ + case queueQUEUE_TYPE_BASE: \ + if (isQueueReceiveHookActuallyPeek) \ + prvTraceStoreEvent3(PSF_EVENT_QUEUE_PEEK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting - 1); \ + else\ + prvTraceStoreEvent3(PSF_EVENT_QUEUE_RECEIVE, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting - 1); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + if (isQueueReceiveHookActuallyPeek) \ + prvTraceStoreEvent3(PSF_EVENT_SEMAPHORE_PEEK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting - 1); \ + else \ + prvTraceStoreEvent3(PSF_EVENT_SEMAPHORE_TAKE, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting - 1); \ + break; \ + case queueQUEUE_TYPE_MUTEX: \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + if (isQueueReceiveHookActuallyPeek) \ + prvTraceStoreEvent2(PSF_EVENT_MUTEX_PEEK, (uint32_t)pxQueue, xTicksToWait); \ + else \ + prvTraceStoreEvent2(PSF_EVENT_MUTEX_TAKE, (uint32_t)pxQueue, xTicksToWait); \ + break; \ + } /* Called when a receive operation on a queue fails (timeout) */ #undef traceQUEUE_RECEIVE_FAILED #define traceQUEUE_RECEIVE_FAILED( pxQueue ) \ - switch (pxQueue->ucQueueType) \ - { \ - case queueQUEUE_TYPE_BASE: \ - prvTraceStoreEvent3(xJustPeeking == pdFALSE ? PSF_EVENT_QUEUE_RECEIVE_FAILED : PSF_EVENT_QUEUE_PEEK_FAILED, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \ - break; \ - case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ - case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ - prvTraceStoreEvent3(xJustPeeking == pdFALSE ? PSF_EVENT_SEMAPHORE_TAKE_FAILED : PSF_EVENT_SEMAPHORE_PEEK_FAILED, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \ - break; \ - case queueQUEUE_TYPE_MUTEX: \ - case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ - prvTraceStoreEvent2(xJustPeeking == pdFALSE ? PSF_EVENT_MUTEX_TAKE_FAILED : PSF_EVENT_MUTEX_PEEK_FAILED, (uint32_t)pxQueue, xTicksToWait); \ - break; \ - } + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \ + switch (pxQueue->ucQueueType) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent3(isQueueReceiveHookActuallyPeek ? PSF_EVENT_QUEUE_PEEK_FAILED : PSF_EVENT_QUEUE_RECEIVE_FAILED, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent3(isQueueReceiveHookActuallyPeek ? PSF_EVENT_SEMAPHORE_PEEK_FAILED : PSF_EVENT_SEMAPHORE_TAKE_FAILED, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \ + break; \ + case queueQUEUE_TYPE_MUTEX: \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + prvTraceStoreEvent2(isQueueReceiveHookActuallyPeek ? PSF_EVENT_MUTEX_PEEK_FAILED : PSF_EVENT_MUTEX_TAKE_FAILED, (uint32_t)pxQueue, xTicksToWait); \ + break; \ + } /* Called when the task is blocked due to a receive operation on an empty queue */ #undef traceBLOCKING_ON_QUEUE_RECEIVE #define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ) \ - switch (pxQueue->ucQueueType) \ - { \ - case queueQUEUE_TYPE_BASE: \ - prvTraceStoreEvent3(xJustPeeking == pdFALSE ? PSF_EVENT_QUEUE_RECEIVE_BLOCK : PSF_EVENT_QUEUE_PEEK_BLOCK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \ - break; \ - case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ - case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ - prvTraceStoreEvent3(xJustPeeking == pdFALSE ? PSF_EVENT_SEMAPHORE_TAKE_BLOCK : PSF_EVENT_SEMAPHORE_PEEK_BLOCK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \ - break; \ - case queueQUEUE_TYPE_MUTEX: \ - case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ - prvTraceStoreEvent2(xJustPeeking == pdFALSE ? PSF_EVENT_MUTEX_TAKE_BLOCK : PSF_EVENT_MUTEX_PEEK_BLOCK, (uint32_t)pxQueue, xTicksToWait); \ - break; \ - } - -#undef traceTAKE_MUTEX_RECURSIVE -#if TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_8_X || TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_X -#define traceTAKE_MUTEX_RECURSIVE( pxQueue ) \ - prvTraceStoreEvent2(PSF_EVENT_MUTEX_TAKE_RECURSIVE, (uint32_t)pxQueue, xTicksToWait); -#else /* TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_8_X || TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_X */ -#define traceTAKE_MUTEX_RECURSIVE( pxQueue ) \ - prvTraceStoreEvent2(PSF_EVENT_MUTEX_TAKE_RECURSIVE, (uint32_t)pxQueue, xBlockTime); -#endif /* TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_8_X || TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_X */ - -#undef traceTAKE_MUTEX_RECURSIVE_FAILED -#if TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_8_X || TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_X -#define traceTAKE_MUTEX_RECURSIVE_FAILED( pxQueue ) \ - prvTraceStoreEvent2(PSF_EVENT_MUTEX_TAKE_RECURSIVE_FAILED, (uint32_t)pxQueue, xTicksToWait); -#else /* TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_8_X || TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_X */ -#define traceTAKE_MUTEX_RECURSIVE_FAILED( pxQueue ) \ - prvTraceStoreEvent2(PSF_EVENT_MUTEX_TAKE_RECURSIVE_FAILED, (uint32_t)pxQueue, xBlockTime); -#endif /* TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_8_X || TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_X */ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \ + switch (pxQueue->ucQueueType) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent3(isQueueReceiveHookActuallyPeek ? PSF_EVENT_QUEUE_PEEK_BLOCK : PSF_EVENT_QUEUE_RECEIVE_BLOCK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent3(isQueueReceiveHookActuallyPeek ? PSF_EVENT_SEMAPHORE_PEEK_BLOCK : PSF_EVENT_SEMAPHORE_TAKE_BLOCK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \ + break; \ + case queueQUEUE_TYPE_MUTEX: \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + prvTraceStoreEvent2(isQueueReceiveHookActuallyPeek ? PSF_EVENT_MUTEX_PEEK_BLOCK : PSF_EVENT_MUTEX_TAKE_BLOCK, (uint32_t)pxQueue, xTicksToWait); \ + break; \ + } + +#if (TRC_CFG_FREERTOS_VERSION > TRC_FREERTOS_VERSION_9_0_1) +/* Called when a peek operation on a queue fails (timeout) */ +#undef traceQUEUE_PEEK_FAILED +#define traceQUEUE_PEEK_FAILED( pxQueue ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \ + switch (pxQueue->ucQueueType) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent3(PSF_EVENT_QUEUE_PEEK_FAILED, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent3(PSF_EVENT_SEMAPHORE_PEEK_FAILED, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \ + break; \ + case queueQUEUE_TYPE_MUTEX: \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + prvTraceStoreEvent2(PSF_EVENT_MUTEX_PEEK_FAILED, (uint32_t)pxQueue, xTicksToWait); \ + break; \ + } + +/* Called when the task is blocked due to a peek operation on an empty queue */ +#undef traceBLOCKING_ON_QUEUE_PEEK +#define traceBLOCKING_ON_QUEUE_PEEK( pxQueue ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \ + switch (pxQueue->ucQueueType) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent3(PSF_EVENT_QUEUE_PEEK_BLOCK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent3(PSF_EVENT_SEMAPHORE_PEEK_BLOCK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \ + break; \ + case queueQUEUE_TYPE_MUTEX: \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + prvTraceStoreEvent2(PSF_EVENT_MUTEX_PEEK_BLOCK, (uint32_t)pxQueue, xTicksToWait); \ + break; \ + } + +#endif /* (TRC_CFG_FREERTOS_VERSION > TRC_FREERTOS_VERSION_9_0_1) */ /* Called when a message is received in interrupt context, e.g., using xQueueReceiveFromISR */ #undef traceQUEUE_RECEIVE_FROM_ISR #define traceQUEUE_RECEIVE_FROM_ISR( pxQueue ) \ -switch (pxQueue->ucQueueType) \ - { \ - case queueQUEUE_TYPE_BASE: \ - prvTraceStoreEvent2(PSF_EVENT_QUEUE_RECEIVE_FROMISR, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting - 1); \ - break; \ - case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ - case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ - prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_TAKE_FROMISR, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting - 1); \ - break; \ - } + if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \ + switch (pxQueue->ucQueueType) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent2(PSF_EVENT_QUEUE_RECEIVE_FROMISR, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting - 1); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_TAKE_FROMISR, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting - 1); \ + break; \ + } /* Called when a message receive from interrupt context fails (since the queue was empty) */ #undef traceQUEUE_RECEIVE_FROM_ISR_FAILED #define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ) \ - switch (pxQueue->ucQueueType) \ - { \ - case queueQUEUE_TYPE_BASE: \ - prvTraceStoreEvent2(PSF_EVENT_QUEUE_RECEIVE_FROMISR_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \ - break; \ - case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ - case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ - prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_TAKE_FROMISR_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \ - break; \ - } + if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \ + switch (pxQueue->ucQueueType) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent2(PSF_EVENT_QUEUE_RECEIVE_FROMISR_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_TAKE_FROMISR_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \ + break; \ + } /* Called on xQueuePeek */ #undef traceQUEUE_PEEK #define traceQUEUE_PEEK( pxQueue ) \ - switch (pxQueue->ucQueueType) \ - { \ - case queueQUEUE_TYPE_BASE: \ - prvTraceStoreEvent3(PSF_EVENT_QUEUE_PEEK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \ - break; \ - case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ - case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ - prvTraceStoreEvent3(PSF_EVENT_SEMAPHORE_PEEK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \ - break; \ - case queueQUEUE_TYPE_MUTEX: \ - case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ - prvTraceStoreEvent1(PSF_EVENT_MUTEX_PEEK, (uint32_t)pxQueue); \ - break; \ - } + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \ + switch (pxQueue->ucQueueType) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent3(PSF_EVENT_QUEUE_PEEK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent3(PSF_EVENT_SEMAPHORE_PEEK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \ + break; \ + case queueQUEUE_TYPE_MUTEX: \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + prvTraceStoreEvent1(PSF_EVENT_MUTEX_PEEK, (uint32_t)pxQueue); \ + break; \ + } /* Called in vTaskPrioritySet */ #undef traceTASK_PRIORITY_SET #define traceTASK_PRIORITY_SET( pxTask, uxNewPriority ) \ prvTraceSaveObjectData(pxTask, uxNewPriority); \ - prvTraceStoreEvent2(PSF_EVENT_TASK_PRIORITY, (uint32_t)pxTask, uxNewPriority); + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_TASK_FILTER(pxTask) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_TASK_PRIORITY, (uint32_t)pxTask, uxNewPriority); /* Called in vTaskPriorityInherit, which is called by Mutex operations */ #undef traceTASK_PRIORITY_INHERIT #define traceTASK_PRIORITY_INHERIT( pxTask, uxNewPriority ) \ - prvTraceStoreEvent2(PSF_EVENT_TASK_PRIO_INHERIT, (uint32_t)pxTask, uxNewPriority); + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_TASK_FILTER(pxTask) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_TASK_PRIO_INHERIT, (uint32_t)pxTask, uxNewPriority); /* Called in vTaskPriorityDisinherit, which is called by Mutex operations */ #undef traceTASK_PRIORITY_DISINHERIT #define traceTASK_PRIORITY_DISINHERIT( pxTask, uxNewPriority ) \ - prvTraceStoreEvent2(PSF_EVENT_TASK_PRIO_DISINHERIT, (uint32_t)pxTask, uxNewPriority); + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_TASK_FILTER(pxTask) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_TASK_PRIO_DISINHERIT, (uint32_t)pxTask, uxNewPriority); /* Called in vTaskResume */ #undef traceTASK_RESUME #define traceTASK_RESUME( pxTaskToResume ) \ - prvTraceStoreEvent1(PSF_EVENT_TASK_RESUME, (uint32_t)pxTaskToResume); + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_TASK_FILTER(pxTaskToResume) & CurrentFilterMask) \ + prvTraceStoreEvent1(PSF_EVENT_TASK_RESUME, (uint32_t)pxTaskToResume); /* Called in vTaskResumeFromISR */ #undef traceTASK_RESUME_FROM_ISR #define traceTASK_RESUME_FROM_ISR( pxTaskToResume ) \ - prvTraceStoreEvent1(PSF_EVENT_TASK_RESUME_FROMISR, (uint32_t)pxTaskToResume); + if (TRACE_GET_TASK_FILTER(pxTaskToResume) & CurrentFilterMask) \ + prvTraceStoreEvent1(PSF_EVENT_TASK_RESUME_FROMISR, (uint32_t)pxTaskToResume); + +#if (TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1) #undef traceMALLOC #define traceMALLOC( pvAddress, uiSize ) \ - prvTraceStoreEvent2(PSF_EVENT_MALLOC, (uint32_t)pvAddress, uiSize); + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_MALLOC, (uint32_t)pvAddress, uiSize); #undef traceFREE #define traceFREE( pvAddress, uiSize ) \ - prvTraceStoreEvent2(PSF_EVENT_FREE, (uint32_t)pvAddress, (uint32_t)(-uiSize)); + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_FREE, (uint32_t)pvAddress, (uint32_t)(0 - uiSize)); /* "0 -" instead of just "-" to get rid of a warning... */ + +#endif /* (TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1) */ + +#if (TRC_CFG_INCLUDE_TIMER_EVENTS == 1) /* Called in timer.c - xTimerCreate */ #undef traceTIMER_CREATE #define traceTIMER_CREATE(tmr) \ + TRACE_SET_OBJECT_FILTER(TIMER, tmr, CurrentFilterGroup); \ prvTraceSaveSymbol(tmr, tmr->pcTimerName); \ prvTraceStoreStringEvent(1, PSF_EVENT_OBJ_NAME, tmr->pcTimerName, tmr); \ - prvTraceStoreEvent2(PSF_EVENT_TIMER_CREATE, (uint32_t)tmr, tmr->xTimerPeriodInTicks); + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(TIMER, tmr) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_TIMER_CREATE, (uint32_t)tmr, tmr->xTimerPeriodInTicks); #undef traceTIMER_CREATE_FAILED #define traceTIMER_CREATE_FAILED() \ - prvTraceStoreEvent0(PSF_EVENT_TIMER_CREATE_FAILED); + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + prvTraceStoreEvent0(PSF_EVENT_TIMER_CREATE_FAILED); -#if (TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_8_X || TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_X) +#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X) #define traceTIMER_COMMAND_SEND_8_0_CASES(tmr) \ - case tmrCOMMAND_RESET: \ - prvTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_RESET : PSF_EVENT_TIMER_RESET_FAILED, (uint32_t)tmr, xOptionalValue); \ - break; \ - case tmrCOMMAND_START_FROM_ISR: \ - prvTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_START_FROMISR : PSF_EVENT_TIMER_START_FROMISR_FAILED, (uint32_t)tmr, xOptionalValue); \ - break; \ - case tmrCOMMAND_RESET_FROM_ISR: \ - prvTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_RESET_FROMISR : PSF_EVENT_TIMER_RESET_FROMISR_FAILED, (uint32_t)tmr, xOptionalValue); \ - break; \ - case tmrCOMMAND_STOP_FROM_ISR: \ - prvTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_STOP_FROMISR : PSF_EVENT_TIMER_STOP_FROMISR_FAILED, (uint32_t)tmr, xOptionalValue); \ - break; \ - case tmrCOMMAND_CHANGE_PERIOD_FROM_ISR: \ - prvTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_CHANGEPERIOD_FROMISR : PSF_EVENT_TIMER_CHANGEPERIOD_FROMISR_FAILED, (uint32_t)tmr, xOptionalValue); \ - break; -#else /* TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_8_X || TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_X */ + case tmrCOMMAND_RESET: \ + prvTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_RESET : PSF_EVENT_TIMER_RESET_FAILED, (uint32_t)tmr, xOptionalValue); \ + break; \ + case tmrCOMMAND_START_FROM_ISR: \ + prvTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_START_FROMISR : PSF_EVENT_TIMER_START_FROMISR_FAILED, (uint32_t)tmr, xOptionalValue); \ + break; \ + case tmrCOMMAND_RESET_FROM_ISR: \ + prvTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_RESET_FROMISR : PSF_EVENT_TIMER_RESET_FROMISR_FAILED, (uint32_t)tmr, xOptionalValue); \ + break; \ + case tmrCOMMAND_STOP_FROM_ISR: \ + prvTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_STOP_FROMISR : PSF_EVENT_TIMER_STOP_FROMISR_FAILED, (uint32_t)tmr, xOptionalValue); \ + break; \ + case tmrCOMMAND_CHANGE_PERIOD_FROM_ISR: \ + prvTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_CHANGEPERIOD_FROMISR : PSF_EVENT_TIMER_CHANGEPERIOD_FROMISR_FAILED, (uint32_t)tmr, xOptionalValue); \ + break; +#else /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X */ #define traceTIMER_COMMAND_SEND_8_0_CASES(tmr) -#endif /* TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_8_X || TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_X */ +#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X */ /* Note that xCommandID can never be tmrCOMMAND_EXECUTE_CALLBACK (-1) since the trace macro is not called in that case */ #undef traceTIMER_COMMAND_SEND #define traceTIMER_COMMAND_SEND(tmr, xCommandID, xOptionalValue, xReturn) \ - switch(xCommandID) \ - { \ - case tmrCOMMAND_START: \ - prvTraceStoreEvent1((xReturn == pdPASS) ? PSF_EVENT_TIMER_START : PSF_EVENT_TIMER_START_FAILED, (uint32_t)tmr); \ - break; \ - case tmrCOMMAND_STOP: \ - prvTraceStoreEvent1((xReturn == pdPASS) ? PSF_EVENT_TIMER_STOP : PSF_EVENT_TIMER_STOP_FAILED, (uint32_t)tmr); \ - break; \ - case tmrCOMMAND_CHANGE_PERIOD: \ - prvTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_CHANGEPERIOD : PSF_EVENT_TIMER_CHANGEPERIOD_FAILED, (uint32_t)tmr, xOptionalValue); \ - break; \ - case tmrCOMMAND_DELETE: \ - prvTraceStoreEvent1((xReturn == pdPASS) ? PSF_EVENT_TIMER_DELETE : PSF_EVENT_TIMER_DELETE_FAILED, (uint32_t)tmr); \ - break; \ - traceTIMER_COMMAND_SEND_8_0_CASES(tmr) \ - } + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(TIMER, tmr) & CurrentFilterMask) \ + switch(xCommandID) \ + { \ + case tmrCOMMAND_START: \ + prvTraceStoreEvent1((xReturn == pdPASS) ? PSF_EVENT_TIMER_START : PSF_EVENT_TIMER_START_FAILED, (uint32_t)tmr); \ + break; \ + case tmrCOMMAND_STOP: \ + prvTraceStoreEvent1((xReturn == pdPASS) ? PSF_EVENT_TIMER_STOP : PSF_EVENT_TIMER_STOP_FAILED, (uint32_t)tmr); \ + break; \ + case tmrCOMMAND_CHANGE_PERIOD: \ + prvTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_CHANGEPERIOD : PSF_EVENT_TIMER_CHANGEPERIOD_FAILED, (uint32_t)tmr, xOptionalValue); \ + break; \ + case tmrCOMMAND_DELETE: \ + prvTraceStoreEvent1((xReturn == pdPASS) ? PSF_EVENT_TIMER_DELETE : PSF_EVENT_TIMER_DELETE_FAILED, (uint32_t)tmr); \ + break; \ + traceTIMER_COMMAND_SEND_8_0_CASES(tmr) \ + } + +#undef traceTIMER_EXPIRED +#define traceTIMER_EXPIRED(tmr) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(TIMER, tmr) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_TIMER_EXPIRED, (uint32_t)tmr->pxCallbackFunction, (uint32_t)tmr->pvTimerID); + +#endif /* #if (TRC_CFG_INCLUDE_TIMER_EVENTS == 1) */ + + +#if (TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS == 1) #undef tracePEND_FUNC_CALL #define tracePEND_FUNC_CALL(func, arg1, arg2, ret) \ @@ -1808,123 +2305,254 @@ switch (pxQueue->ucQueueType) \ #define tracePEND_FUNC_CALL_FROM_ISR(func, arg1, arg2, ret) \ prvTraceStoreEvent1((ret == pdPASS) ? PSF_EVENT_TIMER_PENDFUNCCALL_FROMISR : PSF_EVENT_TIMER_PENDFUNCCALL_FROMISR_FAILED, (uint32_t)func); +#endif /* (TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS == 1) */ + +#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1) + #undef traceEVENT_GROUP_CREATE #define traceEVENT_GROUP_CREATE(eg) \ - prvTraceStoreEvent1(PSF_EVENT_EVENTGROUP_CREATE, (uint32_t)eg); + TRACE_SET_OBJECT_FILTER(EVENTGROUP, eg, CurrentFilterGroup); \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \ + prvTraceStoreEvent1(PSF_EVENT_EVENTGROUP_CREATE, (uint32_t)eg); #undef traceEVENT_GROUP_DELETE #define traceEVENT_GROUP_DELETE(eg) \ - prvTraceStoreEvent1(PSF_EVENT_EVENTGROUP_DELETE, (uint32_t)eg); \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \ + prvTraceStoreEvent1(PSF_EVENT_EVENTGROUP_DELETE, (uint32_t)eg); \ prvTraceDeleteSymbol(eg); #undef traceEVENT_GROUP_CREATE_FAILED #define traceEVENT_GROUP_CREATE_FAILED() \ - prvTraceStoreEvent0(PSF_EVENT_EVENTGROUP_CREATE_FAILED); + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + prvTraceStoreEvent0(PSF_EVENT_EVENTGROUP_CREATE_FAILED); #undef traceEVENT_GROUP_SYNC_BLOCK #define traceEVENT_GROUP_SYNC_BLOCK(eg, bitsToSet, bitsToWaitFor) \ - prvTraceStoreEvent2(PSF_EVENT_EVENTGROUP_SYNC_BLOCK, (uint32_t)eg, bitsToWaitFor); + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_EVENTGROUP_SYNC_BLOCK, (uint32_t)eg, bitsToWaitFor); #undef traceEVENT_GROUP_SYNC_END #define traceEVENT_GROUP_SYNC_END(eg, bitsToSet, bitsToWaitFor, wasTimeout) \ - prvTraceStoreEvent2((wasTimeout != pdTRUE) ? PSF_EVENT_EVENTGROUP_SYNC : PSF_EVENT_EVENTGROUP_SYNC_FAILED, (uint32_t)eg, bitsToWaitFor); + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \ + prvTraceStoreEvent2((wasTimeout != pdTRUE) ? PSF_EVENT_EVENTGROUP_SYNC : PSF_EVENT_EVENTGROUP_SYNC_FAILED, (uint32_t)eg, bitsToWaitFor); #undef traceEVENT_GROUP_WAIT_BITS_BLOCK #define traceEVENT_GROUP_WAIT_BITS_BLOCK(eg, bitsToWaitFor) \ - prvTraceStoreEvent2(PSF_EVENT_EVENTGROUP_WAITBITS_BLOCK, (uint32_t)eg, bitsToWaitFor); + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_EVENTGROUP_WAITBITS_BLOCK, (uint32_t)eg, bitsToWaitFor); #undef traceEVENT_GROUP_WAIT_BITS_END #define traceEVENT_GROUP_WAIT_BITS_END(eg, bitsToWaitFor, wasTimeout) \ - prvTraceStoreEvent2((wasTimeout != pdTRUE) ? PSF_EVENT_EVENTGROUP_WAITBITS : PSF_EVENT_EVENTGROUP_WAITBITS_FAILED, (uint32_t)eg, bitsToWaitFor); + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \ + prvTraceStoreEvent2((wasTimeout != pdTRUE) ? PSF_EVENT_EVENTGROUP_WAITBITS : PSF_EVENT_EVENTGROUP_WAITBITS_FAILED, (uint32_t)eg, bitsToWaitFor); #undef traceEVENT_GROUP_CLEAR_BITS #define traceEVENT_GROUP_CLEAR_BITS(eg, bitsToClear) \ - prvTraceStoreEvent2(PSF_EVENT_EVENTGROUP_CLEARBITS, (uint32_t)eg, bitsToClear); + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_EVENTGROUP_CLEARBITS, (uint32_t)eg, bitsToClear); #undef traceEVENT_GROUP_CLEAR_BITS_FROM_ISR #define traceEVENT_GROUP_CLEAR_BITS_FROM_ISR(eg, bitsToClear) \ - prvTraceStoreEvent2(PSF_EVENT_EVENTGROUP_CLEARBITS_FROMISR, (uint32_t)eg, bitsToClear); + if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_EVENTGROUP_CLEARBITS_FROMISR, (uint32_t)eg, bitsToClear); #undef traceEVENT_GROUP_SET_BITS #define traceEVENT_GROUP_SET_BITS(eg, bitsToSet) \ - prvTraceStoreEvent2(PSF_EVENT_EVENTGROUP_SETBITS, (uint32_t)eg, bitsToSet); + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_EVENTGROUP_SETBITS, (uint32_t)eg, bitsToSet); #undef traceEVENT_GROUP_SET_BITS_FROM_ISR #define traceEVENT_GROUP_SET_BITS_FROM_ISR(eg, bitsToSet) \ - prvTraceStoreEvent2(PSF_EVENT_EVENTGROUP_SETBITS_FROMISR, (uint32_t)eg, bitsToSet); + if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_EVENTGROUP_SETBITS_FROMISR, (uint32_t)eg, bitsToSet); + +#endif /* (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1) */ #undef traceTASK_NOTIFY_TAKE -#if (TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_X) +#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0) #define traceTASK_NOTIFY_TAKE() \ - if (pxCurrentTCB->ucNotifyState == taskNOTIFICATION_RECEIVED) \ - prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_TAKE, (uint32_t)pxCurrentTCB, xTicksToWait); \ - else \ - prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_TAKE_FAILED, (uint32_t)pxCurrentTCB, xTicksToWait); -#else /* TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_X */ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask){ \ + if (pxCurrentTCB->ucNotifyState == taskNOTIFICATION_RECEIVED) \ + prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_TAKE, (uint32_t)pxCurrentTCB, xTicksToWait); \ + else \ + prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_TAKE_FAILED, (uint32_t)pxCurrentTCB, xTicksToWait);} +#else /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */ #define traceTASK_NOTIFY_TAKE() \ - if (pxCurrentTCB->eNotifyState == eNotified) \ - prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_TAKE, (uint32_t)pxCurrentTCB, xTicksToWait); \ - else \ - prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_TAKE_FAILED, (uint32_t)pxCurrentTCB, xTicksToWait); -#endif /* TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_X */ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask){ \ + if (pxCurrentTCB->eNotifyState == eNotified) \ + prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_TAKE, (uint32_t)pxCurrentTCB, xTicksToWait); \ + else \ + prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_TAKE_FAILED, (uint32_t)pxCurrentTCB, xTicksToWait);} +#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */ #undef traceTASK_NOTIFY_TAKE_BLOCK #define traceTASK_NOTIFY_TAKE_BLOCK() \ - prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_TAKE_BLOCK, (uint32_t)pxCurrentTCB, xTicksToWait); + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_TAKE_BLOCK, (uint32_t)pxCurrentTCB, xTicksToWait); #undef traceTASK_NOTIFY_WAIT -#if (TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_X) +#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0) #define traceTASK_NOTIFY_WAIT() \ - if (pxCurrentTCB->ucNotifyState == taskNOTIFICATION_RECEIVED) \ - prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_WAIT, (uint32_t)pxCurrentTCB, xTicksToWait); \ - else \ - prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_WAIT_FAILED, (uint32_t)pxCurrentTCB, xTicksToWait); -#else /* TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_X */ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask){ \ + if (pxCurrentTCB->ucNotifyState == taskNOTIFICATION_RECEIVED) \ + prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_WAIT, (uint32_t)pxCurrentTCB, xTicksToWait); \ + else \ + prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_WAIT_FAILED, (uint32_t)pxCurrentTCB, xTicksToWait);} +#else /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */ #define traceTASK_NOTIFY_WAIT() \ - if (pxCurrentTCB->eNotifyState == eNotified) \ - prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_WAIT, (uint32_t)pxCurrentTCB, xTicksToWait); \ - else \ - prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_WAIT_FAILED, (uint32_t)pxCurrentTCB, xTicksToWait); -#endif /* TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_X */ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask){ \ + if (pxCurrentTCB->eNotifyState == eNotified) \ + prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_WAIT, (uint32_t)pxCurrentTCB, xTicksToWait); \ + else \ + prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_WAIT_FAILED, (uint32_t)pxCurrentTCB, xTicksToWait);} +#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */ #undef traceTASK_NOTIFY_WAIT_BLOCK #define traceTASK_NOTIFY_WAIT_BLOCK() \ - prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_WAIT_BLOCK, (uint32_t)pxCurrentTCB, xTicksToWait); + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_WAIT_BLOCK, (uint32_t)pxCurrentTCB, xTicksToWait); #undef traceTASK_NOTIFY #define traceTASK_NOTIFY() \ - prvTraceStoreEvent1(PSF_EVENT_TASK_NOTIFY, (uint32_t)xTaskToNotify); + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_TASK_FILTER(xTaskToNotify) & CurrentFilterMask) \ + prvTraceStoreEvent1(PSF_EVENT_TASK_NOTIFY, (uint32_t)xTaskToNotify); #undef traceTASK_NOTIFY_FROM_ISR #define traceTASK_NOTIFY_FROM_ISR() \ - prvTraceStoreEvent1(PSF_EVENT_TASK_NOTIFY_FROM_ISR, (uint32_t)xTaskToNotify); + if (TRACE_GET_TASK_FILTER(xTaskToNotify) & CurrentFilterMask) \ + prvTraceStoreEvent1(PSF_EVENT_TASK_NOTIFY_FROM_ISR, (uint32_t)xTaskToNotify); #undef traceTASK_NOTIFY_GIVE_FROM_ISR #define traceTASK_NOTIFY_GIVE_FROM_ISR() \ - prvTraceStoreEvent1(PSF_EVENT_TASK_NOTIFY_GIVE_FROM_ISR, (uint32_t)xTaskToNotify); + if (TRACE_GET_TASK_FILTER(xTaskToNotify) & CurrentFilterMask) \ + prvTraceStoreEvent1(PSF_EVENT_TASK_NOTIFY_GIVE_FROM_ISR, (uint32_t)xTaskToNotify); #undef traceQUEUE_REGISTRY_ADD #define traceQUEUE_REGISTRY_ADD(object, name) \ prvTraceSaveSymbol(object, (const char*)name); \ prvTraceStoreStringEvent(1, PSF_EVENT_OBJ_NAME, name, object); -#endif /*#if TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING */ +#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1) + +#undef traceSTREAM_BUFFER_CREATE +#define traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer ) \ + TRACE_SET_OBJECT_FILTER(STREAMBUFFER, pxStreamBuffer, CurrentFilterGroup); \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, pxStreamBuffer) & CurrentFilterMask) \ + prvTraceStoreEvent2(xIsMessageBuffer == 1 ? PSF_EVENT_MESSAGEBUFFER_CREATE : PSF_EVENT_STREAMBUFFER_CREATE, (uint32_t)pxStreamBuffer, xBufferSizeBytes); + +#undef traceSTREAM_BUFFER_CREATE_FAILED +#define traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + prvTraceStoreEvent2(xIsMessageBuffer == 1 ? PSF_EVENT_MESSAGEBUFFER_CREATE_FAILED : PSF_EVENT_STREAMBUFFER_CREATE_FAILED, 0 , xBufferSizeBytes); + +#undef traceSTREAM_BUFFER_CREATE_STATIC_FAILED +#define traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer ) \ + traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ) + +#undef traceSTREAM_BUFFER_DELETE +#define traceSTREAM_BUFFER_DELETE( xStreamBuffer ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, pxStreamBuffer) & CurrentFilterMask) \ + prvTraceStoreEvent2(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_DELETE : PSF_EVENT_STREAMBUFFER_DELETE, (uint32_t)xStreamBuffer, prvBytesInBuffer(xStreamBuffer)); \ + prvTraceDeleteSymbol(xStreamBuffer); + +#undef traceSTREAM_BUFFER_RESET +#define traceSTREAM_BUFFER_RESET( xStreamBuffer ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \ + prvTraceStoreEvent2(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_RESET : PSF_EVENT_STREAMBUFFER_RESET, (uint32_t)xStreamBuffer, 0); + +#undef traceSTREAM_BUFFER_SEND +#define traceSTREAM_BUFFER_SEND( xStreamBuffer, xReturn ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \ + prvTraceStoreEvent2(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_SEND : PSF_EVENT_STREAMBUFFER_SEND, (uint32_t)xStreamBuffer, prvBytesInBuffer(xStreamBuffer)); + +#undef traceBLOCKING_ON_STREAM_BUFFER_SEND +#define traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \ + prvTraceStoreEvent1(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_SEND_BLOCK : PSF_EVENT_STREAMBUFFER_SEND_BLOCK, (uint32_t)xStreamBuffer); + +#undef traceSTREAM_BUFFER_SEND_FAILED +#define traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \ + prvTraceStoreEvent1(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_SEND_FAILED : PSF_EVENT_STREAMBUFFER_SEND_FAILED, (uint32_t)xStreamBuffer); + +#undef traceSTREAM_BUFFER_RECEIVE +#define traceSTREAM_BUFFER_RECEIVE( xStreamBuffer, xReceivedLength ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \ + prvTraceStoreEvent2(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_RECEIVE: PSF_EVENT_STREAMBUFFER_RECEIVE, (uint32_t)xStreamBuffer, prvBytesInBuffer(xStreamBuffer)); + +#undef traceBLOCKING_ON_STREAM_BUFFER_RECEIVE +#define traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \ + prvTraceStoreEvent1(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_RECEIVE_BLOCK: PSF_EVENT_STREAMBUFFER_RECEIVE_BLOCK, (uint32_t)xStreamBuffer); + +#undef traceSTREAM_BUFFER_RECEIVE_FAILED +#define traceSTREAM_BUFFER_RECEIVE_FAILED( xStreamBuffer ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \ + prvTraceStoreEvent1(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_RECEIVE_FAILED: PSF_EVENT_STREAMBUFFER_RECEIVE_FAILED, (uint32_t)xStreamBuffer); + +#undef traceSTREAM_BUFFER_SEND_FROM_ISR +#define traceSTREAM_BUFFER_SEND_FROM_ISR( xStreamBuffer, xReturn ) \ + if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \ + { \ + if ( xReturn > ( size_t ) 0 ) \ + { \ + prvTraceStoreEvent2(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_SEND_FROM_ISR : PSF_EVENT_STREAMBUFFER_SEND_FROM_ISR, (uint32_t)xStreamBuffer, prvBytesInBuffer(xStreamBuffer)); \ + } \ + else \ + { \ + prvTraceStoreEvent1(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_SEND_FROM_ISR_FAILED : PSF_EVENT_STREAMBUFFER_SEND_FROM_ISR_FAILED, (uint32_t)xStreamBuffer); \ + } \ + } -#else /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/ +#undef traceSTREAM_BUFFER_RECEIVE_FROM_ISR +#define traceSTREAM_BUFFER_RECEIVE_FROM_ISR( xStreamBuffer, xReceivedLength ) \ +if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \ + { \ + if ( xReceivedLength > ( size_t ) 0 ) \ + { \ + prvTraceStoreEvent2(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_RECEIVE_FROM_ISR : PSF_EVENT_STREAMBUFFER_RECEIVE_FROM_ISR, (uint32_t)xStreamBuffer, prvBytesInBuffer(xStreamBuffer)); \ + } \ + else \ + { \ + prvTraceStoreEvent1(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_RECEIVE_FROM_ISR_FAILED : PSF_EVENT_STREAMBUFFER_RECEIVE_FROM_ISR_FAILED, (uint32_t)xStreamBuffer); \ + } \ + } + +#endif /* (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1) */ + +#endif /* (TRC_CFG_SCHEDULING_ONLY == 0) */ + +#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + +#else /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ + +/* When recorder is disabled */ +#define vTraceSetQueueName(object, name) +#define vTraceSetSemaphoreName(object, name) +#define vTraceSetMutexName(object, name) +#define vTraceSetEventGroupName(object, name) +#define vTraceSetStreamBufferName(object, name) +#define vTraceSetMessageBufferName(object, name) - /* when recorder disabled */ - #define vTraceSetQueueName(object, name) - #define vTraceSetSemaphoreName(object, name) - #define vTraceSetMutexName(object, name) - - #define vTraceExcludeQueue(handle) - #define vTraceExcludeSemaphore(handle) - #define vTraceExcludeMutex(handle) - #define vTraceExcludeTimer(handle) - #define vTraceExcludeEventGroup(handle) - #define vTraceExcludeDelays() - -#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/ +#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ #ifdef __cplusplus } diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcPortDefines.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcPortDefines.h index 58d75ba01..36cf0b2b3 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcPortDefines.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcPortDefines.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 * * trcPortDefines.h @@ -38,7 +38,7 @@ * * Tabs are used for indent in this file (1 tab = 4 spaces) * - * Copyright Percepio AB, 2017. + * Copyright Percepio AB, 2018. * www.percepio.com ******************************************************************************/ @@ -70,6 +70,23 @@ #define TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC (0x01) #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 @@ -116,5 +133,5 @@ #define TRC_HARDWARE_PORT_NXP_LPC210X 14 /* No Any */ #define TRC_HARDWARE_PORT_ARM_CORTEX_A9 15 /* Yes Any */ #define TRC_HARDWARE_PORT_POWERPC_Z4 16 /* No FreeRTOS */ - +#define TRC_HARDWARE_PORT_Altera_NiosII 17 /* No Any */ #endif /*TRC_PORTDEFINES_H*/ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcRecorder.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcRecorder.h index ed0de0399..a7012fbed 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcRecorder.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcRecorder.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 * * trcRecorder.h @@ -38,7 +38,7 @@ * * Tabs are used for indent in this file (1 tab = 4 spaces) * - * Copyright Percepio AB, 2017. + * Copyright Percepio AB, 2018. * www.percepio.com ******************************************************************************/ @@ -51,11 +51,11 @@ extern "C" { #include #include +#include #include "trcConfig.h" #include "trcPortDefines.h" - #if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT) typedef uint16_t traceString; typedef uint8_t traceUBChannel; @@ -84,7 +84,12 @@ typedef const void* traceHandle; #endif #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 ****************************/ /******************************************************************************/ @@ -208,11 +213,14 @@ void vTraceEnable(int startOption); * 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 * 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, ...); +#else +#define vTracePrintF(chn, ...) (void)chn +#endif -/****************************************************************************** + /****************************************************************************** * vTracePrint * * 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"); * ... * vTracePrint(chn, "Hello World!"); -* ******************************************************************************/ +#if (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) void vTracePrint(traceString chn, const char* str); +#else +#define vTracePrint(chn, ...) (void)chn +#endif /******************************************************************************* * xTraceRegisterString @@ -235,9 +246,12 @@ void vTracePrint(traceString chn, const char* str); * myEventHandle = xTraceRegisterString("MyUserEvent"); * ... * vTracePrintF(myEventHandle, "My value is: %d", myValue); -* ******************************************************************************/ +#if (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) traceString xTraceRegisterString(const char* name); +#else +#define xTraceRegisterString(x) (x) +#endif /******************************************************************************* * 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 * 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 @@ -277,7 +281,6 @@ traceString xTraceRegisterString(const char* name); * ... * vTraceStoreISREnd(0); * } - * ******************************************************************************/ traceHandle xTraceSetISRProperties(const char* name, uint8_t priority); @@ -298,7 +301,6 @@ traceHandle xTraceSetISRProperties(const char* name, uint8_t priority); * ... * vTraceStoreISREnd(0); * } - * ******************************************************************************/ void vTraceStoreISRBegin(traceHandle handle); @@ -323,7 +325,6 @@ void vTraceStoreISRBegin(traceHandle handle); * ... * vTraceStoreISREnd(0); * } - * ******************************************************************************/ void vTraceStoreISREnd(int isTaskSwitchRequired); @@ -352,7 +353,7 @@ void vTraceInstanceFinishedNext(void); /******************************************************************************* * xTraceGetLastError * - * Returns the last error, if any. + * Returns the last error or warning as a string, or NULL if none. *****************************************************************************/ 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 * directives to place it in a particular memory region. +* * - Snapshot mode: "RecorderDataType " -* - Streaming mode: "char []", with from trcStreamingPort.h. +* +* - Streaming mode: "char []", +* where is defined in trcStreamingConfig.h. * * Example: * @@ -434,17 +438,96 @@ void vTraceSetRecorderDataBuffer(void* pRecorderData); * vTraceSetRecorderDataBuffer(&myTraceBuffer); // Note the "&" * ... * 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) -#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 -#define TRC_ALLOC_CUSTOM_BUFFER(bufname) -#endif + #define TRC_ALLOC_CUSTOM_BUFFER(bufname) #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) +* +* +* // Assign Q1 and Q2 to FilterGroup1 +* vTraceSetFilterGroup(FilterGroup1); +* +* +* +* // Assigns Q3 to FilterGroup2 +* vTraceSetFilterGroup(FilterGroup2); +* +* +* // 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); +* +* +* 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) @@ -494,7 +577,6 @@ void vTraceSetStopHook(TRACE_STOP_HOOK stopHookFunction); * error. In that case, check xTraceGetLastError to get the error message. * Any error message is also presented when opening a trace file. * -* * Snapshot mode only! ******************************************************************************/ uint32_t uiTraceStart(void); @@ -527,11 +609,7 @@ void vTraceClear(void); /*** INTERNAL SNAPSHOT FUNCTIONS *********************************************/ /*****************************************************************************/ -#undef INCLUDE_xTaskGetSchedulerState -#define INCLUDE_xTaskGetSchedulerState 1 - -#undef INCLUDE_xTaskGetCurrentTaskHandle -#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define TRC_UNUSED #ifndef TRC_CFG_INCLUDE_OBJECT_DELETE #define TRC_CFG_INCLUDE_OBJECT_DELETE 0 @@ -545,82 +623,105 @@ void vTraceClear(void); #define TRC_CFG_INCLUDE_OSTICK_EVENTS 0 #endif -#define TRC_UNUSED +/* This macro will create a task in the object table */ +#undef trcKERNEL_HOOKS_TASK_CREATE +#define trcKERNEL_HOOKS_TASK_CREATE(SERVICE, CLASS, 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)); \ + prvTraceSetPriorityProperty(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), TRACE_GET_TASK_PRIORITY(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)); -#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); \ +#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)); -#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 */ -#undef trcKERNEL_HOOKS_TASK_CREATE -#define trcKERNEL_HOOKS_TASK_CREATE(SERVICE, CLASS, pxTCB) \ - TRACE_SET_TASK_NUMBER(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)); \ - prvTraceStoreKernelCall(TRACE_GET_TASK_EVENT_CODE(SERVICE, SUCCESS, CLASS, pxTCB), 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 */ #undef trcKERNEL_HOOKS_OBJECT_CREATE #define trcKERNEL_HOOKS_OBJECT_CREATE(SERVICE, 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));\ - 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); -/* This macro will create a failed create call to create an object */ -#undef trcKERNEL_HOOKS_OBJECT_CREATE_FAILED -#define trcKERNEL_HOOKS_OBJECT_CREATE_FAILED(SERVICE, CLASS, kernelClass) \ - prvTraceStoreKernelCall(TRACE_GET_CLASS_EVENT_CODE(SERVICE, FAILED, CLASS, kernelClass), TRACE_GET_CLASS_TRACE_CLASS(CLASS, kernelClass), 0); +/* This macro will remove the object and store it in the event buffer */ +#undef trcKERNEL_HOOKS_OBJECT_DELETE +#define trcKERNEL_HOOKS_OBJECT_DELETE(SERVICE, SERVICE_NAME, SERVICE_PROP, 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)); \ + 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 */ #undef trcKERNEL_HOOKS_KERNEL_SERVICE -#define trcKERNEL_HOOKS_KERNEL_SERVICE(SERVICE, RESULT, 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)); +#define trcKERNEL_HOOKS_KERNEL_SERVICE(SERVICE, 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 */ #undef trcKERNEL_HOOKS_SET_OBJECT_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 */ #undef 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) /* This macro will create an event to indicate that a task became Ready */ #undef trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE #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)*/ #undef trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE #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 */ #undef 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) /* 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 */ #undef trcKERNEL_HOOKS_TASK_SWITCH #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 */ #undef trcKERNEL_HOOKS_TASK_SUSPEND #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)); /* This macro will create an event to indicate that a task has called a wait/delay function */ #undef trcKERNEL_HOOKS_TASK_DELAY #define trcKERNEL_HOOKS_TASK_DELAY(SERVICE, pxTCB, xValue) \ - prvTraceStoreKernelCallWithNumericParamOnly(SERVICE, xValue); \ - prvTraceSetTaskInstanceFinished((uint8_t)TRACE_GET_TASK_NUMBER(pxTCB)); + if (TRACE_GET_TASK_FILTER(pxTCB) & CurrentFilterMask) \ + { \ + 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 */ #undef trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE #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)));\ - prvTraceSetPriorityProperty(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), (uint8_t)uxNewPriority); + if (TRACE_GET_TASK_FILTER(pxTCB) & CurrentFilterMask) \ + { \ + 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 */ #undef trcKERNEL_HOOKS_TASK_RESUME #define trcKERNEL_HOOKS_TASK_RESUME(SERVICE, pxTCB) \ - prvTraceStoreKernelCall(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB)); - -#undef trcKERNEL_HOOKS_TIMER_EVENT -#define trcKERNEL_HOOKS_TIMER_EVENT(SERVICE, pxTimer) \ - prvTraceStoreKernelCall(SERVICE, TRACE_CLASS_TIMER, TRACE_GET_TIMER_NUMBER(pxTimer)); - -/* 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 (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_TASK_RESUME_FROM_ISR +#define trcKERNEL_HOOKS_TASK_RESUME_FROM_ISR(SERVICE, pxTCB) \ + if (TRACE_GET_TASK_FILTER(pxTCB) & CurrentFilterMask) \ + prvTraceStoreKernelCall(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB)); #if !defined TRC_CFG_INCLUDE_READY_EVENTS || TRC_CFG_INCLUDE_READY_EVENTS == 1 void prvTraceSetReadyEventsEnabled(int status); @@ -725,15 +828,11 @@ void prvTraceSetObjectState(uint8_t objectclass, traceHandle id, uint8_t value); void prvMarkObjectAsUsed(traceObjectClass objectclass, traceHandle handle); - -#if (TRC_CFG_INCLUDE_OBJECT_DELETE == 1) - -void prvTraceStoreObjectNameOnCloseEvent(traceHandle handle, +void prvTraceStoreObjectNameOnCloseEvent(uint8_t evtcode, traceHandle handle, traceObjectClass objectclass); -void prvTraceStoreObjectPropertiesOnCloseEvent(traceHandle handle, +void prvTraceStoreObjectPropertiesOnCloseEvent(uint8_t evtcode, traceHandle handle, traceObjectClass objectclass); -#endif /* Internal constants for task state */ #define TASK_STATE_INSTANCE_NOT_ACTIVE 0 @@ -742,9 +841,6 @@ void prvTraceStoreObjectPropertiesOnCloseEvent(traceHandle handle, #if (TRC_CFG_INCLUDE_ISR_TRACING == 0) -//void prvTraceIncreaseISRActive(void); - -//void prvTraceDecreaseISRActive(void); #undef vTraceSetISRProperties #define vTraceSetISRProperties(handle, name, priority) @@ -824,12 +920,6 @@ void vTraceUBEvent(traceUBChannel channel); #define trcCRITICAL_SECTION_END_ON_CORTEX_M_ONLY() recorder_busy--; #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 * 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" * objects, that have been deleted - that number is only limited by the size of * the symbol table. + * * 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. @@ -851,7 +942,6 @@ extern uint8_t trcExcludedEventCodes[NEventCodes / 8 + 1]; * 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 * index of the popped handle instead. - * *****************************************************************************/ typedef struct { @@ -884,6 +974,7 @@ extern objectHandleStackType objectHandleStacks; * 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 is found in the Object Property Table). + * * 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) * and for "isActive", where the value decides if the task switch event type @@ -927,7 +1018,7 @@ typedef struct uint32_t nextFreeSymbolIndex; /* 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 connecting all entries with the same 6 bit checksum. @@ -979,8 +1070,8 @@ typedef struct typedef struct { uint8_t type; - uint8_t objHandle; /* the handle of the closed object */ - uint16_t symbolIndex; /* the name of the closed object */ + uint8_t objHandle; /* the handle of the closed object */ + uint16_t symbolIndex; /* the name of the closed object */ } ObjCloseNameEvent; typedef struct @@ -1060,9 +1151,9 @@ typedef struct uint8_t padding1; uint8_t padding2; uint8_t padding3; - 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 dataBuffer[TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE * 4]; /* 4 bytes per slot */ + 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 dataBuffer[(TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE) * 4]; /* 4 bytes per slot */ } UserEventBuffer; #endif @@ -1182,7 +1273,7 @@ typedef struct int32_t debugMarker3; /* 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) UserEventBuffer userEventBuffer; @@ -1249,14 +1340,6 @@ RecorderDataPtr->ObjectPropertyTable.objbytes[uiIndexOfObject(handle, objectclas RecorderDataPtr->ObjectPropertyTable.objbytes[uiIndexOfObject(handle, objectclass) \ + 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 */ #if defined TRC_CFG_USE_TRACE_ASSERT && TRC_CFG_USE_TRACE_ASSERT != 0 #define TRACE_ASSERT(eval, msg, defRetVal) \ @@ -1273,6 +1356,279 @@ if (!(eval)) \ #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 *********************************************/ /******************************************************************************/ @@ -1320,10 +1676,7 @@ void prvPagedEventBufferInit(char* buffer); void* prvPagedEventBufferGetWritePointer(int sizeOfEvent); /* Transfer a full buffer page */ -int32_t prvPagedEventBufferTransfer(int32_t(*writeFunc)(void* data, uint32_t size, int32_t* ptrBytesWritten), int32_t* nofBytes); - -/* Resets the paged event buffer */ -void prvPagedEventBufferReset(void); +uint32_t prvPagedEventBufferTransfer(void); /* The data structure for commands (a bit overkill) */ typedef struct @@ -1344,6 +1697,7 @@ int prvIsValidCommand(TracealyzerCommandType* cmd); /* Executed the received command (Start or Stop) */ void prvProcessCommand(TracealyzerCommandType* cmd); +#define vTraceSetStopHook(x) #endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/ @@ -1363,6 +1717,9 @@ void prvProcessCommand(TracealyzerCommandType* cmd); #define vTraceChannelPrint(label) #define vTraceUBData(label, ...) +#define vTraceSetFilterGroup(x) +#define vTraceSetFilterMask(x) + #define prvTraceSetReadyEventsEnabled(status) #define vTraceExcludeTask(handle) @@ -1379,6 +1736,10 @@ void prvProcessCommand(TracealyzerCommandType* cmd); #define TRC_ALLOC_CUSTOM_BUFFER(bufname) #endif +#define xTraceIsRecordingEnabled() (0) + +#define vTraceSetStopHook(x) + #endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/ #ifdef __cplusplus diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcConfig.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcConfig.h index 598072c65..ba6ddd299 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcConfig.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcConfig.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 * * trcConfig.h @@ -10,7 +10,7 @@ * Read more at http://percepio.com/2016/10/05/rtos-tracing/ * * 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 * license as follows. * The RECORDER may be used free of charge for the purpose of recording data @@ -19,14 +19,14 @@ * 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 + * 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. + * 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 + * 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. @@ -41,10 +41,10 @@ * * Tabs are used for indent in this file (1 tab = 4 spaces) * - * Copyright Percepio AB, 2016. + * Copyright Percepio AB, 2018. * www.percepio.com ******************************************************************************/ - + #ifndef TRC_CONFIG_H #define TRC_CONFIG_H @@ -56,8 +56,8 @@ extern "C" { /****************************************************************************** * Include of processor header file - * - * Here you may need to include the header file for your processor. This is + * + * Here you may need to include the header file for your processor. This is * required at least for the ARM Cortex-M port, that uses the ARM CMSIS API. * Try that in case of build problems. Otherwise, remove the #error line below. *****************************************************************************/ @@ -71,14 +71,14 @@ extern "C" { * All ARM Cortex-M MCUs are supported by "TRC_HARDWARE_PORT_ARM_Cortex_M". * This port uses the DWT cycle counter for Cortex-M3/M4/M7 devices, which is * available on most such devices. In case your device don't have DWT support, - * you will get an error message opening the trace. In that case, you may + * you will get an error message opening the trace. In that case, you may * force the recorder to use SysTick timestamping instead, using this define: * * #define TRC_CFG_ARM_CM_USE_SYSTICK * * For ARM Cortex-M0/M0+ devices, SysTick mode is used automatically. * - * See trcHardwarePort.h for available ports and information on how to + * See trcHardwarePort.h for available ports and information on how to * define your own port, if not already present. ******************************************************************************/ #define TRC_CFG_HARDWARE_PORT TRC_HARDWARE_PORT_NOT_SET @@ -88,7 +88,7 @@ extern "C" { * * Specify what recording mode to use. Snapshot means that the data is saved in * an internal RAM buffer, for later upload. Streaming means that the data is - * transferred continuously to the host PC. + * transferred continuously to the host PC. * * For more information, see http://percepio.com/2016/10/05/rtos-tracing/ * and the Tracealyzer User Manual. @@ -99,6 +99,161 @@ extern "C" { ******************************************************************************/ #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 * @@ -110,37 +265,24 @@ extern "C" { * TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC - Malloc in vTraceEnable * TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM - Use vTraceSetRecorderDataBuffer * - * Static and dynamic mode does the allocation for you, either in compile time - * (static) or in runtime (malloc). - * The custom mode allows you to control how and where the allocation is made, + * Static and dynamic mode does the allocation for you, either in compile time + * (static) or in runtime (malloc). + * The custom mode allows you to control how and where the allocation is made, * for details see TRC_ALLOC_CUSTOM_BUFFER and vTraceSetRecorderDataBuffer(). ******************************************************************************/ #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 - * + * * Defines how many levels of interrupt nesting the recorder can handle, in * case multiple ISRs are traced and ISR nesting is possible. If this - * is exceeded, the particular ISR will not be traced and the recorder then + * is exceeded, the particular ISR will not be traced and the recorder then * logs an error message. This setting is used to allocate an internal stack - * for keeping track of the previous execution context (4 byte per entry). + * for keeping track of the previous execution context (4 byte per entry). * * This value must be a non-zero positive constant, at least 1. - * + * * Default value: 8 *****************************************************************************/ #define TRC_CFG_MAX_ISR_NESTING 8 diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcSnapshotConfig.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcSnapshotConfig.h index 1158afc04..e926139e6 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcSnapshotConfig.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcSnapshotConfig.h @@ -1,14 +1,14 @@ /******************************************************************************* - * Trace Recorder Library for Tracealyzer v3.1.2 + * Trace Recorder Library for Tracealyzer v4.1.1 * Percepio AB, www.percepio.com * * trcSnapshotConfig.h * - * Configuration parameters for trace recorder library in snapshot mode. + * Configuration parameters for trace recorder library in snapshot mode. * Read more at http://percepio.com/2016/10/05/rtos-tracing/ * * 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 * license as follows. * The RECORDER may be used free of charge for the purpose of recording data @@ -17,14 +17,14 @@ * 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 + * 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. + * 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 + * 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. @@ -39,7 +39,7 @@ * * Tabs are used for indent in this file (1 tab = 4 spaces) * - * Copyright Percepio AB, 2017. + * Copyright Percepio AB, 2018. * www.percepio.com ******************************************************************************/ @@ -57,44 +57,28 @@ * - TRC_SNAPSHOT_MODE_STOP_WHEN_FULL * Default is TRC_SNAPSHOT_MODE_RING_BUFFER. * - * With TRC_CFG_SNAPSHOT_MODE set to TRC_SNAPSHOT_MODE_RING_BUFFER, the - * events are stored in a ring buffer, i.e., where the oldest events are + * With TRC_CFG_SNAPSHOT_MODE set to TRC_SNAPSHOT_MODE_RING_BUFFER, the + * events are stored in a ring buffer, i.e., where the oldest events are * overwritten when the buffer becomes full. This allows you to get the last - * events leading up to an interesting state, e.g., an error, without having + * events leading up to an interesting state, e.g., an error, without having * to store the whole run since startup. * - * When TRC_CFG_SNAPSHOT_MODE is TRC_SNAPSHOT_MODE_STOP_WHEN_FULL, the + * When TRC_CFG_SNAPSHOT_MODE is TRC_SNAPSHOT_MODE_STOP_WHEN_FULL, the * recording is stopped when the buffer becomes full. This is useful for * recording events following a specific state, e.g., the startup sequence. *****************************************************************************/ #define TRC_CFG_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 * * Macro which should be defined as an integer value. * * This defines the capacity of the event buffer, i.e., the number of records - * it may store. Most events use one record (4 byte), although some events + * it may store. Most events use one record (4 byte), although some events * require multiple 4-byte records. You should adjust this to the amount of RAM * available in the target system. - * + * * Default value is 1000, which means that 4000 bytes is allocated for the * event buffer. ******************************************************************************/ @@ -106,111 +90,43 @@ * A group of macros which should be defined as integer values, zero or larger. * * These define the capacity of the Object Property Table, i.e., the maximum - * number of objects active at any given point, within each object class (e.g., + * number of objects active at any given point, within each object class (e.g., * task, queue, semaphore, ...). - * + * * If tasks or other objects are deleted in your system, this * setting does not limit the total amount of objects created, only the number * of objects that have been successfully created but not yet deleted. * - * Using too small values will cause vTraceError to be called, which stores an + * Using too small values will cause vTraceError to be called, which stores an * error message in the trace that is shown when opening the trace file. The * error message can also be retrieved using xTraceGetLastError. * - * It can be wise to start with large values for these constants, + * It can be wise to start with large values for these constants, * unless you are very confident on these numbers. Then do a recording and - * check the actual usage by selecting View menu -> Trace Details -> - * Resource Usage -> Object Table. + * check the actual usage by selecting View menu -> Trace Details -> + * Resource Usage -> Object Table. ******************************************************************************/ -#define TRC_CFG_NTASK 10 +#define TRC_CFG_NTASK 15 #define TRC_CFG_NISR 5 #define TRC_CFG_NQUEUE 10 #define TRC_CFG_NSEMAPHORE 10 #define TRC_CFG_NMUTEX 10 #define TRC_CFG_NTIMER 5 #define TRC_CFG_NEVENTGROUP 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 +#define TRC_CFG_NSTREAMBUFFER 5 +#define TRC_CFG_NMESSAGEBUFFER 5 /****************************************************************************** * TRC_CFG_INCLUDE_FLOAT_SUPPORT * - * Macro which should be defined as either zero (0) or one (1). + * Macro which should be defined as either zero (0) or one (1). * - * If this is zero (0), the support for logging floating point values in + * If this is zero (0), the support for logging floating point values in * vTracePrintF is stripped out, in case floating point values are not used or * supported by the platform used. * - * Floating point values are only used in vTracePrintF and its subroutines, to - * allow for storing float (%f) or double (%lf) arguments. + * Floating point values are only used in vTracePrintF and its subroutines, to + * allow for storing float (%f) or double (%lf) arguments. * * vTracePrintF can be used with integer and string arguments in either case. * @@ -218,29 +134,16 @@ *****************************************************************************/ #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 * * Macro which should be defined as an integer value. * - * This defines the capacity of the symbol table, in bytes. This symbol table + * This defines the capacity of the symbol table, in bytes. This symbol table * stores User Events labels and names of deleted tasks, queues, or other kernel - * objects. If you don't use User Events or delete any kernel + * objects. If you don't use User Events or delete any kernel * objects you set this to a very low value. The minimum recommended value is 4. - * A size of zero (0) is not allowed since a zero-sized array may result in a + * A size of zero (0) is not allowed since a zero-sized array may result in a * 32-bit pointer, i.e., using 4 bytes rather than 0. * * Default value is 800. @@ -265,6 +168,8 @@ #define TRC_CFG_NAME_LEN_MUTEX 15 #define TRC_CFG_NAME_LEN_TIMER 15 #define TRC_CFG_NAME_LEN_EVENTGROUP 15 +#define TRC_CFG_NAME_LEN_STREAMBUFFER 15 +#define TRC_CFG_NAME_LEN_MESSAGEBUFFER 15 /****************************************************************************** *** ADVANCED SETTINGS ******************************************************** @@ -272,14 +177,14 @@ * The remaining settings are not necessary to modify but allows for optimizing * the recorder setup for your specific needs, e.g., to exclude events that you * are not interested in, in order to get longer traces. - *****************************************************************************/ + *****************************************************************************/ /****************************************************************************** * TRC_CFG_HEAP_SIZE_BELOW_16M * * An integer constant that can be used to reduce the buffer usage of memory -* allocation events (malloc/free). This value should be 1 if the heap size is -* below 16 MB (2^24 byte), and you can live with reported addresses showing the +* allocation events (malloc/free). This value should be 1 if the heap size is +* below 16 MB (2^24 byte), and you can live with reported addresses showing the * lower 24 bits only. If 0, you get the full 32-bit addresses. * * Default value is 0. @@ -289,16 +194,16 @@ /****************************************************************************** * TRC_CFG_USE_IMPLICIT_IFE_RULES * - * Macro which should be defined as either zero (0) or one (1). + * Macro which should be defined as either zero (0) or one (1). * Default is 1. * * Tracealyzer groups the events into "instances" based on Instance Finish * Events (IFEs), produced either by default rules or calls to the recorder - * functions vTraceInstanceFinishedNow and vTraceInstanceFinishedNext. + * functions vTraceInstanceFinishedNow and vTraceInstanceFinishedNext. * * If TRC_CFG_USE_IMPLICIT_IFE_RULES is one (1), the default IFE rules is * used, resulting in a "typical" grouping of events into instances. - * If these rules don't give appropriate instances in your case, you can + * If these rules don't give appropriate instances in your case, you can * override the default rules using vTraceInstanceFinishedNow/Next for one * or several tasks. The default IFE rules are then disabled for those tasks. * @@ -306,15 +211,15 @@ * disabled globally. You must then call vTraceInstanceFinishedNow or * vTraceInstanceFinishedNext to manually group the events into instances, * otherwise the tasks will appear a single long instance. - * + * * The default IFE rules count the following events as "instance finished": * - Task delay, delay until * - Task suspend - * - Blocking on "input" operations, i.e., when the task is waiting for the + * - Blocking on "input" operations, i.e., when the task is waiting for the * next a message/signal/event. But only if this event is blocking. * - * For details, see trcSnapshotKernelPort.h and look for references to the - * macro trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED. + * For details, see trcSnapshotKernelPort.h and look for references to the + * macro trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED. *****************************************************************************/ #define TRC_CFG_USE_IMPLICIT_IFE_RULES 1 @@ -322,21 +227,21 @@ * TRC_CFG_USE_16BIT_OBJECT_HANDLES * * Macro which should be defined as either zero (0) or one (1). - * - * If set to 0 (zero), the recorder uses 8-bit handles to identify kernel + * + * If set to 0 (zero), the recorder uses 8-bit handles to identify kernel * objects such as tasks and queues. This limits the supported number of * concurrently active objects to 255 of each type (tasks, queues, mutexes, * etc.) Note: 255, not 256, since handle 0 is reserved. * - * If set to 1 (one), the recorder uses 16-bit handles to identify kernel + * If set to 1 (one), the recorder uses 16-bit handles to identify kernel * objects such as tasks and queues. This limits the supported number of * concurrent objects to 65535 of each type (object class). However, since the * object property table is limited to 64 KB, the practical limit is about - * 3000 objects in total. - * + * 3000 objects in total. + * * Default is 0 (8-bit handles) * - * NOTE: An object with handle above 255 will use an extra 4-byte record in + * NOTE: An object with handle above 255 will use an extra 4-byte record in * the event buffer whenever the object is referenced. Moreover, some internal * tables in the recorder gets slightly larger when using 16-bit handles. *****************************************************************************/ @@ -345,11 +250,11 @@ /****************************************************************************** * TRC_CFG_USE_TRACE_ASSERT * - * Macro which should be defined as either zero (0) or one (1). + * Macro which should be defined as either zero (0) or one (1). * Default is 1. * - * If this is one (1), the TRACE_ASSERT macro (used at various locations in the - * trace recorder) will verify that a relevant condition is true. + * If this is one (1), the TRACE_ASSERT macro (used at various locations in the + * trace recorder) will verify that a relevant condition is true. * If the condition is false, prvTraceError() will be called, which stops the * recording and stores an error message that is displayed when opening the * trace in Tracealyzer. @@ -365,18 +270,18 @@ * * Macro which should be defined as an integer value. * - * Set TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER to 1 to enable the + * Set TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER to 1 to enable the * separate user event buffer (UB). - * In this mode, user events are stored separately from other events, - * e.g., RTOS events. Thereby you can get a much longer history of - * user events as they don't need to share the buffer space with more - * frequent events. + * In this mode, user events are stored separately from other events, + * e.g., RTOS events. Thereby you can get a much longer history of + * user events as they don't need to share the buffer space with more + * frequent events. * * The UB is typically used with the snapshot ring-buffer mode, so the - * recording can continue when the main buffer gets full. And since the + * recording can continue when the main buffer gets full. And since the * main buffer then overwrites the earliest events, Tracealyzer displays * "Unknown Actor" instead of task scheduling for periods with UB data only. - * + * * In UB mode, user events are structured as UB channels, which contains * a channel name and a default format string. Register a UB channel using * xTraceRegisterUBChannel. @@ -390,31 +295,31 @@ * traceString chn1 = xTraceRegisterString("Channel 1"); * traceString fmt1 = xTraceRegisterString("Event!"); * traceUBChannel UBCh1 = xTraceRegisterUBChannel(chn1, fmt1); - * + * * traceString chn2 = xTraceRegisterString("Channel 2"); * traceString fmt2 = xTraceRegisterString("X: %d, Y: %d"); * traceUBChannel UBCh2 = xTraceRegisterUBChannel(chn2, fmt2); - * + * * // Result in "[Channel 1] Event!" - * vTraceUBEvent(UBCh1); + * vTraceUBEvent(UBCh1); * * // Result in "[Channel 2] X: 23, Y: 19" * vTraceUBData(UBCh2, 23, 19); * * You can also use the other user event functions, like vTracePrintF. * as they are then rerouted to the UB instead of the main event buffer. - * vTracePrintF then looks up the correct UB channel based on the + * vTracePrintF then looks up the correct UB channel based on the * provided channel name and format string, or creates a new UB channel - * if no match is found. The format string should therefore not contain + * if no match is found. The format string should therefore not contain * "random" messages but mainly format specifiers. Random strings should * be stored using %s and with the string as an argument. * * // Creates a new UB channel ("Channel 2", "%Z: %d") * vTracePrintF(chn2, "%Z: %d", value1); - * + * * // Finds the existing UB channel * vTracePrintF(chn2, "%Z: %d", value2); - + ******************************************************************************/ #define TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER 0 @@ -449,22 +354,22 @@ * * Macro which should be defined as an integer value. * - * If tracing multiple ISRs, this setting allows for accurate display of the + * If tracing multiple ISRs, this setting allows for accurate display of the * context-switching also in cases when the ISRs execute in direct sequence. - * + * * vTraceStoreISREnd normally assumes that the ISR returns to the previous - * context, i.e., a task or a preempted ISR. But if another traced ISR + * context, i.e., a task or a preempted ISR. But if another traced ISR * executes in direct sequence, Tracealyzer may incorrectly display a minimal * fragment of the previous context in between the ISRs. * - * By using TRC_CFG_ISR_TAILCHAINING_THRESHOLD you can avoid this. This is + * By using TRC_CFG_ISR_TAILCHAINING_THRESHOLD you can avoid this. This is * however a threshold value that must be measured for your specific setup. * See http://percepio.com/2014/03/21/isr_tailchaining_threshold/ * - * The default setting is 0, meaning "disabled" and that you may get an + * The default setting is 0, meaning "disabled" and that you may get an * extra fragments of the previous context in between tail-chained ISRs. * - * Note: This setting has separate definitions in trcSnapshotConfig.h and + * Note: This setting has separate definitions in trcSnapshotConfig.h and * trcStreamingConfig.h, since it is affected by the recorder mode. ******************************************************************************/ #define TRC_CFG_ISR_TAILCHAINING_THRESHOLD 0 diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcStreamingConfig.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcStreamingConfig.h index 7ad11d47b..5b916c33a 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcStreamingConfig.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcStreamingConfig.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 * * trcStreamingConfig.h @@ -39,7 +39,7 @@ * * Tabs are used for indent in this file (1 tab = 4 spaces) * - * Copyright Percepio AB, 2017. + * Copyright Percepio AB, 2018. * www.percepio.com ******************************************************************************/ @@ -57,7 +57,7 @@ extern "C" { * - Task names * - Named ISRs (vTraceSetISRProperties) * - 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 * trace display will be affected. In that case, there will be warnings @@ -72,7 +72,7 @@ extern "C" { * - Task names * - Named ISRs (vTraceSetISRProperties) * - 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, * 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. * 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 @@ -134,7 +134,7 @@ extern "C" { * to match any internal low-level buffers used by the streaming interface, like * 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 diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/Keil-uVision-Tracealyzer-ITM-Exporter.ini b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/Keil-uVision-Tracealyzer-ITM-Exporter.ini new file mode 100644 index 000000000..5e2c8b99b --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/Keil-uVision-Tracealyzer-ITM-Exporter.ini @@ -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)"; \ No newline at end of file diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/Readme-ARM_ITM.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/Readme-ARM_ITM.txt new file mode 100644 index 000000000..0802b5331 --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/Readme-ARM_ITM.txt @@ -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 \ No newline at end of file diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/include/trcStreamingPort.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/include/trcStreamingPort.h new file mode 100644 index 000000000..559c46ce9 --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/include/trcStreamingPort.h @@ -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 */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/trcStreamingPort.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/trcStreamingPort.c new file mode 100644 index 000000000..51f7c3b6a --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/trcStreamingPort.c @@ -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 diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/Readme-Streamport.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/Readme-Streamport.txt new file mode 100644 index 000000000..afc5a0951 --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/Readme-Streamport.txt @@ -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 \ No newline at end of file diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/include/trcStreamingPort.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/include/trcStreamingPort.h new file mode 100644 index 000000000..55088508f --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/include/trcStreamingPort.h @@ -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 + +#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 */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/trcStreamingPort.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/trcStreamingPort.c new file mode 100644 index 000000000..edd71d9b5 --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/trcStreamingPort.c @@ -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)*/ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/SEGGER_RTT_Printf.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/SEGGER_RTT_Printf.c deleted file mode 100644 index 01358682e..000000000 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/SEGGER_RTT_Printf.c +++ /dev/null @@ -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 -#include - - -#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 ****************************/ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/include/trcStreamingPort.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/include/trcStreamingPort.h index aeb0d02d7..815a61e08 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/include/trcStreamingPort.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/include/trcStreamingPort.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 * * trcStreamingPort.h @@ -7,6 +7,11 @@ * The interface definitions for trace streaming ("stream ports"). * This "stream port" sets up the recorder to use SEGGER RTT as streaming channel. * + * Note that this stream port is more complex than the typical case, since + * the J-Link interface uses a separate RAM buffer in SEGGER_RTT.c, instead + * of the default buffer included in the recorder core. The other stream ports + * offer more typical examples of how to define a custom streaming interface. + * * Terms of Use * This file is part of the trace recorder library (RECORDER), which is the * intellectual property of Percepio AB (PERCEPIO) and provided under a @@ -39,7 +44,7 @@ * * Tabs are used for indent in this file (1 tab = 4 spaces) * - * Copyright Percepio AB, 2017. + * Copyright Percepio AB, 2018. * www.percepio.com ******************************************************************************/ @@ -113,17 +118,18 @@ extern "C" { * internal RAM buffer read by the J-Link probes during execution. * * Possible values: - * - SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL (default) - * - SEGGER_RTT_MODE_NO_BLOCK_SKIP + * - SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL + * - SEGGER_RTT_MODE_NO_BLOCK_SKIP (default) * - * We recommend using SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL, to ensure you get a + * Using SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL ensure that you get a * complete and valid trace. This may however cause blocking if your streaming * interface isn't fast enough, which may disturb the real-time behavior. - * We therefore recommend to try SEGGER_RTT_MODE_NO_BLOCK_SKIP as well. - * In this mode, Tracealyzer will report lost events if the transfer is not + * + * We therefore recommend SEGGER_RTT_MODE_NO_BLOCK_SKIP. In this mode, + * Tracealyzer will report lost events if the transfer is not * fast enough. In that case, try increasing the size of the "up buffer". ******************************************************************************/ -#define TRC_CFG_RTT_MODE SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL +#define TRC_CFG_RTT_MODE SEGGER_RTT_MODE_NO_BLOCK_SKIP #include "SEGGER_RTT_Conf.h" #include "SEGGER_RTT.h" @@ -140,22 +146,18 @@ extern "C" { #if TRC_CFG_RTT_UP_BUFFER_INDEX == 0 #define TRC_RTT_ALLOC_UP() static char* _TzTraceData = NULL; /* Not actually used. Ignore allocation method. */ #define TRC_STREAM_PORT_MALLOC() /* Static allocation. Not used. */ -#define TRC_ALLOC_CUSTOM_BUFFER(bufname) /* Only for custom allocation */ #else #if TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_STATIC #define TRC_RTT_ALLOC_UP() char _TzTraceData[TRC_CFG_RTT_BUFFER_SIZE_UP]; /* Static allocation */ #define TRC_STREAM_PORT_MALLOC() /* Static allocation. Not used. */ -#define TRC_ALLOC_CUSTOM_BUFFER(bufname) /* Only for custom allocation */ #endif #if TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC #define TRC_RTT_ALLOC_UP() char* _TzTraceData = NULL; /* Dynamic allocation */ #define TRC_STREAM_PORT_MALLOC() _TzTraceData = TRC_PORT_MALLOC(TRC_CFG_RTT_BUFFER_SIZE_UP); -#define TRC_ALLOC_CUSTOM_BUFFER(bufname) /* Only for custom allocation */ #endif #if TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM #define TRC_RTT_ALLOC_UP() char* _TzTraceData = NULL; /* Custom allocation, user needs to call vTraceSetRecorderDataBuffer before vTraceEnable, to assign this */ #define TRC_STREAM_PORT_MALLOC() /* Not used in custom mode */ -#define TRC_ALLOC_CUSTOM_BUFFER(bufname) char bufname [TRC_CFG_RTT_BUFFER_SIZE_UP]; /* Not static in this case, since declared in user code */ #endif #endif @@ -170,20 +172,22 @@ extern "C" { TRC_RTT_ALLOC_UP() /* Macro that will result in proper UP buffer allocation */ \ TRC_RTT_ALLOC_DOWN() /* Macro that will result in proper DOWN buffer allocation */ +int32_t readFromRTT(void* ptrData, uint32_t size, int32_t* ptrBytesRead); + +int32_t writeToRTT(void* ptrData, uint32_t size, int32_t* ptrBytesWritten); + + #define TRC_STREAM_PORT_INIT() \ TRC_STREAM_PORT_MALLOC(); /*Dynamic allocation or empty if static */ \ SEGGER_RTT_ConfigUpBuffer(TRC_CFG_RTT_UP_BUFFER_INDEX, "TzData", _TzTraceData, TRC_CFG_RTT_BUFFER_SIZE_UP, TRC_CFG_RTT_MODE ); \ SEGGER_RTT_ConfigDownBuffer(TRC_CFG_RTT_DOWN_BUFFER_INDEX, "TzCtrl", _TzCtrlData, TRC_CFG_RTT_BUFFER_SIZE_DOWN, TRC_CFG_RTT_MODE); -#define TRC_STREAM_PORT_ALLOCATE_EVENT(_type, _ptrData, _size) _type _tmpArray[_size / sizeof(_type)]; _type* _ptrData = _tmpArray; -#define TRC_STREAM_PORT_ALLOCATE_DYNAMIC_EVENT(_type, _ptrData, _size) _type _tmpArray[sizeof(largestEventType) / sizeof(_type)]; _type* _ptrData = _tmpArray; -#define TRC_STREAM_PORT_COMMIT_EVENT(_ptrData, _size) SEGGER_RTT_Write(TRC_CFG_RTT_UP_BUFFER_INDEX, (const char*)_ptrData, _size); -#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) if (SEGGER_RTT_HASDATA(TRC_CFG_RTT_DOWN_BUFFER_INDEX)) *_ptrBytesRead = (int)SEGGER_RTT_Read(TRC_CFG_RTT_DOWN_BUFFER_INDEX, (char*)_ptrData, _size); -#define TRC_STREAM_PORT_PERIODIC_SEND_DATA(_ptrBytesSent) +/* Important for the J-Link port, in most other ports this can be skipped (default is 1) */ +#define TRC_STREAM_PORT_USE_INTERNAL_BUFFER 0 + +#define TRC_STREAM_PORT_WRITE_DATA(_ptrData, _size, _ptrBytesWritten) writeToRTT(_ptrData, _size, _ptrBytesWritten) -#define TRC_STREAM_PORT_ON_TRACE_BEGIN() /* Do nothing */ -#define TRC_STREAM_PORT_ON_TRACE_END() /* Do nothing */ - +#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) readFromRTT(_ptrData, _size, _ptrBytesRead) #ifdef __cplusplus } diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/trcStreamingPort.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/trcStreamingPort.c new file mode 100644 index 000000000..d279f83b9 --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/trcStreamingPort.c @@ -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 diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/include/trcStreamingPort.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/include/trcStreamingPort.h index 43f780696..c9edd9ee2 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/include/trcStreamingPort.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/include/trcStreamingPort.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 * * trcStreamingPort.h @@ -40,7 +40,7 @@ * * Tabs are used for indent in this file (1 tab = 4 spaces) * - * Copyright Percepio AB, 2017. + * Copyright Percepio AB, 2018. * www.percepio.com ******************************************************************************/ @@ -51,37 +51,13 @@ extern "C" { #endif -/******************************************************************************* - * TRC_RECORDER_TRANSFER_METHOD_TCPIP - * - * This stream port for TCP/IP uses a temporary buffer consisting of multiple - * pages, that are transmitted periodically by the TzCtrl task. You can modify - * the supporting functions to match your system. See trcStreamingPort.c - ******************************************************************************/ - -int32_t trcTcpWrite(void* data, uint32_t size, int32_t *ptrBytesWritten); int32_t trcTcpRead(void* data, uint32_t size, int32_t *ptrBytesRead); -#if TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_STATIC -#define TRC_STREAM_PORT_ALLOCATE_FIELDS() static char _TzTraceData[TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT * TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE]; /* Static allocation. */ -#define TRC_STREAM_PORT_MALLOC() /* Static allocation. Not used. */ -#else -#define TRC_STREAM_PORT_ALLOCATE_FIELDS() static char* _TzTraceData = NULL; /* Dynamic allocation. */ -#define TRC_STREAM_PORT_MALLOC() _TzTraceData = TRC_PORT_MALLOC(TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT * TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE); -#endif - -#define TRC_STREAM_PORT_INIT() \ - TRC_STREAM_PORT_MALLOC(); /*Dynamic allocation or empty if static */ \ - prvPagedEventBufferInit(_TzTraceData); +int32_t trcTcpWrite(void* data, uint32_t size, int32_t *ptrBytesWritten); -#define TRC_STREAM_PORT_ALLOCATE_EVENT(_type, _ptrData, _size) _type* _ptrData; _ptrData = (_type*)prvPagedEventBufferGetWritePointer(_size); -#define TRC_STREAM_PORT_ALLOCATE_DYNAMIC_EVENT(_type, _ptrData, _size) TRC_STREAM_PORT_ALLOCATE_EVENT(_type, _ptrData, _size) /* We do the same thing as for non-dynamic event sizes */ -#define TRC_STREAM_PORT_COMMIT_EVENT(_ptrData, _size) /* Not needed since we write immediately into the buffer received above by TRC_STREAM_PORT_ALLOCATE_EVENT, and the TRC_STREAM_PORT_PERIODIC_SEND_DATA defined below will take care of the actual trace transfer. */ -#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) trcTcpRead(_ptrData, _size, _ptrBytesRead); -#define TRC_STREAM_PORT_PERIODIC_SEND_DATA(_ptrBytesSent) prvPagedEventBufferTransfer(trcTcpWrite, _ptrBytesSent); +#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) trcTcpRead(_ptrData, _size, _ptrBytesRead) -#define TRC_STREAM_PORT_ON_TRACE_BEGIN() prvPagedEventBufferInit(_TzTraceData); -#define TRC_STREAM_PORT_ON_TRACE_END() /* Do nothing */ +#define TRC_STREAM_PORT_WRITE_DATA(_ptrData, _size, _ptrBytesSent) trcTcpWrite(_ptrData, _size, _ptrBytesSent) #ifdef __cplusplus } diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/trcStreamingPort.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/trcStreamingPort.c index 487aede75..0d06a1f39 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/trcStreamingPort.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/trcStreamingPort.c @@ -1,5 +1,5 @@ /******************************************************************************* - * Trace Recorder Library for Tracealyzer v3.1.2 + * Trace Recorder Library for Tracealyzer v4.1.1 * Percepio AB, www.percepio.com * * trcStreamingPort.c @@ -41,7 +41,7 @@ * * Tabs are used for indent in this file (1 tab = 4 spaces) * - * Copyright Percepio AB, 2017. + * Copyright Percepio AB, 2018. * www.percepio.com ******************************************************************************/ @@ -50,7 +50,7 @@ #if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) #if (TRC_USE_TRACEALYZER_RECORDER == 1) -/* TCP/IP includes */ +/* TCP/IP includes - for lwIP in this case */ #include "lwip/tcpip.h" #include "lwip/sockets.h" @@ -68,11 +68,14 @@ int32_t trcSocketSend( void* data, int32_t size, int32_t* bytesWritten ) if (new_sd < 0) return -1; + if (bytesWritten == NULL) + return -1; + *bytesWritten = send( new_sd, data, size, 0 ); if (*bytesWritten < 0) { /* EWOULDBLOCK may be expected when buffers are full */ - if (errno != EWOULDBLOCK) + if (errno != 0 && errno != EWOULDBLOCK) { closesocket(new_sd); new_sd = -1; @@ -94,7 +97,7 @@ int32_t trcSocketReceive( void* data, int32_t size, int32_t* bytesRead ) if ( *bytesRead < 0 ) { /* EWOULDBLOCK may be expected when there is no data to receive */ - if (errno != EWOULDBLOCK) + if (errno != 0 && errno != EWOULDBLOCK) { closesocket(new_sd); new_sd = -1; diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/USB_CDC/include/trcStreamingPort.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/USB_CDC/include/trcStreamingPort.h index 65ffc3b27..34c2e0c5f 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/USB_CDC/include/trcStreamingPort.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/USB_CDC/include/trcStreamingPort.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 * * trcStreamingPort.h @@ -40,7 +40,7 @@ * * Tabs are used for indent in this file (1 tab = 4 spaces) * - * Copyright Percepio AB, 2017. + * Copyright Percepio AB, 2018. * www.percepio.com ******************************************************************************/ @@ -51,16 +51,6 @@ extern "C" { #endif -/******************************************************************************* - * Implement the below macros to define your own stream port. If your transfer - * method uses RTOS functions, you should not send the data directly but use - * the recorder's internal buffer to store the trace data, for later transfer by - * the TzCtrl task. Check the predefined stream ports for examples on how to use - * the internal buffer (e.g., TCP/IP, UART or USB CDC). - * - * Read more at http://percepio.com/2016/10/05/rtos-tracing/ - ******************************************************************************/ - /* Include files as needed, in this case it is files from STM32Cube FW_F7 V1.4.1 */ #include "usb_device.h" #include "usbd_cdc.h" @@ -70,32 +60,21 @@ extern "C" { /* Tested on STM32 devices using Keil/CMSIS USB stack */ extern USBD_CDC_ItfTypeDef USBD_Interface_fops_FS; + uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len); int32_t trcCDCReceive(void *data, uint32_t size, int32_t* NumBytes); -int32_t trcCDCTransmit(void* data, uint32_t size, int32_t * noOfBytesSent ); -#if TRC_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_STATIC -#define TRC_STREAM_PORT_ALLOCATE_FIELDS() static char _TzTraceData[TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT * TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE]; /* Static allocation. */ -#define TRC_STREAM_PORT_MALLOC() /* Static allocation. Not used. */ -#else -#define TRC_STREAM_PORT_ALLOCATE_FIELDS() static char* _TzTraceData = NULL; /* Dynamic allocation. */ -#define TRC_STREAM_PORT_MALLOC() _TzTraceData = TRC_PORT_MALLOC(TRC_PAGED_EVENT_BUFFER_PAGE_COUNT * TRC_PAGED_EVENT_BUFFER_PAGE_SIZE); -#endif +int32_t trcCDCTransmit(void* data, uint32_t size, int32_t * noOfBytesSent ); #define TRC_STREAM_PORT_INIT() \ MX_USB_DEVICE_Init(); \ TRC_STREAM_PORT_MALLOC(); /*Dynamic allocation or empty if static */ -#define TRC_STREAM_PORT_ALLOCATE_EVENT(_type, _ptrData, _size) _type* _ptrData; _ptrData = (_type*)prvPagedEventBufferGetWritePointer(_size); +#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) trcCDCReceive(_ptrData, _size, _ptrBytesRead) -#define TRC_STREAM_PORT_ALLOCATE_DYNAMIC_EVENT(_type, _ptrData, _size) TRC_STREAM_PORT_ALLOCATE_EVENT(_type, _ptrData, _size) /* We do the same thing as for non-dynamic event sizes */ -#define TRC_STREAM_PORT_COMMIT_EVENT(_ptrData, _size) /* Not needed since we write immediately into the buffer received above by TRC_STREAM_PORT_ALLOCATE_EVENT, and the TRC_STREAM_PORT_PERIODIC_SEND_DATA defined below will take care of the actual trace transfer. */ -#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) trcCDCReceive(_ptrData, _size, _ptrBytesRead); -#define TRC_STREAM_PORT_PERIODIC_SEND_DATA(_ptrBytesSent) prvPagedEventBufferTransfer(trcCDCTransmit, _ptrBytesSent); +#define TRC_STREAM_PORT_WRITE_DATA(_ptrData, _size, _ptrBytesSent) trcCDCTransmit(_ptrData, _size, _ptrBytesSent) -#define TRC_STREAM_PORT_ON_TRACE_BEGIN() { prvPagedEventBufferInit(_TzTraceData); } -#define TRC_STREAM_PORT_ON_TRACE_END() /* Do nothing */ #ifdef __cplusplus } diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/USB_CDC/trcStreamingPort.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/USB_CDC/trcStreamingPort.c index 61755542a..800022a1b 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/USB_CDC/trcStreamingPort.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/USB_CDC/trcStreamingPort.c @@ -1,7 +1,8 @@ + #include "trcRecorder.h" #if (TRC_USE_TRACEALYZER_RECORDER == 1) -#if(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) +#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) #include "stdint.h" @@ -29,8 +30,8 @@ uint8_t UserRxBufferFS[APP_RX_DATA_SIZE]; uint8_t UserTxBufferFS[APP_TX_DATA_SIZE]; extern USBD_HandleTypeDef hUsbDeviceFS; -extern PCD_HandleTypeDef hpcd_USB_OTG_FS; +extern PCD_HandleTypeDef hpcd_USB_OTG_FS; recBuf commandBuffer; @@ -186,6 +187,7 @@ uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len) return result; } +/* The READ function, used in trcStreamingPort.h */ int32_t trcCDCReceive(void *data, uint32_t size, int32_t* NumBytes) { uint32_t i,diff; @@ -217,13 +219,18 @@ int32_t trcCDCReceive(void *data, uint32_t size, int32_t* NumBytes) return 0; } +/* The WRITE function, used in trcStreamingPort.h */ int32_t trcCDCTransmit(void* data, uint32_t size, int32_t * noOfBytesSent ) { int32_t result; - result=CDC_Transmit_FS(data,size); - *noOfBytesSent=size; - - return result; + result=CDC_Transmit_FS(data, size); + *noOfBytesSent = size; + + /* Return value should be 0 on success (not sure what the value of USBD_OK is) */ + if (result == USBD_OK) + return 0; + else + return -1; } /** diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/tracealyzer_readme.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/tracealyzer_readme.txt new file mode 100644 index 000000000..1e191f584 --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/tracealyzer_readme.txt @@ -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. \ No newline at end of file diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcKernelPort.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcKernelPort.c index 96e568a1a..e86f88ed8 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcKernelPort.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcKernelPort.c @@ -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 * * trcKernelPort.c @@ -7,7 +7,7 @@ * The FreeRTOS-specific parts of the trace recorder * * 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 * license as follows. * The RECORDER may be used free of charge for the purpose of recording data @@ -16,14 +16,14 @@ * 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 + * 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. + * 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 + * 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. @@ -38,7 +38,7 @@ * * Tabs are used for indent in this file (1 tab = 4 spaces) * - * Copyright Percepio AB, 2017. + * Copyright Percepio AB, 2018. * www.percepio.com ******************************************************************************/ @@ -50,40 +50,210 @@ #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)) - /* + /* The below error message is to alert you on the following issue: - - 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. - - When using tickless idle, the recorder needs an independent time source in order to - correctly record the durations of the idle times. Otherwise, the trace may appear + + When using "tickless idle" mode, the recorder needs an independent time source in + 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. - + You may override this warning by defining the TRC_CFG_ACKNOWLEDGE_TICKLESS_IDLE_WARNING macro in your trcConfig.h file. But then the time scale may be incorrect during tickless idle periods. - + To get this correct, override the default timestamping by setting TRC_CFG_HARDWARE_PORT in trcConfig.h to TRC_HARDWARE_PORT_APPLICATION_DEFINED and define the HWTC macros accordingly, using a free running counter or an independent periodic interrupt timer. See trcHardwarePort.h for details. - - For ARM Cortex-M3, M4 and M7 MCUs this is not an issue, since the recorder uses the - DWT cycle counter for timestamping in these cases. + + For ARM Cortex-M3, M4 and M7 MCUs this is not an issue, since the recorder uses the + DWT cycle counter for timestamping in these cases. */ - + #ifndef TRC_CFG_ACKNOWLEDGE_TICKLESS_IDLE_WARNING #error Trace Recorder: This timestamping mode is not recommended with Tickless Idle. #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 "queue.h" -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) +#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) + static void* pCurrentTCB = NULL; #if (defined(configENABLE_BACKWARD_COMPATIBILITY) && configENABLE_BACKWARD_COMPATIBILITY == 0) /* We're explicitly not using compatibility mode */ @@ -93,10 +263,12 @@ static TaskHandle_t HandleTzCtrl = NULL; /* TzCtrl task TCB */ static xTaskHandle HandleTzCtrl = NULL; /* TzCtrl task TCB */ #endif +#if defined(configSUPPORT_STATIC_ALLOCATION) #if (configSUPPORT_STATIC_ALLOCATION == 1) static StackType_t stackTzCtrl[TRC_CFG_CTRL_TASK_STACK_SIZE]; static StaticTask_t tcbTzCtrl; #endif +#endif /* Monitored by TzCtrl task, that give warnings as User Events */ extern volatile uint32_t NoRoomForSymbol; @@ -120,6 +292,8 @@ TRC_STREAM_PORT_ALLOCATE_FIELDS() /* Called by TzCtrl task periodically (Normally every 100 ms) */ static void prvCheckRecorderStatus(void); +extern void prvTraceWarning(int errCode); + /* The TzCtrl task - receives commands from Tracealyzer (start/stop) */ static portTASK_FUNCTION( TzCtrl, pvParameters ); @@ -132,14 +306,31 @@ static portTASK_FUNCTION( TzCtrl, pvParameters ); ******************************************************************************/ void vTraceEnable(int startOption) { - int bytes = 0; + int32_t bytes = 0; + int32_t status; extern uint32_t RecorderEnabled; TracealyzerCommandType msg; - if (HandleTzCtrl != NULL) - return; /* Seems we already initiated */ - - TRC_STREAM_PORT_INIT(); + /* Only do this first time...*/ + if (HandleTzCtrl == NULL) + { + 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) { @@ -147,9 +338,15 @@ void vTraceEnable(int startOption) do { bytes = 0; - TRC_STREAM_PORT_READ_DATA(&msg, sizeof(TracealyzerCommandType), &bytes); + + status = TRC_STREAM_PORT_READ_DATA(&msg, sizeof(TracealyzerCommandType), (int32_t*)&bytes); + + if (status != 0) + { + prvTraceWarning(PSF_WARNING_STREAM_PORT_READ); + } - if (bytes == sizeof(TracealyzerCommandType)) + if ((status == 0) && (bytes == sizeof(TracealyzerCommandType))) { if (prvIsValidCommand(&msg)) { @@ -158,7 +355,7 @@ void vTraceEnable(int startOption) /* On start, init and reset the timestamping */ TRC_PORT_SPECIFIC_INIT(); } - + prvProcessCommand(&msg); } } @@ -169,7 +366,7 @@ void vTraceEnable(int startOption) { /* We start streaming directly - this assumes that the interface is ready! */ TRC_PORT_SPECIFIC_INIT(); - + msg.cmdCode = CMD_SET_ACTIVE; msg.param1 = 1; prvProcessCommand(&msg); @@ -179,38 +376,9 @@ void vTraceEnable(int startOption) /* On TRC_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) * @@ -243,13 +411,58 @@ void vTraceSetSemaphoreName(void* object, const char* name) * Parameter object: pointer to the Mutex that shall be named * 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) { 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 * @@ -283,9 +496,9 @@ uint32_t prvIsNewTCB(void* pNewTCB) * Returns true if the RTOS scheduler currently is disabled, thus preventing any * 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 FreeRTOSConfig.h for this function to be available. */ @@ -304,47 +517,37 @@ static void prvCheckRecorderStatus(void) { if (NoRoomForSymbol > NoRoomForSymbol_last) { - vTracePrintF(trcWarningChannel, "TRC_CFG_SYMBOL_TABLE_SLOTS too small. Add %d slots.", - NoRoomForSymbol); - + if (NoRoomForSymbol > 0) + { + prvTraceWarning(PSF_WARNING_SYMBOL_TABLE_SLOTS); + } NoRoomForSymbol_last = NoRoomForSymbol; } if (NoRoomForObjectData > NoRoomForObjectData_last) { - vTracePrintF(trcWarningChannel, "TRC_CFG_OBJECT_DATA_SLOTS too small. Add %d slots.", - NoRoomForObjectData); - + if (NoRoomForObjectData > 0) + { + prvTraceWarning(PSF_WARNING_OBJECT_DATA_SLOTS); + } NoRoomForObjectData_last = NoRoomForObjectData; } 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.", - LongestSymbolName); + prvTraceWarning(PSF_WARNING_SYMBOL_MAX_LENGTH); } LongestSymbolName_last = LongestSymbolName; } if (MaxBytesTruncated > MaxBytesTruncated_last) { - /* Some string event generated a too long string that was truncated. - This may happen for the following functions: - - vTracePrintF - - vTracePrintF - - vTraceStoreKernelObjectName - - vTraceStoreUserEventChannelName - - vTraceSetISRProperties - - A PSF event may store maximum 60 bytes payload, including data arguments - and string characters. For User Events, also the User Event Channel ptr - must be squeezed in, if a channel is specified. */ - - vTracePrintF(trcWarningChannel, "String event too long, up to %d bytes truncated.", - MaxBytesTruncated); - + if (MaxBytesTruncated > 0) + { + prvTraceWarning(PSF_WARNING_STRING_TOO_LONG); + } MaxBytesTruncated_last = MaxBytesTruncated; } } @@ -352,14 +555,15 @@ static void prvCheckRecorderStatus(void) /******************************************************************************* * 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 ) { TracealyzerCommandType msg; - int bytes = 0; - + int32_t bytes = 0; + int32_t status = 0; (void)pvParameters; while (1) @@ -368,8 +572,14 @@ static portTASK_FUNCTION( TzCtrl, pvParameters ) { /* Listen for new commands */ 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)) { @@ -377,15 +587,21 @@ static portTASK_FUNCTION( TzCtrl, pvParameters ) } } - /* Send periodic data */ - bytes = 0; - TRC_STREAM_PORT_PERIODIC_SEND_DATA(&bytes); - /* 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. */ - } - while (bytes != 0); +/* If the internal buffer is disabled, the COMMIT macro instead sends the data directly + from the "event functions" (using TRC_STREAM_PORT_WRITE_DATA). */ +#if (TRC_STREAM_PORT_USE_INTERNAL_BUFFER == 1) + /* If there is a buffer page, this sends it to the streaming interface using TRC_STREAM_PORT_WRITE_DATA. */ + bytes = prvPagedEventBufferTransfer(); +#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(); - 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; /****************************************************************************** - * TraceObjectClassTable + * TraceQueueClassTable * Translates a FreeRTOS QueueType into trace objects classes (TRACE_CLASS_). * Has one entry for each QueueType, gives TRACE_CLASS ID. ******************************************************************************/ -traceObjectClass TraceObjectClassTable[5] = { +traceObjectClass TraceQueueClassTable[5] = { TRACE_CLASS_QUEUE, TRACE_CLASS_MUTEX, TRACE_CLASS_SEMAPHORE, @@ -410,6 +626,7 @@ traceObjectClass TraceObjectClassTable[5] = { TRACE_CLASS_MUTEX }; +#if (TRC_CFG_SCHEDULING_ONLY == 0) /******************************************************************************* * vTraceSetQueueName(void* object, const char* name) * @@ -420,7 +637,7 @@ traceObjectClass TraceObjectClassTable[5] = { ******************************************************************************/ 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) { - 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,34 +663,57 @@ void vTraceSetSemaphoreName(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); } -void* prvTraceGetCurrentTaskHandle() +#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) { - return xTaskGetCurrentTaskHandle(); + 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_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) +#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) { - return (traceHandle) uxQueueGetQueueNumber(handle); + prvTraceSetObjectName(TRACE_CLASS_STREAMBUFFER, TRACE_GET_OBJECT_NUMBER(STREAMBUFFER, object), name); } -#endif -uint8_t prvTraceGetObjectType(void* handle) +/******************************************************************************* +* 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) { - return ucQueueGetQueueType(handle); + 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) */ -traceHandle prvTraceGetTaskNumber(void* handle) +void* prvTraceGetCurrentTaskHandle() { - return (traceHandle)uxTaskGetTaskNumber(handle); + return xTaskGetCurrentTaskHandle(); } /* Initialization of the object property table */ @@ -487,6 +727,8 @@ void vTraceInitObjectPropertyTable() RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[4] = TRC_CFG_NISR; RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[5] = TRC_CFG_NTIMER; 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[1] = TRC_CFG_NAME_LEN_SEMAPHORE; 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[5] = TRC_CFG_NAME_LEN_TIMER; 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[1] = PropertyTableSizeSemaphore; RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[2] = PropertyTableSizeMutex; @@ -501,6 +745,8 @@ void vTraceInitObjectPropertyTable() RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[4] = PropertyTableSizeISR; RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[5] = PropertyTableSizeTimer; RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[6] = PropertyTableSizeEventGroup; + RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[7] = PropertyTableSizeStreamBuffer; + RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[8] = PropertyTableSizeMessageBuffer; RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[0] = StartIndexQueue; RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[1] = StartIndexSemaphore; RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[2] = StartIndexMutex; @@ -508,6 +754,8 @@ void vTraceInitObjectPropertyTable() RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[4] = StartIndexISR; RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[5] = StartIndexTimer; RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[6] = StartIndexEventGroup; + RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[7] = StartIndexStreamBuffer; + RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[8] = StartIndexMessageBuffer; RecorderDataPtr->ObjectPropertyTable.ObjectPropertyTableSizeInBytes = TRACE_OBJECT_TABLE_SIZE; } @@ -515,20 +763,24 @@ void vTraceInitObjectPropertyTable() void vTraceInitObjectHandleStack() { objectHandleStacks.indexOfNextAvailableHandle[0] = objectHandleStacks.lowestIndexOfClass[0] = 0; - objectHandleStacks.indexOfNextAvailableHandle[1] = objectHandleStacks.lowestIndexOfClass[1] = TRC_CFG_NQUEUE; - 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[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[6] = objectHandleStacks.lowestIndexOfClass[6] = TRC_CFG_NQUEUE + TRC_CFG_NSEMAPHORE + TRC_CFG_NMUTEX + TRC_CFG_NTASK + TRC_CFG_NISR + TRC_CFG_NTIMER; - - objectHandleStacks.highestIndexOfClass[0] = TRC_CFG_NQUEUE - 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[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[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.indexOfNextAvailableHandle[1] = objectHandleStacks.lowestIndexOfClass[1] = (TRC_CFG_NQUEUE); + 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[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[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[1] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) - 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[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[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 */ @@ -550,39 +802,15 @@ const char* pszTraceGetErrorNotEnoughHandles(traceObjectClass objectclass) return "Not enough TIMER handles - increase TRC_CFG_NTIMER in trcSnapshotConfig.h"; case TRACE_CLASS_EVENTGROUP: 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: 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 * @@ -590,9 +818,9 @@ uint8_t uiTraceIsObjectExcluded(traceObjectClass objectclass, traceHandle handle * task-switches from occurring. Only called from vTraceStoreISREnd. ******************************************************************************/ #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 FreeRTOSConfig.h for this function to be available. */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcSnapshotRecorder.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcSnapshotRecorder.c index 6da362010..76a1345f5 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcSnapshotRecorder.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcSnapshotRecorder.c @@ -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 * * trcSnapshotRecorder.c @@ -38,7 +38,7 @@ * * Tabs are used for indent in this file (1 tab = 4 spaces) * - * Copyright Percepio AB, 2017. + * Copyright Percepio AB, 2018. * www.percepio.com ******************************************************************************/ @@ -66,6 +66,7 @@ int32_t isPendingContextSwitch = 0; #if !defined TRC_CFG_INCLUDE_READY_EVENTS || TRC_CFG_INCLUDE_READY_EVENTS == 1 static int readyEventsEnabled = 1; #endif /*!defined TRC_CFG_INCLUDE_READY_EVENTS || TRC_CFG_INCLUDE_READY_EVENTS == 1*/ + /******************************************************************************* * uiTraceTickCount * @@ -77,7 +78,9 @@ static int readyEventsEnabled = 1; uint32_t uiTraceTickCount = 0; uint32_t trace_disable_timestamp = 0; + static uint32_t last_timestamp = 0; + /* Flag that shows if inside a critical section of the recorder */ 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. */ const char* traceErrorMessage = NULL; - int8_t nISRactive = 0; -traceHandle handle_of_last_logged_task = 0; -uint8_t inExcludedTask = 0; -extern uint8_t inExcludedTask; -extern int8_t nISRactive; -extern traceHandle handle_of_last_logged_task; +traceHandle handle_of_last_logged_task = 0; /* Called when the recorder is stopped, set by vTraceSetStopHook. */ 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 *******************************************/ static void prvStrncpy(char* dst, const char* src, uint32_t maxLength); 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 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) static void prvCheckDataToBeOverwrittenForMultiEntryEvents(uint8_t nEntries); #endif @@ -137,8 +145,7 @@ static uint8_t prvTraceGet8BitHandle(traceHandle handle); #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 #if (TRC_CFG_SCHEDULING_ONLY == 0) @@ -261,7 +268,8 @@ void vTraceSetRecorderDataBuffer(void* pRecorderData) * vTraceSetStopHook * * 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) { @@ -314,7 +322,7 @@ uint32_t uiTraceStart(void) 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; } @@ -368,7 +376,10 @@ void vTraceStart(void) ******************************************************************************/ void vTraceStop(void) { - RecorderDataPtr->recorderActive = 0; + if (RecorderDataPtr != NULL) + { + RecorderDataPtr->recorderActive = 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 * @@ -433,7 +460,6 @@ uint32_t uiTraceGetTraceBufferSize(void) * prvTraceTaskInstanceFinish * * Private common function for the vTraceTaskInstanceFinishXXX functions. - * *****************************************************************************/ static void prvTraceTaskInstanceFinish(int8_t direct) { @@ -443,7 +469,7 @@ static void prvTraceTaskInstanceFinish(int8_t direct) TRACE_ALLOC_CRITICAL_SECTION(); 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); tis = (TaskInstanceStatusEvent*) prvTraceNextFreeEventBufferSlot(); @@ -482,9 +508,6 @@ static void prvTraceTaskInstanceFinish(int8_t direct) * processCommand(command); * vTraceInstanceFinishedNext(); * } - * - * Note: This is only supported in Tracealyzer tools v2.7 or later - * *****************************************************************************/ void vTraceInstanceFinishedNext(void) { @@ -514,9 +537,6 @@ void vTraceInstanceFinishedNext(void) * DoSometingElse(); * vTraceInstanceFinishedNext(); * } - * - * Note: This is only supported in Tracealyzer tools v2.7 or later - * *****************************************************************************/ void vTraceInstanceFinishedNow(void) { @@ -546,15 +566,16 @@ void vTraceInstanceFinishedNow(void) * ... * vTraceStoreISREnd(0); * } - * ******************************************************************************/ traceHandle xTraceSetISRProperties(const char* name, uint8_t priority) { - static traceHandle handle = 0; - handle++; + static traceHandle handle = 0; + 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(name != NULL, "xTraceSetISRProperties: name == NULL", 0); + handle++; + prvTraceSetObjectName(TRACE_CLASS_ISR, handle, name); prvTraceSetPriorityProperty(TRACE_CLASS_ISR, handle, priority); @@ -578,7 +599,6 @@ void vTraceInstanceFinishedNow(void) * ... * vTraceStoreISREnd(0); * } - * ******************************************************************************/ void vTraceStoreISRBegin(traceHandle handle) { @@ -605,7 +625,8 @@ void vTraceStoreISRBegin(traceHandle handle) { 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); @@ -657,7 +678,6 @@ void vTraceStoreISRBegin(traceHandle handle) * ... * vTraceStoreISREnd(0); * } - * ******************************************************************************/ void vTraceStoreISREnd(int pendingISR) { @@ -742,6 +762,7 @@ void prvTraceDecreaseISRActive(void) } #endif /* (TRC_CFG_INCLUDE_ISR_TRACING == 1)*/ + /********************************************************************************/ /* User Event functions */ /********************************************************************************/ @@ -1036,13 +1057,13 @@ static void prvTraceClearChannelBuffer(uint32_t count) { 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); /* 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[0], 0, (count - slots)); } @@ -1063,12 +1084,12 @@ static void prvTraceCopyToDataBuffer(uint32_t* data, uint32_t count) TRACE_ASSERT(data != NULL, "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); /* 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[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_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(); /* 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 */ 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 */ if (channel != 0) @@ -1174,7 +1195,7 @@ traceUBChannel xTraceRegisterUBChannel(traceString channel, traceString formatSt TRACE_ASSERT(formatStr != 0, "xTraceRegisterChannelFormat: formatStr == 0", (traceUBChannel)0); 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) { @@ -1203,9 +1224,8 @@ traceUBChannel xTraceRegisterUBChannel(traceString channel, traceString formatSt * * 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 - * trcConfig.h - * + * Note: This is only available if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is + * enabled in trcSnapshotConfig.h ******************************************************************************/ #if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)) void vTraceUBData(traceUBChannel channelPair, ...) @@ -1228,7 +1248,7 @@ void vTraceUBData_Helper(traceUBChannel channelPair, va_list vl) traceString formatStr; 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; formatStr = RecorderDataPtr->userEventBuffer.channels[channelPair].defaultFormat; @@ -1248,7 +1268,7 @@ void vTraceUBEvent(traceUBChannel channelPair) uint32_t data[(3 + MAX_ARG_SIZE) / 4]; 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 */ } @@ -1331,7 +1351,7 @@ void vTracePrintF_Helper(traceString eventLabel, const char* formatStr, va_list 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 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->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) /* 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; traceUBChannel channel; - if (RecorderDataPtr->recorderActive && (! inExcludedTask || nISRactive) && handle_of_last_logged_task) + if (RecorderDataPtr->recorderActive && handle_of_last_logged_task) { formatLabel = xTraceRegisterString(formatStr); @@ -1452,7 +1472,7 @@ void vTracePrint(traceString chn, const char* str) TRACE_ALLOC_CRITICAL_SECTION(); 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); ue = (UserEvent*) prvTraceNextFreeEventBufferSlot(); @@ -1470,7 +1490,7 @@ void vTracePrint(traceString chn, const char* str) traceUBChannel channel; uint32_t noOfSlots = 1; 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); channel = xTraceRegisterUBChannel(chn, trcStr); @@ -1498,13 +1518,12 @@ void vTracePrint(traceString chn, const char* str) * myEventHandle = xTraceRegisterString("MyUserEvent"); * ... * vTracePrintF(myEventHandle, "My value is: %d", myValue); - * ******************************************************************************/ #if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)) traceString xTraceRegisterString(const char* label) { 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); } #endif @@ -1545,7 +1564,7 @@ void prvTraceStoreTaskReady(traceHandle handle) 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) { @@ -1566,18 +1585,15 @@ void prvTraceStoreTaskReady(traceHandle handle) trcCRITICAL_SECTION_BEGIN(); 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); - hnd8 = prvTraceGet8BitHandle(handle); - tr = (TREvent*)prvTraceNextFreeEventBufferSlot(); - if (tr != NULL) - { - tr->type = DIV_TASK_READY; - tr->dts = dts3; - tr->objHandle = hnd8; - prvTraceUpdateCounters(); - } + tr->type = DIV_TASK_READY; + tr->dts = dts3; + tr->objHandle = hnd8; + prvTraceUpdateCounters(); } } trcCRITICAL_SECTION_END(); @@ -1667,44 +1683,40 @@ void vTraceStoreMemMangEvent(uint32_t ecode, uint32_t address, int32_t signed_si if (RecorderDataPtr->recorderActive) { - /* If it is an ISR or NOT an excluded task, this kernel call will be stored in the trace */ - if (nISRactive || !inExcludedTask) + dts1 = (uint8_t)prvTraceGetDTS(0xFF); + size_low = (uint16_t)prvTraceGetParam(0xFFFF, size); + ms = (MemEventSize *)prvTraceNextFreeEventBufferSlot(); + + if (ms != NULL) { - dts1 = (uint8_t)prvTraceGetDTS(0xFF); - size_low = (uint16_t)prvTraceGetParam(0xFFFF, size); - ms = (MemEventSize *)prvTraceNextFreeEventBufferSlot(); + ms->dts = dts1; + ms->type = NULL_EVENT; /* Updated when all events are written */ + ms->size = size_low; + prvTraceUpdateCounters(); - if (ms != NULL) - { - ms->dts = dts1; - ms->type = NULL_EVENT; /* Updated when all events are written */ - ms->size = size_low; - prvTraceUpdateCounters(); - - /* 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 + /* 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; - } + 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(); if (RecorderDataPtr->recorderActive) { - /* If it is an ISR or NOT an excluded task, this kernel call will be stored in the trace */ - if (nISRactive || !inExcludedTask) + dts1 = (uint16_t)prvTraceGetDTS(0xFFFF); + hnd8 = prvTraceGet8BitHandle((traceHandle)objectNumber); + kse = (KernelCall*) prvTraceNextFreeEventBufferSlot(); + if (kse != NULL) { - /* Check if the referenced object or the event code is excluded */ - if (!uiTraceIsObjectExcluded(objectClass, (traceHandle)objectNumber) && !TRACE_GET_EVENT_CODE_FLAG_ISEXCLUDED(ecode)) - { - dts1 = (uint16_t)prvTraceGetDTS(0xFFFF); - hnd8 = prvTraceGet8BitHandle((traceHandle)objectNumber); - kse = (KernelCall*) prvTraceNextFreeEventBufferSlot(); - if (kse != NULL) - { - kse->dts = dts1; - kse->type = (uint8_t)ecode; - kse->objHandle = hnd8; - prvTraceUpdateCounters(); - } - } + kse->dts = dts1; + kse->type = (uint8_t)ecode; + kse->objHandle = hnd8; + prvTraceUpdateCounters(); } } trcCRITICAL_SECTION_END(); @@ -1818,24 +1822,19 @@ void prvTraceStoreKernelCallWithParam(uint32_t evtcode, } 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 */ - if (!uiTraceIsObjectExcluded(objectClass, (traceHandle)objectNumber) && - !TRACE_GET_EVENT_CODE_FLAG_ISEXCLUDED(evtcode)) + dts2 = (uint8_t)prvTraceGetDTS(0xFF); + p8 = (uint8_t) prvTraceGetParam(0xFF, param); + hnd8 = prvTraceGet8BitHandle((traceHandle)objectNumber); + kse = (KernelCallWithParamAndHandle*) prvTraceNextFreeEventBufferSlot(); + if (kse != NULL) { - dts2 = (uint8_t)prvTraceGetDTS(0xFF); - p8 = (uint8_t) prvTraceGetParam(0xFF, param); - hnd8 = prvTraceGet8BitHandle((traceHandle)objectNumber); - kse = (KernelCallWithParamAndHandle*) prvTraceNextFreeEventBufferSlot(); - if (kse != NULL) - { - kse->dts = dts2; - kse->type = (uint8_t)evtcode; - kse->objHandle = hnd8; - kse->param = p8; - prvTraceUpdateCounters(); - } + kse->dts = dts2; + kse->type = (uint8_t)evtcode; + kse->objHandle = hnd8; + kse->param = p8; + prvTraceUpdateCounters(); } } trcCRITICAL_SECTION_END(); @@ -1913,22 +1912,17 @@ void prvTraceStoreKernelCallWithNumericParamOnly(uint32_t evtcode, uint32_t para } trcCRITICAL_SECTION_BEGIN(); - if (RecorderDataPtr->recorderActive && handle_of_last_logged_task - && (! inExcludedTask || nISRactive)) + if (RecorderDataPtr->recorderActive && handle_of_last_logged_task) { - /* Check if the event code is excluded */ - if (!TRACE_GET_EVENT_CODE_FLAG_ISEXCLUDED(evtcode)) + dts6 = (uint8_t)prvTraceGetDTS(0xFF); + restParam = (uint16_t)prvTraceGetParam(0xFFFF, param); + kse = (KernelCallWithParam16*) prvTraceNextFreeEventBufferSlot(); + if (kse != NULL) { - dts6 = (uint8_t)prvTraceGetDTS(0xFF); - restParam = (uint16_t)prvTraceGetParam(0xFFFF, param); - kse = (KernelCallWithParam16*) prvTraceNextFreeEventBufferSlot(); - if (kse != NULL) - { - kse->dts = dts6; - kse->type = (uint8_t)evtcode; - kse->param = restParam; - prvTraceUpdateCounters(); - } + kse->dts = dts6; + kse->type = (uint8_t)evtcode; + kse->param = restParam; + prvTraceUpdateCounters(); } } trcCRITICAL_SECTION_END(); @@ -1944,44 +1938,18 @@ void prvTraceStoreTaskswitch(traceHandle task_handle) { uint16_t dts3; TSEvent* ts; - int8_t skipEvent; uint8_t hnd8; #if (TRC_CFG_INCLUDE_ISR_TRACING == 1) extern int32_t isPendingContextSwitch; #endif 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); - /* 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(); - /* Skip the event if the same task is scheduled */ - 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 ((task_handle != handle_of_last_logged_task) && (RecorderDataPtr->recorderActive)) { #if (TRC_CFG_INCLUDE_ISR_TRACING == 1) 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 * "old" one, valid up until this point. ******************************************************************************/ -#if (TRC_CFG_INCLUDE_OBJECT_DELETE == 1) -void prvTraceStoreObjectNameOnCloseEvent(traceHandle handle, +void prvTraceStoreObjectNameOnCloseEvent(uint8_t evtcode, traceHandle handle, traceObjectClass objectclass) { ObjCloseNameEvent * ce; @@ -2049,7 +2016,7 @@ void prvTraceStoreObjectNameOnCloseEvent(traceHandle handle, ce = (ObjCloseNameEvent*) prvTraceNextFreeEventBufferSlot(); if (ce != NULL) { - ce->type = (uint8_t) (EVENTGROUP_OBJCLOSE_NAME + objectclass); + ce->type = (uint8_t) evtcode; ce->objHandle = hnd8; ce->symbolIndex = idx; prvTraceUpdateCounters(); @@ -2057,7 +2024,7 @@ void prvTraceStoreObjectNameOnCloseEvent(traceHandle handle, } } -void prvTraceStoreObjectPropertiesOnCloseEvent(traceHandle handle, +void prvTraceStoreObjectPropertiesOnCloseEvent(uint8_t evtcode, traceHandle handle, traceObjectClass objectclass) { ObjClosePropEvent * pe; @@ -2081,12 +2048,11 @@ void prvTraceStoreObjectPropertiesOnCloseEvent(traceHandle handle, { pe->arg1 = TRACE_PROPERTY_OBJECT_STATE(objectclass, handle); } - pe->type = (uint8_t) (EVENTGROUP_OBJCLOSE_PROP + objectclass); + pe->type = evtcode; prvTraceUpdateCounters(); } } } -#endif void prvTraceSetPriorityProperty(uint8_t objectclass, traceHandle id, uint8_t value) { @@ -2142,16 +2108,6 @@ void prvTraceSetTaskInstanceFinished(traceHandle handle) * 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. 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 @@ -2222,7 +2178,7 @@ void prvTraceInitTraceData() RecorderDataPtr->minor_version = TRACE_MINOR_VERSION; RecorderDataPtr->irq_priority_order = TRC_IRQ_PRIORITY_ORDER; RecorderDataPtr->filesize = sizeof(RecorderDataType); - RecorderDataPtr->maxEvents = TRC_CFG_EVENT_BUFFER_SIZE; + RecorderDataPtr->maxEvents = (TRC_CFG_EVENT_BUFFER_SIZE); RecorderDataPtr->debugMarker0 = (int32_t) 0xF0F0F0F0; RecorderDataPtr->isUsing16bitHandles = TRC_CFG_USE_16BIT_OBJECT_HANDLES; RecorderDataPtr->isrTailchainingThreshold = TRC_CFG_ISR_TAILCHAINING_THRESHOLD; @@ -2231,7 +2187,7 @@ void prvTraceInitTraceData() vTraceInitObjectPropertyTable(); 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; #if (TRC_CFG_INCLUDE_FLOAT_SUPPORT == 1) RecorderDataPtr->exampleFloatEncoding = 1.0f; /* otherwise already zero */ @@ -2255,8 +2211,8 @@ void prvTraceInitTraceData() #if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER RecorderDataPtr->userEventBuffer.bufferID = 1; RecorderDataPtr->userEventBuffer.version = 0; - RecorderDataPtr->userEventBuffer.numberOfSlots = TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE; - RecorderDataPtr->userEventBuffer.numberOfChannels = TRC_CFG_UB_CHANNELS + 1; + RecorderDataPtr->userEventBuffer.numberOfSlots = (TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE); + RecorderDataPtr->userEventBuffer.numberOfChannels = (TRC_CFG_UB_CHANNELS) + 1; #endif /* Kernel specific initialization of the objectHandleStacks variable */ @@ -2289,6 +2245,15 @@ void prvTraceInitTraceData() RecorderDataPtr->startmarker1 = 0x02; 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 TRC_PORT_SPECIFIC_INIT(); @@ -2305,7 +2270,7 @@ void* prvTraceNextFreeEventBufferSlot(void) 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!"); return NULL; @@ -2336,9 +2301,14 @@ traceHandle prvTraceGetObjectHandle(traceObjectClass objectclass) traceHandle handle; static int indexOfHandle; + TRACE_ALLOC_CRITICAL_SECTION(); + + TRACE_ASSERT(RecorderDataPtr != NULL, "Recorder not initialized, call vTraceEnable() first!", (traceHandle)0); + TRACE_ASSERT(objectclass < TRACE_NCLASSES, "prvTraceGetObjectHandle: Invalid value for objectclass", (traceHandle)0); + trcCRITICAL_SECTION_BEGIN(); indexOfHandle = objectHandleStacks.indexOfNextAvailableHandle[objectclass]; if (objectHandleStacks.objectHandles[indexOfHandle] == 0) { @@ -2372,8 +2342,9 @@ traceHandle prvTraceGetObjectHandle(traceObjectClass objectclass) objectHandleStacks.handleCountWaterMarksOfClass[objectclass] = (traceHandle)hndCount; } - TRACE_CLEAR_OBJECT_FLAG_ISEXCLUDED(objectclass, handle); } + trcCRITICAL_SECTION_END(); + return handle; } @@ -2537,8 +2508,11 @@ void vTraceSetFrequency(uint32_t frequency) void prvTraceError(const char* msg) { /* Stop the recorder */ - vTraceStop(); - + if (RecorderDataPtr != NULL) + { + vTraceStop(); + } + /* If first error only... */ 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 * @@ -2623,7 +2607,7 @@ void prvTraceUpdateCounters(void) 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) RecorderDataPtr->bufferIsFull = 1; @@ -2663,16 +2647,16 @@ uint16_t prvTraceGetDTS(uint16_t param_maxDTS) if (timestampFrequency != 0) { /* 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. Note: If the default frequency value set here would be incorrect, e.g., if the timer has actually not been configured yet, override this 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 */ } @@ -2819,7 +2803,7 @@ uint16_t prvTraceCreateSymbolTableEntry(const char* name, TRACE_ASSERT(name != NULL, "prvTraceCreateSymbolTableEntry: name == NULL", 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"); 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. */ #if (TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_INCR) /* 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) /* 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 #error "TRC_HWTC_TYPE has unexpected value" #endif @@ -3081,9 +3065,9 @@ void prvTracePortGetTimeStamp(uint32_t *pTimestamp) if (pTimestamp) { /* 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. */ - 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 */ last_traceTickCount = traceTickCount; @@ -3099,10 +3083,10 @@ void prvTracePortGetTimeStamp(uint32_t *pTimestamp) diff = (hwtc_count - last_hwtc_count) + last_hwtc_rest; /* 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 */ - last_hwtc_rest = diff % TRC_HWTC_DIVISOR; + last_hwtc_rest = diff % (TRC_HWTC_DIVISOR); /* We increase the scaled timestamp by the scaled amount */ last_timestamp += diff_scaled; diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcStreamingRecorder.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcStreamingRecorder.c index 65a7d11a4..c86d688e6 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcStreamingRecorder.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcStreamingRecorder.c @@ -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 * * trcStreamingRecorder.c @@ -38,7 +38,7 @@ * * Tabs are used for indent in this file (1 tab = 4 spaces) * - * Copyright Percepio AB, 2017. + * Copyright Percepio AB, 2018. * www.percepio.com ******************************************************************************/ @@ -121,7 +121,7 @@ typedef struct{ } ObjectDataTable; typedef struct{ - uint8_t Status; + uint16_t Status; /* 16 bit to avoid implicit padding (warnings) */ uint16_t BytesRemaining; char* WritePointer; } PageType; @@ -135,13 +135,6 @@ typedef struct{ #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 */ #define PARAM_COUNT(n) ((n & 0xF) << 12) @@ -190,9 +183,9 @@ int32_t isPendingContextSwitch = 0; uint32_t uiTraceTickCount = 0; uint32_t timestampFrequency = 0; -uint32_t DroppedEventCounter = 0; // Total number of dropped events (failed allocations) -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 DroppedEventCounter = 0; +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); PageType PageInfo[TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT]; @@ -228,9 +221,9 @@ volatile uint32_t NoRoomForObjectData = 0; /******************************************************************************* * LongestSymbolName * - * Updated in prvTraceSaveSymbol. Should not exceed SYMBOL_MAX_LENGTH, otherwise - * symbol names will be truncated. In that case, set SYMBOL_MAX_LENGTH to (at - * least) this value. + * Updated in prvTraceSaveSymbol. Should not exceed TRC_CFG_SYMBOL_MAX_LENGTH, + * otherwise symbol names will be truncated. In that case, set + * TRC_CFG_SYMBOL_MAX_LENGTH to (at least) this value. ******************************************************************************/ volatile uint32_t LongestSymbolName = 0; @@ -245,15 +238,23 @@ volatile uint32_t LongestSymbolName = 0; ******************************************************************************/ volatile uint32_t MaxBytesTruncated = 0; +uint16_t CurrentFilterMask = 0xFFFF; + +uint16_t CurrentFilterGroup = FilterGroup0; + /* Internal common function for storing string events */ static void prvTraceStoreStringEventHelper( int nArgs, uint16_t eventID, traceString userEvtChannel, + int len, const char* str, 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 */ static void prvTraceStoreHeader(void); @@ -278,7 +279,8 @@ static void prvPageReadComplete(int pageIndex); /* Retrieve a buffer page to write to. */ 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); /* Performs timestamping using definitions in trcHardwarePort.h */ @@ -287,6 +289,9 @@ static uint32_t prvGetTimestamp32(void); /* Signal an error. */ void prvTraceError(int errCode); +/* Signal an warning (does not stop the recorder). */ +void prvTraceWarning(int errCode); + /****************************************************************************** * vTraceInstanceFinishedNow * @@ -315,21 +320,6 @@ void vTraceInstanceFinishedNext(void) 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 * @@ -362,6 +352,23 @@ void vTraceSetFrequency(uint32_t 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 * @@ -450,7 +457,7 @@ void vTracePrintF(traceString chn, const char* fmt, ...) { if (fmt[i] == '%') { - if (fmt[i + 1] != '%') + if (fmt[i + 1] != 0 && fmt[i + 1] != '%') { nArgs++; /* Found an argument */ } @@ -463,15 +470,15 @@ void vTracePrintF(traceString chn, const char* fmt, ...) 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 { - 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); } +#endif /* (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) */ /******************************************************************************* * xTraceSetISRProperties @@ -536,11 +543,13 @@ void vTraceStoreISRBegin(traceHandle handle) if (ISR_stack_index == -1) 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[ISR_stack_index] = (uint32_t)handle; +#if (TRC_CFG_INCLUDE_ISR_TRACING == 1) prvTraceStoreEvent1(PSF_EVENT_ISR_BEGIN, (uint32_t)handle); +#endif TRACE_EXIT_CRITICAL_SECTION(); } else @@ -578,6 +587,8 @@ void vTraceStoreISREnd(int isTaskSwitchRequired) TRACE_ALLOC_CRITICAL_SECTION(); TRACE_ENTER_CRITICAL_SECTION(); + + (void)ISR_stack; /* Is there a pending task-switch? (perhaps from an earlier ISR) */ isPendingContextSwitch |= isTaskSwitchRequired; @@ -586,8 +597,10 @@ void vTraceStoreISREnd(int isTaskSwitchRequired) { ISR_stack_index--; +#if (TRC_CFG_INCLUDE_ISR_TRACING == 1) /* Store return to interrupted ISR (if nested ISRs)*/ prvTraceStoreEvent1(PSF_EVENT_ISR_RESUME, (uint32_t)ISR_stack[ISR_stack_index]); +#endif } else { @@ -596,7 +609,9 @@ void vTraceStoreISREnd(int isTaskSwitchRequired) /* Store return to interrupted task, if no context switch will occur in between. */ if ((isPendingContextSwitch == 0) || (prvTraceIsSchedulerSuspended())) { +#if (TRC_CFG_INCLUDE_ISR_TRACING == 1) prvTraceStoreEvent1(PSF_EVENT_TS_RESUME, (uint32_t)TRACE_GET_CURRENT_TASK()); +#endif } } @@ -607,43 +622,106 @@ void vTraceStoreISREnd(int isTaskSwitchRequired) /******************************************************************************* * xTraceGetLastError * - * Returns the last error, if any. + * Returns the last error or warning, as a string, or NULL if none. *****************************************************************************/ 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.*/ + + switch (errorCode) { - return "TRC_CFG_SYMBOL_TABLE_SLOTS too small."; - } + + 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)"; - if (LongestSymbolName > (TRC_CFG_SYMBOL_MAX_LENGTH)) - { - return "TRC_CFG_SYMBOL_MAX_LENGTH too small."; - } + case PSF_WARNING_STRING_TOO_LONG: + /* Some string argument was longer than the maximum payload size + and has been truncated by "MaxBytesTruncated" bytes. - if (NoRoomForObjectData > 0) - { - return "TRC_CFG_OBJECT_DATA_SLOTS too small."; - } + This may happen for the following functions: + - vTracePrint + - vTracePrintF + - vTraceStoreKernelObjectName + - xTraceRegisterString + - vTraceSetISRProperties - if (MaxBytesTruncated > 0) - { - return "String or User Event too long."; - } + 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)."; - switch (errorCode) - { 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: - 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: - 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: - 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 + +/******************************************************************************* +* 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 *******************************************************/ /******************************************************************************/ @@ -697,6 +796,11 @@ static void prvSetRecorderEnabled(uint32_t isEnabled) TRACE_ALLOC_CRITICAL_SECTION(); + if (RecorderEnabled == isEnabled) + { + return; + } + currentTask = TRACE_GET_CURRENT_TASK(); TRACE_ENTER_CRITICAL_SECTION(); @@ -710,8 +814,12 @@ static void prvSetRecorderEnabled(uint32_t isEnabled) if (RecorderEnabled) { - prvTraceOnBegin(); - + TRC_STREAM_PORT_ON_TRACE_BEGIN(); + + #if (TRC_STREAM_PORT_USE_INTERNAL_BUFFER == 1) + prvPagedEventBufferInit(_TzTraceData); + #endif + eventCounter = 0; ISR_stack_index = -1; prvTraceStoreHeader(); @@ -726,14 +834,14 @@ static void prvSetRecorderEnabled(uint32_t isEnabled) } else { - prvTraceOnEnd(); + TRC_STREAM_PORT_ON_TRACE_END(); } TRACE_EXIT_CRITICAL_SECTION(); } /* Stores the symbol table on Start */ -static void prvTraceStoreSymbolTable() +static void prvTraceStoreSymbolTable(void) { uint32_t i = 0; uint32_t j = 0; @@ -760,7 +868,7 @@ static void prvTraceStoreSymbolTable() } /* Stores the object table on Start */ -static void prvTraceStoreObjectDataTable() +static void prvTraceStoreObjectDataTable(void) { uint32_t i = 0; uint32_t j = 0; @@ -787,7 +895,7 @@ static void prvTraceStoreObjectDataTable() } /* Stores the header information on Start */ -static void prvTraceStoreHeader() +static void prvTraceStoreHeader(void) { TRACE_ALLOC_CRITICAL_SECTION(); @@ -807,7 +915,7 @@ static void prvTraceStoreHeader() header->symbolSize = SYMBOL_TABLE_SLOT_SIZE; header->symbolCount = (TRC_CFG_SYMBOL_TABLE_SLOTS); 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)); } } @@ -815,64 +923,17 @@ static void prvTraceStoreHeader() } /* Store the current warnings */ -static void prvTraceStoreWarnings() +static void prvTraceStoreWarnings(void) { - TRACE_ALLOC_CRITICAL_SECTION(); - - TRACE_ENTER_CRITICAL_SECTION(); - if (RecorderEnabled) { - if (NoRoomForSymbol > 0) - { - vTracePrintF(trcWarningChannel, "TRC_CFG_SYMBOL_TABLE_SLOTS too small. Add %d slots.", NoRoomForSymbol); - } - - 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."); - } + const char* errStr = xTraceGetLastError(); - if (MaxBytesTruncated > 0) + if (errStr != NULL) { - /* 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; + vTracePrint(trcWarningChannel, errStr); } } - TRACE_EXIT_CRITICAL_SECTION(); } /* 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 32-bit integer parameters */ void prvTraceStoreStringEvent(int nArgs, uint16_t eventID, const char* str, ...) { + int len; va_list vl; + for (len = 0; (str[len] != 0) && (len < 52); len++); /* empty loop */ + va_start(vl, str); - prvTraceStoreStringEventHelper(nArgs, eventID, NULL, str, &vl); + prvTraceStoreStringEventHelper(nArgs, eventID, NULL, len, str, &vl); va_end(vl); } /* Internal common function for storing string events */ -static void prvTraceStoreStringEventHelper( int nArgs, +static void prvTraceStoreStringEventHelper(int nArgs, uint16_t eventID, traceString userEvtChannel, - const char* str, va_list* vl) + int len, + const char* str, + va_list* vl) { - int len; int nWords; int nStrWords; int i; @@ -1056,8 +1121,6 @@ static void prvTraceStoreStringEventHelper( int nArgs, TRACE_ALLOC_CRITICAL_SECTION(); 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) */ nStrWords = (len+1+3)/4; @@ -1140,8 +1203,8 @@ static void prvTraceStoreStringEventHelper( int nArgs, } /* Internal common function for storing string events without additional arguments */ -static void prvTraceStoreSimpleStringEventHelper( traceString userEvtChannel, - const char* str) +void prvTraceStoreSimpleStringEventHelper(traceString userEvtChannel, + const char* str) { int len; 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! */ void prvTraceError(int errCode) { @@ -1472,7 +1545,7 @@ void prvTraceError(int errCode) { errorCode = errCode; prvTraceStoreWarnings(); - vTracePrintF(trcWarningChannel, "Error detected. Stopped recorder."); + vTracePrintF(trcWarningChannel, "Recorder stopped in prvTraceError()"); 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)) uint32_t ticks = TRACE_GET_OS_TICKS(); - return (TRC_HWTC_COUNT & 0x00FFFFFFU) + ((ticks & 0x000000FFU) << 24); + return ((TRC_HWTC_COUNT) & 0x00FFFFFFU) + ((ticks & 0x000000FFU) << 24); #endif } @@ -1563,25 +1636,25 @@ static void prvTraceStoreTSConfig(void) 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, PSF_EVENT_TS_CONFIG, (uint32_t)timestampFrequency, - (uint32_t)TRACE_TICK_RATE_HZ, - (uint32_t)TRC_HWTC_TYPE, - (uint32_t)TRC_CFG_ISR_TAILCHAINING_THRESHOLD, - (uint32_t)TRC_HWTC_PERIOD); - } - else - { + (uint32_t)(TRACE_TICK_RATE_HZ), + (uint32_t)(TRC_HWTC_TYPE), + (uint32_t)(TRC_CFG_ISR_TAILCHAINING_THRESHOLD), + (uint32_t)(TRC_HWTC_PERIOD)); + + #else + prvTraceStoreEvent(4, PSF_EVENT_TS_CONFIG, (uint32_t)timestampFrequency, - (uint32_t)TRACE_TICK_RATE_HZ, - (uint32_t)TRC_HWTC_TYPE, - (uint32_t)TRC_CFG_ISR_TAILCHAINING_THRESHOLD); - } + (uint32_t)(TRACE_TICK_RATE_HZ), + (uint32_t)(TRC_HWTC_TYPE), + (uint32_t)(TRC_CFG_ISR_TAILCHAINING_THRESHOLD)); + #endif } /* Retrieve a buffer page to write to. */ @@ -1590,11 +1663,11 @@ static int prvAllocateBufferPage(int prevPage) int index; 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) @@ -1611,11 +1684,11 @@ static void prvPageReadComplete(int pageIndex) TRACE_ALLOC_CRITICAL_SECTION(); TRACE_ENTER_CRITICAL_SECTION(); - PageInfo[pageIndex].BytesRemaining = TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE; - PageInfo[pageIndex].WritePointer = &EventBuffer[pageIndex * 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].Status = PAGE_STATUS_FREE; - TotalBytesRemaining += TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE; + TotalBytesRemaining += (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE); TRACE_EXIT_CRITICAL_SECTION(); } @@ -1625,16 +1698,16 @@ static int prvGetBufferPage(int32_t* bytesUsed) { static int8_t lastPage = -1; 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) { - *bytesUsed = TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE - PageInfo[index].BytesRemaining; + *bytesUsed = (TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE) - PageInfo[index].BytesRemaining; lastPage = index; return index; } @@ -1645,63 +1718,58 @@ static int prvGetBufferPage(int32_t* bytesUsed) } /******************************************************************************* - -int32_t prvPagedEventBufferTransfer(int32_t (*writeFunc)(void* data, - uint32_t size), - int32_t* nofBytes) - -Transfers one block of trace data, if available for reading. Returns the number -of bytes transfered, or a negative error code. If data was transferred (return -value > 0), it can be good to call this function again until all data available -has been transfered. - -This function is intended to be called by a periodic task with a suitable -delay (e.g. 10-100 ms). - -Return value: as returned from writeFunc (0 == OK) - -Parameters: - -- writeFunc -Function pointer (example: int32_t write(void* data, uint32_t size)) -The function passed as writeFunc should write "size" bytes from "data" to the -socket/file/channel, and return a status code where 0 means OK, -and any other non-zero value means an error. - -- int32_t* nofBytes -Pointer to an integer assigned the number of bytes that was transfered. - -*******************************************************************************/ -int32_t prvPagedEventBufferTransfer(int32_t (*writeFunc)(void* data, uint32_t size, int32_t* ptrBytesWritten), int32_t* nofBytes) + * uint32_t prvPagedEventBufferTransfer(void) + * + * Transfers one buffer page of trace data, if a full page is available, using + * the macro TRC_STREAM_PORT_WRITE_DATA as defined in trcStreamingPort.h. + * + * This function is intended to be called the periodic TzCtrl task with a suitable + * delay (e.g. 10-100 ms). + * + * 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. + * If zero, wait a while before calling again. + * + * In case of errors from the streaming interface, it registers a warning + * (PSF_WARNING_STREAM_PORT_WRITE) provided by xTraceGetLastError(). + * + *******************************************************************************/ +uint32_t prvPagedEventBufferTransfer(void) { int8_t pageToTransfer = -1; - int32_t transferred = 0; - int32_t size = 0; - - pageToTransfer = (int8_t)prvGetBufferPage(nofBytes); - size = *nofBytes; // The number of bytes we want to transfer - transferred = 0; // The number of bytes we have transferred so far + int32_t bytesTransferredTotal = 0; + int32_t bytesTransferredNow = 0; + int32_t bytesToTransfer; + + pageToTransfer = (int8_t)prvGetBufferPage(&bytesToTransfer); + /* 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) { - 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. - transferred += *nofBytes; - if (size == transferred) + /* Write was successful. Update the number of transferred bytes. */ + bytesTransferredTotal += bytesTransferredNow; + + if (bytesTransferredTotal == bytesToTransfer) { - // All bytes have been transferred. Mark as Complete and return. - *nofBytes = transferred; + /* All bytes have been transferred. Mark the buffer page as "Read Complete" (so it can be written to) and return OK. */ prvPageReadComplete(pageToTransfer); - return 0; + return (uint32_t)bytesTransferredTotal; } } else { - *nofBytes = 0; - return 1; + /* Some error from the streaming interface... */ + 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) - -Returns a pointer to an available location in the buffer able to store the -requested size. - -Return value: The pointer. - -Parameters: - -- sizeOfEvent -The size of the event that is to be placed in the buffer. - + * void* prvPagedEventBufferGetWritePointer(int sizeOfEvent) + * + * Returns a pointer to an available location in the buffer able to store the + * requested size. + * + * Return value: The pointer. + * + * Parameters: + * - sizeOfEvent: The size of the event that is to be placed in the buffer. + * *******************************************************************************/ void* prvPagedEventBufferGetWritePointer(int sizeOfEvent) { @@ -1767,19 +1832,15 @@ void* prvPagedEventBufferGetWritePointer(int sizeOfEvent) } /******************************************************************************* - -void prvPagedEventBufferInit(char* buffer) - -Assigns the buffer to use and initializes the PageInfo structure. - -Return value: void - -Parameters: - -- buffer -Pointer to the buffer location that is dynamically or statically allocated by -the caller. - + * void prvPagedEventBufferInit(char* buffer) + * + * Assigns the buffer to use and initializes the PageInfo structure. + * + * Return value: void + * + * Parameters: + * - char* buffer: pointer to the trace data buffer, allocated by the caller. + * *******************************************************************************/ void prvPagedEventBufferInit(char* buffer) { @@ -1789,13 +1850,14 @@ void prvPagedEventBufferInit(char* buffer) EventBuffer = buffer; 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].WritePointer = &EventBuffer[i * 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].Status = PAGE_STATUS_FREE; } TRACE_EXIT_CRITICAL_SECTION(); + } #endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/ diff --git a/FreeRTOS-Plus/Source/readme.txt b/FreeRTOS-Plus/Source/readme.txt deleted file mode 100644 index 85de14c70..000000000 --- a/FreeRTOS-Plus/Source/readme.txt +++ /dev/null @@ -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. - -- 2.39.5