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.

[参考译文] TDA4VM:GTC 寄存器未在 HI & amp;LO 之间同步

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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/935239/tda4vm-gtc-register-not-synced-between-hi-lo

器件型号:

尊敬的专家:

我们的客户发现从 A72读取 GTC 将会出现以下问题:

LO 过流时、HI 应增加1。 但他们发现、LO 溢出、但 HI 不会增加。

您是否有任何建议的最佳做法来读取这2个32位寄存器?

谢谢、致以最诚挚的问候!

ZM

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

    [引用用户="Ming Zhong10"]

    器件型号: TDA4VM

    尊敬的专家:

    我们的客户发现从 A72读取 GTC 将会出现以下问题:

    LO 过流时、HI 应增加1。 但他们发现、LO 溢出、但 HI 不会增加。

    您是否有任何建议的最佳做法来读取这2个32位寄存器?

    谢谢、致以最诚挚的问候!

    ZM

    [/报价]

    大家好、 专家也很好

    我们发现、在特定时刻、HI  增加1、 但 LO 未清除、因此当我们读取 GTC 时间时、它比实时时间大约增加21秒。

    我们如何解决这个问题? 如果无法解决此问题、该时间(HI  增加1、 但 LO 未清零)将持续多长时间?

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

    在我看来、ZM 和 Subin Li 描述了两个不同的问题。  我不知道这个问题。  您能否提供寄存器转储、以便我尝试重新创建问题?

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

    Subin、

    您能否提供一段代码和日志来解释此问题?

    我认为如果您可以打印寄存器、将有助于我们的专家了解。

    谢谢、致以最诚挚的问候!

    ZM

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

    我们的示例代码如下所示:

    #define MAP_SIZE 4096UL
    #define MAP_MASK (MAP_SIZE - 1)
    #define GTC_BASE_寄存 器0x00A90000
    
    OFF_t GTC_TARGET = GTC_BASE_REGTER;
    
    FD = OPEN ("/dev/mem、O_RDWR | O_SYNC));
    
    GTC_MAP_BASE = mMAP (0、MAP_SIZE、 PROT_READ | PROT_WRITE、MAP_SHARED、FD、GTC_TARGET 和~MAP_MASK);
    
    GTC_virt_addr = GTC_MAP_BASE +(GTC_TARGET 和 MAP_MASK);
    
    uint64_t READ_RESULT =*((unsigned long *) GTC_virt_addr + 1); 

    在特定时刻、READ_RESULT 为0x01FFFFFFFD、然后我们快速得到 READ_RESULT agian、即0x02FFFFFFFD、应为0x0200000000。

    我们认为此时 HI (0x00A9000C)增加1、但 LO (0x00A90008)不会被清除。

    我们如何解决这个问题? 如果无法解决此问题、该时间(HI  增加1、 但 LO 未清零)将持续多长时间?

    谢谢!

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

    ZM 误解了我们的问题、请帮助解决我的问题。 谢谢你。

    我们的示例代码如下所示:

    #define MAP_SIZE 4096UL
    #define MAP_MASK (MAP_SIZE - 1)
    #define GTC_BASE_寄存 器0x00A90000
    
    OFF_t GTC_TARGET = GTC_BASE_REGTER;
    
    FD = OPEN ("/dev/mem、O_RDWR | O_SYNC));
    
    GTC_MAP_BASE = mMAP (0、MAP_SIZE、 PROT_READ | PROT_WRITE、MAP_SHARED、FD、GTC_TARGET 和~MAP_MASK);
    
    GTC_virt_addr = GTC_MAP_BASE +(GTC_TARGET 和 MAP_MASK);
    
    uint64_t READ_RESULT =*((unsigned long *) GTC_virt_addr + 1); 

    在特定时刻、READ_RESULT 为0x01FFFFFFFD、然后我们再次快速获取 READ_RESULT、即0x02FFFFFFFD、应为0x0200000000。

    我们认为此时 HI (0x00A9000C) 增加1、但 LO (0x00A90008)不会被清除。

    我们如何解决这个问题? 如果无法解决此问题、该时间(HI  增加1、 但 LO 未清零)将持续多长时间?

    谢谢!

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

    到目前为止、我无法复制您的错误。  GTC 源时钟的频率是多少?  此外、 GTC_CNTFID0寄存器中的值是多少?  在读取0x02FFFFFFFD 之后、如果您从寄存器中读取足够多的时间、最终是否会读取0x200000000?

    您可以尝试以不同方式执行的操作之一是从 GTC_CNTVS 读取、该寄存器在只读寄存器中包含相同的信息。  由于我无法重新创建您的问题、我不确定这是否可以解决。

    -Zack

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

    您好、Zack

    关于 GTC 源时钟,我们没有更改 CTRLMMR_GTC_CLKSEL 的值(位0~3)、所以它的值默认为0、我们使用 MAIN_PLL3_HSDIV1_CLKOUT 作为源时钟、它是200MHz。

      GTC_CNTFID0寄存器中的值为0。

    在我读取0x02FFFFFFFD 后、如果我从寄存器中读取足够多的时间、我最终会读取0x200000000 (或0x200000XXX)。 我们想知道、当 我们得到错误的值(0x02FFFFFFFD)时、我们必须等待多长时间才能获得正确的值((0x200000XXX)?

     您所说的 GTC_CNTVS 寄存器是 GTC_CNTCMS_HI 和 GTC_CNTCMS_LO、我发现这些值与 0x00A90008和 0x00A9000C 相同。

    也许您可以使用下面显示的测试代码来复制错误:

    uint64_t LAST_RESULT = 0;
    uint64_t READ_RESULT = 0;
    
    while (1){
    Read_Result =*((unsigned long *) GTC_virt_addr + 1);
    if (abs(read_result-last_result)> 200000000){
    printf ("出错!\n");
    }
    LAST_RESULT = READ_RESULT;
    usleep(1);
    } 

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

    当我离开它运行几个小时时、我遇到了这个问题。  为了捕捉故障、我必须在正确的时刻查询计数器、让计数器运行一段时间、从而找出故障。

    我将继续研究这个问题以找到解决方案。

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

    谢谢、期待收到您的好消息。

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

    向上

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

    Subin、

    无法在 GTC 上同步 HI 和 LO 的存储器映射寄存器。  由于 GTC 计数器的接口宽度仅为32位、因此对计数器的任何读取都必须是两次32位读取。  如果通过翻转 LO 寄存器来分隔这两次读取、则会遇到错误。

    我建议使用以下权变措施:以尽可能短的延迟对计时器计数器执行第二次读取、以检测是否存在错误读取。  第二次读取应始终大于第一次读取。  如果不是、则第一次读取无效。  有几个警告:

    1) 1)读取 GTC 计数器时、应始终先读取 LO、然后读取 HI。  示例中的 C 代码将计数器视为单个64位数、但根据您提供的值序列、汇编代码首先读取 LO、然后读取 HI。

    2) 2)第二次读取必须在 LO 的翻转时间内发生。  换句话说、读取之间的时间必须小于(2^32)/(GTC_CLK 频率)。

    3) 3)读取 GTC 计数器两次后、丢弃第二次读取、并使用第一次读取作为返回值。

    请告诉我、这是否是您可以接受的解决方法、如果您还有任何疑问、请告知我。

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

    您好、Zack

    您是否在该问题上取得了进展?

    如果目前没有好的解决方案、您能否先向我们确认 这一时刻   (HI 增加1、但 LO 未清除)的持续时间?

    谢谢!

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

    Subin、

    我不确定你是否错过了这个机会,但我在9月4日作了答复。  请查看该回复、并告诉我该解决方案是否适合您。

    谢谢、

    Zack

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

    您好、Zack

    我认为您的解决方案存在一些问题。

    1、第一次读取后多久开始第二次读取?如果两次读取之间的时间太短、则两次读取的值始终相同或非常接近。 因此 、两个读数的值可能都是错误的。

    2、我们认为存在以下情况:

    ①first 读取:0x1FFFFFF00(真)

      usleep(XXX)

      第二个读取:0x1FFFFFFFE(真)

      返回:0x1FFFFFFFE

    ②first 读取:0x1FFFFFFFE(真)

      usleep(XXX)

      第二个读取:0x2FFFFFFFF(false)

      usleep(XXX)

      第三次读取:0x20000000E(true)

      返回 :0x20000000E

    ③first 读取:0x2FFFFFFFE(错误)

      usleep(XXX)

      第二个读取: 0x20000000E(true)

      usleep(XXX)

      第三次读取: 0x20000001E(true)

      返回: 0x20000001E

    现在、我们想知道最短的使用时间 XXX。

    但我们不能在这里使用 usleep、因为调用时会导致上下文切换。  如果经常调用它、则会导致效率低下。

    因此、我们将使用忙等待函数、因为它不会导致上下文切换。  

    因此 、我们需要知道最短的使用时间 XXX。

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

    Subin、

    您在上一篇帖子中说过:

    "如果两次读取之间的时间太短、两次读取的值始终相同或非常接近。"

    您是否观察到连续多次读取错误值?  我在测试中没有观察到这一点、如果您发现这一点、那么它的运行方式与我对根本问题的理解背道而驰。

    如果是这种情况、那么我同意读取之间必须有一定的最短等待时间、我将努力弄清楚延迟必须是什么。

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

    您好、Zack

    我的意思是、如果我读出这样的时间:

      首先读取:0x2FFFFFF0E

      第二个读取:0x2FFFFFF0E

    如果在两个读数之间不等待一段时间、则第二次读数将与第一次读数相同或非常接近。

    如果第一次读取为 true、第二次读取也为 true。  如果第一次读取为 false、第二次读取也为 false。

    因此、我们必须知道 读取之间的最短等待时间。

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

    上述两个错误读取的情形是假设的还是观察到的?  我认为不可能在类似的一行中获得两个错误的读数。  误差的来源是 LO 在读取 LO 和 HI 之间发生翻转。  事件按以下顺序发生:

    1) 1)您读取 LO

    2) 2) LO 翻转、HI 递增。

    3) 3)您读为 HI。

    现在、您已读取了一个递增的 HI 值、但在翻转之前读取了一个 LO 值。  您的代码会将它们作为一个64位值粘在一起。  这是导致错误读数的原因。  但是、通过这种机制、只要两次连续读取之间的时间远小于 LO 的翻转周期、两次连续读取就不能同时为 false。

    -Zack

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

    您好、Zack

    我认为您的想法是错误的。

    下面是我的测试日志:

    读取 GTC:(最后一个:2796023698067) 0x28AFFFFD293

    读取 GTC:(第一个: 2796023698067) 0x28AFFFFD293

    usleep (1)

    读取 GTC:(第二个:2800318676976) 0x28BFFFFFFF0

    读取 GTC:(第三个: 2800318676976) 0x28BFFFFFFF0

    因此、如果我在没有睡眠的情况下读取寄存器、这些值将是相同的。

    因此、我们需要知道读取寄存器的间隔时间、该间隔应 至少保证  一次读取正确。

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

    您从哪个内核访问该寄存器、该内核的运行速度是多少?

    -Zack

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

    我们从 A72访问该寄存器、它以2GHz 的频率运行。

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

    向上

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

    Subin、

    我联系了设计师、他给出了以下评论:

    至少从 CPU 内核的角度来看,这实际上不是 GTC 的预期用途。  GTC 部分用于实现 ARMv8通用定时器架构的系统计数器功能。  因此、它通过一个灰色的编码系统定时器总线将时间计数分配给 ARM 处理器  每个 ARM 内核都包含处理器元件计时器、这些计时器通过系统计时器总线从 GTC 获取其计数器值  因此、我希望 A72内核能够通过 使用系统控制寄存器读取其本地 CNTPCT 而不是尝试从 GTC 计数器寄存器读取来获得时间。

    这是可行的解决方案吗?

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

    您好、Zack

    我们不仅需要从 A72获取时间、还需要从其他内核(R5、C66和 C7X)获取时间。 我们发现只有 RTC 寄存器可以用作公共时间源。 您说过、我们可以读取 其本地 CNTPCT 以在 A72中获得时间、但我们无法在其他内核中以相同的方式获得时间。 如果我们使用其他方法来获取其他内核中的时间、我们得到的时间将会有所不同。

    另一方面、无论 GTC 的用途如何、我们之前描述的问题都存在。  现在我们无法解决这个问题。

    现在、我们只想知道 GTC 寄存器错误将持续多长时间。

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

    向上

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

    Subin、

    读取 GTC:(最后一个:2796023698067) 0x28AFFFFD293

    读取 GTC:(第一个: 2796023698067) 0x28AFFFFD293

    usleep (1)

    读取 GTC:(第二个:2800318676976) 0x28BFFFFFFF0

    读取 GTC:(第三个: 2800318676976) 0x28BFFFFFFF0

    我不是很了解上面的测试日志。  您是否按顺序读取了最后、第一、第二、第三次?

    因此、如果我在没有睡眠的情况下读取寄存器、这些值将是相同的。

    因此、我们需要知道读取寄存器的间隔时间、该间隔应 至少保证  一次读取正确。

    您能否使用计数器值填充大型数组、而不在 READ_GTC 之间调用 usleep?  在跳转之前、跳转会破坏 READ_GTC 值、在跳转之后、至少有足够大的数组来查看 GTC 中的一些转换。  这样、我们就可以更好地了解 GTC 寄存器的访问速度、这将有助于回答您的问题。

    -Zack

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

    您好、Zack

    1、是的、我 按顺序阅读最后、第一、第二、第三。

       测试日志告诉我们、我读取了两次、它们的值为0x28AFFFFD293、它们是对的。

       但是在使用睡眠之后(1),我读取了两次, 它们的值是0x28BFFFFFFF0, 它们是错误的(与0x28AFFFFD293比较时大跳) 。

    2、我想我们已经清楚地描述了这个问题。

        从理论分析的角度来看、我们需要知道该误差时间将持续多长时间。

        我们的测试不完全可靠、具体取决于实际环境。

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

    此问题已延迟很长时间、请尽快帮助我们解决、谢谢。

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

    向上

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

    预期持续时间为1 GTC 时钟周期。