使用Tracealyzer进行RTOS调试分析

原创 嵌入式Lee 2024-05-30 08:00

一. 前言

本文来介绍RTOS调试利器,可视化Trace工具,常见的有以下几个

PercepioTracealyzer;

SEGGERSystemView;

MicriumμC/Probe

lμC/Probe是元老级别工具,相信很多人最开始接触RTOS Trace的技术就是从它开始的,它也是伴随着uC/OS而知名,甚至很早前还流出过其上位机源码,是配合uCOS调试的最佳利器。当然也可以调试其他RTOS甚至NO OS,其特点是上位机GUI灵活的配置,可以拖拽GUI显示不同的界面,类似GUIBuildTarget源码可以从以下地址下载

https://github.com/weston-embedded/uC-Probe-Target

分享上位机工具下载

链接:https://pan.baidu.com/s/1s60qEaSoFEmGBxm3sFb-dA?pwd=mzy7

提取码:mzy7

lSystemViewSEGGER开发,原配自家RTOS embOS,当然也支持其他主流RTOS比如uC/OS-III, Micrium OS Kernel, FreeRTOS, NuttX Zephyr ,上位机和Target源码可从如下地址下载https://www.segger.com/downloads/systemview/

lPercepio则是目前最亮眼之星,丰富的事件,信号等图表,使用简单,UI个人感觉更适合时序分析。分享上位机工具如下:

链接:https://pan.baidu.com/s/1agHqqQ0M-Yo9wv30Ft-C3g?pwd=kzcq

提取码:kzcq

二. 安装Tracealyzer

注意:安装软件仅供学习使用,请支持正版软件。

双击打开Tracealyzer-4.6.5-windows64.exe,弹出用户账户控制,点击是

点击Next

选择安装路径,点击Install

点击Finish

使用Tracealyzer.exe, Tracealyzer.exe.config替换安装目录D:\Program Files\Percepio\Tracealyzer 4下的文件.

打开Tracealyzer.exe

解压I_LOVE_DVT.rar
打开TracealyzerKeyfileMaker.exe点击Generate生成license文件

弹出对话框点击确认,点击Exit退出。把license文件保存在某个地方,我这里放在安装路径D:\Program Files\Percepio\Tracealyzer 4下。

运行Tracealyzer,指定刚生成的license文件

.工程中添加Tracealyzer源码

3.1下载源码

https://github.com/percepio/TraceRecorderSource/tags

选择对应版本

查看工具版本,我这里是4.6.5

Help->About Percepio Tracealyzer

git clone --branch Tz4/4.6/v4.6.5 https://github.com/percepio/TraceRecorderSource.git

3.2添加源码到自己的工程

需要以下源码

以下源码无需任何修改

|-- 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

配置如下头文件包含路径

TraceRecorderSource/include

TraceRecorderSource/config

3.3平台适配

3.3.1头文件包含路径

配置头文件包含路径,这里以FreeRTOS为例,其他平台参考kernelports对应目录

TraceRecorderSource/kernelports/FreeRTOS/config

TraceRecorderSource/kernelports/FreeRTOS/include

3.3.2配置FREERTOS版本

TraceRecorderSource/kernelports/FreeRTOS/config/trcKernelPortConfig.h下修改

#define TRC_CFG_FREERTOS_VERSION FREERTOS_VERSION_NOT_SET

#define TRC_CFG_FREERTOS_VERSION TRC_FREERTOS_VERSION_10_2_1

我这里使用的是10.2.1版本。

3.3.3配置头文件

TraceRecorderSource/config/trcConfig.h

注释掉

#error "Trace Recorder: Please include your processor's header file here and remove this line."

添加

#include "FreeRTOS.h"

3.3.4 Kernel port

我这里直接使用

TraceRecorderSource/kernelports/FreeRTOS/,其他平台可以根据模板修改,实现对应的接口。

添加头文件包含路径

TraceRecorderSource/kernelports/FreeRTOS/config

TraceRecorderSource/kernelports/FreeRTOS/include

和源码

TraceRecorderSource/kernelports/FreeRTOS/trcKernelPort.c

该源码需要实现

xTraceKernelPortEnable

xTraceKernelPortInitialize

3.3.5 trace宏接口

FreeRTOSConfig.h的最后#include "trcRecorder.h"

portmacro.h

#define portBASE_TYPE   int32_t

改为

#define portBASE_TYPE   int

3.4适配时间相关硬件接口

TraceRecorderSource/include/trcDefines.h下定义了支持的port

/****** 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         FreeRTOS            */

如果你的硬件在上面中存在,则在文件TraceRecorderSource/config/trcConfig.h中定义宏TRC_CFG_HARDWARE_PORT为上述指定值。

我这里将

#define TRC_CFG_HARDWARE_PORT TRC_HARDWARE_PORT_NOT_SET

改为上述指定的值,我这里改为TRC_HARDWARE_PORT_APPLICATION_DEFINED即自行实现

#define TRC_CFG_HARDWARE_PORT TRC_HARDWARE_PORT_APPLICATION_DEFINED

可以看到TraceRecorderSource/include/trcHardwarePort.h中根据配置宏TRC_CFG_HARDWARE_PORT实现的接口

比如配置为TRC_HARDWARE_PORT_APPLICATION_DEFINED如下

#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

则需要在上述位置实现以下接口

TRC_HWTC_TYPE

可配置为如下值

#define TRC_FREE_RUNNING_32BIT_INCR 1  /* 0计数到0xFFFFFFFF */

#define TRC_FREE_RUNNING_32BIT_DECR 2  /* 0xFFFFFFFF计数到0 */

#define TRC_OS_TIMER_INCR 3   /*OS TICK为单位 0 计数到(TRC_HWTC_PERIOD-1)*/

#define TRC_OS_TIMER_DECR 4  /*OS TICK为单位 (TRC_HWTC_PERIOD-1)计数到0*/

#define TRC_CUSTOM_TIMER_INCR 5  /* 0计数到TRC_HWTC_PERIOD-1 */

#define TRC_CUSTOM_TIMER_DECR 6 /*TRC_HWTC_PERIOD-1 计数到 0*/

TRC_HWTC_COUNT

获取当前的时间戳,原型为TraceUnsignedBaseType_t TRC_HWTC_COUNT(void)

TRC_HWTC_PERIOD

HWTC_COUNT获取的时间戳的范围

如果前面TRC_HWTC_TYPE使用TRC_FREE_RUNNING_32BIT_INCR/DECR则必须配置为0

TRC_HWTC_FREQ_HZ

HWTC_COUNT获取的时间戳的频率

TRC_IRQ_PRIORITY_ORDER

配置为1表示高优先级任务的优先级数越大,配置为0则反之。FREERTOS配置为1

我这里最终实现如下

#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

需要实现获取时间戳接口

我这里xx_timer_get_time是获取的1uS为单位的定时器的时间

uint32_t my_stream_get_tick(void){    return xx_timer_get_time();}

3.5 适配通讯接口

streamports下有模板,需要和模板实现一样的目录和文件名

我这里新建一个文件夹MY_STREAM,内容如下,可以直接从其他模板复制。

|-- config

| `-- trcStreamPortConfig.h

|-- include

| `-- trcStreamPort.h

`-- trcStreamPort.c

需要将上述trcStreamPortConfig.htrcStreamPort.h添加到头文件包含路径

TraceRecorderSource/streamports/MY_STREAM/includeTraceRecorderSource/streamports/MY_STREAM/config

TraceRecorderSource/streamports/MY_STREAM/trcStreamPort.c添加到工程源码中。

该文件下需要实现以下接口

其中以下几个是必须需要实现的

/** * @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);

以下几个可以使用内部Buffer,使用宏

#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如下

#include 
#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 #include
#ifdef __cplusplusextern "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 */

TraceRecorderSource/streamports/MY_STREAM/config/trcStreamPortConfig.h内容如下

/* * 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 __cplusplusextern "C" {#endif
/** * @def 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 */

需要注意的是,使用TRC_USE_INTERNAL_BUFFER=1

TraceRecorderSource/streamports/MY_STREAM/config/trcStreamPortConfig.h

#define TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_SIZE 35000

可能太大导致RAM不够,可以改小该内部存储。

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初始化

vStartScheduler();前 调用如下接口初始化

#include 
    /* First initialize */    xTraceInitialize();    /*启动kernel*/    /* Start tracing */    xTraceEnable(TRC_START);或者xTraceEnable(TRC_START_FROM_HOST);

3.7 中断栈 任务栈 堆

由于中断中回调执行一些trace回调函数,所以中断栈注意要加大一点。

注意设置任务栈大小要合适

TraceRecorderSource/config/trcConfig.h

#define TRC_CFG_CTRL_TASK_STACK_SIZE 2048

注意内部堆大小设置

/streamports/MY_STREAM/config/trcStreamPortConfig.h

#define TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_SIZE 10240

系统使用堆大小,FreeRTOSConfig.h

#define configTOTAL_HEAP_SIZE           ((size_t)((unsigned char *)&_heap_size))

.创建Tracealyzer工程测试

打开Tracealyzer软件

创建流trace,对应源码

TRC_USE_TRACEALYZER_RECORDER配置为1 使能trace

TRC_CFG_RECORDER_MODE 配置为TRC_RECORDER_MODE_STREAMING 流模式

配置通讯接口我这里使用CDC,和串口一样,点击OK

点击Start Session,启动。

抓取到数据后,各窗口显示相应的图表

比如事件窗口可以清晰的看到任务的调度过程

比如CPU负载

.总结

我们这里搭建了基于FreeRTOSTracealyzer环境,后续我们再分享一系列文章,分享下Tracealyzer的原理,然后分享一些典型的案例。

注意代码和Tracealyzer工具的版本要匹配,否则会提示错误

比如如下提示代码版本高于工具

另外就是注意堆栈的设置,以及数据收发接口,最好是使用fifo方式。












评论
  • 高速先生成员--黄刚这不马上就要过年了嘛,高速先生就不打算给大家上难度了,整一篇简单但很实用的文章给大伙瞧瞧好了。相信这个标题一出来,尤其对于PCB设计工程师来说,心就立马凉了半截。他们辛辛苦苦进行PCB的过孔设计,高速先生居然说设计多大的过孔他们不关心!另外估计这时候就跳出很多“挑刺”的粉丝了哈,因为翻看很多以往的文章,高速先生都表达了过孔孔径对高速性能的影响是很大的哦!咋滴,今天居然说孔径不关心了?别,别急哈,听高速先生在这篇文章中娓娓道来。首先还是要对各位设计工程师的设计表示肯定,毕竟像我
    一博科技 2025-01-21 16:17 169浏览
  •     IPC-2581是基于ODB++标准、结合PCB行业特点而指定的PCB加工文件规范。    IPC-2581旨在替代CAM350格式,成为PCB加工行业的新的工业规范。    有一些免费软件,可以查看(不可修改)IPC-2581数据文件。这些软件典型用途是工艺校核。    1. Vu2581        出品:Downstream     
    电子知识打边炉 2025-01-22 11:12 153浏览
  • 故障现象 一辆2007款日产天籁车,搭载VQ23发动机(气缸编号如图1所示,点火顺序为1-2-3-4-5-6),累计行驶里程约为21万km。车主反映,该车起步加速时偶尔抖动,且行驶中加速无力。 图1 VQ23发动机的气缸编号 故障诊断接车后试车,发动机怠速运转平稳,但只要换挡起步,稍微踩下一点加速踏板,就能感觉到车身明显抖动。用故障检测仪检测,发动机控制模块(ECM)无故障代码存储,且无失火数据流。用虹科Pico汽车示波器测量气缸1点火信号(COP点火信号)和曲轴位置传感器信
    虹科Pico汽车示波器 2025-01-23 10:46 95浏览
  • 数字隔离芯片是一种实现电气隔离功能的集成电路,在工业自动化、汽车电子、光伏储能与电力通信等领域的电气系统中发挥着至关重要的作用。其不仅可令高、低压系统之间相互独立,提高低压系统的抗干扰能力,同时还可确保高、低压系统之间的安全交互,使系统稳定工作,并避免操作者遭受来自高压系统的电击伤害。典型数字隔离芯片的简化原理图值得一提的是,数字隔离芯片历经多年发展,其应用范围已十分广泛,凡涉及到在高、低压系统之间进行信号传输的场景中基本都需要应用到此种芯片。那么,电气工程师在进行电路设计时到底该如何评估选择一
    华普微HOPERF 2025-01-20 16:50 134浏览
  • 2024年是很平淡的一年,能保住饭碗就是万幸了,公司业绩不好,跳槽又不敢跳,还有一个原因就是老板对我们这些员工还是很好的,碍于人情也不能在公司困难时去雪上加霜。在工作其间遇到的大问题没有,小问题还是有不少,这里就举一两个来说一下。第一个就是,先看下下面的这个封装,你能猜出它的引脚间距是多少吗?这种排线座比较常规的是0.6mm间距(即排线是0.3mm间距)的,而这个规格也是我们用得最多的,所以我们按惯性思维来看的话,就会认为这个座子就是0.6mm间距的,这样往往就不会去细看规格书了,所以这次的运气
    wuliangu 2025-01-21 00:15 378浏览
  • 现在为止,我们已经完成了Purple Pi OH主板的串口调试和部分配件的连接,接下来,让我们趁热打铁,完成剩余配件的连接!注:配件连接前请断开主板所有供电,避免敏感电路损坏!1.1 耳机接口主板有一路OTMP 标准四节耳机座J6,具备进行音频输出及录音功能,接入耳机后声音将优先从耳机输出,如下图所示:1.21.2 相机接口MIPI CSI 接口如上图所示,支持OV5648 和OV8858 摄像头模组。接入摄像头模组后,使用系统相机软件打开相机拍照和录像,如下图所示:1.3 以太网接口主板有一路
    Industio_触觉智能 2025-01-20 11:04 200浏览
  • 嘿,咱来聊聊RISC-V MCU技术哈。 这RISC-V MCU技术呢,简单来说就是基于一个叫RISC-V的指令集架构做出的微控制器技术。RISC-V这个啊,2010年的时候,是加州大学伯克利分校的研究团队弄出来的,目的就是想搞个新的、开放的指令集架构,能跟上现代计算的需要。到了2015年,专门成立了个RISC-V基金会,让这个架构更标准,也更好地推广开了。这几年啊,这个RISC-V的生态系统发展得可快了,好多公司和机构都加入了RISC-V International,还推出了不少RISC-V
    丙丁先生 2025-01-21 12:10 751浏览
  • 飞凌嵌入式基于瑞芯微RK3562系列处理器打造的FET3562J-C全国产核心板,是一款专为工业自动化及消费类电子设备设计的产品,凭借其强大的功能和灵活性,自上市以来得到了各行业客户的广泛关注。本文将详细介绍如何启动并测试RK3562J处理器的MCU,通过实际操作步骤,帮助各位工程师朋友更好地了解这款芯片。1、RK3562J处理器概述RK3562J处理器采用了4*Cortex-A53@1.8GHz+Cortex-M0@200MHz架构。其中,4个Cortex-A53核心作为主要核心,负责处理复杂
    飞凌嵌入式 2025-01-24 11:21 88浏览
  •  万万没想到!科幻电影中的人形机器人,正在一步步走进我们人类的日常生活中来了。1月17日,乐聚将第100台全尺寸人形机器人交付北汽越野车,再次吹响了人形机器人疯狂进厂打工的号角。无独有尔,银河通用机器人作为一家成立不到两年时间的创业公司,在短短一年多时间内推出革命性的第一代产品Galbot G1,这是一款轮式、双臂、身体可折叠的人形机器人,得到了美团战投、经纬创投、IDG资本等众多投资方的认可。作为一家成立仅仅只有两年多时间的企业,智元机器人也把机器人从梦想带进了现实。2024年8月1
    刘旷 2025-01-21 11:15 726浏览
  • 临近春节,各方社交及应酬也变得多起来了,甚至一月份就排满了各式约见。有的是关系好的专业朋友的周末“恳谈会”,基本是关于2025年经济预判的话题,以及如何稳定工作等话题;但更多的预约是来自几个客户老板及副总裁们的见面,他们为今年的经济预判与企业发展焦虑而来。在聊天过程中,我发现今年的聊天有个很有意思的“点”,挺多人尤其关心我到底是怎么成长成现在的多领域风格的,还能掌握一些经济趋势的分析能力,到底学过哪些专业、在企业管过哪些具体事情?单单就这个一个月内,我就重复了数次“为什么”,再辅以我上次写的:《
    牛言喵语 2025-01-22 17:10 203浏览
  • Ubuntu20.04默认情况下为root账号自动登录,本文介绍如何取消root账号自动登录,改为通过输入账号密码登录,使用触觉智能EVB3568鸿蒙开发板演示,搭载瑞芯微RK3568,四核A55处理器,主频2.0Ghz,1T算力NPU;支持OpenHarmony5.0及Linux、Android等操作系统,接口丰富,开发评估快人一步!添加新账号1、使用adduser命令来添加新用户,用户名以industio为例,系统会提示设置密码以及其他信息,您可以根据需要填写或跳过,命令如下:root@id
    Industio_触觉智能 2025-01-17 14:14 154浏览
我要评论
1
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦