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.

[参考译文] AM263P4-Q1:FreeRTOS CPU 负载计算稳定时间

Guru**** 2454880 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1468701/am263p4-q1-freertos-cpu-load-calculation-settling-time

器件型号:AM263P4-Q1

工具/软件:

您好:

我正在 以一个间隔在两个内核中读取 TaskP_loadGetTotalCpuLoad()的值。  configGENERATE_RUN_TIME_STATS=1。 FreeRTOS 来自 SDK 09_02_00_56。

内核0具有 FreeRTOS、带有一些 CAN 代码、但没有太多其他代码。 内核3只有 FreeRTOS、会调度某些任务。

问题是对 CPU 负载计算进行了大量过滤。 大约需要一分钟才能达到稳定值。 是否有任何方法可以对其进行调整以更快地做出响应? 我不介意有一点噪音。

以下是 FreeRTOS 配置文件:

/*
 *  Copyright (C) 2018-2021 Texas Instruments Incorporated
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *    Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 *    Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the
 *    distribution.
 *
 *    Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 *  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 THE COPYRIGHT
 *  OWNER OR CONTRIBUTORS 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.
 */


#ifndef TI_FREERTOS_CONFIG_H
#define TI_FREERTOS_CONFIG_H

#ifdef __cplusplus
extern "C"
{
#endif

#include <kernel/dpl/DebugP.h>

/*-----------------------------------------------------------
 * Application specific definitions.
 *
 * These definitions should be adjusted for your particular hardware and
 * application requirements.
 *
 * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
 * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE AND IN THE
 * FreeRTOS REFERENCE MANUAL.
 *----------------------------------------------------------*/

/* Keep below as 1 if the most optimized task switching latency is needed.
 * This disables tracing, logging, assert and other error checks.
 * So unless every last cycle of task switching is important leave this as 0.
 *
 * This is not a FreeRTOS defined config and is defined by TI to quickly switch
 * between optimized and not-so-optimized config
 */
#define configOPTIMIZE_FOR_LATENCY              (0)

#define configUSE_PREEMPTION					(1)
#define configUSE_PORT_OPTIMISED_TASK_SELECTION	(0)
#define configUSE_TICKLESS_IDLE                 (1)
#define configUSE_IDLE_HOOK                     (1)  /* when 1, make sure to implement void vApplicationIdleHook(void) as the hook function */
#define configUSE_MALLOC_FAILED_HOOK            (0)
#define configUSE_DAEMON_TASK_STARTUP_HOOK      (0)
#define configUSE_TICK_HOOK                     (0)
#define configCPU_CLOCK_HZ                      (0) /* NOT USED in TI ports */
#define configSYSTICK_CLOCK_HZ                  (0) /* NOT USED in TI ports */
#define configTICK_RATE_HZ                      (10000)
#define configMAX_PRIORITIES                    (32)
#define configMINIMAL_STACK_SIZE                (1024) /* in units of configSTACK_DEPTH_TYPE, not bytes */
#define configMAX_TASK_NAME_LEN                 (32)
#define configUSE_TRACE_FACILITY                (1)
#if (configOPTIMIZE_FOR_LATENCY==0)
#define configUSE_STATS_FORMATTING_FUNCTIONS    (1)
#else
#define configUSE_STATS_FORMATTING_FUNCTIONS    (0)
#endif
#define configUSE_16_BIT_TICKS                  (0)
#define configIDLE_SHOULD_YIELD                 (1)
#define configUSE_TASK_NOTIFICATIONS            (1)
#define configTASK_NOTIFICATION_ARRAY_ENTRIES   (1)
#define configUSE_MUTEXES                       (1)
#define configUSE_RECURSIVE_MUTEXES             (1)
#define configUSE_COUNTING_SEMAPHORES           (1)
#define configUSE_ALTERNATIVE_API               (0)

/* when = 1, Need to provied below,
 *    void vApplicationStackOverflowHook( TaskHandle_t xTask,
 *           char *pcTaskName );
 */
#if (configOPTIMIZE_FOR_LATENCY==0)
#define configCHECK_FOR_STACK_OVERFLOW          (1)
#else
#define configCHECK_FOR_STACK_OVERFLOW          (0)
#endif
#define configQUEUE_REGISTRY_SIZE               (32)
#define configUSE_QUEUE_SETS                    (0)
#define configUSE_TIME_SLICING                  (0) /* keep as 0 to get same functionality as SysBIOS6 */
#define configUSE_NEWLIB_REENTRANT              (0)
#define configENABLE_BACKWARD_COMPATIBILITY     (1)
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS (4)
#define configSTACK_DEPTH_TYPE                  UBaseType_t
#define configMESSAGE_BUFFER_LENGTH_TYPE        size_t
#define configSUPPORT_STATIC_ALLOCATION         (1) /* when = 1, need to provide below,
                                                     *
                                                     * void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer,
                                                     *      StackType_t **ppxTimerTaskStackBuffer,
                                                     *      uint32_t *pulTimerTaskStackSize );
                                                     *
                                                     * void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer,
                                                     *      StackType_t **ppxIdleTaskStackBuffer,
                                                     *      uint32_t *pulIdleTaskStackSize );
                                                     */
#define configSUPPORT_DYNAMIC_ALLOCATION        (1)
#define configTOTAL_HEAP_SIZE                   (4*1024) /* not used when heap_3.c is the selected heap */
#define configAPPLICATION_ALLOCATED_HEAP        (0)

/* run-time stats config */
#if (configOPTIMIZE_FOR_LATENCY==0)
#define configGENERATE_RUN_TIME_STATS           (1)
#else
#define configGENERATE_RUN_TIME_STATS           (0)
#endif
void vPortConfigTimerForRunTimeStats();
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vPortConfigTimerForRunTimeStats()
uint32_t uiPortGetRunTimeCounterValue();
#define portGET_RUN_TIME_COUNTER_VALUE()        uiPortGetRunTimeCounterValue()

/* co-routine related config */
#define configUSE_CO_ROUTINES                   (0)
#define configMAX_CO_ROUTINE_PRIORITIES         (0)

/* timer related config */
#define configUSE_TIMERS                        (1)
#define configTIMER_TASK_PRIORITY               (configMAX_PRIORITIES - 1)
#define configTIMER_QUEUE_LENGTH                (16)
#define configTIMER_TASK_STACK_DEPTH            (256)

/* used in M4F & R5F, not applicable in C66x, A53 */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY    (0x4U)

/* used in M4F, not applicable in R5F, C66x, A53 */
#define configKERNEL_INTERRUPT_PRIORITY         (configMAX_SYSCALL_INTERRUPT_PRIORITY)
#define configMAX_API_CALL_INTERRUPT_PRIORITY   (configMAX_SYSCALL_INTERRUPT_PRIORITY)

#if (configOPTIMIZE_FOR_LATENCY==0)
#define configASSERT(x)                        DebugP_assert( (uint32_t)(x))
#endif

/* MPU aware FreeRTOS, not supported as TI */
#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS  (0)
#define configTOTAL_MPU_REGIONS                                 (0)
#undef  configTEX_S_C_B_FLASH
#undef  configTEX_S_C_B_SRAM
#define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY             (0)

/* defines need for FreeRTOS+POSIX*/
#define configUSE_POSIX_ERRNO           (1)
#define configUSE_APPLICATION_TASK_TAG  (1)

/* include specific functions */
#define INCLUDE_vTaskDelete             (1)
#define INCLUDE_vTaskDelay              (1)
#define INCLUDE_vTaskSuspend            (1)
#define INCLUDE_xTimerDelete            (1)
#define INCLUDE_vSemaphoreDelete        (1)
#define INCLUDE_xTimerPendFunctionCall  (1)
#define INCLUDE_xTaskGetIdleTaskHandle  (1)
#define INCLUDE_xTaskDelayUntil  (1)

#ifdef __cplusplus
}
#endif

#endif /* TI_FREERTOS_CONFIG_H */

谢谢你。

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

    尊敬的 Kier:

    1.我看到的标准 FreeRTOSConfig.h 文件和上面分享的唯一区别是节拍率提高到10,000。 行为是否与降低的节拍率相同?

    2.与标准 SDK 配置相比、FreeRTOS 内核中是否有任何其他配置更改?

    3.我在我这边运行了一些测试、我修改了 AM263Px-LP 上的 MCAN 中断环回示例、以便在进行 MCAN 通信时和通信后每2秒打印一次 CPU 负载。 (标准 SDK 中提供的节拍率为1000)

    此致、
    Shaunak

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

    尊敬的 Shaunak:

    感谢您的回复和确认

    我将我们的配置 与 SDK 配置进行了比较、可以看到两个差异:


    1)我们的项目使用 Tickless_idle、而 SDK 则不使用。

    2)如您所述,我们的项目使用更高的 tick_rate_Hz。


    您认为1)可能会影响 CPU 负载计算?

    不管怎么说, 我将扭转这两种情况,看看这是否改善了响应。

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

    嗨、kier、

    无论如何、 我将反转这两个选项、看看这是否改善了响应。

    是否恢复了此帮助?

    此致、
    Shaunak

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

    抱歉、我还没有机会查看。

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

    尊敬的 Shaunak:

    我将节拍率更改为与 SDK 相同(1000Hz)、并关闭 TICLESS_IDLE (不管它是什么)、但没有区别:



    另外, 它似乎与调用  TaskP_loadGetTotalCpuLoad ()的频率无关。 如果我把它叫做20ms、它就不会有什么不同、这是我们预期的。

    除了以下内容外、现在我具有与 SDK 相同的 RTOS 配置:

    include_xTaskDelayUntil = 1


    我无法关闭此功能、否则我们的操作系统调度程序将无法正常工作。

    您还有其他想法吗?

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

    尊敬的 Kier:

    在评估" TaskP_loadUpdateAll "和 " Taskp_calcCpuLoad "函数、由" TaskP_loadGetTotalCpuLoad "函数、我确实看到有一些过滤发生

    累积的运行时间似乎持续增长、这可能会导致 CPU 负载计算缓慢(需要时间来稳定)

    accTotalTime 变量随着时间的推移不断增加、这意味着新的更新具有较小的相对影响。  差值(增量)是根据上次记录的时间计算的。  如果更新不频繁、较大的增量值会在新负载稳定之前产生一个"滞后"。  

    由于新的发布活动、我不确定现在是否可以在这方面花费大量带宽。此外、我在之前的测试中还无法重现。

    如果这些方法适合您、您可以尝试一下吗?

    1.定期重置 accTotalTime、以便为较短的平均值计算 CPU 负载

    if (gTaskP_ctrl.accTotalTime > SOME_THRESHOLD) {
        gTaskP_ctrl.accTotalTime = 0;
    }

     accRunTime 和 accTotalTime 变量是随时间累积的、 delta 其值是根据运行时间计数器的当前值和之前值之间的差值计算得出的。 这意味着 accRunTime 和 accTotalTime 变量实际上是低通滤波器、可以平滑运行时间计数器随时间的变化。  因此、 cpuLoad  TaskP_loadGetTotalCpuLoad 函数中的计算基于这些滤波值、这可能导致 CPU 负载看起来高于实际值、尤其是在高活动状态的瞬态期间。


    2.较高的初始 CPU 负载可能是由于内核的空闲时间不能立即可用或在应用程序开始时未准确计算,从而导致计算出的 CPU 负载较高。 当系统运行且准确计算空闲时间时、CPU 负载稳定到较低的值。

    此致、
    Shaunak

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

    尊敬的 Shaunak:

    非常感谢您的调查。

    FYI、我注意到问题越来越严重。

    我编程了 CPU 负载的一个大阶跃变化(约50%)、可以从外部进行控制。 在下图中、初始 CPU 负载约为4%。 然后、我在~4s 时开启人工高 CPU 负载、负载向上移动、然后在~30s 时关闭、然后在~60s 时再次打开。 随着时间的推移、滤波会变得更恶劣。 想象一下、几分钟后、CPU 负载计算实际上会卡住。

    我认为这种连续累积是没有必要的。 它只需要在每个 CPU 负载调用之间累加。 每次调用结束时、计数器都可以(并且在我看来应该重置)。

    在你的引导下,我注意到 在 SDK 实现中永远不会调用函数 taskP_loadResetAll(),其中相关的计数器被重置。  我认为,在每个加载计算窗口(taskP_load_update_window_msec)之后,调用 taskP_loadResetAll() 将执行以下操作:

    当然也是如此。  现在、对于 CPU 负载的实际阶跃变化、我得到计算出的 CPU 负载几乎瞬时的变化(到~50%):

    在这里,它看起来像是 在 SDK 实现中缺少调用 TaskP_loadResetAll()。

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

    尊敬的 Kier:

    我认为这种连续累积是不必要的。 它只需要在每个 CPU 负载调用之间累加。 每次调用结束时、计数器都可以(并且应该在我的视图中)重置。

    同意。

    [引述 userid="47999" url="~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1468701/am263p4-q1-freertos-cpu-load-calculation-settling-time/5751898 #5751898"]

    FYI、我注意到问题越来越严重。

    我编程了 CPU 负载的一个大阶跃变化(约50%)、可以从外部进行控制。 在下图中、初始 CPU 负载约为4%。 然后、我在~4s 时开启人工高 CPU 负载、负载向上移动、然后在~30s 时关闭、然后在~60s 时再次打开。 随着时间的推移、滤波会变得更恶劣。 想象一下、几分钟后、CPU 负载计算实际上会卡住。

    [/报价]

    感谢您的测试和分享。

    在这里、它看起来 在 SDK 实现中调用 TaskP_loadResetAll()。

    让我与其他一些 FreeRTOS 专家交谈、他们可能知道为什么会出现这种情况。  

     在加载计算窗口结束时调用 TaskP_loadResetAll()是否可以修复您最初观察到的过滤问题?

    此致、
    Shaunak

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

    尊敬的 Shaunak:

    也许是应用程序的响应性调用  TaskP_loadResetAll()?

    我现在恢复了 FreeRTOS 并在我的应用中添加了此功能:

    当然、我得到了类似(良好)的结果:

    API 显示以下内容:

    从这个描述中不清楚,如果不调用它, CPU 负载响应将逐渐研磨到停止。 也许这需要澄清?

    不管怎样,这个问题已经解决了! 感谢你的帮助。

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

    尊敬的 Kier:

    感谢您分享结果并耐心等待整个调试过程。 根据我们其他一些 FreeRTOS 专家所言、每当测量 CPU 负载时、就需要在应用程序本身中调用此调用、这就是为什么它不是 TaskP 内核代码的一部分。

    在所有 MCU+ SDK 示例中、该函数在应用程序本身中被调用。 您可以搜索如何计算 CPU 负载以及如何 在 SDK 示例中调用 TaskP_loadResetAll()。

    此致、
    Shaunak

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

    尊敬的 Shaunak:

    我毫无疑问、这是在示例中、这是我的疏忽。 但我仍然认为文件仍有改进的余地。 我想我们已经确定调用  TaskP_loadResetAll()是必需的。 如果是这种情况、您的 API 文档应提到这一点。 这将节省我们的大部分时间。

    基尔。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    但我仍然认为文档有改进的余地

    同意后、我将更新文档以提及这一点。

    此致、
    Shaunak