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.

[参考译文] TMS320F28388D:了解 GSx RAM

Guru**** 2539500 points
Other Parts Discussed in Thread: C2000WARE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1320941/tms320f28388d-understanding-gsx-ram

器件型号:TMS320F28388D
主题中讨论的其他器件:C2000WARE

尊敬的专家:
我正在执行测试以验证 CPU 中是否由于另一个 CPU 执行的读取/写入操作而产生任何干扰。
在这两种场景中、我都在使用不同的 IPC 计数器来捕获时间差(gf32TimeU)。 在这两种情况下、我都用两个部分
根据系统控制器模块中的 gu16CpuId 在已加载内核中执行的代码的描述。

在所有情况下、我已经在 CPU1中加载了启用以下函数的输出(.out)文件、并在 CPU2中加载了.out 文件以禁用相同功能、而且我得到了以下时序。

#1. 场景:
----------------
结果/输出:
观察到的时序方面为:

CPU1读取-> 430.125微秒
CPU1写入-> 430.125微秒

CPU2读取-> 409.64微秒
CPU2写入-> 430.125微秒

  • 代码片段:

void ReadIntinCPU1due2CPU2Read_SameBlock()
{
    UINT16 i = 0;
    while (1)
    {
        i = 0;
        if( CPUID_1 == gu16CpuId )
        {
            start = guniIpcRegs.gstrCpu1IpcRegs.IPCCOUNTERL;
            for (i = 0; i < u16size; i++)
            {
                gu16GS0_Array[i];                               // For write, replacing this line to "gu16GS0_Array[i] = 6;"
            }
            end = guniIpcRegs.gstrCpu1IpcRegs.IPCCOUNTERL;
            gf32TimeUs = (FLOAT32)(end - start)*0.005f;
        }

        i = 0;
        if( CPUID_2 == gu16CpuId )
        {
            start = guniIpcRegs.gstrCpu1IpcRegs.IPCCOUNTERL;
            for (i = 0; i < u16size; i++)
            {
                gu16GS0_Array[i];                               // For write, replacing this line to "gu16GS0_Array[i] = 7;"
            }
            end = guniIpcRegs.gstrCpu1IpcRegs.IPCCOUNTERL;
            gf32TimeUs = (FLOAT32)(end - start)*0.005f;
        }
    }
}

#2. 场景:
----------------
我已经颠倒了 CPU 块中代码的执行顺序、即(cpue_2 == gu16CpuId)、然后(cpu_1 == gu16CpuId)并执行相同的测试并获得以下结果。

#结果/输出:
观察到的时序方面为:


CPU1读取-> 409.64微秒
CPU1写入-> 430.125微秒

CPU2读取-> 430.125微秒
CPU2写入-> 430.125微秒

  • 代码片段:

void ReadIntinCPU1due2CPU2Read_SameBlock()
{
    UINT16 i = 0;
    while (1)
    {
        i = 0;
        if( CPUID_2 == gu16CpuId )
        {
            start = guniIpcRegs.gstrCpu2IpcRegs.IPCCOUNTERL;
            for (i = 0; i < u16size; i++)
            {
                gu16GS0_Array[i];                               // For write, replacing this line to "gu16GS0_Array[i] = 7;"
            }
            end = guniIpcRegs.gstrCpu2IpcRegs.IPCCOUNTERL;
            gf32TimeUs = (FLOAT32)(end - start)*0.005f;
        }

        i = 0;
        if( CPUID_1 == gu16CpuId )
        {
            start = guniIpcRegs.gstrCpu1IpcRegs.IPCCOUNTERL;
            for (i = 0; i < u16size; i++)
            {
                gu16GS0_Array[i];                              // For write, replacing this line to "gu16GS0_Array[i] = 6;"
            }
            end = guniIpcRegs.gstrCpu1IpcRegs.IPCCOUNTERL;
            gf32TimeUs = (FLOAT32)(end - start)*0.005f;
        }
    }
}

#查询/观察:

  • 如果我比较 CPU1上的读取时序、我就会发现有区别、即、在场景1中、 CPU1读取-> 430.125 微秒 情形2中的情形 CPU1读取-> 409.64 微秒 。                CPU2读取也发生了同样的情况、例如、在情形1中 CPU2读取-> 409.64 微秒 在情形#2中 CPU2读取-> 430.125微秒
  • 上述两个函数的唯一区别是执行这些任务的 CPU 的位置、但这不应影响计时、因为这些任务是在特定 CPU 中执行的。


第1季度 。 为什么会出现这些行为?
Q2 。 有什么影响的广告吗?
Q3 。 在访问像 GS0-GS4这样的 RAM 段时是否有任何异常应该被 CPU1访问并且由 CPU2复位?

请分享是否有任何文档可供参考、以了解 GSx RAM 的内部情况来支持该测试。

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

    您好、Surya:

    [quote userid="593108" url="~/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1320941/tms320f28388d-understanding-gsx-ram Q1 。 为什么会观察到这些行为?

    我认为查看反汇编以了解代码编译到什么可能会有所帮助; 我会发现、如果在编译的代码本身不不同的情况下、访问的时间不同会很奇怪、除非同时进行读取和写入、但如果您的程序中没有其他代码正在运行、则不应导致此问题。

    [quote userid="593108" url="~/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1320941/tms320f28388d-understanding-gsx-ram Q2 。 有没有影响的广告?

    我不确定这句话是什么意思、如果您问这种 计时是否是由哪个 CPU 拥有 RAM 引起的 、我认为不是这样。 查看参考手册存储器控制器模块中的存储器架构图、CPU1和 CPU2具有到 GSxRAM 的相同类型的访问路径、因此不拥有 RAM 的 CPU 似乎无需使用其他路径。 您能告诉我选择哪个 CPU 作为您正在访问的特定 GSxRAM 的所有者吗? 我将请设计专家看看是否在架构上可以解释时序差异。

    [quote userid="593108" url="~/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1320941/tms320f28388d-understanding-gsx-ram Q3 。 在访问像 GS0-GS4这样的 RAM 段时,CPU1应访问并由 CPU2复位,是否有任何异常?

    否、根据我所看到的内容、所有 GSxRAM 的行为都应作为参考手册中所述的全局共享 RAM。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 Amir:
    第2季度 。 有什么影响的广告吗?

    我不确定这句话是什么意思、如果您问这种 计时是否是由哪个 CPU 拥有 RAM 引起的 、我认为不是这样。 查看参考手册存储器控制器模块中的存储器架构图、CPU1和 CPU2具有到 GSxRAM 的相同类型的访问路径、因此不拥有 RAM 的 CPU 似乎无需使用其他路径。 您能告诉我选择哪个 CPU 作为您正在访问的特定 GSxRAM 的所有者吗? 我将请设计专家看看是否在架构上可以解释时序差异。

    我已经逐一检查了两个 CPU、它们都显示了与前面提到的相同的行为。

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

    您好、Surya:

    我将向设计专家提出这个问题、看看他们是否熟悉原因、我应该会在本周结束前得到答复。

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

    您是否可以为我提供您用于验证此情况的 CPU1和 CPU2的代码? 一旦我得到机会、我将尝试在 F2838x 器件上测试这个。

    此外、您是否验证过、从用于访问两个内核的 GSx 存储器的代码生成的汇编代码完全相同? 您在"Disassembly"视图中是否注意到任何不同之处?

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

    尊敬的 Amir:
    我没有注意到"Disassembly"视图中的任何差异。

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

    请查找以下汇编代码片段:

    #1. 场景:

    void ReadIntinCPU1due2CPU2Read_SameBlock()
    {
        UINT16 i = 0;
        while (1)
        {
            i = 0;
            if( CPUID_1 == gu16CpuId )
            {...
            }
    
            i = 0;
            if( CPUID_2 == gu16CpuId )
            {...
            }
        }
    }
    
    //////////////////////////////////////////////////////
    
    622             if( CPUID_1 == gu16CpuId )
    0883a9:   761F025A    MOVW         DP, #0x25a
    0883ab:   920D        MOV          AL, @0xd
    0883ac:   5201        CMPB         AL, #0x1
    0883ad:   602A        SB           $C$L96, NEQ
    624                 start = guniIpcRegs.gstrCpu1IpcRegs.IPCCOUNTERL;
    0883ae:   761F1738    MOVW         DP, #0x1738
    0883b0:   060C        MOVL         ACC, @0xc
    0883b1:   761F0259    MOVW         DP, #0x259
    0883b3:   1E2C        MOVL         @0x2c, ACC
    625                 for (i = 0; i < u16size; i++)
    0883b4:   2B41        MOV          *-SP[1], #0
    0883b5:   9226        MOV          AL, @0x26
    0883b6:   5441        CMP          AL, *-SP[1]
    0883b7:   6909        SB           $C$L95, LOS
    0883b8:   8F00D000    MOVL         XAR4, #0x00d000
    627                     gu16GS0_Array[i];// = 7;
            $C$L94:
    0883ba:   5841        MOVZ         AR0, *-SP[1]
    0883bb:   9294        MOV          AL, *+XAR4[AR0]
    625                 for (i = 0; i < u16size; i++)
    0883bc:   0A41        INC          *-SP[1]
    0883bd:   9226        MOV          AL, @0x26
    0883be:   5441        CMP          AL, *-SP[1]
    0883bf:   66FB        SB           $C$L94, HI
    629                 end = guniIpcRegs.gstrCpu1IpcRegs.IPCCOUNTERL;
            $C$L95:
    0883c0:   761F1738    MOVW         DP, #0x1738
    0883c2:   060C        MOVL         ACC, @0xc
    0883c3:   761F0259    MOVW         DP, #0x259
    0883c5:   1E2E        MOVL         @0x2e, ACC
    630                 gf32TimeUs = (FLOAT32)(end - start)*0.005f;

    #2. 场景:

    void ReadIntinCPU1due2CPU2Read_SameBlock()
    {
        UINT16 i = 0;
        while (1)
        {
            i = 0;
            if( CPUID_2 == gu16CpuId )
            {...
            }
    
            i = 0;
            if( CPUID_1 == gu16CpuId )
            {...
            }
        }
    }
    
    ///////////////////////////////////////////////////////////
    
    633             if( CPUID_1 == gu16CpuId )
            $C$L96:
    0883d7:   761F025A    MOVW         DP, #0x25a
    0883d9:   920D        MOV          AL, @0xd
    0883da:   5201        CMPB         AL, #0x1
    0883db:   60CD        SB           $C$L93, NEQ
    635                         start = guniIpcRegs.gstrCpu1IpcRegs.IPCCOUNTERL;
    0883dc:   761F1738    MOVW         DP, #0x1738
    0883de:   060C        MOVL         ACC, @0xc
    0883df:   761F0259    MOVW         DP, #0x259
    0883e1:   1E2C        MOVL         @0x2c, ACC
    636                         for (i = 0; i < u16size; i++)
    0883e2:   2B41        MOV          *-SP[1], #0
    0883e3:   9226        MOV          AL, @0x26
    0883e4:   5441        CMP          AL, *-SP[1]
    0883e5:   6909        SB           $C$L98, LOS
    0883e6:   8F00D000    MOVL         XAR4, #0x00d000
    638                             gu16GS0_Array[i];// = 7;
            $C$L97:
    0883e8:   5841        MOVZ         AR0, *-SP[1]
    0883e9:   9294        MOV          AL, *+XAR4[AR0]
    636                         for (i = 0; i < u16size; i++)
    0883ea:   0A41        INC          *-SP[1]
    0883eb:   9226        MOV          AL, @0x26
    0883ec:   5441        CMP          AL, *-SP[1]
    0883ed:   66FB        SB           $C$L97, HI
    640                         end = guniIpcRegs.gstrCpu1IpcRegs.IPCCOUNTERL;
            $C$L98:
    0883ee:   761F1738    MOVW         DP, #0x1738
    0883f0:   060C        MOVL         ACC, @0xc
    0883f1:   761F0259    MOVW         DP, #0x259
    0883f3:   1E2E        MOVL         @0x2e, ACC
    641                         gf32TimeUs = (FLOAT32)(end - start)*0.005f;

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

    找到下面的配置代码:

    CPU 选择:

    ScGsMemInit_Struct strGsMemInit =
    {
    .uniGsxMsel.bit.MSEL_GS0 = GS_MSEL_CPU2,
    ...

    函数调用:

    ScConfigGsMemory(&strGsMemInit, BOOL_FALSE, BOOL_FALSE);

    在函数"ScConfigGsMemory"内部:

    gstrMemCfgRegs.GSxMSEL.all = 0x0;
    gstrMemCfgRegs.GSxINIT.all = 0x0000FFFF;

    # 这是必要和迫切需要知道有关该行为的 GSx RAM ,因为这是一个 A 的一部分 erospace 项目 。  因此、请与您分享 内部总线架构 GSx RAM、  如果有的话。

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

    您好、Surya:

    组装过程中似乎没有明显的差异。 您是否只是将 CPU2用作项目的内核? 我感到困惑、如何将不同的场景加载到每个内核、您是将场景1加载到 CPU1、将场景2加载到 CPU2、反之亦然、还是其他情况?

    我试图创建一个类似的示例(我无法执行完全相同的示例、因为您的完整代码不可用)、但未能发现两个 CPU 的访问时间有任何差异:

    #include "driverlib.h"
    #include "device.h"
    #include "board.h"
    #include "c2000ware_libraries.h"
    
    uint64_t start, end;
    volatile uint16_t gu16GS0_Array[2048];
    float32_t time;
    
    void main(void)
    {
        MemCfg_setGSRAMControllerSel(MEMCFG_SECT_GS0, MEMCFG_GSRAMCONTROLLER_CPU1);
        uint16_t i = 0;
        start = IPC_getCounter(IPC_CPU1_L_CPU2_R);
        for (i = 0; i < 2048; i++)
        {
            gu16GS0_Array[i];// = 6;
        }
        end = IPC_getCounter(IPC_CPU1_L_CPU2_R);
        time = (float32_t)(end - start)*0.005f;
        while (1);
    }
    

    两个 CPU 的代码相同、我更改的唯一项目是用于访问 IPC 计时器的宏。 我将代码分别加载到两个 CPU、并测试了读取与写入操作、两个内核上的两个次数都得到了 174.474991的时间变量。 1)除非您向我提供包含您使用的所有变量/结构的整个项目、否则我认为我无法在我身边复制此内容、或2) 根据 C2000Ware 中的示例重新创建简化的测试用例、以便我可以轻松复制您添加的代码、以便能够测试时序。 如果这两种情况都不能发生、那么我就不能做太多事情来支持该线程。

    所以,请分享 内部总线架构 GSx RAM、  如果有可用。

    我会检查以便在哪里可以找到此数据、但我认为它可能受 NDA 的约束。

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

    尊敬的 Amir:

    您是否只是将 CPU2用作您项目的核心?

    我们正在项目中同时使用两个内核、现在我将 分别测试两个 CPU 的计时方面、以便我们可以以该计时(无干扰计时)为基础、并找到由于两个 CPU 的干扰而导致的计时偏差。  

    我感到困惑如何将不同的方案加载到每个内核、您是将方案1加载到 CPU1还是将方案2加载到 CPU2、反之亦然?

    #1. 场景:

    • 我已经使用以下函数构建该代码、并将其加载到 CPU1中。
      • void ReadIntinCPU1due2CPU2Read_SameBlock()
        {
            UINT16 i = 0;
            while (1)
            {
                i = 0;
                if( CPUID_1 == gu16CpuId )
                {
                    start = guniIpcRegs.gstrCpu1IpcRegs.IPCCOUNTERL;
                    for (i = 0; i < u16size; i++)
                    {
                        gu16GS0_Array[i];   // For write, replacing this line to "gu16GS0_Array[i] = 6;"
                    }
                    end = guniIpcRegs.gstrCpu1IpcRegs.IPCCOUNTERL;
                    gf32TimeUs = (FLOAT32)(end - start)*0.005f;
                }
        
                i = 0;
                if( CPUID_2 == gu16CpuId )
                {
                    start = guniIpcRegs.gstrCpu2IpcRegs.IPCCOUNTERL;
                    for (i = 0; i < u16size; i++)
                    {
                        gu16GS0_Array[i];   // For write, replacing this line to "gu16GS0_Array[i] = 7;"
                    }
                    end = guniIpcRegs.gstrCpu2IpcRegs.IPCCOUNTERL;
                    gf32TimeUs = (FLOAT32)(end - start)*0.005f;
                }
            }
        }

    • 对于 CPU2、我添加了相同(上述)函数的注释、进行构建并将其加载到 CPU2。
    • 重要的一点是、我还保留了 if 语句中的 CPU2  在函数中 我在 CPU1中加载了该文件 例如、
      •     if( CPUID_2 == gu16CpuId )
                   {
                        start = guniIpcRegs.gstrCpu2IpcRegs.IPCCOUNTERL;
                        for (i = 0; i < u16size; i++)
                       {
                            gu16GS0_Array[i];           // For write, replacing this line to "gu16GS0_Array[i] = 7;"
                        }
                        end = guniIpcRegs.gstrCpu2IpcRegs.IPCCOUNTERL;
                         gf32TimeUs = (FLOAT32)(end - start)*0.005f;
                    }

    • 理想情况下、在这种情况下、CPU2不应影响 CPU1读取/写入的时序方面、因为我们仅在 CPU1中加载其编译(启用此函数)。
    • 但我发现 CPU2操作(读取和写入)也会影响 CPU1读取/写入时序方面。  
    • 情况_1 :  CPU2" if 语句部分" 在这种情况下、以下代码行将影响 CPU1的时序并提供不同的时序方面。
      • for (i = 0; i < u16size; i++)
            {
                gu16GS0_Array[i];           
            }

    • 情况_2 :  CPU2" if 语句部分" 在这种情况下、以下代码行将影响 CPU1的时序、并与 case_1相比提供不同的时序方面。
      • for (i = 0; i < u16size; i++)
            {
                gu16GS0_Array[i] = 7;           
            }

    #2. 场景:反之亦然

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

    我想我的困惑是你的数字背后关于你当时正在测试哪些内核的背景. 例如、对于场景1、您是通过哪种方式获得时序的?

    情况 A (A1和 A2在器件上单独运行):

    • A1:内核1给定 GS0控制:
      • 内核1:
        • CPU1读取-> 430.125微秒
      • 内核2:  
        • CPU2写入-> 430.125微秒
    • A2:内核2给定 GS0控制
      • 内核1:
        • CPU1写入-> 430.125微秒
      • 内核2:  
        • CPU2读取-> 409.64微秒

    情况 B (B1和 B2 分别在器件上运行):

    • B1:内核1给定的 GS0控制:
      • 内核1:
        • CPU1读取-> 430.125微秒
      • 内核2:  
        • CPU2读取-> 409.64微秒
    • B2:内核2给定 GS0控制
      • 内核1:
        • CPU1写入-> 430.125微秒
      • 内核2:  
        • CPU2写入-> 430.125微秒

    用例 C:

    • 内核1:
      • CPU1读取-> 430.125微秒
      • CPU1写入-> 430.125微秒
    • 内核2:  
      • CPU2读取-> 409.64微秒
      • CPU2写入-> 430.125微秒

    请记住、B2和 C 是无效的、因为您不能让两个内核都写入到全局 RAM 中、而不能更改选择 GS0RAM 控制器的多路复用器、而且您的代码也不会显示 GS0控制器的任何差异/更改。 如果您要 更改内核之间的 GS0RAM 控制器、敬请告知。

    如果您正在执行情况 A、我无法在 我拥有的硬件上重新创建这个、因此请尝试运行我之前附上的代码、看看这是否仍然会导致不一致的时序。  在时间安排不再一致的情况下、可能与不应输入的后续条件有关、但我没有您的完整项目、因此我无法在我身边复制此内容。