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.

[参考译文] CCS/F28M35H22C:两个内核之间的共享存储器

Guru**** 2609955 points
Other Parts Discussed in Thread: CONTROLSUITE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/683559/ccs-f28m35h22c-shared-memory-between-two-cores

器件型号:F28M35H22C
Thread 中讨论的其他器件:controlSUITE

工具/软件:Code Composer Studio

您好!  

您能否帮助确认如何控制两个内核之间的共享存储器数据交换?

我尝试在 M3和 C28端写入和读取数据、然后通过共享存储器 S0~S7交换数据。 但我想知道我们是否需要特别注意何时开始一边书写(例如、 C28)、那么何时开始在另一侧(M3)读取?  

到目前为止、我的理解是、我们可以随时在 C28上写入数据、在 M3侧、我们可以检查是否有任何可用数据写入 C28、然后从 M3侧读取。  

在 C28端、我计划使用缓冲区来不断地将数据写入或覆盖到共享存储器中;M3端还会持续监控 M3端的数据。   

它能起作用吗? 或者、如果我们希望使用共享存储器进行两个内核之间的数据交换、那么典型的设计是什么?

谢谢、

是的

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

    您好!

    [引用]到目前为止、我的理解是我们可以随时在 C28上写入数据、在 M3侧、我们可以检查是否有任何可用数据写入 C28、然后从 M3侧读取。  [/报价]

    是的、您可以同时从两个内核写入和读取数据。 访问在 两个主器件和给定的存储器块之间进行仲裁。

    [引用]在 C28端、我计划使用缓冲区不断将数据写入或覆盖到共享存储器;M3端还不断监控 M3端的数据[/引用]

    这一点没有问题。 如果 M3读取的地址与 C28x 更新的地址相同、并且基于仲裁、则 M3可能会获取旧数据或新更新的数据。 您需要在代码中处理它。

    此致、

    Vivek Singh

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

    您好、Vivek、

    非常感谢您的快速响应。  

    关于"M3可能会获取旧数据或新的更新数据。 您需要在您的代码中对此进行处理。" ,该部件的典型设计是什么? 有什么建议吗?

    现在、我想也许可以在 M3侧写一个缓冲区、用最新更新的数据不断覆盖旧数据;然后可能有某种数据流控制来决定何时开始读取数据或暂时缓冲最新数据。  

    谢谢、

    是的

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

    最好的做法是通过 IPC 标志(中断)在两个内核之间使用握手。 更新数据后、C28x 可以设置 IPC 标志。 M3可以在看到 IPC 标志设置后读取数据、并在读取完成后确认 IPC 标志。

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

    您好、Vivek、  

    非常感谢您的回答。 您能通过一些示例帮助我更好地理解吗? 或者简单的代码框架来说明此 IPC (中断)和 IPC 标志的确认?

    如果我看一下 controlSUITE、以下是有关 IPC 的3个示例? 它们之间有何不同? 我们应该遵循什么最佳做法?

    controlSUITE\device_support\f28m35x\v220\F28M35x_examples_Dual:

    ctom_ipcdrivers

    ctom_ipcdrivers_lite

    ctom_ipcdrivers_wrprotect

    提前非常感谢~!

    是的

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我们提供了两种不同类型的 IPC 驱动程序-基本"lite"版本和更高级版本、可以处理命令和多个通道的一些队列。 ctom_ipcdrivers_lite 和 ctom_ipcdrivers 正在演示这两个选项的功能。 wrProtect 示例仅显示了写入 MWRALLOW 受保护存储器的某些驱动程序函数的功能。

    ctom_ipcdrivers_lite 示例可能是一个很好的起点。 您可以单步执行代码并了解函数的作用。 如果驱动程序超出您的需求、您仍然可以使用它们来了解如何使用 IPC 标志通知其他内核已准备好新数据。

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

    尊敬的惠特尼:  

    非常感谢您的回复。 您能不能帮助我更详细地了解这个示例 F28M35x_examples_Dual\ctom_ipcdrivers_lite?

    我不是很确定如何实现此 IPC 机制。 例如、 共享存储器 S0已分配给拥有所有权的 M3、并且我们将 C28上的数据写入分配给 C28_MTOC_PASSMSG 的地址? 另外,您能否帮助解释一下以下代码?

    在 ctom_ipcdrivers_lite_m3.c 上、有一些代码行、如下所示

    //初始化 M3toC28消息 RAM 和 Sx SARAM 并等待初始化
    RAMMReqSharedMemAccess (S0_ACCESS、SX_M3MASTER);
    
    HWREG (RAM_CONFIG_BASE + RAM_O_MSXRTESTINIT1)|= 0x1;
    while ((HWREG (RAM_CONFIG_BASE + RAM_O_MSXRINITDONE1)&0x1)!= 0x1)
    {
    }
    HWREG (RAM_CONFIG_BASE + RAM_O_MTOCCRTESTINIT1)|= 0x1;
    while ((HWREG (RAM_CONFIG_BASE + RAM_O_MTOCRINITDONE)&0x1)!= 0x1)
    {
    } 

      在 ctom_ipcdrivers_lite_c28.c 中、有 FLAG17和 Flag1的使用方式不同、还有如下代码行  

    #define C28_MTOC_PASSMSG 0x0003FFF4 //由 M3用来传递要执行的局部变量地址
    
    uint32 * pulMsgRam =(void *) C28_MTOC_PASSMSG;
    //在此旋转,直至 M3就绪
    while (!IPCMtoCMFLAGBusy (IPC_FLAG17));
    IPCMtoCFlagAcknowledge (IPC_FLAG17);
    // 16位和32位数据写入
    //将16位字写入 M3 16位写入字变量。
    IPCLiteCtoMDataWrite (IPC_FLAG1、pulMsgRam[0]、(UINT32) usWWord16、
    IPC_LENGTH_16_BITS、
    IPC_FLAG32); 

    2. IPC 机制似乎也用于从 M3启动到 C28的过程、例如从闪存或 RAM 启动等 您能不能帮助我理解我们是如何做到这一点的? 在头文件描述中、这意味着什么?  

    我们如何实现从 m3到 c28的引导? 我遇到的一个问题是、如果我重启处理器、M3仍将正常运行、但 C28无法启动。 似乎缺少从 m3到 c28内核的 IPC 启动函数。 请您帮助理解这一点吗?  

    我看到其他 TI 示例中的一个实现方式是、我们还在下面配置 M3存储器 L0、L1、M0、M1。 但我不太理解、您能帮我处理 M3内核吗?分配存储器映射的最佳做法是什么?我们如何设计从 m3到 c28的引导过程?

    /*Function Name:master_ram_init_control_m1_msgram_Memories
    *说明:-调用到零初始化控制子系统 M1和消息 RAM 存储器
    的函数*使用 MTOCIPC 命令到 C-Boot ROM
    *
    //
    void main_ram_init_control_m0m1_msgram_Memories ()
    {
    unsigned int ii = 0;
    针对 M1的//RAM 初始化、和 CTOM MsgRAM - M0 RAM 初始化由 C-BootROM 完成
    //#define ccore_M0M1_CTOM_MSG_RAM_INIT_REG_ADDR 0x4920
    //#define ccore_m0_RAM_init_bit 0x01
    //#define ccore_M1_RAM_init_bit 0x04
    //#define ccore_ctom_MSG_RAM_init_bit 0x10
    IPCLiteMtoCSetBits_protected (IPC_FLAG1、0x4920、0x14、IPC_LENGTH_32_Bits、IPC_FLAG32);
    
    //等待直至 C-Bootack ROM
    
    while (HWREG (MTOCIPC_BASE + IPC_O_MTOCIPCFLG)& IPC_FLAG1);
    
    //检查是否通过或失败
    if (HWREG (MTOCIPC_BASE + IPC_O_MTOCIPCFLG)& IPC_FLAG32)
    {//still set - SO 命令失败。
    //错误-闪烁 SLOOOOOWWW
    while (1)
    {
    //如果您在这里,这是坏
    的}
    
    }
    //等待上面的 RAM_INIT 完成。
    //在 ccore 执行 RAM 初始化之前提供一些周期延迟
    for (ii =0;ii < 2048;i++);
    
    //读取 RAM_INIT_DONE 寄存器
    //#define ccore_M0M1_CTOM_MSG_RAM_INIT_DONE_REG_ADDR 0x4930
    //#define ccore_m0_RAM_init_done 位 0x01
    //#define ccore_M1_RAM_init_done 位0x04
    //#define ccore_CTOM_MSG_RAM_INIT_DONE_BIT 0x10
    
    操作
    {
    IPCLiteMtoCDataRead (IPC_FLAG1、0x4930、IPC_LENGTH_32_Bits、IPC_FLAG32);
    
    //等待直至 C-Bootack ROM
    while (HWREG (MTOCIPC_BASE + IPC_O_MTOCIPCFLG)& IPC_FLAG1);
    
    //检查是否通过或失败
    if (HWREG (MTOCIPC_BASE + IPC_O_MTOCIPCFLG)& IPC_FLAG32)
    {//still set - SO 命令失败。
    while (1)
    {
    //如果您在这里,这是坏
    的}
    
    }
    其他
    {
    if (HWREG (MTOCIPC_BASE + IPC_O_MTOCIPCDATAR)& 0x14)
    {
    //RAM_INIT COMPLEed -不执行任何操作:-)
    中断;
    }
    其他
    {
    //RAM_INIT 尚未完成、因此请等待更多时间并读取 RAM INIT DONE 寄存器。
    //在 ccore 执行 RAM 初始化之前提供一些周期延迟
    for (ii =0;ii < 2048;i++);
    继续;
    }
    }
    } while (1);
    }
    void master_ram_init_control_L0_L4_Memories ()
    {
    unsigned int ii = 0;
    针对 L0、L1、L2、L3的//RAM 初始化
    //#define ccore_L0L4_RAM_init_REG_ADDR 0x4922
    //#define ccore_L0_RAM_init_bit 0x01
    //#define ccore_L1_RAM_init_bit 0x04
    //#define ccore_L2_RAM_init_bit 0x10
    //#define ccore_L3_RAM_init_bit 0x40
    IPCLiteMtoCSetBits_protected (IPC_FLAG1、0x4922、0x55、IPC_LENGTH_32_Bits、IPC_FLAG32);
    
    //等待直至 C-Bootack ROM
    while (HWREG (MTOCIPC_BASE + IPC_O_MTOCIPCFLG)& IPC_FLAG1);
    
    //检查是否通过或失败
    if (HWREG (MTOCIPC_BASE + IPC_O_MTOCIPCFLG)& IPC_FLAG32)
    {//still set - SO 命令失败。
    while (1)
    {
    //如果您在这里,这是坏的;
    }
    
    }
    //等待上面的 RAM_INIT 完成。
    //在 ccore 执行 RAM 初始化之前提供一些周期延迟
    for (ii =0;ii < 2048;i++);
    
    //读取 RAM_INIT_DONE 寄存器
    //#define ccore_L0_L4_RAM_INIT_DONE_REG_ADDR 0x4932
    //#define ccore_L0_RAM_init_done 位 0x01
    //#define ccore_L1_RAM_init_done 位0x04
    //#define ccore_L2_RAM_init_done 位0x10
    //#define ccore_L3_RAM_init_done 位0x40
    
    操作
    {
    IPCLiteMtoCDataRead (IPC_FLAG1、0x4932、IPC_LENGTH_32_Bits、IPC_FLAG32);
    
    //等待直至 C-Bootack ROM
    while (HWREG (MTOCIPC_BASE + IPC_O_MTOCIPCFLG)& IPC_FLAG1);
    
    //检查是否通过或失败
    if (HWREG (MTOCIPC_BASE + IPC_O_MTOCIPCFLG)& IPC_FLAG32)
    {//still set - SO 命令失败。
    while (1)
    {
    //如果您在这里,这是坏
    的}
    
    }
    其他
    {
    if (HWREG (MTOCIPC_BASE + IPC_O_MTOCIPCDATAR)& 0x55)
    {
    //RAM_INIT COMPLEed -不执行任何操作:-)
    中断;
    }
    其他
    {
    //RAM_INIT 尚未完成、因此请等待更多时间并读取 RAM INIT DONE 寄存器。
    //在 ccore 执行 RAM 初始化之前提供一些周期延迟
    for (ii =0;ii < 2048;i++);
    继续;
    }
    }
    } while (1);
    
    } 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    MtoC 消息 RAM 用于告知 C28它将通过 IPC 函数与其交互的变量、寄存器和函数的地址。 由于它是 MtoC RAM、因此您无需更改示例针对 S0所做的权限。 此外,该示例看起来不像是实际向 S0写入任何内容--它只是使用它来演示访问请求过程。

    此示例使用 IPC_FLAG17作为一种方法、确保 C28在 M3完成其全部初始化之前不会开始测试。 IPC_FLAG1用于指示正在发送命令-请注意、M3侧的函数正在等待看到命令已设置、然后再继续。 它还用于生成中断。 IPC_FLAG32用于返回状态。

    有关引导 ROM 操作的详细信息、请阅读技术参考手册的该部分。 至于您看到的问题、您是否使用项目的闪存独立编译配置? 您需要确保对 IPCMtoCBootControlSystem()的调用已编译到您的项目中。

    惠特尼