The book shares many theories, methods and cases.
Based on this book, I will share some case studies that are closer to actual combat.
My official account (Embedded hardware and software technology: RTOS, GUI, FS, protocol stack, ARM, bus, embedded C, development environment and blablaba... Years of experience sharing, only hard stuff will be published, take you to uncover the fundamental principles behind each technology.)
I. Introduction
This article introduces RTOS debugging tools, visual trace tools, the common ones are the following
Tracealyzer by Percepio;
SystemView by SEGGER;
Micrium's μC/Probe.
lμC/Probe is a veteran tool. I believe that many people first came into contact with RTOS Trace technology from it. It is also well-known along with uC/OS. Even its host computer source code was leaked a long time ago. It is the best tool for debugging with uCOS. Of course, it can also debug other RTOS or even NO OS. Its feature is the flexible configuration of the host computer GUI. You can drag and drop the GUI to display different interfaces, similar to GUIBuild. The Target source code can be downloaded from the following address
https://github.com/weston-embedded/uC-Probe-Target .
Share PC tool download
Link: https://pan.baidu.com/s/1s60qEaSoFEmGBxm3sFb-dA?pwd=mzy7
Extraction code: mzy7
lSystemView is developed by SEGGER and comes with its own RTOS embOS. Of course, it also supports other mainstream RTOS such as uC/OS-III, Micrium OS Kernel, FreeRTOS, NuttX and Zephyr. The host and Target source code can be downloaded from the following address: https://www.segger.com/downloads/systemview/
lPercepio is the brightest star at present, with rich event, signal and other charts, easy to use, and UI that I personally feel is more suitable for timing analysis. The upper computer tools are as follows:
Link: https://pan.baidu.com/s/1agHqqQ0M-Yo9wv30Ft-C3g?pwd=kzcq
Extraction code: kzcq
2. Install Tracealyzer
Note: The installation software is for learning purposes only, please support genuine software.
Double-click to open Tracealyzer-4.6.5-windows64.exe, the User Account Control pops up, click Yes
Click Next
Select the installation path and click Install
Click Finish
Use Tracealyzer.exe and Tracealyzer.exe.config to replace the files in the installation directory D:\Program Files\Percepio\Tracealyzer 4.
Open Tracealyzer.exe
Unzip I_LOVE_DVT.rar,
open TracealyzerKeyfileMaker.exe, and click Generate! to generate a license file
Click Confirm in the pop-up dialog box, and then click Exit to exit. Save the license file somewhere, I put it in the installation path D:\Program Files\Percepio\Tracealyzer 4.
Run Tracealyzer and specify the license file just generated
3. Add Tracealyzer source code to the project
3.1 Download source code
https://github.com/percepio/TraceRecorderSource/tags
Select the corresponding version
Check the tool version, mine is 4.6.5
Help->About Percepio Tracealyzer
git clone --branch Tz4/4.6/v4.6.5 https://github.com/percepio/TraceRecorderSource.git
3.2 Add source code to your own project
The following source code is required
The following source code does not require any modification
|-- trcAssert.c
|-- trcCounter.c
|-- trcDiagnostics.c
|-- trcEntryTable.c
|-- trcError.c
|-- trcEvent.c
|-- trcEventBuffer.c
|-- trcExtension.c
|-- trcHardwarePort.c
|-- trcHeap.c
|-- trcISR.c
|-- trcInternalEventBuffer.c
|-- trcInterval.c
|-- trcMultiCoreEventBuffer.c
|-- trcObject.c
|-- trcPrint.c
|-- trcSnapshotRecorder.c
|-- trcStackMonitor.c
|-- trcStateMachine.c
|-- trcStaticBuffer.c
|-- trcStreamingRecorder.c
|-- trcString.c
|-- trcTask.c
`-- trcTimestamp.c
Configure the following header file include path
TraceRecorderSource/include
TraceRecorderSource/config
3.3 Platform Adaptation
3.3.1 Header file include path
Configure the header file include path. Here we take FreeRTOS as an example. For other platforms, refer to the kernelports directory.
TraceRecorderSource/kernelports/FreeRTOS/config
TraceRecorderSource/kernelports/FreeRTOS/include
3.3.2Configure FREERTOS version
Modify TraceRecorderSource/kernelports/FreeRTOS/config/trcKernelPortConfig.h
#define TRC_CFG_FREERTOS_VERSION FREERTOS_VERSION_NOT_SET
for
#define TRC_CFG_FREERTOS_VERSION TRC_FREERTOS_VERSION_10_2_1
I am using version 10.2.1 here.
3.3.3 Configuration header file
TraceRecorderSource/config/trcConfig.h
Comment out
#error "Trace Recorder: Please include your processor's header file here and remove this line."
Add to
#include "FreeRTOS.h"
3.3.4 Kernel port
I use it directly here
TraceRecorderSource/kernelports/FreeRTOS/. Other platforms can be modified according to the template to implement the corresponding interface.
Add header file include path
TraceRecorderSource/kernelports/FreeRTOS/config
TraceRecorderSource/kernelports/FreeRTOS/include
and source code
TraceRecorderSource/kernelports/FreeRTOS/trcKernelPort.c
This source code needs to be implemented
xTraceKernelPortEnable
xTraceKernelPortInitialize
3.3.5 trace macro interface
At the end of FreeRTOSConfig.h #include "trcRecorder.h"
portmacro.h
#define portBASE_TYPE int32_t
Change to
#define portBASE_TYPE int
3.4 Adapting time-related hardware interfaces
The supported ports are defined in TraceRecorderSource/include/trcDefines.h.
/****** Port Name ************************************* Code ** Official ** OS Platform *********/
#define TRC_HARDWARE_PORT_APPLICATION_DEFINED 98 /* - - */
#define TRC_HARDWARE_PORT_NOT_SET 99 /* - - */
#define TRC_HARDWARE_PORT_HWIndependent 0 /* Yes Any */
#define TRC_HARDWARE_PORT_Win32 1 /* Yes FreeRTOS on Win32 */
#define TRC_HARDWARE_PORT_Atmel_AT91SAM7 2 /* No Any */
#define TRC_HARDWARE_PORT_Atmel_UC3A0 3 /* No Any */
#define TRC_HARDWARE_PORT_ARM_Cortex_M 4 /* Yes Any */
#define TRC_HARDWARE_PORT_Renesas_RX600 6 /* Yes Any */
#define TRC_HARDWARE_PORT_MICROCHIP_PIC24_PIC32 7 /* Yes Any */
#define TRC_HARDWARE_PORT_TEXAS_INSTRUMENTS_TMS570_RM48 8 /* Yes Any */
#define TRC_HARDWARE_PORT_TEXAS_INSTRUMENTS_MSP430 9 /* No Any */
#define TRC_HARDWARE_PORT_XILINX_PPC405 11 /* No FreeRTOS */
#define TRC_HARDWARE_PORT_XILINX_PPC440 12 /* No FreeRTOS */
#define TRC_HARDWARE_PORT_XILINX_MICROBLAZE 13 /* No Any */
#define TRC_HARDWARE_PORT_XILINX_ZyncUltraScaleR5 14 /* No FreeRTOS */
#define TRC_HARDWARE_PORT_NXP_LPC210X 15 /* No Any */
#define TRC_HARDWARE_PORT_ARM_CORTEX_A9 16 /* Yes Any */
#define TRC_HARDWARE_PORT_POWERPC_Z4 17 /* No FreeRTOS */
#define TRC_HARDWARE_PORT_Altera_NiosII 18 /* Yes Any (Tested with FreeRTOS) */
#define TRC_HARDWARE_PORT_ZEPHYR 19 /* Yes Zephyr */
#define TRC_HARDWARE_PORT_XTensa_LX6 20 /* Yes ESP-IDF FreeRTOS */
#define TRC_HARDWARE_PORT_XTensa_LX7 21 /* Yes ESP-IDF FreeRTOS */
#define TRC_HARDWARE_PORT_Win64 22 /* Yes FreeRTOS on Win64 */
#define TRC_HARDWARE_PORT_XMOS_XCOREAI 23 /* Yes FreeRTOS SMP */
#define TRC_HARDWARE_PORT_RISCV_RV32I 24 /* Yes FreeRTOS */
#define TRC_HARDWARE_PORT_CYCLONE_V_HPS 25 /* Yes
If your hardware exists in the above, define the macro TRC_CFG_HARDWARE_PORT in the file TraceRecorderSource/config/trcConfig.h to the specified value above.
I will
#define TRC_CFG_HARDWARE_PORT TRC_HARDWARE_PORT_NOT_SET
Change to the value specified above. I changed it to TRC_HARDWARE_PORT_APPLICATION_DEFINED to implement it myself
#define TRC_CFG_HARDWARE_PORT TRC_HARDWARE_PORT_APPLICATION_DEFINED
You can see the interface implemented by the configuration macro TRC_CFG_HARDWARE_PORT in TraceRecorderSource/include/trcHardwarePort.h
For example, the configuration is TRC_HARDWARE_PORT_APPLICATION_DEFINED as follows
#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_APPLICATION_DEFINED)
#if !( defined (TRC_HWTC_TYPE) && defined (TRC_HWTC_COUNT) && defined (TRC_HWTC_PERIOD) && defined (TRC_HWTC_FREQ_HZ) && defined (TRC_IRQ_PRIORITY_ORDER) )
#error "The hardware port is not completely defined!"
#endif
You need to implement the following interface in the above location
TRC_HWTC_TYPE
Can be configured as follows
#define TRC_FREE_RUNNING_32BIT_INCR 1 /* Count from 0 to 0xFFFFFFFF */
#define TRC_FREE_RUNNING_32BIT_DECR 2 /* Count from 0xFFFFFFFF to 0 */
#define TRC_OS_TIMER_INCR 3 /*Count in units of OS TICK 0 to (TRC_HWTC_PERIOD-1)*/
#define TRC_OS_TIMER_DECR 4 /*Count to 0 in units of OS TICK (TRC_HWTC_PERIOD-1)*/
#define TRC_CUSTOM_TIMER_INCR 5 /* Count from 0 to TRC_HWTC_PERIOD-1 */
#define TRC_CUSTOM_TIMER_DECR 6 /*Count from TRC_HWTC_PERIOD-1 to 0*/
TRC_HWTC_COUNT
Get the current timestamp, the prototype is TraceUnsignedBaseType_t TRC_HWTC_COUNT(void)
TRC_HWTC_PERIOD
The range of timestamps obtained by HWTC_COUNT
If the previous TRC_HWTC_TYPE uses TRC_FREE_RUNNING_32BIT_INCR/DECR, it must be configured to 0
TRC_HWTC_FREQ_HZ
HWTC_COUNT obtains the frequency of timestamps
TRC_IRQ_PRIORITY_ORDER
Configuring it to 1 means that the higher the priority number of the high-priority task, and configuring it to 0 means the opposite. FREERTOS is configured to 1.
Here is what I finally achieved:
#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_APPLICATION_DEFINED)
extern uint32_t my_stream_get_tick(void);
#define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR
#define TRC_HWTC_COUNT my_stream_get_tick()
#define TRC_HWTC_FREQ_HZ 1000000
#define TRC_HWTC_PERIOD 0
#define TRC_IRQ_PRIORITY_ORDER 1
#if !( defined (TRC_HWTC_TYPE) && defined (TRC_HWTC_COUNT) && defined (TRC_HWTC_PERIOD) && defined (TRC_HWTC_FREQ_HZ) && defined (TRC_IRQ_PRIORITY_ORDER) )
#error "The hardware port is not completely defined!"
#endif
Need to implement the timestamp interface
Here, xx_timer_get_time is the time of the timer in 1uS units.
uint32_t my_stream_get_tick(void)
{
return xx_timer_get_time();
}
3.5 Communication interface adapter
There are templates under streamports, which need the same directory and file name as the template implementation
I create a new folder MY_STREAM here, the content is as follows, you can copy it directly from other templates.
|-- config
| `-- trcStreamPortConfig.h
|-- include
| `-- trcStreamPort.h
`-- trcStreamPort.c needs to add the above trcStreamPortConfig.h, trcStreamPort.h to the header file include path
TraceRecorderSource/streamports/MY_STREAM/include
TraceRecorderSource/streamports/MY_STREAM/config
TraceRecorderSource/streamports/MY_STREAM/trcStreamPort.c is added to the project source code.
The following interface needs to be implemented in this file
The following are the ones that must be implemented
/**
* @internal Stream port initialize callback.
*
* This function is called by the recorder as part of its initialization phase.
*
* @param[in] pxBuffer Buffer
*
* @retval TRC_FAIL Initialization failed
* @retval TRC_SUCCESS Success
*/
traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer);
/**
* [url=home.php?mod=space&uid=159083]@brief[/url] Reads data through the stream port interface.
*
* @param[in] pvData Destination data buffer
* @param[in] uiSize Destination data buffer size
* @param[out] piBytesRead Bytes read
*
* @retval TRC_FAIL Read failed
* @retval TRC_SUCCESS Success
*/
traceResult xTraceStreamPortReadData(void* pvData, uint32_t uiSize, int32_t* piBytesRead);
/**
* @brief Writes data through the stream port interface.
*
* @param[in] pvData Data to write
* @param[in] uiSize Data to write size
* @param[out] piBytesWritten Bytes written
*
* @retval TRC_FAIL Write failed
* @retval TRC_SUCCESS Success
*/
traceResult xTraceStreamPortWriteData(void* pvData, uint32_t uiSize, int32_t* piBytesWritten);
The following can use the internal Buffer, using macros
#define TRC_USE_INTERNAL_BUFFER 1
/**
* @brief Allocates data from the stream port.
*
* @param[in] uiSize Allocation size
* @param[out] ppvData Allocation data pointer
*
* @retval TRC_FAIL Allocate failed
* @retval TRC_SUCCESS Success
*/
#define xTraceStreamPortAllocate xTraceInternalEventBufferAlloc
/**
* @brief Commits data to the stream port, depending on the implementation/configuration of the
* stream port this data might be directly written to the stream port interface, buffered, or
* something else.
*
* @param[in] pvData Data to commit
* @param[in] uiSize Data to commit size
* @param[out] piBytesCommitted Bytes committed
*
* @retval TRC_FAIL Commit failed
* @retval TRC_SUCCESS Success
*/
#define xTraceStreamPortCommit xTraceInternalEventBufferAllocCommit
#define xTraceStreamPortOnEnable(uiStartOption) ((void)(uiStartOption), TRC_SUCCESS)
#define xTraceStreamPortOnDisable() (TRC_SUCCESS)
#define xTraceStreamPortOnTraceBegin() (TRC_SUCCESS)
#define xTraceStreamPortOnTraceEnd() (TRC_SUCCESS)
TraceRecorderSource/streamports/MY_STREAM/trcStreamPort.c is as follows
#include <trcRecorder.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
/**
* @brief Reads data through the stream port interface.
*
* @param[in] pvData Destination data buffer
* @param[in] uiSize Destination data buffer size
* @param[out] piBytesRead Bytes read
*
* @retval TRC_FAIL Read failed
* @retval TRC_SUCCESS Success
*/
traceResult xTraceStreamPortReadData(void* pvData, uint32_t uiSize, int32_t* piBytesRead)
{
(void)pvData;
(void)uiSize;
(void)piBytesRead;
return TRC_SUCCESS;
}
traceResult xTraceStreamPortWriteData(void* pvData, uint32_t uiSize, int32_t* piBytesWritten)
{
(void)pvData;
(void)uiSize;
(void)piBytesWritten;
return TRC_SUCCESS;
}
traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer)
{
TRC_ASSERT_EQUAL_SIZE(TraceStreamPortBuffer_t, TraceStreamPortRTT_t);
if (pxBuffer == 0)
{
return TRC_FAIL;
}
#if (TRC_USE_INTERNAL_BUFFER == 1)
return xTraceInternalEventBufferInitialize(pxBuffer->buffer,sizeof(pxBuffer->buffer));
#else
return TRC_SUCCESS;
#endif
}
#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/
#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/
TraceRecorderSource/streamports/MY_STREAM/include/trcStreamPort.h内容如下
#ifndef TRC_STREAM_PORT_H
#define TRC_STREAM_PORT_H
#include <trcTypes.h>
#include <trcStreamPortConfig.h>
#ifdef __cplusplus
extern "C" {
#endif
#define TRC_USE_INTERNAL_BUFFER 1
#define TRC_INTERNAL_EVENT_BUFFER_WRITE_MODE (TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_WRITE_MODE)
#define TRC_INTERNAL_EVENT_BUFFER_TRANSFER_MODE (TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_TRANSFER_MODE)
#define TRC_INTERNAL_BUFFER_CHUNK_SIZE (TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_CHUNK_SIZE)
#define TRC_INTERNAL_BUFFER_CHUNK_TRANSFER_AGAIN_SIZE_LIMIT (TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_CHUNK_TRANSFER_AGAIN_SIZE_LIMIT)
#define TRC_INTERNAL_BUFFER_CHUNK_TRANSFER_AGAIN_COUNT_LIMIT (TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_CHUNK_TRANSFER_AGAIN_COUNT_LIMIT)
#define TRC_STREAM_PORT_USB_BUFFER_SIZE ((((TRC_CFG_STREAM_PORT_USB_BUFFER_SIZE) + sizeof(TraceUnsignedBaseType_t) - 1) / sizeof(TraceUnsignedBaseType_t)) * sizeof(TraceUnsignedBaseType_t))
#define TRC_STREAM_PORT_INTERNAL_BUFFER_SIZE ((((TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_SIZE) + sizeof(TraceUnsignedBaseType_t) - 1) / sizeof(TraceUnsignedBaseType_t)) * sizeof(TraceUnsignedBaseType_t))
typedef struct TraceStreamPortBuffer /* Aligned */
{
uint8_t buffer[(TRC_STREAM_PORT_USB_BUFFER_SIZE) + (TRC_STREAM_PORT_INTERNAL_BUFFER_SIZE) + sizeof(TraceUnsignedBaseType_t)];
} TraceStreamPortBuffer_t;
/**
* @internal Stream port initialize callback.
*
* This function is called by the recorder as part of its initialization phase.
*
* @param[in] pxBuffer Buffer
*
* @retval TRC_FAIL Initialization failed
* @retval TRC_SUCCESS Success
*/
traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer);
/**
* @brief Reads data through the stream port interface.
*
* @param[in] pvData Destination data buffer
* @param[in] uiSize Destination data buffer size
* @param[out] piBytesRead Bytes read
*
* @retval TRC_FAIL Read failed
* @retval TRC_SUCCESS Success
*/
traceResult xTraceStreamPortReadData(void* pvData, uint32_t uiSize, int32_t* piBytesRead);
/**
* @brief Writes data through the stream port interface.
*
* @param[in] pvData Data to write
* @param[in] uiSize Data to write size
* @param[out] piBytesWritten Bytes written
*
* @retval TRC_FAIL Write failed
* @retval TRC_SUCCESS Success
*/
traceResult xTraceStreamPortWriteData(void* pvData, uint32_t uiSize, int32_t* piBytesWritten);
/**
* @brief Allocates data from the stream port.
*
* @param[in] uiSize Allocation size
* @param[out] ppvData Allocation data pointer
*
* @retval TRC_FAIL Allocate failed
* @retval TRC_SUCCESS Success
*/
#define xTraceStreamPortAllocate xTraceInternalEventBufferAlloc
/**
* @brief Commits data to the stream port, depending on the implementation/configuration of the
* stream port this data might be directly written to the stream port interface, buffered, or
* something else.
*
* @param[in] pvData Data to commit
* @param[in] uiSize Data to commit size
* @param[out] piBytesCommitted Bytes committed
*
* @retval TRC_FAIL Commit failed
* @retval TRC_SUCCESS Success
*/
#define xTraceStreamPortCommit xTraceInternalEventBufferAllocCommit
#define xTraceStreamPortOnEnable(uiStartOption) ((void)(uiStartOption), TRC_SUCCESS)
#define xTraceStreamPortOnDisable() (TRC_SUCCESS)
#define xTraceStreamPortOnTraceBegin() (TRC_SUCCESS)
#define xTraceStreamPortOnTraceEnd() (TRC_SUCCESS)
#ifdef __cplusplus
}
#endif
#endif /* TRC_STREAM_PORT_H */
The content of TraceRecorderSource/streamports/MY_STREAM/config/trcStreamPortConfig.h is as follows
/*
* Trace Recorder for Tracealyzer v4.8.2
* Copyright 2023 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The configuration for trace streaming ("stream ports").
*/
#ifndef TRC_STREAM_PORT_CONFIG_H
#define TRC_STREAM_PORT_CONFIG_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* [url=home.php?mod=space&uid=567129]@def[/url] TRC_CFG_STREAM_PORT_DELAY_ON_BUSY
*
* @brief The time to wait if the USB interface is busy.
*/
#define TRC_CFG_STREAM_PORT_DELAY_ON_BUSY 1
/**
* @def TRC_CFG_STREAM_PORT_USB_BUFFER_SIZE
*
* @brief Specifies the size of the usb buffer.
*/
#define TRC_CFG_STREAM_PORT_USB_BUFFER_SIZE 64
/**
* @def TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_SIZE
*
* @brief Configures the size of the internal buffer if used.
*/
#define TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_SIZE 10240
/**
* @def TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_WRITE_MODE
*
* @brief This should be set to TRC_INTERNAL_EVENT_BUFFER_OPTION_WRITE_MODE_DIRECT for best performance.
*/
#define TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_WRITE_MODE TRC_INTERNAL_EVENT_BUFFER_OPTION_WRITE_MODE_DIRECT
/**
* @def TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_TRANSFER_MODE
*
* @brief Defines if the internal buffer will attempt to transfer all data each time or limit it to a chunk size.
*/
#define TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_TRANSFER_MODE TRC_INTERNAL_EVENT_BUFFER_OPTION_TRANSFER_MODE_ALL
/**
* @def TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_CHUNK_SIZE
*
* @brief Defines the maximum chunk size when transferring
* internal buffer events in chunks.
*/
#define TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_CHUNK_SIZE 64
/**
* @def TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_CHUNK_TRANSFER_AGAIN_SIZE_LIMIT
*
* @brief Defines the number of transferred bytes needed to trigger another transfer.
* It also depends on TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_CHUNK_TRANSFER_AGAIN_COUNT_LIMIT to set a maximum number
* of additional transfers this loop.
* This will increase throughput by immediately doing a transfer and not wait for another xTraceTzCtrl() loop.
*/
#define TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_CHUNK_TRANSFER_AGAIN_SIZE_LIMIT 64
/**
* @def TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_CHUNK_TRANSFER_AGAIN_COUNT_LIMIT
*
* @brief Defines the maximum number of times to trigger another transfer before returning to xTraceTzCtrl().
* It also depends on TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_CHUNK_TRANSFER_AGAIN_SIZE_LIMIT to see if a meaningful amount of data was
* transferred in the last loop.
* This will increase throughput by immediately doing a transfer and not wait for another xTraceTzCtrl() loop.
*/
#define TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_CHUNK_TRANSFER_AGAIN_COUNT_LIMIT 5
#ifdef __cplusplus
}
#endif
#endif /* TRC_STREAM_PORT_CONFIG_H */
It should be noted that when using TRC_USE_INTERNAL_BUFFER=1
TraceRecorderSource/streamports/MY_STREAM/config/trcStreamPortConfig.h
#define TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_SIZE 35000
It may be too large, resulting in insufficient RAM. You can reduce the internal storage.
typedef struct TraceStreamPortBuffer
{
uint8_t buffer[(TRC_STREAM_PORT_USB_BUFFER_SIZE) + (TRC_STREAM_PORT_INTERNAL_BUFFER_SIZE) + sizeof(TraceUnsignedBaseType_t)];
} TraceStreamPortBuffer_t;
3.6 Initialization
Call the following interface to initialize before vStartScheduler();
#include <trcRecorder.h>
/* First initialize */
xTraceInitialize();
/*启动kernel*/
/* Start tracing */
xTraceEnable(TRC_START);或者xTraceEnable(TRC_START_FROM_HOST);
3.7 Interrupt Stack Task Stack
Since some trace callback functions are executed during the interrupt, the interrupt stack should be enlarged.
Pay attention to setting the task stack size appropriately
TraceRecorderSource/config/trcConfig.h
#define TRC_CFG_CTRL_TASK_STACK_SIZE 2048
Note the internal heap size settings
/streamports/MY_STREAM/config/trcStreamPortConfig.h
#define TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_SIZE 10240
The system uses the heap size, FreeRTOSConfig.h
#define configTOTAL_HEAP_SIZE ((size_t)((unsigned char *)&_heap_size))
4. Create Tracealyzer Engineering Test
Open Tracealyzer software
Create a stream trace, corresponding to the source code
TRC_USE_TRACEALYZER_RECORDER is set to 1 to enable trace
TRC_CFG_RECORDER_MODE is configured as TRC_RECORDER_MODE_STREAMING streaming mode
Configure the communication interface. I use CDC here, just like the serial port. Click OK.
Click Start Session to start.
After the data is captured, each window displays the corresponding chart
For example, the event window can clearly see the scheduling process of the task
For example, CPU load
5. Conclusion
We have built a Tracealyzer environment based on FreeRTOS. Later, we will share a series of articles to share the principles of Tracealyzer and some typical cases.
Note that the version of the code and the Tracealyzer tool must match, otherwise an error will be prompted
For example, the following prompts that the code version is higher than the tool
In addition, pay attention to the stack settings and data receiving and sending interfaces. It is best to use the fifo method.