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:'从 IPC 消息 RAM 复制并引导至 RAM 的引导模式

Guru**** 2529560 points
Other Parts Discussed in Thread: TMS320F28388D, TMDSCNCD28388D, C2000WARE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1068910/tms320f28388d-copy-from-ipc-message-ram-and-boot-to-ram-boot-mode

部件号:TMS320F28388D
“线程”中讨论的其它部件: TMDSCNCD28388DC2000WARE

您好,

我正在处理位于 TMDSCNCD28388D 评估板上的 TMS320F28388D CPU。 处理器包含3个 CPU 内核:CPU1 (C2000)/ CPU2 (C2000)/ CM (Connectivity Manager - ARM Cortex-M4)。

CPU1内核似乎无法直接访问 CM 内核的闪存。 我假设我必须先通过 CPU1启动 CM 核心,然后通过 IPC 接口在核心之间交换数据,然后 CM 最终可以将数据存储在闪存中。 因此,我认为我必须首先通过名为‘Copy from IPC Message RAM and boot to RAM’(从 IPC 消息 RAM 复制并引导至 RAM)的引导模式引导 CM (请参阅参考手册 spruii0c.pdf 表‘5-1)。 Boot System Overview’(引导系统概述)。

我现在的计划是编写 CPU1应用程序(例如基于闪烁的 LED 示例), 它以‘从 IPC 消息 RAM 复制并引导至 RAM’引导模式引导 CM,我想将 CM 引导映像作为阵列添加到 CPU1项目。 我还想举构建配置 CM_RAM 中 CM 核心的 LED 闪烁示例(整个应用程序驻留在 RAM 内存中),检查 CM 核心是否正在运行该 LED 闪烁应用程序。

我有以下问题

1)请确认 CPU1无法直接访问 CM 闪存吗?

2)我的方法是否正确,是否必须先通过‘Copy from IPC Message RAM and boot to RAM’(从 IPC 消息 RAM 复制并引导至 RAM)引导模式引导 CM? 之后,CM 应用程序可以通过 IPC 消息 RAM 继续与 CPU1核心通信,并访问 CM-FLASH。

3)文件 spruii0c.pdf 表5-1中是否有一个 TI 示例项目,该项目显示了 CPU1如何通过 IPC 启动 CM,称为‘从 IPC 消息 RAM 复制并引导至 RAM’

4)是否有‘Copy from IPC Message RAM and boot to RAM’的应用说明,因为参考手册 spruii0c.pdf 第5.7.1.6章中的信息不够详细? 在本章中,我只能一次写入最大的 CM 启动加载器映像 2[kword]到 IPC 消息 RAM,由 CM 将其复制到 RAM 并执行。 这当然是对 CM 图像大小的限制。

5)我也看不到引导映像必须采用何种格式的信息,因此,如何在 CM 项目中为该引导模式设置‘Arm Hex Utility’工具?

6)如果没有进一步的文档或项目示例:CM ROM 引导加载器源代码是否可用,以便从该代码中了解‘从 IPC 消息 RAM 复制并引导至 RAM’引导模式在 CM 视图中的工作情况? 如果是,我可以在哪里找到它?

谢谢,

Inno

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

    您好,  

    1.正确,CPU1无法直接访问 CM 闪存。  

    2.这是正确的。  

    F2838x 的 SCI 闪存内核示例显示了如何使用此引导模式,该示例位于 C2000Ware_4_00_00_00\driverlib\f2838x\examples\C28x_cm\flash_kernel

    4.我认为没有专门针对此启动模式的应用程序注释,但闪存内核有一个应用程序注释: www.ti.com/lit/sprabv4   

    5.请参阅链接的应用说明。  

    6.没有适用于 CM 的引导加载程序,请参阅示例。  

    谢谢

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

    Anu 您好,  

    我快速查看了应用说明。 让我看看我的回答是否正确:

    您在第4点提到的应用说明也参考了'C2000Ware_4_00_00_00\driverlib\f2838x\examples\C28x_cm\flash_kernel'示例。 该示例项目提供了大量选项,用于通过 UART 与不同 Core 及其对应的闪存进行通信。

    这意味着该项目的某个部分 还使用了我正在寻找的“从 IPC 消息 RAM 复制并引导至 RAM”方法 , 这在运行示例并通过 UART 发送 CM 图像时的特定时间点发生。

    我将首先研究应用程序注释, 然后运行示例。 感谢我对示例项目和应用说明的关注。

    请允许我提出一个补充问题,尽管我可能也会从示例项目中得到答案。 CPU1 -> CM 消息缓冲区大小为2[kword]= 4[kByte]。 但 CM 的内部 RAM 内存(应用程序映像可能驻留)当然更大。  作为‘从 IPC 消息 RAM 复制并引导至 RAM’ 过程的一部分,是否有可能在 CPU1 -> CM 消息 RAM 上下载大小大于2[kword]的 CM RAM 应用程序? 或者,CM 是否仅从 CPU1 -> CM 消息 RAM 中复制一个“数据包”,并尝试立即跳至 CM 应用程序, 以下哪项表示用于“从 IPC 消息 RAM 复制并引导至 RAM” 过程的 RAM 应用程序的最大大小限制为2[ks字数]?

    此致,

    Inno  

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

    您好,  

    [引用 userid="459171" url=~ë/support/icns/c2000-icroms-group/c2000/f/c2000-iclms -forum/1068910/tms320f28388d-copy-fer-IPC-message-ram-and -boot-to-lib-boot-mode/3956524#3956524",另请参阅“c3800_intrab_s”中提到的“c_quot_quote _quid_2800_intrab_s”。 该示例项目提供了大量选项,用于通过 UART 与不同 Core 及其对应的闪存进行通信。

    更具体地说,该示例说明了如何通过 SCI 为 CPU1和 CM 执行固件升级。

    [引用 userid="459171" url=~ë/support/icns/c2000微控制器-组/CC2000 /f/c2000微控制器-论坛/1068910/tms320f28388d-copy-from-IPC-message-ram-and -boot-to-cart -boot-mode/3956524#3956524" ’,这意味  着在特定时间和特定时间内复制并通过复制 RAM,在特定的 RAM 中使用该命令时,并在特定的 RAM 启动过程中使用该命令[引用信息],并在特定的命令时,该命令时,我会从该命令复制到特定的命令。

    是的,您将看到 CPU1项目中使用的方法。 我想澄清的一点是,CPU1 SCI 模块用于 CPU1和 CM,而不使用 CM UART 模块。 CPU1通过 SCI 接收数据,并通过 IPC 消息 RAM 发送给 CM,而 CM 则使用这些信息执行内核操作。  

     ‘引用 userid="459171" URL"~ë/support/icna/c2000-icler-group/c2f/c2000-iclms -forum/1068910/tms320f28388d-copy-from-ipc-message-ram-and -boot-to-id-boot-mode/3956524#3956524"] ,它是否可以从部分 RAM 中复制到部分 RAM,并复制到部分 RAM 中的消息[CPCM-],并复制到部分 RAM 中,以复制到部分 RAM 中的形式从该消息[CPCM-[<]

    这是正确的,您可以按块复制 CM RAM 应用程序。 这在 Flash 内核示例中得到了证明-驻留在 RAM 中的 CM Flash 内核将被成块复制。  

    谢谢

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

    你好,Anu,

    在学习闪存内核示例后,我了解到要查看的重要功能包括:

    • setBootModeForCM
    • 科学 IpcLoadCM
    • copyDataToCPU1ToCMMSGRAM

    ‘,‘copyDataToCPU1ToCMMSGRAM’功能是通过 IPC 接口将 CM 内核 RAM 图像以块形式发送给 CM 的功能。

    我对‘方式有疑问,CPU1如何在引导过程中通过“IPC_sendCommand”向 CM 发送数据,或终止该过程。

    1)复制协议在哪里描述?

    例如,其中描述了在复制数据期间,IPCSENDCOM/IPCREVCOM 寄存器需要保存数据需要复制到 CM RAM 的目标地址。 或者,IPCSENDADDR/IPCRECVATE 将 kernelBuffer[]数组地址保存在消息 RAM 中。 或者,IPCSENDDATA/IPCRECVATE 保留字节数。

    请参见此处:

    2)以及在何处描述了该流程的终止方式:

    这意味着 IPCSENDCOM/IPCREVCOM 寄存器需要保留入口点地址,而 IPCSENDDATA/IPCRECVDATE 值0意味着‘跳转至 IPCSENDCOM/IPCREVCOM 内部入口点的应用程序映像’。

     

    我在 CPU 参考手册中没有找到“CPU1 -> CM IPC 复制和引导到 RAM”过程的某种流程图或其他任何内容,该手册详细描述了该过程。

    3) BTW,是否需要使用 IPC FLAG2复制数据 并终止 FLAG3? 或者,我可以决定使用哪些标志,ROM 引导加载程序只轮询所有 IPC 请求标志吗?

     

    谢谢,

    Inno

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

    您好,  

    复印协议/终止过程在前一份答复中链接的应用说明中进行了描述,特别是第5.2.2节。 标志可以由您决定,它不需要是标志2和标志3。 我想澄清一点,这是一个在 RAM 而不是 ROM 中运行的辅助引导加载程序。  

    谢谢

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

    Anu 您好,

    我真的很抱歉,但我仍在挣扎。 让我解释一下我在学习闪存内核示例(至少部分)后尝试做什么。 我为 内部版本配置 RAM 中的 CM 核心编译了一个闪烁的 LED 示例项目,并按如下所示设置 ARM HEX 实用程序:

    之后,我获取 了由 ARM HEX 实用程序生成的文件,并从中创建了一个数组(我删除了文本开头/文本结尾字符0x02/0x03), 之后,我在构建配置闪存中添加了 CPU1闪烁 LED 项目(因为否则,内存不足)。 请在此处查看我的代码:

    #include "device.h"
    
    uint8_t Boot_IMG[]=
    {
    0x08, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x0B, 0x09, 0x00, 0x06, 
    0x20, 0x00, 0x08, 0x00, 0x00, 0xF0, 0x82, 0xB9, 0x70, 0x47, 
    0x01, 0x40, 0x20, 0x00, 0x0C, 0x00, 0x00, 0xC2, 0xFF, 0x1F, 0x01, 0x08, 0x00, 0x20, 0xA9, 0x0B, 0x00, 0x20, 0x47, 0x0B, 0x00, 0x20, 0x17, 0x0A,
    0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A,
    0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A,
    0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A,
    0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A,
    0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A,
    0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A,
    0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A,
    0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A,
    0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A,
    0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A,
    0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A,
    0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20,
    0x00, 0x06, 0x1F, 0xFF, 0xE0, 0x00, 0x40, 0x1E, 0xFD, 0xD1, 0x70, 0x47,
    0x00, 0x18, 0x1F, 0xFF, 0xE0, 0x08, 0xAF, 0x09, 0x00, 0x20, 0x93, 0x0B, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x10, 0xE0,
    0xFF, 0x1F, 0x00, 0xC0, 0x00, 0x20,
    0x03, 0xA2, 0x20, 0x00, 0x08, 0x08, 0x00, 0x2A, 0x4A, 0xD0, 0x5F, 0xEA, 0x00, 0x0C, 0x8B, 0x07, 0x1C, 0xD1, 0x83, 0x07, 0x22, 0xD1, 0x10, 0x2A,
    0x08, 0xD3, 0x70, 0xB4, 0x10, 0x3A, 0x78, 0xC9, 0x78, 0xC0, 0x10, 0x3A, 0xFB, 0xD2, 0x70, 0xBC, 0x10, 0x32, 0x38, 0xD0, 0x04, 0x2A, 0x2C, 0xD3,
    0x08, 0x2A, 0x05, 0xD3, 0x0C, 0x2A, 0x24, 0xBF, 0x08, 0xC9, 0x08, 0xC0, 0x08, 0xC9, 0x08, 0xC0, 0x08, 0xC9, 0x08, 0xC0, 0x92, 0x07, 0x2A, 0xD0,
    0x92, 0x0F, 0x22, 0xE0, 0x0B, 0x78, 0x03, 0x70, 0x49, 0x1C, 0x40, 0x1C, 0x52, 0x1E, 0x22, 0xD0, 0x8B, 0x07, 0xF7, 0xD1, 0xC3, 0x07, 0x14, 0xD1,
    0x83, 0x07, 0xD8, 0xD0, 0x12, 0x1F, 0x12, 0xD3, 0x08, 0xC9, 0x03, 0x80, 0x1B, 0x0C, 0x43, 0x80, 0x00, 0x1D, 0x12, 0x1F, 0xF8, 0xD2, 0x0A, 0xE0,
    0x08, 0xC9, 0x03, 0x70, 0x1B, 0x0A, 0x43, 0x70, 0x1B, 0x0A, 0x83, 0x70, 0x1B, 0x0A, 0xC3, 0x70, 0x00, 0x1D, 0x12, 0x1F, 0xF4, 0xD2, 0x12, 0x1D,
    0x05, 0xD0, 0x0B, 0x78, 0x03, 0x70, 0x49, 0x1C, 0x40, 0x1C, 0x52, 0x1E, 0xF9, 0xD1, 0x60, 0x46, 0x70, 0x47, 0x00, 0xB5, 0xAD, 0xF1, 0x14, 0x0D,
    0x01, 0x91, 0x00, 0x90, 0x00, 0x98, 0x00, 0xF0, 0x3C, 0xF9, 0x18, 0xB9, 0x0D, 0xA0, 0xE9, 0x21, 0x00, 0xF0, 0x63, 0xF9, 0x00, 0x99, 0x1C, 0x48,
    0x49, 0x09, 0x00, 0xEB, 0x01, 0x10, 0x02, 0x90, 0x00, 0x98, 0x01, 0x21, 0x00, 0xF0, 0x1F, 0x00, 0x81, 0x40, 0x03, 0x91, 0x01, 0x98, 0x18, 0xB9,
    0x03, 0x98, 0x02, 0x99, 0x88, 0x60, 0x02, 0xE0, 0x03, 0x98, 0x02, 0x99, 0x48, 0x60, 0x05, 0xB0, 0x00, 0xBD, 0x43, 0x3A, 0x2F, 0x74, 0x69, 0x2F,
    0x63, 0x32, 0x30, 0x30, 0x30, 0x2F, 0x43, 0x32, 0x30, 0x30, 0x30, 0x57, 0x61, 0x72, 0x65, 0x5F, 0x33, 0x5F, 0x30, 0x34, 0x5F, 0x30, 0x30, 0x5F,
    0x30, 0x30, 0x2F, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x6C, 0x69, 0x62, 0x2F, 0x66, 0x32, 0x38, 0x33, 0x38, 0x78, 0x2F, 0x64, 0x72, 0x69, 0x76,
    0x65, 0x72, 0x6C, 0x69, 0x62, 0x5F, 0x63, 0x6D, 0x2F, 0x67, 0x70, 0x69, 0x6F, 0x2E, 0x68, 0x00, 0xC0, 0x46, 0x00, 0x30, 0x08, 0x40, 0x08, 0xB5,
    0x00, 0x20, 0x00, 0xF0, 0x9E, 0xF8, 0x4F, 0xF4, 0x80, 0x60, 0x00, 0xF0, 0x9A, 0xF8, 0x4F, 0xF4, 0x00, 0x60, 0x00, 0xF0, 0x96, 0xF8, 0x4F, 0xF4,
    0x40, 0x60, 0x00, 0xF0, 0x92, 0xF8, 0x01, 0x20, 0x00, 0xF0, 0x8F, 0xF8, 0x40, 0xF2, 0x01, 0x20, 0x00, 0xF0, 0x8B, 0xF8, 0x40, 0xF2, 0x01, 0x40,
    0x00, 0xF0, 0x87, 0xF8, 0x40, 0xF2, 0x01, 0x50, 0x00, 0xF0, 0x83, 0xF8, 0x40, 0xF6, 0x01, 0x00, 0x00, 0xF0, 0x7F, 0xF8, 0x02, 0x20, 0x00, 0xF0,
    0x7C, 0xF8, 0x4F, 0xF4, 0x81, 0x70, 0x00, 0xF0, 0x78, 0xF8, 0x40, 0xF2, 0x02, 0x20, 0x00, 0xF0, 0x74, 0xF8, 0x40, 0xF2, 0x02, 0x40, 0x00, 0xF0,
    0x70, 0xF8, 0x40, 0xF2, 0x02, 0x60, 0x00, 0xF0, 0x6C, 0xF8, 0x40, 0xF6, 0x02, 0x00, 0x00, 0xF0, 0x68, 0xF8, 0x08, 0xBD, 0xF8, 0xB5, 0x84, 0x46,
    0x40, 0xF6, 0xFF, 0x74, 0x1C, 0xF8, 0x01, 0x3B, 0x00, 0x22, 0x10, 0xE0, 0x48, 0x1B, 0x40, 0x1E, 0x10, 0xF8, 0x01, 0x5B, 0x7F, 0x1E, 0x01, 0xF8,
    0x01, 0x5B, 0xF9, 0xD1, 0x03, 0xE0, 0x1C, 0xF8, 0x01, 0x0B, 0x01, 0xF8, 0x01, 0x0B, 0x52, 0x1C, 0x5B, 0x08, 0x08, 0x2A, 0xEA, 0xDA, 0x58, 0x08,
    0xF5, 0xD2, 0x1C, 0xF8, 0x01, 0x0B, 0x1C, 0xF8, 0x01, 0x5B, 0x05, 0xF0, 0x0F, 0x07, 0xFF, 0x1C, 0xC5, 0xF3, 0x03, 0x15, 0x12, 0x2F, 0x45, 0xEA,
    0x00, 0x15, 0x08, 0xD1, 0x1C, 0xF8, 0x01, 0x6B, 0x30, 0x0A, 0x24, 0xBF, 0x1C, 0xF8, 0x01, 0x0B, 0x60, 0xF3, 0xDF, 0x16, 0xBF, 0x19, 0xAC, 0x42,
    0xD4, 0xD1, 0xF8, 0xBD, 0xFE, 0xE7, 0x08, 0xB5, 0x00, 0xF0, 0x95, 0xF8, 0x22, 0x20, 0x00, 0x21, 0xFF, 0xF7, 0x3F, 0xFF, 0x12, 0x48, 0x00, 0x68,
    0x08, 0x28, 0x03, 0xDA, 0x11, 0x48, 0xFD, 0xF7, 0xE6, 0xFA, 0x02, 0xE0, 0x10, 0x48, 0xFD, 0xF7, 0xE2, 0xFA, 0x22, 0x20, 0x01, 0x21, 0xFF, 0xF7,
    0x30, 0xFF, 0x0A, 0x48, 0x00, 0x68, 0x08, 0x28, 0x03, 0xDA, 0x09, 0x48, 0xFD, 0xF7, 0xD7, 0xFA, 0x02, 0xE0, 0x08, 0x48, 0xFD, 0xF7, 0xD3, 0xFA,
    0x05, 0x49, 0x08, 0x68, 0x40, 0x1C, 0x08, 0x60, 0x03, 0x48, 0x02, 0x49, 0x00, 0x68, 0x00, 0xF0, 0x0F, 0x00, 0x08, 0x60, 0xD6, 0xE7, 0x00, 0xC0,
    0x00, 0x20, 0x32, 0xE4, 0x3D, 0x01, 0x67, 0xC8, 0x7B, 0x02, 0x1C, 0xB5, 0xAD, 0xF8, 0x00, 0x00, 0xBD, 0xF8, 0x00, 0x00, 0x00, 0xF0, 0x1F, 0x00,
    0x80, 0x00, 0xAD, 0xF8, 0x02, 0x00, 0xBD, 0xF8, 0x00, 0x00, 0x00, 0xF4, 0xF8, 0x50, 0x00, 0x0A, 0xAD, 0xF8, 0x04, 0x00, 0x07, 0x49, 0x07, 0x4A,
    0xBD, 0xF8, 0x02, 0x00, 0xBD, 0xF8, 0x04, 0x40, 0x40, 0x18, 0x03, 0x68, 0x01, 0x21, 0xA1, 0x40, 0x19, 0x43, 0x0A, 0x43, 0x02, 0x60, 0x1C, 0xBD,
    0xC0, 0x46, 0x00, 0xC0, 0x0F, 0x40, 0x00, 0x00, 0x34, 0x56, 0xB0, 0xB5, 0x0C, 0x48, 0x0C, 0x4D, 0xA8, 0x42, 0x10, 0xD0, 0x0C, 0x48, 0x0C, 0x4C,
    0xA0, 0x42, 0x0C, 0xD0, 0x00, 0x1B, 0x08, 0x3C, 0xC7, 0x10, 0x54, 0xF8, 0x08, 0x0F, 0x01, 0x78, 0x55, 0xF8, 0x21, 0x20, 0x61, 0x68, 0x40, 0x1C,
    0x90, 0x47, 0x7F, 0x1E, 0xF5, 0xD1, 0x00, 0xBF, 0x00, 0xBF, 0xB0, 0xBD, 0xC0, 0x46, 0x10, 0xE0, 0xFF, 0x1F, 0x08, 0xE0, 0xFF, 0x1F, 0x20, 0xE0,
    0xFF, 0x1F, 0x18, 0xE0, 0xFF, 0x1F, 0x07, 0x48, 0x80, 0xF3, 0x08, 0x88, 0x00, 0xBF, 0x00, 0xBF, 0x00, 0xF0, 0x45, 0xF8, 0x08, 0xB1, 0xFF, 0xF7,
    0xD4, 0xFF, 0x00, 0x20, 0xFF, 0xF7, 0x7B, 0xFF, 0x01, 0x20, 0x00, 0xF0, 0x3E, 0xF8, 0x00, 0xC2, 0xFF, 0x1F, 0xAD, 0xF1, 0x08, 0x0D, 0x00, 0x90,
    0x00, 0x9A, 0x00, 0x21, 0x00, 0x20, 0xA8, 0x2A, 0x00, 0xD8, 0x01, 0x21, 0x01, 0xB1, 0x01, 0x20, 0x02, 0xB0, 0x70, 0x47, 0xFE, 0xE7, 0x08, 0xB5,
    0x00, 0xF0, 0x13, 0xF8, 0xFF, 0xF7, 0xF3, 0xFE, 0x02, 0x48, 0x00, 0xF0, 0x04, 0xF8, 0x08, 0xBD, 0xC0, 0x46, 0x00, 0x0C, 0x00, 0x20, 0xAD, 0xF1,
    0x08, 0x0D, 0x00, 0x90, 0x02, 0x49, 0x00, 0x98, 0x08, 0x60, 0x02, 0xB0, 0x70, 0x47, 0x08, 0xED, 0x00, 0xE0, 0x02, 0x49, 0x08, 0x88, 0x40, 0xF0,
    0x68, 0x00, 0x08, 0x80, 0x70, 0x47, 0x0C, 0x00, 0x08, 0x40, 0xAD, 0xF1, 0x08, 0x0D, 0x01, 0x91, 0x00, 0x90, 0x00, 0xBE, 0x02, 0xB0, 0x70, 0x47,
    0xD0, 0xF8, 0x03, 0x20, 0xC3, 0x1D, 0x08, 0x46, 0x19, 0x46, 0xFF, 0xF7, 0x34, 0xBE, 0x01, 0x20, 0x70, 0x47, 0x00, 0xBF, 0xFE, 0xE7, 0xFE, 0xE7,
    0x00, 0x00
    };
    
    uint32_t u32_ram_array_index = 0;
    uint32_t EntryAddrCMKernel_Avi;
    #define KERNEL_BUFFER_SIZE_AVI 250 // Must be the same as '#define KERNEL_BUFFER_SIZE 250' inside file 'flash_kernel_c28x_cm_ex1_sci_boot_cpu1.c'
    
    #pragma DATA_SECTION(kernelBuffer, "MSGRAM_CPU_TO_CM")
    uint16_t kernelBuffer[KERNEL_BUFFER_SIZE_AVI];
    //extern uint16_t kernelBuffer[KERNEL_BUFFER_SIZE_AVI];
    
    //
    // This function sets the boot mode for CM
    //
    void setBootModeForCM_Avi(void){
    
       Flash_releasePumpSemaphore();
    
       //Clear all flags
       IPC_clearFlagLtoR(IPC_CPU1_L_CM_R, IPC_FLAG_ALL);
    
       //set boot mode
       Device_bootCM(BOOTMODE_IPC_MSGRAM_COPY_LENGTH_200W | BOOTMODE_IPC_MSGRAM_COPY_BOOT_TO_S0RAM);
    }
    
    uint16_t sciaGetByteDataCM_Avi(void)
    {
       uint8_t byteData;
       byteData = 0x00;
    
       //
       // Fetch the MSB and verify back to the host
       //
       byteData = Boot_IMG[u32_ram_array_index];
       u32_ram_array_index++;
    
       return byteData;
    }
    
    uint16_t sciaGetWordDataCM_Avi(void)
    {
        uint16_t wordData;
        uint16_t byteData;
    
        wordData = 0x0000;
        byteData = 0x0000;
    
        //
        // Fetch the LSB and verify back to the host
        //
        wordData = Boot_IMG[u32_ram_array_index];
        u32_ram_array_index++;
    
        //
        // Fetch the MSB and verify back to the host
        //
        byteData = Boot_IMG[u32_ram_array_index];
        u32_ram_array_index++;
    
        //
        // form the wordData from the MSB:LSB
        //
        wordData |= (byteData << 8);
    
        return wordData;
    }
    
    uint32_t getLongData_Avi()
    {
        uint32_t longData;
    
        //
        // Fetch the upper 1/2 of the 32-bit value
        //
        longData = ( (uint32_t)sciaGetWordDataCM_Avi() << 16);
    
        //
        // Fetch the lower 1/2 of the 32-bit value
        //
        longData |= (uint32_t)sciaGetWordDataCM_Avi();
    
        return(longData);
    }
    
    
    //
    // readReservedFn - This function reads 8 reserved words in the header.
    //                   None of these reserved words are used by the
    //                   this boot loader at this time, they may be used in
    //                   future devices for enhancements.  Loaders that use
    //                   these words use their own read function.
    //
    void readReservedFn_Avi()
    {
        uint16_t i;
    
        //
        // Read and discard the 8 reserved words.
        //
        for(i = 1; i <= 8; i++)
        {
            sciaGetWordDataCM_Avi();
        }
        return;
    }
    
    
    void clearKernelBuffer_Avi(void){
        uint16_t index = 0;
        for (index = 0; index < KERNEL_BUFFER_SIZE_AVI; index++){
            kernelBuffer[index] = 0x0000;
        }
    
    }
    
    //
    // CopyDataToCPU1ToCMMSGRAM
    // This function takes the CM kernel being streamed through SCI and places it
    // in a buffer in CPU1TOCMMSGRAM where it can be accessed by CM to then copy
    // into CM RAM. CPU1 and CM first synchronize with each other and then CPU1
    // starts sending the kernel to CM. Once it hasfilled up the buffer, it signals
    // CM. It then waits on CM to signal that it has finished copying the contents
    // of the buffer before filling it up again with the next section of the
    // kernel. CPU1 continues this operation until a blocksize of 00 00 is
    // encountered, at which point it lets CM know that it has finished
    // transmitting the kernel and waits for an acknowledgement from CM before
    // exiting the function.
    //
    void copyDataToCPU1ToCMMSGRAM_Avi(void)
    {
        IPC_sync(IPC_CPU1_L_CM_R, IPC_FLAG1);
    
        struct HEADER {
            uint32_t DestAddr;
            uint16_t BlockSize;
        } BlockHeader;
    
        uint16_t i;
        uint16_t j;
        uint32_t byte4;
        uint32_t byte3;
        uint32_t byte2;
        uint32_t byte1;
        uint16_t bufferIndex = 0;
        uint16_t wordData = 0;
    
        //
        // Get the size in words of the first block
        //
        BlockHeader.BlockSize = sciaGetWordDataCM_Avi();
        byte2 = BlockHeader.BlockSize & 0x0000FF00;
        byte1 = BlockHeader.BlockSize & 0x000000FF;
        byte2 = byte2 >> 8;
        byte1 = byte1 << 8;
        BlockHeader.BlockSize = byte1 | byte2;
    
        //
        // While the block size is > 0 copy the data
        // to the DestAddr.  There is no error checking
        // as it is assumed the DestAddr is a valid
        // memory location
        //
    
        while(BlockHeader.BlockSize != (uint16_t)0x0000U)
        {
           BlockHeader.DestAddr = getLongData_Avi();
           byte4 = BlockHeader.DestAddr & 0xFF000000;
           byte3 = BlockHeader.DestAddr & 0x00FF0000;
           byte2 = BlockHeader.DestAddr & 0x0000FF00;
           byte1 = BlockHeader.DestAddr & 0x000000FF;
           byte4 = byte4 >> 8;
           byte3 = byte3 << 8;
           byte2 = byte2 >> 8;
           byte1 = byte1 << 8;
           BlockHeader.DestAddr = byte3 | byte4 | byte1 | byte2;
           for(i = 0; i < BlockHeader.BlockSize; i += 0)
           {
               //
               // The size of the block is less than the buffer size, so the entire
               // block is written to the buffer and sent to CM
               // For example. block size is 4 and buffer size is 5, so all 4 bytes
               // are sent to CM via the buffer
               //
    
               //
               // BlockSize is in bytes, KERNEL_BUFFER_SIZE is in words
               //
               if(BlockHeader.BlockSize < (KERNEL_BUFFER_SIZE_AVI << 1))
               {
                   //
                   // fill up the buffer with the SCI data stream
                   //
                   for(j = 0; j < BlockHeader.BlockSize; j += 0)
                   {
                       byte1 = sciaGetByteDataCM_Avi();
                       j++;
    
                       //
                       //when there are an odd number of bytes, we don't want to
                       //get an extra byte from the data stream, so pad with 0xFF
                       //
                       if(j == BlockHeader.BlockSize)
                       {
                           byte2 = 0xFF;
                       }
                       else
                       {
                           byte2 = sciaGetByteDataCM_Avi();
                           j++;
                       }
    
                       wordData = (byte2 << 8) | byte1;
                       kernelBuffer[bufferIndex] = wordData;
                       bufferIndex++;
                   }
                   i += j;
    
                   IPC_sendCommand(IPC_CPU1_L_CM_R, IPC_FLAG2,
                                   IPC_ADDR_CORRECTION_ENABLE,
                                   BlockHeader.DestAddr,
                                   (uint32_t)kernelBuffer, j);
                   //
                   //set flag l to r
                   //
                   IPC_setFlagLtoR(IPC_CPU1_L_CM_R, IPC_FLAG2);
    
                   bufferIndex = 0;
    
                   //
                   //wait for ack
                   //
                   IPC_waitForAck(IPC_CPU1_L_CM_R, IPC_FLAG2);
                   clearKernelBuffer_Avi();
    
               }
    
               //
               // The size of the block is greater than the buffer, so it will be
               // split up and sent in chunks until the entire block is sent
               // For example, block size is 7 and buffer size is 5, so first 5
               // bytes will be sent over and then the remaining 2 bytes will be
               // sent over
               //
               else //BlockHeader.BlockSize >= BUFFER_SIZE
               {
                   //
                   // keep sending until we have sent over the entire block
                   //
                   while(i < BlockHeader.BlockSize){
                       if((BlockHeader.BlockSize - i) < (KERNEL_BUFFER_SIZE_AVI << 1))
                       {
                           for(j = 0; j < BlockHeader.BlockSize - i; j += 0)
                           {
                              byte1 = sciaGetByteDataCM_Avi();
                              j++;
    
                              //
                              //when there are an odd number of bytes, we don't
                              //want to get an extra byte from the data stream,
                              //so pad with 0xFF
                              //
                              if(j == BlockHeader.BlockSize)
                              {
                                  byte2 = 0xFF;
                              }
                              else
                              {
                                  byte2 = sciaGetByteDataCM_Avi();
                                  j++;
                              }
                              wordData = (byte2 << 8) | byte1;
                              kernelBuffer[bufferIndex] = wordData;
                              bufferIndex++;
                           }
                           //
                           // increment i outside here so it doesn't affect loop
                           // above
                           //
                           i += j;
    
                           IPC_sendCommand(IPC_CPU1_L_CM_R, IPC_FLAG2,
                                           IPC_ADDR_CORRECTION_ENABLE,
                                           BlockHeader.DestAddr,
                                           (uint32_t)kernelBuffer, j);
                           //
                           //set flag l to r
                           //
                           IPC_setFlagLtoR(IPC_CPU1_L_CM_R, IPC_FLAG2);
    
                           bufferIndex = 0;
    
                           //
                           //wait for ack
                           //
                           IPC_waitForAck(IPC_CPU1_L_CM_R, IPC_FLAG2);
                           clearKernelBuffer_Avi();
                       }
                       else
                       {
                           for(j = 0; j < (KERNEL_BUFFER_SIZE_AVI << 1); j += 2)
                           {
                               wordData = sciaGetWordDataCM_Avi();
                               kernelBuffer[bufferIndex] = wordData;
                               bufferIndex++;
                           }
                           i += j;
                           IPC_sendCommand(IPC_CPU1_L_CM_R, IPC_FLAG2,
                                           IPC_ADDR_CORRECTION_ENABLE,
                                           BlockHeader.DestAddr,
                                           (uint32_t)kernelBuffer, j);
                           //
                           //to account for byte addressing in CM
                           //
                           BlockHeader.DestAddr += j;
    
                           //
                           //set flag l to r
                           //
                           IPC_setFlagLtoR(IPC_CPU1_L_CM_R, IPC_FLAG2);
    
                           bufferIndex = 0;
    
                           //
                           //wait for ack
                           //
                           IPC_waitForAck(IPC_CPU1_L_CM_R, IPC_FLAG2);
                           clearKernelBuffer_Avi();
                       }
                   }
               }
           }
           //
           // Get the size of the next block
           //
           BlockHeader.BlockSize = sciaGetWordDataCM_Avi();
           byte2 = BlockHeader.BlockSize & 0x0000FF00;
           byte1 = BlockHeader.BlockSize & 0x000000FF;
           byte2 = byte2 >> 8;
           byte1 = byte1 << 8;
           BlockHeader.BlockSize = byte1 | byte2;
        }
        //BlockSize is 0, CM will exit out of the loop
        IPC_sendCommand(IPC_CPU1_L_CM_R, IPC_FLAG2, IPC_ADDR_CORRECTION_ENABLE,
                        EntryAddrCMKernel_Avi, (uint32_t)kernelBuffer, 0);
        IPC_setFlagLtoR(IPC_CPU1_L_CM_R, IPC_FLAG3);
        IPC_waitForAck(IPC_CPU1_L_CM_R, IPC_FLAG3);
    
        return;
    }
    
    
    
    void sciIpcLoadCM_Avi(void)
    {
        //statusCode.status = NO_ERROR;
        //statusCode.address = 0x12346578;
    
        //
        // Assign GetWordData to the SCI-A version of the
        // function. GetWordData is a pointer to a function.
        //
        //getWordData = sciaGetWordDataCM;
    
        //
        // If the KeyValue was invalid, abort the load
        // and return the flash entry point.
        //
        if(sciaGetWordDataCM_Avi() != 0x08AA)
        {
            while(1)
            {
                // Stay inside since error!!!
            }
        }
    
        readReservedFn_Avi(); //reads and discards 8 reserved words
    
        EntryAddrCMKernel_Avi = getLongData_Avi();
        uint32_t byte4 = EntryAddrCMKernel_Avi & 0xFF000000;
        uint32_t byte3 = EntryAddrCMKernel_Avi & 0x00FF0000;
        uint32_t byte2 = EntryAddrCMKernel_Avi & 0x0000FF00;
        uint32_t byte1 = EntryAddrCMKernel_Avi & 0x000000FF;
        byte4 = byte4 >> 8;
        byte3 = byte3 << 8;
        byte2 = byte2 >> 8;
        byte1 = byte1 << 8;
        EntryAddrCMKernel_Avi = byte3 | byte4 | byte1 | byte2;
    
        copyDataToCPU1ToCMMSGRAM_Avi();
    
        uint16_t x = 0;
        for(x = 0; x < 32676; x++){}
        for(x = 0; x < 32676; x++){}
    
    }
    
    
    void BootGpioRamImageToCm (void)
    {
        u32_ram_array_index = 0; // Set Index to RAM image array to 0 = start of array
    
        setBootModeForCM_Avi();
        sciIpcLoadCM_Avi();
    }
    

    该代码基本上只是闪存内核示例项目的副本, 其函数名略有修改。 我只是想避免通过 UART (因此是阵列)发送数据的过程,因为我只想检查是否可以使用闪烁的 LED CM 示例通过 CPU1引导 CM。 我要调用 CPU1主函数的函数称为“BootGpioRamImageToCm”。

    但不幸 的是,一开始就有一个问题,因为阵列的第一个词不是0x08AA,但如果我第一次调用“ciaGetWordDataCM_Avi”,那么我就收到0xAA08。 下面是我在其中输入无限循环的代码:

    我发现,C2000十六进 制实用程序生成的文件与 ARM 十六进制实用程序之间的第一个词有所不同。

    问题1:

    请问我的方法是否基本正常,是否通过阵列将 CM RAM 应用程序添加到 CPU1 (闪存配置)应用程序? 我是否错过了有关调用 ARM HEX 实用程序的 endian 设置的任何信息,因为我是根据应用程序注释“3 ROM bootloader”一章进行设置的?

    之后,我决定使用 “串行闪存编程器.exe”实用程序玩一会。 我为 CPU1和构建配置闪存中的 CM 创建了一个新的闪烁 LED 示例项目:

    当然,“内核”项目是在构建配置 RAM 中编译 的,但构建配置中闪烁的 LED 示例会闪烁。 我调用了以下命令:

    serial_flash_programr.exe -d f2838x -k flash_kernel_c28x_cm_ex1_c28x1.txt -a led_ex1_c28x_cm_blinky_cpu1.txt -o flash_kernel_c28x_cm_ex1_cm.txt -r led_ex1_c28x_cm_blinky_cm.txt -b 9600 -p COM5 -v

    几分钟后,CPU1闪存内核被发送并调用:

    我输入了第一个选项1,我的 flle 'led_ex1_C28x_cm_link_CPU1.txt'被写入闪存(当我将引导模式引脚更改为闪存引导和电源循环时,我看到 CPU1正在连接 LED 1)。

    之后我再次调用了该工具(启动模式引脚设置为 UART),并随后使用了选项1 - DFU CPU1。 但当我 使用选项22时,我希望 CM 闪存内核和随后的应用程序'LED_ex1_C28x_cm_blink_cm.txt'会被下载,但出于某种原因,该工具会要求我输入一个入口点地址:

    问题2:

    我不明白为什么我必须输入任何入口点地址,因为入口点已经 放在 *.txt 文件(以引导表格式保存应用程序的文件)中。 在此处输入哪个地址,来自 CM 闪存内核或 CM 应用程序的入口点? 我是否需要输入前面带有0x 的地址,还是只输入十六进制值?  

    谢谢,

    Inno

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

    您好,  

    如果我理解正确,您是否正在尝试通过 IPC 将 CM LED 示例复制到 CM 核心? 我不确定是什么导致了字节序的转换,我建议先在 C2000Ware 中逐步完成闪存内核项目,特别是您所指的 GetWordData 函数,以正确理解该功能。 您可以在 CCS 中加载项目,请参阅应用说明的第5.2.4节。 加载项目后,可以设置断点以查看 GetWordData 函数的功能。

    第二个问题是,正在询问 CPU1应用程序的入口点。 选项22将 CPU1内核控制权移交给 CM 内核,但首先 CPU1内核需要一个用于 CPU1应用程序的入口点,该入口点在 DFU CPU1选项的末尾提供。 键入地址时,地址前面应该有0x。  

    谢谢

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

    Anu 您好,

    你‘对,我正在尝试通过 IPC 将“构建配置 RAM 中的 CM LED 示例”复制到 CM 核心,并让其立即运行。 ‘配置 RAM 中的“CM LED”示例已转换为 C 代码阵列,并添加到“构建配置闪存中的‘CPU1 LED 示例”中,因此我可以放弃 UART 数据传输。 我只想专注于启动 CM。

     我在‘sGetWordData 函数方面取得了一些进展,该函数位于我的上述代码“ciaGetWordDataCM_Avi”中。 这项功能是绝对正确的,做的是正确的。 我的代码在读取‘密钥值’(阵列的前16位)时只有一个小问题,我认为这是由 C++闪存编程器工具补偿的。 请‘s‘一章“ARM 汇编语言工具”的内容第118y.pdf 页。 txt 文件中的密钥值为0x10 0xAA (用于16位 GPIO)或0x08 0xAA (用于16位 GPIO)。

    ‘s你现在看一下闪存内核示例‘GetWordData’函数(更具体地说是‘ciaGetWordDataCM’)的工作方式,你会看到通过 UART 接收到的第一个字节存储在下一个字节中,通过 UART 接收到的第二个字节存储在上一个字节中:

    因此,如果 C++闪存编程器工具将按字节发送 CM 文件,则密钥值将为0xAA08,而不是0x08AA。

    这意味着我稍微修改了我的代码以通过此检查:

    我检查了所有其他值,这些值是通过 sciaGetWordDataCM_Avi/getLongData_Avi 从我的 C 代码数组中读取 的。就像入口点地址,存储数据的地址,字节数信息的长度/数量一样,其他一切都是正确的。

    我现在还有一个问题,那就是我没有得到 CM 的任何 IPC 确认。 ‘程序将在 CM 的“IPC_waitForFlag”中等待 CM 的确认:

    我知道这是一个很大的好处,但我已经没有想法了。 您是否可以在‘TMDSCNCD28388D’评估板上重现我的操作? 我相信这项工作可以很快完成。

    1)导入项目:

    C:\ti\c2000\C2000Ware_4_00_00_00\driverlib\f2838x\examples\C28x_cm\led

     

    2)在 CPU1闪烁 LED 示例中添加一个新的 C 文件(在我的案例中为‘CM_IPC_BOOT_VIC.C’),并在文件中复制以下嵌入的代码(在构建配置闪存中):

    #include "device.h"
    
    uint8_t Boot_IMG[]=
    {
    0x08, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x0B, 0x09, 0x00, 0x06, 
    0x20, 0x00, 0x08, 0x00, 0x00, 0xF0, 0x82, 0xB9, 0x70, 0x47, 
    0x01, 0x40, 0x20, 0x00, 0x0C, 0x00, 0x00, 0xC2, 0xFF, 0x1F, 0x01, 0x08, 0x00, 0x20, 0xA9, 0x0B, 0x00, 0x20, 0x47, 0x0B, 0x00, 0x20, 0x17, 0x0A,
    0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A,
    0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A,
    0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A,
    0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A,
    0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A,
    0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A,
    0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A,
    0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A,
    0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A,
    0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A,
    0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A,
    0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20, 0x17, 0x0A, 0x00, 0x20,
    0x00, 0x06, 0x1F, 0xFF, 0xE0, 0x00, 0x40, 0x1E, 0xFD, 0xD1, 0x70, 0x47,
    0x00, 0x18, 0x1F, 0xFF, 0xE0, 0x08, 0xAF, 0x09, 0x00, 0x20, 0x93, 0x0B, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x10, 0xE0,
    0xFF, 0x1F, 0x00, 0xC0, 0x00, 0x20,
    0x03, 0xA2, 0x20, 0x00, 0x08, 0x08, 0x00, 0x2A, 0x4A, 0xD0, 0x5F, 0xEA, 0x00, 0x0C, 0x8B, 0x07, 0x1C, 0xD1, 0x83, 0x07, 0x22, 0xD1, 0x10, 0x2A,
    0x08, 0xD3, 0x70, 0xB4, 0x10, 0x3A, 0x78, 0xC9, 0x78, 0xC0, 0x10, 0x3A, 0xFB, 0xD2, 0x70, 0xBC, 0x10, 0x32, 0x38, 0xD0, 0x04, 0x2A, 0x2C, 0xD3,
    0x08, 0x2A, 0x05, 0xD3, 0x0C, 0x2A, 0x24, 0xBF, 0x08, 0xC9, 0x08, 0xC0, 0x08, 0xC9, 0x08, 0xC0, 0x08, 0xC9, 0x08, 0xC0, 0x92, 0x07, 0x2A, 0xD0,
    0x92, 0x0F, 0x22, 0xE0, 0x0B, 0x78, 0x03, 0x70, 0x49, 0x1C, 0x40, 0x1C, 0x52, 0x1E, 0x22, 0xD0, 0x8B, 0x07, 0xF7, 0xD1, 0xC3, 0x07, 0x14, 0xD1,
    0x83, 0x07, 0xD8, 0xD0, 0x12, 0x1F, 0x12, 0xD3, 0x08, 0xC9, 0x03, 0x80, 0x1B, 0x0C, 0x43, 0x80, 0x00, 0x1D, 0x12, 0x1F, 0xF8, 0xD2, 0x0A, 0xE0,
    0x08, 0xC9, 0x03, 0x70, 0x1B, 0x0A, 0x43, 0x70, 0x1B, 0x0A, 0x83, 0x70, 0x1B, 0x0A, 0xC3, 0x70, 0x00, 0x1D, 0x12, 0x1F, 0xF4, 0xD2, 0x12, 0x1D,
    0x05, 0xD0, 0x0B, 0x78, 0x03, 0x70, 0x49, 0x1C, 0x40, 0x1C, 0x52, 0x1E, 0xF9, 0xD1, 0x60, 0x46, 0x70, 0x47, 0x00, 0xB5, 0xAD, 0xF1, 0x14, 0x0D,
    0x01, 0x91, 0x00, 0x90, 0x00, 0x98, 0x00, 0xF0, 0x3C, 0xF9, 0x18, 0xB9, 0x0D, 0xA0, 0xE9, 0x21, 0x00, 0xF0, 0x63, 0xF9, 0x00, 0x99, 0x1C, 0x48,
    0x49, 0x09, 0x00, 0xEB, 0x01, 0x10, 0x02, 0x90, 0x00, 0x98, 0x01, 0x21, 0x00, 0xF0, 0x1F, 0x00, 0x81, 0x40, 0x03, 0x91, 0x01, 0x98, 0x18, 0xB9,
    0x03, 0x98, 0x02, 0x99, 0x88, 0x60, 0x02, 0xE0, 0x03, 0x98, 0x02, 0x99, 0x48, 0x60, 0x05, 0xB0, 0x00, 0xBD, 0x43, 0x3A, 0x2F, 0x74, 0x69, 0x2F,
    0x63, 0x32, 0x30, 0x30, 0x30, 0x2F, 0x43, 0x32, 0x30, 0x30, 0x30, 0x57, 0x61, 0x72, 0x65, 0x5F, 0x33, 0x5F, 0x30, 0x34, 0x5F, 0x30, 0x30, 0x5F,
    0x30, 0x30, 0x2F, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x6C, 0x69, 0x62, 0x2F, 0x66, 0x32, 0x38, 0x33, 0x38, 0x78, 0x2F, 0x64, 0x72, 0x69, 0x76,
    0x65, 0x72, 0x6C, 0x69, 0x62, 0x5F, 0x63, 0x6D, 0x2F, 0x67, 0x70, 0x69, 0x6F, 0x2E, 0x68, 0x00, 0xC0, 0x46, 0x00, 0x30, 0x08, 0x40, 0x08, 0xB5,
    0x00, 0x20, 0x00, 0xF0, 0x9E, 0xF8, 0x4F, 0xF4, 0x80, 0x60, 0x00, 0xF0, 0x9A, 0xF8, 0x4F, 0xF4, 0x00, 0x60, 0x00, 0xF0, 0x96, 0xF8, 0x4F, 0xF4,
    0x40, 0x60, 0x00, 0xF0, 0x92, 0xF8, 0x01, 0x20, 0x00, 0xF0, 0x8F, 0xF8, 0x40, 0xF2, 0x01, 0x20, 0x00, 0xF0, 0x8B, 0xF8, 0x40, 0xF2, 0x01, 0x40,
    0x00, 0xF0, 0x87, 0xF8, 0x40, 0xF2, 0x01, 0x50, 0x00, 0xF0, 0x83, 0xF8, 0x40, 0xF6, 0x01, 0x00, 0x00, 0xF0, 0x7F, 0xF8, 0x02, 0x20, 0x00, 0xF0,
    0x7C, 0xF8, 0x4F, 0xF4, 0x81, 0x70, 0x00, 0xF0, 0x78, 0xF8, 0x40, 0xF2, 0x02, 0x20, 0x00, 0xF0, 0x74, 0xF8, 0x40, 0xF2, 0x02, 0x40, 0x00, 0xF0,
    0x70, 0xF8, 0x40, 0xF2, 0x02, 0x60, 0x00, 0xF0, 0x6C, 0xF8, 0x40, 0xF6, 0x02, 0x00, 0x00, 0xF0, 0x68, 0xF8, 0x08, 0xBD, 0xF8, 0xB5, 0x84, 0x46,
    0x40, 0xF6, 0xFF, 0x74, 0x1C, 0xF8, 0x01, 0x3B, 0x00, 0x22, 0x10, 0xE0, 0x48, 0x1B, 0x40, 0x1E, 0x10, 0xF8, 0x01, 0x5B, 0x7F, 0x1E, 0x01, 0xF8,
    0x01, 0x5B, 0xF9, 0xD1, 0x03, 0xE0, 0x1C, 0xF8, 0x01, 0x0B, 0x01, 0xF8, 0x01, 0x0B, 0x52, 0x1C, 0x5B, 0x08, 0x08, 0x2A, 0xEA, 0xDA, 0x58, 0x08,
    0xF5, 0xD2, 0x1C, 0xF8, 0x01, 0x0B, 0x1C, 0xF8, 0x01, 0x5B, 0x05, 0xF0, 0x0F, 0x07, 0xFF, 0x1C, 0xC5, 0xF3, 0x03, 0x15, 0x12, 0x2F, 0x45, 0xEA,
    0x00, 0x15, 0x08, 0xD1, 0x1C, 0xF8, 0x01, 0x6B, 0x30, 0x0A, 0x24, 0xBF, 0x1C, 0xF8, 0x01, 0x0B, 0x60, 0xF3, 0xDF, 0x16, 0xBF, 0x19, 0xAC, 0x42,
    0xD4, 0xD1, 0xF8, 0xBD, 0xFE, 0xE7, 0x08, 0xB5, 0x00, 0xF0, 0x95, 0xF8, 0x22, 0x20, 0x00, 0x21, 0xFF, 0xF7, 0x3F, 0xFF, 0x12, 0x48, 0x00, 0x68,
    0x08, 0x28, 0x03, 0xDA, 0x11, 0x48, 0xFD, 0xF7, 0xE6, 0xFA, 0x02, 0xE0, 0x10, 0x48, 0xFD, 0xF7, 0xE2, 0xFA, 0x22, 0x20, 0x01, 0x21, 0xFF, 0xF7,
    0x30, 0xFF, 0x0A, 0x48, 0x00, 0x68, 0x08, 0x28, 0x03, 0xDA, 0x09, 0x48, 0xFD, 0xF7, 0xD7, 0xFA, 0x02, 0xE0, 0x08, 0x48, 0xFD, 0xF7, 0xD3, 0xFA,
    0x05, 0x49, 0x08, 0x68, 0x40, 0x1C, 0x08, 0x60, 0x03, 0x48, 0x02, 0x49, 0x00, 0x68, 0x00, 0xF0, 0x0F, 0x00, 0x08, 0x60, 0xD6, 0xE7, 0x00, 0xC0,
    0x00, 0x20, 0x32, 0xE4, 0x3D, 0x01, 0x67, 0xC8, 0x7B, 0x02, 0x1C, 0xB5, 0xAD, 0xF8, 0x00, 0x00, 0xBD, 0xF8, 0x00, 0x00, 0x00, 0xF0, 0x1F, 0x00,
    0x80, 0x00, 0xAD, 0xF8, 0x02, 0x00, 0xBD, 0xF8, 0x00, 0x00, 0x00, 0xF4, 0xF8, 0x50, 0x00, 0x0A, 0xAD, 0xF8, 0x04, 0x00, 0x07, 0x49, 0x07, 0x4A,
    0xBD, 0xF8, 0x02, 0x00, 0xBD, 0xF8, 0x04, 0x40, 0x40, 0x18, 0x03, 0x68, 0x01, 0x21, 0xA1, 0x40, 0x19, 0x43, 0x0A, 0x43, 0x02, 0x60, 0x1C, 0xBD,
    0xC0, 0x46, 0x00, 0xC0, 0x0F, 0x40, 0x00, 0x00, 0x34, 0x56, 0xB0, 0xB5, 0x0C, 0x48, 0x0C, 0x4D, 0xA8, 0x42, 0x10, 0xD0, 0x0C, 0x48, 0x0C, 0x4C,
    0xA0, 0x42, 0x0C, 0xD0, 0x00, 0x1B, 0x08, 0x3C, 0xC7, 0x10, 0x54, 0xF8, 0x08, 0x0F, 0x01, 0x78, 0x55, 0xF8, 0x21, 0x20, 0x61, 0x68, 0x40, 0x1C,
    0x90, 0x47, 0x7F, 0x1E, 0xF5, 0xD1, 0x00, 0xBF, 0x00, 0xBF, 0xB0, 0xBD, 0xC0, 0x46, 0x10, 0xE0, 0xFF, 0x1F, 0x08, 0xE0, 0xFF, 0x1F, 0x20, 0xE0,
    0xFF, 0x1F, 0x18, 0xE0, 0xFF, 0x1F, 0x07, 0x48, 0x80, 0xF3, 0x08, 0x88, 0x00, 0xBF, 0x00, 0xBF, 0x00, 0xF0, 0x45, 0xF8, 0x08, 0xB1, 0xFF, 0xF7,
    0xD4, 0xFF, 0x00, 0x20, 0xFF, 0xF7, 0x7B, 0xFF, 0x01, 0x20, 0x00, 0xF0, 0x3E, 0xF8, 0x00, 0xC2, 0xFF, 0x1F, 0xAD, 0xF1, 0x08, 0x0D, 0x00, 0x90,
    0x00, 0x9A, 0x00, 0x21, 0x00, 0x20, 0xA8, 0x2A, 0x00, 0xD8, 0x01, 0x21, 0x01, 0xB1, 0x01, 0x20, 0x02, 0xB0, 0x70, 0x47, 0xFE, 0xE7, 0x08, 0xB5,
    0x00, 0xF0, 0x13, 0xF8, 0xFF, 0xF7, 0xF3, 0xFE, 0x02, 0x48, 0x00, 0xF0, 0x04, 0xF8, 0x08, 0xBD, 0xC0, 0x46, 0x00, 0x0C, 0x00, 0x20, 0xAD, 0xF1,
    0x08, 0x0D, 0x00, 0x90, 0x02, 0x49, 0x00, 0x98, 0x08, 0x60, 0x02, 0xB0, 0x70, 0x47, 0x08, 0xED, 0x00, 0xE0, 0x02, 0x49, 0x08, 0x88, 0x40, 0xF0,
    0x68, 0x00, 0x08, 0x80, 0x70, 0x47, 0x0C, 0x00, 0x08, 0x40, 0xAD, 0xF1, 0x08, 0x0D, 0x01, 0x91, 0x00, 0x90, 0x00, 0xBE, 0x02, 0xB0, 0x70, 0x47,
    0xD0, 0xF8, 0x03, 0x20, 0xC3, 0x1D, 0x08, 0x46, 0x19, 0x46, 0xFF, 0xF7, 0x34, 0xBE, 0x01, 0x20, 0x70, 0x47, 0x00, 0xBF, 0xFE, 0xE7, 0xFE, 0xE7,
    0x00, 0x00
    };
    
    
    
    uint32_t u32_ram_array_index = 0;
    uint32_t EntryAddrCMKernel_Avi;
    #define KERNEL_BUFFER_SIZE_AVI 250 // Must be the same as '#define KERNEL_BUFFER_SIZE 250' inside file 'flash_kernel_c28x_cm_ex1_sci_boot_cpu1.c'
    
    #pragma DATA_SECTION(kernelBuffer, "MSGRAM_CPU_TO_CM")
    uint16_t kernelBuffer[KERNEL_BUFFER_SIZE_AVI];
    //extern uint16_t kernelBuffer[KERNEL_BUFFER_SIZE_AVI];
    
    //
    // This function sets the boot mode for CM
    //
    void setBootModeForCM_Avi(void){
    
       Flash_releasePumpSemaphore();
    
       //Clear all flags
       IPC_clearFlagLtoR(IPC_CPU1_L_CM_R, IPC_FLAG_ALL);
    
       //set boot mode
       Device_bootCM(BOOTMODE_IPC_MSGRAM_COPY_LENGTH_200W | BOOTMODE_IPC_MSGRAM_COPY_BOOT_TO_S0RAM);
    }
    
    uint16_t sciaGetByteDataCM_Avi(void)
    {
       uint8_t byteData;
       byteData = 0x00;
    
       //
       // Fetch the MSB and verify back to the host
       //
       byteData = Boot_IMG[u32_ram_array_index];
       u32_ram_array_index++;
    
       return byteData;
    }
    
    uint16_t sciaGetWordDataCM_Avi(void)
    {
        uint16_t wordData;
        uint16_t byteData;
    
        wordData = 0x0000;
        byteData = 0x0000;
    
        //
        // Fetch the LSB and verify back to the host
        //
        wordData = Boot_IMG[u32_ram_array_index];
        u32_ram_array_index++;
    
        //
        // Fetch the MSB and verify back to the host
        //
        byteData = Boot_IMG[u32_ram_array_index];
        u32_ram_array_index++;
    
        //
        // form the wordData from the MSB:LSB
        //
        wordData |= (byteData << 8);
    
        return wordData;
    }
    
    uint32_t getLongData_Avi()
    {
        uint32_t longData;
    
        //
        // Fetch the upper 1/2 of the 32-bit value
        //
        longData = ( (uint32_t)sciaGetWordDataCM_Avi() << 16);
    
        //
        // Fetch the lower 1/2 of the 32-bit value
        //
        longData |= (uint32_t)sciaGetWordDataCM_Avi();
    
        return(longData);
    }
    
    
    //
    // readReservedFn - This function reads 8 reserved words in the header.
    //                   None of these reserved words are used by the
    //                   this boot loader at this time, they may be used in
    //                   future devices for enhancements.  Loaders that use
    //                   these words use their own read function.
    //
    void readReservedFn_Avi()
    {
        uint16_t i;
    
        //
        // Read and discard the 8 reserved words.
        //
        for(i = 1; i <= 8; i++)
        {
            sciaGetWordDataCM_Avi();
        }
        return;
    }
    
    
    void clearKernelBuffer_Avi(void){
        uint16_t index = 0;
        for (index = 0; index < KERNEL_BUFFER_SIZE_AVI; index++){
            kernelBuffer[index] = 0x0000;
        }
    
    }
    
    //
    // CopyDataToCPU1ToCMMSGRAM
    // This function takes the CM kernel being streamed through SCI and places it
    // in a buffer in CPU1TOCMMSGRAM where it can be accessed by CM to then copy
    // into CM RAM. CPU1 and CM first synchronize with each other and then CPU1
    // starts sending the kernel to CM. Once it hasfilled up the buffer, it signals
    // CM. It then waits on CM to signal that it has finished copying the contents
    // of the buffer before filling it up again with the next section of the
    // kernel. CPU1 continues this operation until a blocksize of 00 00 is
    // encountered, at which point it lets CM know that it has finished
    // transmitting the kernel and waits for an acknowledgement from CM before
    // exiting the function.
    //
    void copyDataToCPU1ToCMMSGRAM_Avi(void)
    {
        IPC_sync(IPC_CPU1_L_CM_R, IPC_FLAG1);
    
        struct HEADER {
            uint32_t DestAddr;
            uint16_t BlockSize;
        } BlockHeader;
    
        uint16_t i;
        uint16_t j;
        uint32_t byte4;
        uint32_t byte3;
        uint32_t byte2;
        uint32_t byte1;
        uint16_t bufferIndex = 0;
        uint16_t wordData = 0;
    
        //
        // Get the size in words of the first block
        //
        BlockHeader.BlockSize = sciaGetWordDataCM_Avi();
        byte2 = BlockHeader.BlockSize & 0x0000FF00;
        byte1 = BlockHeader.BlockSize & 0x000000FF;
        byte2 = byte2 >> 8;
        byte1 = byte1 << 8;
        BlockHeader.BlockSize = byte1 | byte2;
    
        //
        // While the block size is > 0 copy the data
        // to the DestAddr.  There is no error checking
        // as it is assumed the DestAddr is a valid
        // memory location
        //
    
        while(BlockHeader.BlockSize != (uint16_t)0x0000U)
        {
           BlockHeader.DestAddr = getLongData_Avi();
           byte4 = BlockHeader.DestAddr & 0xFF000000;
           byte3 = BlockHeader.DestAddr & 0x00FF0000;
           byte2 = BlockHeader.DestAddr & 0x0000FF00;
           byte1 = BlockHeader.DestAddr & 0x000000FF;
           byte4 = byte4 >> 8;
           byte3 = byte3 << 8;
           byte2 = byte2 >> 8;
           byte1 = byte1 << 8;
           BlockHeader.DestAddr = byte3 | byte4 | byte1 | byte2;
           for(i = 0; i < BlockHeader.BlockSize; i += 0)
           {
               //
               // The size of the block is less than the buffer size, so the entire
               // block is written to the buffer and sent to CM
               // For example. block size is 4 and buffer size is 5, so all 4 bytes
               // are sent to CM via the buffer
               //
    
               //
               // BlockSize is in bytes, KERNEL_BUFFER_SIZE is in words
               //
               if(BlockHeader.BlockSize < (KERNEL_BUFFER_SIZE_AVI << 1))
               {
                   //
                   // fill up the buffer with the SCI data stream
                   //
                   for(j = 0; j < BlockHeader.BlockSize; j += 0)
                   {
                       byte1 = sciaGetByteDataCM_Avi();
                       j++;
    
                       //
                       //when there are an odd number of bytes, we don't want to
                       //get an extra byte from the data stream, so pad with 0xFF
                       //
                       if(j == BlockHeader.BlockSize)
                       {
                           byte2 = 0xFF;
                       }
                       else
                       {
                           byte2 = sciaGetByteDataCM_Avi();
                           j++;
                       }
    
                       wordData = (byte2 << 8) | byte1;
                       kernelBuffer[bufferIndex] = wordData;
                       bufferIndex++;
                   }
                   i += j;
    
                   IPC_sendCommand(IPC_CPU1_L_CM_R, IPC_FLAG2,
                                   IPC_ADDR_CORRECTION_ENABLE,
                                   BlockHeader.DestAddr,
                                   (uint32_t)kernelBuffer, j);
                   //
                   //set flag l to r
                   //
                   IPC_setFlagLtoR(IPC_CPU1_L_CM_R, IPC_FLAG2);
    
                   bufferIndex = 0;
    
                   //
                   //wait for ack
                   //
                   IPC_waitForAck(IPC_CPU1_L_CM_R, IPC_FLAG2);
                   clearKernelBuffer_Avi();
    
               }
    
               //
               // The size of the block is greater than the buffer, so it will be
               // split up and sent in chunks until the entire block is sent
               // For example, block size is 7 and buffer size is 5, so first 5
               // bytes will be sent over and then the remaining 2 bytes will be
               // sent over
               //
               else //BlockHeader.BlockSize >= BUFFER_SIZE
               {
                   //
                   // keep sending until we have sent over the entire block
                   //
                   while(i < BlockHeader.BlockSize){
                       if((BlockHeader.BlockSize - i) < (KERNEL_BUFFER_SIZE_AVI << 1))
                       {
                           for(j = 0; j < BlockHeader.BlockSize - i; j += 0)
                           {
                              byte1 = sciaGetByteDataCM_Avi();
                              j++;
    
                              //
                              //when there are an odd number of bytes, we don't
                              //want to get an extra byte from the data stream,
                              //so pad with 0xFF
                              //
                              if(j == BlockHeader.BlockSize)
                              {
                                  byte2 = 0xFF;
                              }
                              else
                              {
                                  byte2 = sciaGetByteDataCM_Avi();
                                  j++;
                              }
                              wordData = (byte2 << 8) | byte1;
                              kernelBuffer[bufferIndex] = wordData;
                              bufferIndex++;
                           }
                           //
                           // increment i outside here so it doesn't affect loop
                           // above
                           //
                           i += j;
    
                           IPC_sendCommand(IPC_CPU1_L_CM_R, IPC_FLAG2,
                                           IPC_ADDR_CORRECTION_ENABLE,
                                           BlockHeader.DestAddr,
                                           (uint32_t)kernelBuffer, j);
                           //
                           //set flag l to r
                           //
                           IPC_setFlagLtoR(IPC_CPU1_L_CM_R, IPC_FLAG2);
    
                           bufferIndex = 0;
    
                           //
                           //wait for ack
                           //
                           IPC_waitForAck(IPC_CPU1_L_CM_R, IPC_FLAG2);
                           clearKernelBuffer_Avi();
                       }
                       else
                       {
                           for(j = 0; j < (KERNEL_BUFFER_SIZE_AVI << 1); j += 2)
                           {
                               wordData = sciaGetWordDataCM_Avi();
                               kernelBuffer[bufferIndex] = wordData;
                               bufferIndex++;
                           }
                           i += j;
                           IPC_sendCommand(IPC_CPU1_L_CM_R, IPC_FLAG2,
                                           IPC_ADDR_CORRECTION_ENABLE,
                                           BlockHeader.DestAddr,
                                           (uint32_t)kernelBuffer, j);
                           //
                           //to account for byte addressing in CM
                           //
                           BlockHeader.DestAddr += j;
    
                           //
                           //set flag l to r
                           //
                           IPC_setFlagLtoR(IPC_CPU1_L_CM_R, IPC_FLAG2);
    
                           bufferIndex = 0;
    
                           //
                           //wait for ack
                           //
                           IPC_waitForAck(IPC_CPU1_L_CM_R, IPC_FLAG2);
                           clearKernelBuffer_Avi();
                       }
                   }
               }
           }
           //
           // Get the size of the next block
           //
           BlockHeader.BlockSize = sciaGetWordDataCM_Avi();
           byte2 = BlockHeader.BlockSize & 0x0000FF00;
           byte1 = BlockHeader.BlockSize & 0x000000FF;
           byte2 = byte2 >> 8;
           byte1 = byte1 << 8;
           BlockHeader.BlockSize = byte1 | byte2;
        }
        //BlockSize is 0, CM will exit out of the loop
        IPC_sendCommand(IPC_CPU1_L_CM_R, IPC_FLAG2, IPC_ADDR_CORRECTION_ENABLE,
                        EntryAddrCMKernel_Avi, (uint32_t)kernelBuffer, 0);
        IPC_setFlagLtoR(IPC_CPU1_L_CM_R, IPC_FLAG3);
        IPC_waitForAck(IPC_CPU1_L_CM_R, IPC_FLAG3);
    
        return;
    }
    
    
    
    void sciIpcLoadCM_Avi(void)
    {
        //statusCode.status = NO_ERROR;
        //statusCode.address = 0x12346578;
    
        //
        // Assign GetWordData to the SCI-A version of the
        // function. GetWordData is a pointer to a function.
        //
        //getWordData = sciaGetWordDataCM;
    
        //
        // If the KeyValue was invalid, abort the load
        // and return the flash entry point.
        //
        //if(sciaGetWordDataCM_Avi() != 0x08AA)
        if(sciaGetWordDataCM_Avi() != 0xAA08)
        {
            while(1)
            {
                // Stay inside since error!!!
            }
        }
    
        readReservedFn_Avi(); //reads and discards 8 reserved words
    
        EntryAddrCMKernel_Avi = getLongData_Avi();
        uint32_t byte4 = EntryAddrCMKernel_Avi & 0xFF000000;
        uint32_t byte3 = EntryAddrCMKernel_Avi & 0x00FF0000;
        uint32_t byte2 = EntryAddrCMKernel_Avi & 0x0000FF00;
        uint32_t byte1 = EntryAddrCMKernel_Avi & 0x000000FF;
        byte4 = byte4 >> 8;
        byte3 = byte3 << 8;
        byte2 = byte2 >> 8;
        byte1 = byte1 << 8;
        EntryAddrCMKernel_Avi = byte3 | byte4 | byte1 | byte2;
    
        copyDataToCPU1ToCMMSGRAM_Avi();
    
        uint16_t x = 0;
        for(x = 0; x < 32676; x++){}
        for(x = 0; x < 32676; x++){}
    
    }
    
    
    void BootGpioRamImageToCm (void)
    {
        u32_ram_array_index = 0; // Set Index to RAM image array to 0 = start of array
    
        setBootModeForCM_Avi();
        sciIpcLoadCM_Avi();
    }
    

    3)按如下方式更改主要功能:

     您是否能够在“BootGpioRamImageToCm”函数内运行代码并通过 IPC 启动 CM,同时在阵列内启动图像?

    此致,

    Inno

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

    我会在几天内回来。  

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

    你好,Anu,非常感谢你的努力! 我将写下我过去所做的一切。

    虽然我确信你知道我要实现的目标,但我将在下图中显示 我希望完成的任务:

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

    您可以检查的一件事是 CPU1项目中的 CopyDataToCMRAM 阵列是否正确放入内存中。 由于同步功能未完全完成,因此在 CM 启动序列期间,复制功能可能未被置于 S0RAM 中。 需要此复印功能才能将 LED 应用程序传输到 CM。

    当您构建 CPU1项目时,CCS 是否抱怨不能将内存的所有部分写入到? 如果是这样,您需要修改 GEL 文件,以便将 MSGRAM 写入。 C2000Ware 示例文件夹中有一个修改后的 gel 文件。 如果您没有使用 CCS v10.1,请参阅 C2000Ware v4.0发行版的发行说明,获取有关如何更改 gel 文件以允许写入 MSGRAM 的提示。  

    此外,如果 LED 应用程序被放置在 C 阵列中,您在哪里使用 GetWordData? 这仅用于从 SCI 获取数据,如果要访问数据阵列,则不需要它。  

    谢谢

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

    Anu 您好,

    关于您提到的第一件事
    我根本没有将阵列'CopyDataToCMRAM'添加到闪烁的 LED 应用程序中。 我在学习 flash_kernel 示例项目时看到了该阵列,但我不知道 CM boot-loader 需要一个阵列驻留在  CPU1 -> CM messae RAM 1的开头。 此阵列有什么作用,为什么 CM ROM Bootloader 需要它? 但是,我将使 链接器命令文件看起来与 CPU1->CM 消息 RAM 相同,并将阵列添加到闪烁的 LED 项目中。

    关于您上面提到的第二件事
    我没有从编译器/链接器中得到任何抱怨。 但我不得不说,我 使用 C2000器件版本03.04.00.00将 flash_kernel 示例项目部署到 CCS 环境中。 这是因为我正在为这个 CPU 开发一个自己的自定义主板项目,不幸的是,该项目使用的是旧版本的 C2000软件。 我希望这不会阻止我启动 IPC。

    关于您的第三条评论
    请看下面的代码,我将 GetWordData 函数复制到我的项目中,将其重命名为“ciaGetWordDataCM_Avi”,并更改了功能,这意味着我 不从 SCI 读取数据,而是从阵列“Boot_IMG”中读取数据。

    uint16_t sciaGetWordDataCM_Avi(void)
    {
        uint16_t wordData;
        uint16_t byteData;
    
        wordData = 0x0000;
        byteData = 0x0000;
    
        //
        // Fetch the LSB and verify back to the host
        //
        wordData = Boot_IMG[u32_ram_array_index];
        u32_ram_array_index++;
    
        //
        // Fetch the MSB and verify back to the host
        //
        byteData = Boot_IMG[u32_ram_array_index];
        u32_ram_array_index++;
    
        //
        // form the wordData from the MSB:LSB
        //
        wordData |= (byteData << 8);
    
        return wordData;
    }

    但与此同时,我取得了一些进展。 你在上一个问题上的第一个评论是一个很好的暗示。  首先,我将阵列‘CopyDataToCMRAM’复制到闪烁的 LED 项目中,并更改了链接器命令文件以匹配 flash_kernel 示例项目:

    地图文件中的内存声明:

    CPUTOCMRAM_0    :原点= 0x039000,长度= 0x000400 // avi 修改
    CPUTOCMRAM_1    :原点= 0x039400,长度= 0x000400 // avi 修改
    //CPUTOCMRAM     :原点= 0x039000,长度= 0x000800  // avi 修改

     

     地图文件中的分区声明:

    //MSGRAM_CPU_to_CM   :> CPUTOCMRAM,类型=NOINIT            // avi modification
    MSGRAM_CPU_TO_CM  > CPUTOCMRAM_0,类型=NOINIT               // avi modification
    MSGRAM_CPU_TO_CM_COPY_TO_S_RAM > CPUTOCMRAM_1,键入=NOINIT  // avi modification

     

    因此,我在代码中添加了数组“CopyDataToCMRAM”:

    我检查了地图文件以确保阵列位于正确的位置:

    但是,由于某些原因,当刷新示例时,我只从内存地址0x39400的“内存视图”窗口中读取0x0000值,即 CPU1->CM 消息 RAM 1和‘CopyDataToCMRAM’必须位于的位置。 我不知道为什么调试器不在没有通知的情况下向 CPU1->CM 消息 RAM 写入数据。 即使我重新打开主板电源并从闪存启动,主板仍无法正常工作。

    所以我现在做的是:

    在我的 main()函数中:

    如上所述,我正在手动复制‘CopyDataToCMRAM’必须位于该阵列。 只有在‘之后,我才会调用函数“BootGpioRamImageToCm()”。

     

    ‘,程序将从‘copyDataToCPU1ToCMMSGRAM_Avi’开始的函数调用“IPC_SYNC (IPC_CPU1_L_CM_R,IPC_Flag1)”返回。 此外,我还检查了名为‘Boot_IMG’的 CM 闪烁 LED 阵列的内容以及输出部分 .TI.ramfunc.cinit.resetisr.vtable 似乎 通过消息 RAM 复制到 CM,我从 CM 获得了 IPC 确认。 请参阅此处的 CM 闪烁 LED 指示灯的地图文件示例:

    但是,当代码现在继续并尝试将输出部分.text 的第一块500字节(250个字)复制到消息 RAM 并触发 IPC 标志2时,该程序会被卡在“IPC_waitForAck”内,请参见下图:

    让我总结一下:

    1)过去,我没有将阵列“CopyDataToCMRAM”复制到闪烁的 LED 示例中。
    2)即使在复制后,JTAG 调试器似乎也没有将该'CopyDataToCMRAM'的值写入 CPU1->CM 消息 RAM 1。
    3)由于项目2,我在 启动 IPC 启动之前,在 for 循环内手动将阵列“CopyDataToCMRAM”复制到 CPU1->CM 消息 RAM 1。
    4)现在,几乎所有东西都在'copyDataToCPU1ToCMMSGRAM_Avi'内工作。  
      -现在,'IPC_SYNC'返回阵列'CopyDataToCMRAM'位于消息 RAM 1上。
      - CM 闪烁 LED 的前4部分示例(例如 .resetisr,cinit 等)似乎是通过 IPC 复制的。

    问题是,第一次尝试通过 IPC 将.text 输出部分从阵列“Boot_IMG”复制到 CM 时未被确认。 我的 CM 闪烁 LED RAM 示例的程序代码(.text 部分)是否可能位于'CopyDataToCMRAM'数据所在的同一个内存中,并且 CM RAM 中的这一'CopyDataToCMRAM'可能被我的进程覆盖?


    请您进一步解释一下阵列'CopyDataToCMRAM',以及为什么 CM 启动加载程序希望它位于 CPU1->CM 消息 RAM 1内?

    谢谢,

    Inno   

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

    您好,  

    为 CM 闪存内核创建了 CopyDataToCMRAM 函数,以便将整个内核从 CPU1复制到 CM。 整个内核太大,无法装入 CPU1到 CM 消息 RAM,因此创建了复制功能,以便可以一次复制一个以上的部分。 在 CM 启动序列期间,使用启动模式“从 IPC 消息 RAM 复制并引导至 RAM”启动模式,将此功能从 CPU1复制到 CM。 CM 核心完成启动序列后,它将进入 S0RAM,这就是放置此复制功能的位置。 该函数将采用 CPU1复制函数在消息 RAM 中的任何位置,并将其复制到 CPU1复制函数指定的地址。 它会执行此操作,直到收到一个显示文件结尾的0x0000块大小。  

    [引用 userid="459171" url="~ë/support/icns/c2000-icls-group/c2f/c2000微控制器-forum/1068910/tms320f28388d-copyf-fs-ico-message-ram-boot-copy-boot-mode/3965360#3965360"]我的数据存储器可能会覆盖片/存储器中的闪存片[和闪存模块](本程序中的数据)。

    这是可能的,您可以检查 CM LED 示例链接器命令文件,并确保“复制”功能不会与.text 部分重叠。  

    谢谢

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

    Anu 您好,

    这回答了我的问题。 我在构建配置 CM_RAM 中编译了 CM 闪烁 LED 应用程序,并确保永远不使用 CM S0 RAM。 我把所有的部门都放在 S1...S3 RAM 中。 从现在开始,CPU1将通过 TI  的“CopyDataToCMRAM”应用程序使用我自己的应用程序启动 CM。

    下面是一个摘要:

    1)我以前没能将'CopyDataToCMRAM'阵列添加到闪烁的 LED CPU1项目中,也没能确保该阵列位于 CPU1->CM MSGRAM 1中,然后再尝试 第二步复制我自己闪烁的 LED CM 应用程序。

    2)我也没有确保 CM 闪烁 LED 应用程序永远不应驻留在 S0 RAM 中(至少它不应驻留在 S0的开头)。

    现在,我的 CPU1计划使用 RUS,让 CM 切换第二个 LED。

    我现在有一个关于 CM RBL (Rom Boot Loader)的最后一个问题。 TI 应用程序“CopyDataToCMRAM”位于 CPU1->CM MSGRAM 1的开头。 但是,CM RBL 如何知道,他必须从 MSGRAM1而非 MSGRAM0获取数据,才能使用其启动模式“bootmode_IPC_MSGRAM_COPY_BOOT_to_S0RAM”?  这是 CM RBL 始终用于该启动模式的内存,还是该信息 来自 IPC 标志1 (参见此处):

    IPC_SYNC (IPC_CPU1_L_CM_R,IPC_Flag1);

    我想知道当用参数 IPC_FLAG0调用上述函数时,CM RBL 是否会查看 MSGRAM 0以获取“CopyDataToCMRAM”?

    谢谢,

    Inno

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

    使用此引导模式时,CM 引导顺序始终从 MSGRAM1中读取,请参阅以下内容:

    谢谢

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

    Anu 您好,

    非常感谢您的支持。 我相信我可以继续执行任务。

    此致,

    Inno

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

    很高兴听到这个消息,我会继续并结束这个帖子。 如果您有其他问题,请随时开始新的主题。