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.

[参考译文] J784S4XEVM:R5F 内核的计时器周期不一致

Guru**** 2585275 points
Other Parts Discussed in Thread: J784S4XEVM

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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1525319/j784s4xevm-timer-period-not-consistent-for-r5f-core

器件型号:J784S4XEVM


工具/软件:

平台:J784S4XEVM

SDK: ti-processor-sdk-rtos-j784s4-evm-11_00_00_06

内核:R5F (MCU2_0)

操作系统:FreeRTOS

使用 Linux 运行:是

您好、  
我正在尝试使用以下测试代码创建一个计时器中断。

我总是获得计时器中断回调、但具有不同的中断周期时间。

我使用相同的应用二进制文件进行测试。

在断电/上电周期后、我通常得到的中断周期时间为 1000usec(失败)。 在一些断电/接通周期中、我得到的中断周期时间为 5000 个用例(成功)

如果更改周期值、会出现类似的行为。 大多数情况下、我得到的值为 1000usec、至少是我得到正确值的时间。

原因可能是什么?

此致

#include <utils/timer/include/app_timer.h>
#include <utils/rtos/include/app_rtos.h>
#include <ti/osal/osal.h>
#include <ti/osal/TimerP.h>
#include <ti/drv/ipc/ipc.h>
#include <app_ipc_rsctable.h>

static uint8_t  gTskStackMain[64*1024]
__attribute__ ((aligned(8192)));

static void timer_callback(void *arg) {
    Ipc_Trace_printf("Time: %llu\n", TimerP_getTimeInUsecs());   
}

static void initTask(void* arg0, void* arg1)
{
    TimerP_Params params;
    TimerP_Params_init(&params);
    params.startMode = TimerP_StartMode_USER;
    params.runMode   = TimerP_RunMode_CONTINUOUS;
    params.periodType = TimerP_PeriodType_MICROSECS;
    params.startMode = TimerP_StartMode_USER;
    params.period = 5000;

    TimerP_Handle tmhandle = TimerP_create(TimerP_ANY, (TimerP_Fxn)timer_callback, &params);
    if(NULL_PTR != tmhandle) {
        if(TimerP_OK != TimerP_start(tmhandle)) {
            Ipc_Trace_printf("TimerP_start failed!\n");
            return;
        } 
    } else {
        Ipc_Trace_printf("TimerP_create failed!\n");
        return;
    }
}

int main(void)
{
    OS_init();

    Ipc_loadResourceTable((void*)&ti_ipc_remoteproc_ResourceTable); 

    app_rtos_task_params_t tskParams;
    appRtosTaskParamsInit(&tskParams);
    tskParams.priority = 10u;
    tskParams.stack = gTskStackMain;
    tskParams.stacksize = sizeof (gTskStackMain);
    tskParams.taskfxn = &initTask;
    tskParams.name = "initTask";

    app_rtos_task_handle_t task = (void*)appRtosTaskCreate(&tskParams);

    if(NULL == task) {
        Ipc_Trace_printf("Task create failed!\n");
        OS_stop();
        return -1;
    }

    OS_start();

    return 0;
}




成功日志:
时间:2665001
时间:2670001
时间:2675001
时间:2680001

失败日志:
时间:1282001 年
时间:1283001
时间:1284001
时间:1285001.

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

    您好、

    我目前没有带宽来解决这个问题、我将在本周结束时回复您。 感谢您的耐心!

    谢谢、

    Neehar

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

    您好、

    您的引导模式是什么?

    由于与 Linux 存在一些冲突、时钟发生了许多变化。 首先、您是否可以  在成功和失败的场景中检查 MCU_TIMERn_CLKSEL_clk_SEL[2:0]寄存器? 默认值应为“000"。“。

    然后、我们可以查看驱动计时器模块的时钟是否有任何变化。

    谢谢、

    Neehar

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

    嗨、Neehar、

    -引导模式是  eMMC  (SW7 (00000000)、SW11 (10000000))、带 tftp/NFS 配置。

    -下面提供了您提到的寄存器值。 成功和失败情形的值相同。

    地址:0x40F08100 寄存器名称:MCU_TIMER0_CLKSEL_CLK_SEL 值:0x00000001
    地址:0x40F08104 寄存器名称:MCU_Timer1_CLKSEL_CLK_SEL 值:0x00000000
    地址:0x40F08108 寄存器名称:MCU_TIMER2_CLKSEL_CLK_SEL 值:0x00000000
    地址:0x40F0810C 寄存器名称:MCU_TIMER3_CLKSEL_CLK_SEL 值:0x00000000
    地址:0x40F08110 寄存器名称:MCU_TIMER4_CLKSEL_CLK_SEL 值:0x00000000
    地址:0x40F08114 寄存器名称:MCU_TIMER5_CLKSEL_CLK_SEL 值:0x00000000
    地址:0x40F08118 寄存器名称:MCU_TIMER6_CLKSEL_CLK_SEL 值:0x00000000
    地址:0x40F0811C 寄存器名称:MCU_TIMER7_CLKSEL_CLK_SEL 值:0x00000000
    地址:0x40F08120 寄存器名称:MCU_TIMER8_CLKSEL_CLK_SEL 值:0x00000000
    地址:0x40F08124 寄存器名称:MCU_TIMER9_CLKSEL_CLK_SEL 值:0x00000001

    -我想 我将 timer4 用于 MCU2_0、如 ti-processor-sdk-rtos-j784s4-evm-11_00_00_06/pdk_j784s4_11_00_00_21/packages/ti/kernel/freertos/config/j784s4/r5f/FreeRTOSConfig_mcu2_0.h 中所述 TimerP_ANY  创建这个函数。

    /*--j784s4 中各种内核的默认 DMTimer 分配--*/
    /* c7x_1 - DMTimer 0
     * c7x_2 - DMTimer 1  
     * c7x_3 - DMTimer 2  
     * c7x_4 - DMTimer 3  
     * MCU2_0 - DMTimer 4
     * MCU2_1 - DMTimer 5.
     * mcu3_0 - DMTimer 6.
     * mcu3_1 - DMTimer 7.
     * mcu4_0 - DMTimer 8.
     * mcu4_1 - DMTimer 9.
     * mcu1_0 - MCU DMTimer 1.
     * mcu1_1 - MCU DMTimer 2.
     */   

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

    您好、

    我想我正在为 MCU2_0 使用 timer4、如 [/报价]中所述

    我推荐使用  configTIMER_ID 确保您使用 DMTIMER4 作为为 MCU2_0 分配的计时器模块。

    TimerP_Handle tmhandle = TimerP_create(configTIMER_ID, (TimerP_Fxn)timer_callback, &params);

    此外、如果您使用 DMTIMER4、那么您是否会 在成功和失败的场景中为 TIMERn_CLKSEL_clk_sel[3:0]寄存器提供转储?

    谢谢、

    Neehar

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

    您好、

    -当我使用“configTIMER_ID"时“时,永远不会调用计时器回调。 对于 MCU2_0、以下 ID 与 configTIMER_ID“定义一起使用。

    #define OSAL_FREERTOS_OS_TIMER_ID_MCU2_0        ( 4U )   /*  DM Timer 12  */


    -当使用 configTIMER_ID 时,所有计时器的地址 CFG0_TIMERn_CLKSEL 中的值为零。 (CFG0_TIMER0_CLKSEL 的地址为 0x00108100,以确保我读取正确的寄存器)

    -在/pdk_j784s4_11_00_00_21/packages/ti/osal/test/main_osal_test.c 中的示例行 1023 建议我们将 src _any 用于 freeRTOS、这就是我们在示例中使用它的原因。

    #if defined(BARE_METAL)
        int32_t       id    = OSAL_TEST_TIMER_ID;
    #else
        /* Pass TimerP_ANY for FreeRTOS, since FreeRTOS kernel running on each core
         * will use one timer per core. So if there is a conflict in the id passed
         * TimerP_create will fail. See FreeRTOS_config_<core>.h for details about
         * the timer instance used by each core */
        int32_t       id    = TimerP_ANY;
    #endif
     

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

    您好、

    -使用 configTIMER_ID 时、所有计时器的地址 CFG0_TIMERn_CLKSEL 中的值为零。 (CFG0_TIMER0_CLKSEL 的地址为 0x00108100,以确保我读取正确的寄存器)[/报价]

    不用担心、 当使用 TimerP_ANY 时、您是否可以在成功场景和失败场景中为 TIMERn_CLKSEL_clk_sel[3:0]寄存器提供转储?

    是的、0x00108100 是正确的地址、对于 DMTIMER4、确切的地址是 0x00108110。

    谢谢、

    Neehar

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

    您好、
    的 CFG0_TIMERn_CLKSEL 值 所有计时器 & 两种情况 为 0 TimerP_ANY 为零。

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

    您好、

    由于这两种情况下的这些寄存器是相同的、因此您不应该看到差异、因为计时器使用每个板上恒定的 HFOSC0_CLKOUT。 它不会改变。 你还能`一个主 DMTIMER 寄存器的转储以便我检查吗

    谢谢、

    Neehar

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

    您好、  
    -对于这两种情况,DMTIMER4 寄存器与下面相同。


    0x02440000	TIMER4_CFG_CFG_TIDR
    0x02440000	50003900	00000000	00000000	00000000
    0x02440010	TIMER4_CFG_CFG_TIOCP_CFG
    0x02440010	00000000	00000000	00000000	00000000
    0x02440020	TIMER4_CFG_CFG_IRQ_EOI
    0x02440020	00000000
    0x02440024	TIMER4_CFG_CFG_IRQSTATUS_RAW
    0x02440024	00000002
    0x02440028	TIMER4_CFG_CFG_IRQSTATUS
    0x02440028	00000002
    0x0244002C	TIMER4_CFG_CFG_IRQSTATUS_SET
    0x0244002C	00000002
    0x02440030	TIMER4_CFG_CFG_IRQSTATUS_CLR
    0x02440030	00000002
    0x02440034	TIMER4_CFG_CFG_IRQWAKEEN
    0x02440034	00000000
    0x02440038	TIMER4_CFG_CFG_TCLR
    0x02440038	00000043
    0x0244003C	TIMER4_CFG_CFG_TCRR
    0x0244003C	FFFFF497
    0x02440040	TIMER4_CFG_CFG_TLDR
    0x02440040	FFFFB500
    0x02440044	TIMER4_CFG_CFG_TTGR
    0x02440044	FFFFFFFF
    0x02440048	TIMER4_CFG_CFG_TWPS
    0x02440048	00000000
    0x0244004C	TIMER4_CFG_CFG_TMAR
    0x0244004C	00000000
    0x02440050	TIMER4_CFG_CFG_TCAR1
    0x02440050	00000000
    0x02440054	TIMER4_CFG_CFG_TSICR
    0x02440054	00000000
    0x02440058	TIMER4_CFG_CFG_TCAR2
    0x02440058	00000000
    0x0244005C	TIMER4_CFG_CFG_TPIR
    0x0244005C	00000000
    0x02440060	TIMER4_CFG_CFG_TNIR
    0x02440060	00000000
    0x02440064	TIMER4_CFG_CFG_TCVR
    0x02440064	00000000
    0x02440068	TIMER4_CFG_CFG_TOCR
    0x02440068	00000000
    0x0244006C	TIMER4_CFG_CFG_TOWR
    0x0244006C	00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000
    


    -因为您说所有寄存器值都是一样的、所以我将尝试使用不是由 Yocto 生成的映像运行此应用程序。 我将使用 Processor SDK Linux (ti-processor-sdk-linux-adas-j784s4-evm-11_00_00_08) 提供的预编译映像、并检查问题是否存在。

    -我附加了我的二进制文件(调试版本)。 您可以将此二进制文件符号链接到 Linux 中的 MCU2_0 并检查日志。 您应该看到内核的跟踪缓冲区内有“time: 1850001, time: 1855001“。 (对于成功的方案)。 源代码已在主题之上共享。 (周期为 5000)。 您还可以调试和检查寄存器值以确定成功和失败的情况。

    e2e.ti.com/.../hello_5F00_concerto_5F00_r5f.zip

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

    您好、

    -由于您说所有寄存器值都应该是一样的、我将尝试使用不是用 Yocto 生成的映像运行此应用程序。 我将使用 Processor SDK Linux (ti-processor-sdk-linux-adas-j784s4-evm-11_00_00_08) 提供的预编译映像、并检查问题是否存在。
    [/报价]

    这也有助于缩小问题的范围。 请告诉我您的结果。

    我会尝试运行并测试您的二进制文件。

    谢谢、

    Neehar

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

    嗨、Neehar、
    我使用“Processor SDK Linux (ti-processor-sdk-linux-adas-j784s4-evm-11_00_00_08) 提供的预编译映像“执行测试。  
    始终测量中断周期时间为 1000usec、周期设置为 5000usec。 (针对~50 次下电上电迭代进行了测试)

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

    尊敬的 Gokhan:

    使用预构建的映像、您现在能够获得一个一致的周期是否正确?

    始终将中断周期时间测量为 1000usec、周期设置为 5000usec。 (针对~50 次下电上电迭代进行测试)[/报价]

    如何使用预构建的 Linux 映像设置计时器? 您能否提供与以前类似的配置和寄存器值?

    谢谢、

    Neehar

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

    嗨、Neehar、
    否、使用预构建的映像、我无法获得一致的时间段。
    正如我前面说的、如果我将时间周期设置为 5000usec、总能得到中断 1000usec。

    我检查了寄存器值、它们与我在之前消息中发送给您的值完全相同。
    您能试一下这个例子吗? 这是一个简单的计时器示例、它使用 FreeRTOS 在 r5f 远程内核上运行。 无定制代码。 我相信我们在这里遗漏了一些东西、因为这个 soc 被全球许多项目使用、计时器应该能成功运行。 我将在下面再次共享我的代码。  

    #include <utils/timer/include/app_timer.h>
    #include <utils/rtos/include/app_rtos.h>
    #include <ti/osal/osal.h>
    #include <ti/osal/TimerP.h>
    #include <ti/drv/ipc/ipc.h>
    #include <app_ipc_rsctable.h>
    
    static uint8_t  gTskStackMain[64*1024]
    __attribute__ ((aligned(8192)));
    
    static void timer_callback(void *arg) {
        Ipc_Trace_printf("Time: %llu\n", TimerP_getTimeInUsecs());   
    }
    
    static void initTask(void* arg0, void* arg1)
    {
        TimerP_Params params;
        TimerP_Params_init(&params);
        params.startMode = TimerP_StartMode_USER;
        params.runMode   = TimerP_RunMode_CONTINUOUS;
        params.periodType = TimerP_PeriodType_MICROSECS;
        params.period = 5000;
    
        TimerP_Handle tmhandle = TimerP_create(TimerP_ANY, (TimerP_Fxn)timer_callback, &params);
        if(NULL_PTR != tmhandle) {
            if(TimerP_OK != TimerP_start(tmhandle)) {
                Ipc_Trace_printf("TimerP_start failed!\n");
                return;
            } 
        } else {
            Ipc_Trace_printf("TimerP_create failed!\n");
            return;
        }
    }
    
    int main(void)
    {
        OS_init();
    
        Ipc_loadResourceTable((void*)&ti_ipc_remoteproc_ResourceTable); 
    
        app_rtos_task_params_t tskParams;
        appRtosTaskParamsInit(&tskParams);
        tskParams.priority = 10u;
        tskParams.stack = gTskStackMain;
        tskParams.stacksize = sizeof (gTskStackMain);
        tskParams.taskfxn = &initTask;
        tskParams.name = "initTask";
    
        app_rtos_task_handle_t task = (void*)appRtosTaskCreate(&tskParams);
    
        if(NULL == task) {
            Ipc_Trace_printf("Task create failed!\n");
            OS_stop();
            return -1;
        }
    
        OS_start();
    
        return 0;
    }
    

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

    尊敬的 Gokhan:

    让我使用您的应用程序进行测试、看看我是否能够重现您的问题。

    谢谢、

    Neehar

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

    有任何进步 Neehar 吗?

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

    尊敬的 Gokhan:

    很抱歉、我将在接下来的两天内跟进我的结果。

    谢谢、

    Neehar

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

    你好,有任何进步 Neehar 吗?

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

    尊敬的 Gokhan:

    您能否请参阅 PDK 中提供的 OSAL 测试应用?

    我已在 MAIN_OSAL_TEST.c 中运行 OSAL 测试应用、并生成了 5000us 的一致周期。 此测试应用已经过验证、您可以参考它。

    路径:ti-processor-sdk-rtos-j784s4-evm-11_00_00_06/pdk_j784s4_11_00_00_21/packages/ti/osal/test/main_osal_test.c src

    谢谢、

    Neehar

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

    嗨、Neehar、

     在没有 Linux 的情况下运行 main_osal_test.c 时、也没有问题。
    当我们与 Linux 一起运行应用程序时、就会出现问题。

    谢谢

    Gokhan

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

    尊敬的 Gokhan:

    感谢这些信息、让我来看看 Linux 端可能会干扰中断的情况。

    谢谢、

    Neehar

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

    嗨、Neehar、
    是否有任何进展?

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

    尊敬的 Gokhan:

    您是否对默认 Linux 映像或设备树进行了任何更改? 如果是、您做了哪些更改?

    谢谢、

    Neehar

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

    嗨、Neehar、

    我们使用出厂默认 ti-processor-sdk-linux-adas-j784s4-evm-11_00_00_08 使用 create-sdcard.sh 脚本创建的预构建映像。 (使用 tisdk-adas-image-j784s4-evm.rootfs.tar.xz)  

    我们没有改变图像中的任何内容。

    我们使用 concerto 编译系统在票证定义内构建源代码、并将二进制文件符号链接为 j784s4-main-R5f0_0-fw。

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

    尊敬的 Gokhan:

    感谢这些信息、我将进一步研究此问题、并在我这边进行测试。

    谢谢、

    Neehar

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

    尊敬的 Gokhan:

    在 没有 Linux 的情况下运行 main_osal_test.c 时、也没有问题。
    当我们与 Linux 一起运行应用程序时、就会出现问题。

    与 Linux 一起运行应用时、您能否提供中断频率的日志?

    谢谢、

    Neehar

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

    嗨、Neehar、

    当计时器设置为“params.period = 5000“时、我会得到下面的“失败日志“值。 (在大多数下电上电期间)

    但有时(比率较低)、我会得到“成功日志“值。

    在一次下电上电中、周期是恒定的、不会改变。 我的意思是、如果周期日志为 1000、那么该下电上电周期始终为 1000。

    成功日志:
    时间:2665001
    时间:2670001
    时间:2675001
    时间:2680001

    ...

    失败日志:
    时间:1282001 年
    时间:1283001
    时间:1284001
    时间:1285001.

    ...

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

    尊敬的 Gokhan:

    感谢您提供此信息。 在其他计时器实例中也是相同的结果?

    谢谢、

    Neehar

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

    在/pdk_j784s4_11_00_00_21/packages/ti/osal/test/sym/main_osal_test.c 中的示例行 1023 建议我们对使用 TimerP_any、这就是我们在示例中使用 src 的原因。 TI 文档显示、如果传递的 ID 中存在冲突、TimerP_CREATE 将失败。 因此、我知道如果我们使用另一个计时器实例、TimerP_CREATE 将失败。

    #if defined(BARE_METAL)
        int32_t       id    = OSAL_TEST_TIMER_ID;
    #else
        /* Pass TimerP_ANY for FreeRTOS, since FreeRTOS kernel running on each core
         * will use one timer per core. So if there is a conflict in the id passed
         * TimerP_create will fail. See FreeRTOS_config_<core>.h for details about
         * the timer instance used by each core */
        int32_t       id    = TimerP_ANY;
    #endif