970|1

504

帖子

4

TA的资源

纯净的硅(高级)

楼主
 

《嵌入式软件的时间分析》从书中到实践-使用Tracealyzer进行RTOS调试分析 [复制链接]

书中分享了很多理论,方法和案例,

基于本书,本人在此基础上再分享一些更贴近实战的案例分享。

本人公众号(嵌入式软硬件技术:RTOS,GUI,FS,协议栈,ARM,总线,嵌入式C,开发环境 and blablaba....多年经验分享,非硬货不发,带你扒开每一个技术背后的根本原理。)

 

 

一. 前言

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

Percepio的Tracealyzer;

SEGGER的SystemView;

Micrium的μC/Probe。

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

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

分享上位机工具下载

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

提取码:mzy7

lSystemView是SEGGER开发,原配自家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 
 

 

如果你的硬件在上面中存在,则在文件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.h,trcStreamPort.h添加到头文件包含路径

TraceRecorderSource/streamports/MY_STREAM/include
TraceRecorderSource/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);

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

 

以下几个可以使用内部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 <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 */

 

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

 

 

需要注意的是,使用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 <trcRecorder.h>

    /* 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负载

 

 

 

五.总结

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

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

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

 

 

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

 

此帖出自汽车电子论坛

最新回复

大佬好厉害!学到了     详情 回复 发表于 2024-6-25 11:51
点赞(1) 关注

回复
举报

61

帖子

0

TA的资源

一粒金砂(中级)

沙发
 

大佬好厉害!学到了

 

此帖出自汽车电子论坛
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表