This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] F29H859TU-Q1:是否可以查看 CCS 中的存储器停顿数?

Guru**** 2330840 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1485593/f29h859tu-q1-possibility-to-view-number-of-memory-stalls-in-ccs

器件型号:F29H859TU-Q1

工具/软件:

团队、

F29x 架构由于其 CPU 架构、允许并行加载和存储。 如果出现存储器停滞、是否有办法在 Code Composer Studio 中查看这些错误? 也许通过读一些统计寄存器?

分析并行存储器访问是否会导致 CPU 停滞、在这种情况下播放存储器放置位置可能会提高性能、这将非常有用。

谢谢、
 Robert

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 TI 团队:
    可能要补充的是:我们正在寻找硬件上的某种性能计数器、这些计数器会计算失速周期、缓存/缓冲区命中和未命中、计数指令等。 这些内容非常有助于了解我们软件在给定硬件上的行为。

    非常感谢、非常感谢!
    Andre Goebel

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    此器件上没有缓存。 我认为我们没有任何此类计数器可用于读取失速周期。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我与我们的团队讨论了这个问题、看起来我们确实在器件中有一些机制可以通过 ERAD 模块进行检查。 我将把这篇文章分配给我们的 ERAD 专家以提供更多详细信息。

    此致、

    Vivek Singh

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Robert:

    我创建了一个使用 r1_ready 和 exe_ready 来捕获等待状态和内存保护停止的示例。

    exe-ready 计数 :这是由于读写内存等待状态而导致的停止计数。 请注意、由于存储器保护而导致的流水线停滞不会显示在此处。

    R1就绪计数 :这是由于读取等待状态和内存保护停止而导致的停止计数。

    ERAD_Counter_Config sec_params;
    
    ERAD_setCounterOwnership(ERAD_COUNTER0, ERAD_OWNER_APPLICATION);
    sec_params.event = ERAD_EVENT_CPUx_CPI_R1_READY;
    sec_params.event_mode = ERAD_COUNTER_MODE_ACTIVE;
    sec_params.reference = 0xFFFFFFFF;
    ERAD_setCounterInputConditioning(ERAD_COUNTER0, ERAD_COUNTER_COUNT_INPUT, ERAD_INPUT_INVERT_ENABLE);
    ERAD_configCounterInCountingMode(ERAD_COUNTER0, sec_params);
    
    ERAD_setCounterOwnership(ERAD_COUNTER1, ERAD_OWNER_APPLICATION);
    sec_params.event = ERAD_EVENT_CPUx_CPI_EXE_READY;
    sec_params.event_mode = ERAD_COUNTER_MODE_ACTIVE;
    sec_params.reference = 0xFFFFFFFF;
    ERAD_setCounterInputConditioning(ERAD_COUNTER1, ERAD_COUNTER_COUNT_INPUT, ERAD_INPUT_INVERT_ENABLE);
    ERAD_configCounterInCountingMode(ERAD_COUNTER1, sec_params);
    ERAD_enableModules(ERAD_INST_COUNTER0 | ERAD_INST_COUNTER1);

    我正在尝试以将其添加到我们的 SDK 中为例、也可能会将其添加为我们的 TRM 中的小节。

    此致、

    Ryan Ma

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Robert:

    以下是一个完整的示例、您可以复制并粘贴到 ERAD ex1_profile_function_no_syscfg.c 中、其中展示了如何执行启动/停止模式来查找存储器停滞。  

    我使用 EBC BUSCOMP7/6来触发 SEC 计数器0/1的启动/停止计数器条件。 使用 r1_ready 作为 SEC0的源、使用 exe_ready 作为 SEC1的源。

    您可能需要更新结束地址、以防您的结束地址因某种原因而不同。  

    //#############################################################################
    //
    // FILE:   erad_ex1_profile_function_no_syscfg.c
    //
    // TITLE:  ERAD Profile Function.
    //
    //! \addtogroup driver_example_list
    //! <h1>ERAD Profile Function</h1>
    //!
    //!  This example uses BUSCOMP7, BUSCOMP6 and COUNTER0 of the ERAD module to
    //!  profile a function (delayFunction). It calculates the CPU cycles taken
    //!  between the the start address of the function to the end address of the
    //!  function
    //!
    //!  Two dummy variable are written to inside the function - startCount and
    //!  endCount. BUSCOMP5, BUSCOMP4 and COUNTER1 are used to profile the time
    //!  taken between the access to startCount variable till the access to
    //!  endCount variable.
    //!
    //!  Both the counters are setup to operate in START-STOP mode and count the
    //!  number of CPU cycles spend between the respective bus comparator events.
    //!
    //!  Note: The Enhanced Bus Comparator (EBC) modules are used in the
    //!  decreasing order of their instances in this example. This is because, in
    //!  FLASH configuration/ when hardware breakpoints are used while debugging,
    //!  the first few ERAD EBCs are owned by the Debugger and are blocked for the
    //!  application to use.
    //!
    //!  \b Watch \b Variables \n
    //!   - cycles_Function_Max - the maximum number of cycles between the start 
    //!                           of function to the end of function
    //!   - cycles_Function_Min - the minimum number of cycles between the start 
    //!                           of function to the end of function
    //!   - cycles_Data_Max     - the maximum number of cycles taken between
    //!                           accessing startCount variable to endCount 
    //!                           variable
    //!   - cycles_Data_Min     - the minimum number of cycles taken between
    //!                           accessing startCount variable to endCount 
    //!                           variable
    //!
    //! \b External \b Connections \n
    //!  None
    //
    //#############################################################################
    
    //
    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"
    #include "erad.h"
    
    //
    // Global Variables
    //
    
    //
    // Start and end address of the function delayFunction.
    // This value comes from the linker command file.
    //
    extern uint32_t delayFuncStart, delayFuncEnd;
    
    //
    // The variables used in the function which are monitored by bus comparators
    // 3 and 4.
    //
    volatile uint32_t startCount = 0;
    volatile uint32_t endCount = 0;
    
    //
    // Watch variables with the number of CPU cycles elapsed.
    //
    volatile uint32_t cycles_Function_Max = 0;
    volatile uint32_t cycles_Function_Min = 0xFFFFFFFF;
    volatile uint32_t cycles_Data_Max = 0;
    volatile uint32_t cycles_Data_Min = 0xFFFFFFFF;
    
    ERAD_Profile_Params params;
    
    //
    // Function Prototypes
    //
    __attribute__ ((section(".delayFunc"), noinline))
    void delayFunction(uint16_t);
    
    //
    // Main
    //
    int main(void)
    {
        uint16_t i;
    
        //
        // Initializes device clock and peripherals
        //
        Device_init();
    
        //
        // Parameters for profiling function.
        // The PC value is being monitored here.
        //
        params.start_address = (uint32_t)&delayFuncStart;
        params.end_address   = (uint32_t)&delayFuncEnd - 4U;
        params.bus_sel       = ERAD_BUSCOMP_BUS_VPC_I_ALIGNED;
        params.busComp_instance1 = ERAD_BUSCOMP7;
        params.busComp_instance2 = ERAD_BUSCOMP6;
        params.counter_instance  = ERAD_COUNTER2;
    
        //
        // Configuring the required ERAD submodules
        //
        ERAD_profile(params);
    
        //
        // Parameters for profiling the time between the accesses
        // to startCount and endCount variables.
        // The address in the Data Write Address Bus is monitored here.
        //
        params.start_address = (uint32_t)&startCount;
        params.end_address   = (uint32_t)&endCount;
        params.bus_sel       = ERAD_BUSCOMP_BUS_DWAB;
        params.busComp_instance1 = ERAD_BUSCOMP5;
        params.busComp_instance2 = ERAD_BUSCOMP4;
        params.counter_instance  = ERAD_COUNTER3;
        
        //
        // Configuring the required ERAD submodules
        //
        ERAD_profile(params);
    
        ERAD_Counter_Config sec_params;
    
        ERAD_setCounterOwnership(ERAD_COUNTER0, ERAD_OWNER_APPLICATION);
        sec_params.event = ERAD_EVENT_CPUx_CPI_R1_READY;
        sec_params.event_mode = ERAD_COUNTER_MODE_ACTIVE;
        sec_params.reference = 0xFFFFFFFF;
        ERAD_setCounterInputConditioning(ERAD_COUNTER0, ERAD_COUNTER_COUNT_INPUT, ERAD_INPUT_INVERT_ENABLE);
        ERAD_configCounterInStartStopMode(ERAD_COUNTER0, sec_params, ERAD_EVENT_EBC7, ERAD_EVENT_EBC6);
    
        ERAD_setCounterOwnership(ERAD_COUNTER1, ERAD_OWNER_APPLICATION);
        sec_params.event = ERAD_EVENT_CPUx_CPI_EXE_READY;
        sec_params.event_mode = ERAD_COUNTER_MODE_ACTIVE;
        sec_params.reference = 0xFFFFFFFF;
        ERAD_setCounterInputConditioning(ERAD_COUNTER1, ERAD_COUNTER_COUNT_INPUT, ERAD_INPUT_INVERT_ENABLE);
        ERAD_configCounterInStartStopMode(ERAD_COUNTER1, sec_params, ERAD_EVENT_EBC7, ERAD_EVENT_EBC6);
        ERAD_enableModules(ERAD_INST_COUNTER0 | ERAD_INST_COUNTER1 | ERAD_INST_COUNTER2 | ERAD_INST_COUNTER3);
        //
        // Loop to call the delay function repeatedly with different delays
        //
        for(i=0; i<10; i++)
        {
            delayFunction(i % 5);
    
            //
            // View these variables in CCS view
            // Note that calling the function ERAD_getCurrentValue here will
            // return 0 since the stop events have already been occurred.
            //
            cycles_Function_Max = ERAD_getMaxCount(ERAD_COUNTER0);
            cycles_Data_Max     = ERAD_getMaxCount(ERAD_COUNTER1);
    
            cycles_Function_Min = ERAD_getMinCount(ERAD_COUNTER0);
            cycles_Data_Min     = ERAD_getMinCount(ERAD_COUNTER1);
    
            ESTOP0;
    
            //
            // Uncomment the code below to clear the maximum and minimum count
            //
            // ERAD_setMaxCount(ERAD_COUNTER0, 0);
            // ERAD_setMaxCount(ERAD_COUNTER1, 0);
            // ERAD_setMinCount(ERAD_COUNTER0, 0xFFFFFFFF);
            // ERAD_setMinCount(ERAD_COUNTER1, 0xFFFFFFFF);
        }
    
        ESTOP0;
        while(1);
    }
    
    //
    // Delay function
    //
    void delayFunction(uint16_t delay)
    {
        startCount++;
        uint16_t some_math = 15*4;
        uint16_t i = 0;
        for (; i < delay * 100; i++)
        {
            NOP;
            NOP;
            NOP;
            NOP;
            NOP;
            NOP;
            NOP;
            NOP;
            uint16_t output = some_math * 35 - 3 + 139 * startCount;
    
        }
    
        endCount++;
    }
    
    //
    // End of File
    //
    

    此致、

    Ryan Ma

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Robert:

    对此有何反馈? 这对您所寻找的产品有什么帮助吗?

    请注意、

    Vivek Singh

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、 Vivek Singh

    我得为我迟交的答复道歉。 我已经尝试过您的示例、但在链接时仍然收到以下错误:

    ...
    [9] makefile:185:目标"HVB3_OBC_F29_001.out"的配置失败
    [10]警告#10247-D:创建不带段规范的输出段".delayFunc"

    [11]未定义的首次引用
    [12]文件中的符号
    [13]——— ------------------------
    [14] delayFuncEnd /work/bsw/firmware/config/stu/erad_ex1_profile_function_no_syscfg.o
    [15] delayFuncStart /work/bsw/firmware/config/stu/erad_ex1_profile_function_no_syscfg.o

    [16]错误#10234-D:保留未解析的符号
    [17]错误#10010:链接时遇到错误;"HVB3_OBC_F29_001.out"未构建
    [18]c29clang:错误:c29lnk 命令失败、退出代码为1 (使用-v 查看调用)
    [19]gmake[1]:***[HVB3_OBC_F29_001.out]错误1
    [20]makefile:181:目标"全部"的配方失败
    [21]gmake:***[全部]错误2.

    您有什么 解决方法吗?

    我正想使用 address 运算符作为 start 和 sizeof ()来获得结尾 您认为这是合理的吗?

    此致、
    安德烈

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Andre、

    您有没有 办法解决?
    [/报价]

    您能否导入 ERAD ex1_profile_function_no_syscfg  并将其内容替换为我提供的内容?

    这可能是因为您的 HVB3_OB_F29_001工程没有在链接器 cmd 文件中定义这些函数。 在我们的示例中、我们使用以下.cmd 文件设置起始/结束地址。

    此致、

    Ryan Ma

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Ryan:
    非常感谢您的提示。 我已将该部分添加到我的工程中、现在它可以很好地链接。 我想我们现在可以关闭该票证。
    谢谢你。
    此致、
    安德烈