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.

[参考译文] TMS320F28379D:首次使用 UniFlash 配置 DCSM

Guru**** 2524550 points
Other Parts Discussed in Thread: UNIFLASH, CONTROLSUITE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/845038/tms320f28379d-using-uniflash-to-configure-dcsm-for-the-first-time

器件型号:TMS320F28379D
主题中讨论的其他器件:UNIFLASH、controlSUITE

您好!

我正在尝试使用 UniFlash 首次配置 DCSM、并且我必须做一些错误的操作、因为在打开安全性后、即使加载了密码值、我也无法重新编程或连接到目标。 我的错误可能很简单、但在我砖砌另一个电路板之前、我希望获得有关我使用该工具的反馈、以最大程度地减少我所经历的电路板数量。

我的目标是打开 CPU1中的 DCSM、其中所有闪存段和 RAM 都安全在区域1下。 我正在使用第一个区域块、因此我将链路指针保留为全 FS。 我目前没有尝试仅提供 exe 保护、也不需要安全的 CRC 生成功能。 我将引导选项/引脚保留为默认值/引导至闪存。

我的理解是、一旦打开 DCSM 区域安全、如果加载了正确的密码值并正确执行密码匹配流程、您仍然可以使用 UniFlash 对器件进行重新编程 (我假设在加载正确的密码值并单击解锁按钮时、UniFlash 可以执行此操作)。

以下是我的事件序列:

使用 hex2000从.out 文件创建.hex 文件。 创建的十六进制文件中没有链接任何 OTP 配置。 我希望在 Blinky with DCSM 示例项目之后最终实现这一目标、但首先我想了解一种使用 UniFlash 的基本方法。 我不认为这一点很重要、但我的 hex2000命令行是:hex2000.exe -romwidth=16 -memwidth=16 -i "%REL_path%Release\product.out"-o "%REL_path%ProgrammingFiles\production.hex"

在 DCSM 处于默认空白状态的器件上、我可以通过"UniFlash Using Program -> C28xx_CPU1 -> Load Image"成功地对十六进制文件进行编程

对映像进行编程后、我将移至"Settings & Utilities -> C28xx_CPU1"并设置以下内容:

Z1-LINKPOINTER1 (0x78000)(32位) 0xFFFFFFFF -保留所有三个链路指针副本的默认值、以便链路指针指向第一个区域块。
Z1-LINKPOINTER2 (0x78004)(32位) 0xFFFFFFFF
Z1-LINKPOINTER3 (0x78008)(32位) 0xFFFFFFFF

Z1-PSWDLOCK (0x78010)(32位) 0xFFFFFFFE -技术参考手册指出除0xF / 0b1111以外的任何值都应锁定密码、因此我选择了0xE 或0b1110。

Z1-CSMPSWD3 (0x5F016)(32位) 0x111111 -这些不是我正在使用的实际密码值、而是将所有四个位置编程为非0xFFFFFFFF 和非零值(TRM 说所有零都是永久锁定)
Z1-CSMPSWD2 (0x5F014)(32位) 0x22222222
Z1-CSMPSWD1 (0x5F012)(32位) 0x3333
Z1-CSMPSWD0 (0x5F010)(32位) 0x444444

Z1-GRABSECT (0x5F01A)(32位) 0xFF5555 -所有闪存扇区至区域1
Z1-GRABRAM (0x5F01C)(32位) 0xFFFFFF5555 -所有 RAM 至区域1、此时不使用 CLA、因此留空。

该页面上的所有其他设置、我保留默认值。

在将这些值加载到"Settings & Utilities -> C28xx_CPU1"页面上的 UniFlash 字段中后、我单击"Program All Zone 1 Security Settings button"、该操作将在没有错误的情况下完成。

执行上述序列后、我会对目标进行循环通电、然后转至"Settings & Utilities -> C28xx_CPU1"页面。 然后向下滚动到 CSMPSWD 部分并单击解锁按钮。 我假设这是执行密码匹配流程并取消目标安全保护的按钮、因此我需要对电路板进行重新编程。 当我按下 解锁按钮时、我得到并错误:"[ERROR] C28xx_CPU1:连接到目标时出错:(错误-1156 @ 0x0)器件可能在低功耗模式下运行。 是否要使其退出此模式? 选择"是"以强制器件唤醒、然后重试此操作。 选择"否"以在不唤醒器件的情况下重试此操作。 (仿真包8.2.0.00004)"

Blow 是上述序列中导致错误的 UniFlash 控制台输出。 在下面的序列中、我对该器件进行了两次编程、以确认图像未对 OTP 进行编程、因为我之前已经用 DCSM 示例文件复制过 Blinky 进行了实验。

UniFlash 控制台日志:
[10/3/2019、5:15:49 PM][INFO_C28xx_CPU1:GEL 输出:存储器映射初始化完成
[10/3/2019、5:15:49 PM][INFO_C28xx_CPU1:如果在一个内核上执行擦除/编程(E/P)操作、则另一个内核不应从共享 RAM (SR)执行、因为它们用于 E/P 代码。 此外、CPU1将被暂停以确定将运行闪存插件代码的 CPU 的 SR 所有权、之后 CPU1将被设置为运行其应用。 在对两个闪存组进行编程后、可以开始从 SR 执行用户代码。
[10/3/2019、5:16:00 PM][成功]程序加载已成功完成。
[10/3/2019、5:16:06 PM][INFO_C28xx_CPU1:GEL 输出:存储器映射初始化完成
[10/3/2019、5:16:17 PM][成功]程序加载已成功完成。
[10/3/2019、5:22:29 PM][INFO_C28xx_CPU1:GEL 输出:存储器映射初始化完成
[10/3/2019、5:22:29 PM][INFO_C28xx_CPU1:执行安全操作...
[10/3/2019、5:22:29 PM][INFO_C28xx_CPU1:对 LINKPOINTER 寄存器进行编程...
[10/3/2019、5:22:30 PM][INFO_C28xx_CPU1:计算得出的链路指针偏移:0x20
[10/3/2019、5:22:30 PM][信息] C28xx_CPU1:对 OTPSECLOCK 寄存器进行编程...
[2019年10月3日、5:22:31 PM][信息] C28xx_CPU1:对 OTPBOOTCTRL 寄存器进行编程...
[10/3/2019、5:22:32 PM][INFO_C28xx_CPU1:编程密码...
[10/3/2019、5:22:33 PM][INFO_C28xx_CPU1:对 EXEONLYGRABProgram 寄存器进行编程...
[10/3/2019、5:22:34 PM][成功] C28xx_CPU1:操作成功完成。 -->此时,我对目标进行循环通电。 当我尝试解锁目标时、日志会继续下面的内容。
[10/3/2019、5:23:02 PM][错误] C28xx_CPU1:连接到目标时出错:(错误-1156 @ 0x0)器件可能在低功耗模式下运行。 是否要使其退出此模式? 选择"是"以强制器件唤醒、然后重试此操作。 选择"否"以在不唤醒器件的情况下重试此操作。 (仿真包8.2.0.00004)

我使用的是 Code Composer Studio 版本:9.1.0.00010和 XDS200USB JTAG 电缆。 对于 CCS"检查更新"报告、未找到更新、因此我认为开发工具都是最新版本。

UniFlash 版本: 5.1.0.2397 (上周下载)。

我还尝试仅使用 UniFlash 按钮对每个字段单独编程密码值、密码锁定、捕捉器和 grabsect 值、而不对所有其他值进行编程、并获得相同的结果。

对于硬件、引导模式选择引脚(GPIO72和 GPIO84)通过上拉电阻器(GET/Flash 引导模式)被拉高。 目标硬件是定制的控制板、但 DSP 硬件的电源、JTAG、复位过孔 IC、PCB 布局等... 基本上是 TI 参考设计。

下一步是再次读取引导引脚和引导模式以及 OTP ECC 的工作原理、以查看我是否未正确处理这些引脚、但目前引导模式设置完全为默认值、并且我没有更改任何 ECC 设置 默认值。

如果有人看到我做了些错误的事,我将非常感谢对建议的任何更正。 感谢你能抽出时间。

以下是对理解项目的一些确认:

作为 DCSM 新手、我已经阅读了 TRM 中的 DCSM 部分、 并在此处搜索论坛帖子。 以下是我迄今为止学到的一些要点。 如果我在这些问题上有任何问题、请告诉我、因为这将帮助我找出问题(以及未来的问题)。 我还将更正或删除任何不正确的陈述、以便不会使人感到困惑。

-将所有零编程为您的密码值可能不是您想要做的-完成此操作后、器件将被永久锁定。

-您可能会认为,如果您将所有内存锁定在一个区域中,就不会有任何内存访问问题。 这种情况并非如此、因为共享 RAM (GSx)和 M0/M1无法受到保护。 此外、您还无法将数据从安全闪存复制到非安全 RAM (我认为)。 这意味着、如果 ramfuncs 段运行的是 GSx RAM 或非安全本地 RAM、则当您尝试将 ramfuncs 从安全闪存复制到不安全 RAM 时、在运行时会遇到问题。 如果 ramfuncs 闪存是安全的、那么 Ramfuncs 应该位于安全 RAM 中。

-您可能希望堆栈处于不安全的 RAM 中、以便任何函数调用都可以使用堆栈。 如果您的堆栈位于安全 RAM 中、并且调用了不安全闪存中的函数、则该函数将无法访问堆栈。 如果在不安全的存储器中有一组函数指针被调用、如果栈位于安全 RAM 中、它们也会有问题。

-如果您在链接 ramfunc 的闪存上打开了 exe Only 选项、则需要使用 TI 提供的内置 SafeCopy 函数。 如果只打开 exe、则即使在同一安全区域内完成该闪存段、也无法将其读取到 RAM 中、这就是提供 SaveCopy 函数的原因。

-有两个安全区域。 双区域允许您将代码/IP 锁定在一个区域下、并将 RAM/Flash 保持打开状态以便第三方进行开发、然后第三方可以使用另一个区域锁定其 IP。 如果您是单个开发人员、只想锁定所有内存、您实际上只需要使用一个区域。

双核 F28379D 部件的每个内核都有自己的 DCSM。 如果您希望保护两个内核、则需要配置两个 DSM。 在 CPU1中打开安全功能不会保护 CPU2。

-DCSM OTP 值只能写入一次,但某些值(password、grab RAM/Sect 和 exe only 设置)在 OTP 内存中有30个副本。 如果您希望在对初始集编程后更改为其他集、这些选项将非常有用。 LINKPOINTER 选择30个区域块中的哪一个。 如果链接指针全部为 fs、则默认情况下将使用第一个区域块。 要选择第二个区域块、您需要将链接指针中的位0设置为零。 要选择第三个区域块、您需要将位1设置为零、以此来通过位29将区域块重置至块30。

- LINKPOINTER 有三个副本,它们都应设置为相同的值。 使用三个副本是因为 LINKPOINTER 不受 ECC 内存保护。

-即使将所有 FS 写入 OTP 值、也会为该空值写入相应的 ECC (链接指针除外)。 这意味着、如果您写入所有0xFFs、您将无法稍后返回并写入非0xFF 值 、因为 ECC 将之前被写入、并且您的新值将不会相同。

-如果您要将 OTP 配置链接到您的项目、请按照安装 controlSUITE 后获得的 Blinky with DCSM 示例项目中的示例进行操作。 示例工程位于文件夹结构中的 device_support 下。 OTP 段被有意拆分以避免保留区域。 如果写入这些保留区域、则会产生错误。 此外、当您准备好尝试 OTP 的实际编程时、请记住注释掉2837xD_DSCM_lnk_CPU1.cmd 文件中的 type = DSECT 选项。 type = DSECT 是一个虚拟加载选项、可防止段链接到中。 最后、如果您使用除默认第一个区域块之外的任何区域块(指向链接指针是否为全 FS)、则必须将 DCSM_ZSEL_Z1_Px 的原点更新到所使用的区域、每个区域的长度为0x10。   

- OTP 中有 DCSM 内存,CPU RAM 寄存器中也有 DCSM 相关寄存器。 您想要设置的任何配置都应编程到 OTP 存储器中。 CPU RAM 寄存器用于查看 OTP 存储器中的内容。 当 OTP 被访问时、RAM 寄存器被更新。 DCSM RAM 寄存器还有一些与 DCSM 相关的状态值(如安全或非安全状态)、用于解锁目标的密码密钥值被写入 CPU 寄存器(Zx_CSMKEY0至 ZxCSMKEY3)。

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

    如果您没有丢失密码、我认为您没有使设备砖型、除非...  问题是您需要使用来自 Get/Flash 的引导模式引脚切换引导模式以等待。 这有点烦人、我不记得在文档中指定了它的位置、但您需要等待取消保护。

    Z1-PSWDLOCK (0x78010)(32位) 0xFFFFFFFE -技术参考手册指出除0xF / 0b1111以外的任何值都应锁定密码、因此我选择了0xE 或0b1110。

    不幸的是,事实并非如此。 我还尝试仅切换单个位、一些密码片段在锁定给任何人后仍然可见、密码的其他部分 读取为全零。 由于您无法更改 PSWDLOCK、 因此单元安全性永久不那么安全。 值0x00000000似乎执行得很好、当被保护时、整个密码读取为全0。

     您写了很多、请尝试切换引导模式等待、然后重新尝试解锁。  

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

    您好、EK、

    感谢您的建议。 你是对的。 我将引导模式选择引脚切换为等待模式(0b10、GPIO72高电平、GPIO84低电平)、然后能够在 UniFlash 中解锁并重新编程。 幸运的是、我在 DIP 开关上有这些引导引脚、因此将该步骤添加到生产交付产品的编程手册中不会很麻烦。

    在您的注释中继续了解要写入密码锁的值以使其真正起作用:我将连接仿真器、并查看0xFFFFFFFE 锁的值是什么样子。 目标未连接、因此我无法连接。 我认为我必须使用密码值修改 GEL 文件、然后它将起作用。 如果我能弄清楚这一点、并且在将其标记为已解决后仍可以更新此帖子、我将确认您看到的内容。

    感谢你的帮助。 非常感谢。

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

    跟进密码锁定。 对于我来说、它看起来像是一个值0xFFFFFFFE 的工作方式。

    我首先要检查的是、让仿真器再次与受保护的目标一起工作。 为此,我修改了 GEL 文件(位于 C:\ti\ccs901\ccs\ccs_base\emulation\gel\f28379d_CPU1.gel),在 SetupDCSM()函数底部(在对选定区域块进行虚拟读取之后)有以下语句。  在此示例中、我使用的是虚拟密钥值、而不是我的真实密钥。

       //写入密码密钥以解锁设备
       *(无符号长整型*) 0x0005F010 = 0x11111111;    //Zone1 CSMKey 0
       *(无符号长整型*) 0x0005F012 = 0x22222222;    //Zone1 CSMKey 1
       *(unsigned long *) 0x0005F014 = 0x333333;    //Zone1 CSMKey 2
       *(无符号长整型*) 0x0005F016 = 0x44444444;    //Zone1 CSMKey 3

    然后、我添加了一些调试 GEL 指令、以在 GEL 文件解锁目标之前和之后打印 OTP 存储器中的密码值。 请注意、地址是第一个区域块的地址。

    在我解锁目标之前、在 OnReset() GEL 函数的开头添加了以下内容:
       GEL_TextOut ("在解锁器件之前读取 zone1 CSM 密钥\n");
       GEL_TextOut ("Zone1 CSMKey 0 =%x\n"、、、、 *(unsigned long *) 0x78028);
       GEL_TextOut ("Zone1 CSMKey 0 =%x\n"、、、、 *(unsigned long *) 0x7802A);
       GEL_TextOut ("Zone1 CSMKey 0 =%x\n"、、、、 *(unsigned long *) 0x7802C);
       GEL_TextOut ("Zone1 CSMKey 0 =%x\n"、、、、 *(unsigned long *) 0x7802E);

    在目标解锁后添加了以下内容:
       GEL_TextOut ("解锁器件后读取 zone1 CSM 密钥\n");
       GEL_TextOut ("Zone1 CSMKey 0 =%x\n"、、、、 *(unsigned long *) 0x78028);
       GEL_TextOut ("Zone1 CSMKey 0 =%x\n"、、、、 *(unsigned long *) 0x7802A);
       GEL_TextOut ("Zone1 CSMKey 0 =%x\n"、、、、 *(unsigned long *) 0x7802C);
       GEL_TextOut ("Zone1 CSMKey 0 =%x\n"、、、、 *(unsigned long *) 0x7802E);

    在该测试中、密码在解锁前读回所有零、然后在解锁后、您可以看到密码。

    控制台输出如下:

    C28xx_CPU1:GEL 输出:在解锁器件之前读取 zone1 CSM 密钥
    C28xx_CPU1:GEL 输出:ZONE1 CSMKey 0 = 0x00000000
    C28xx_CPU1:GEL 输出:ZONE1 CSMKey 0 = 0x00000000
    C28xx_CPU1:GEL 输出:ZONE1 CSMKey 0 = 0x00000000
    C28xx_CPU1:GEL 输出:ZONE1 CSMKey 0 = 0x00000000
    C28xx_CPU1:GEL 输出:解锁器件后读取 zone1 CSM 密钥
    C28xx_CPU1:GEL 输出:ZONE1 CSMKey 0 = 0x11111111
    C28xx_CPU1:GEL 输出:ZONE1 CSMKey 0 = 0x22222222
    C28xx_CPU1:GEL 输出:ZONE1 CSMKey 0 = 0x333333
    C28xx_CPU1:GEL 输出:ZONE1 CSMKey 0 = 0x44444444

    从我的测试来看、0xFFFFFFFE 密码锁定正常。

    无论如何、再次感谢您在引导模式问题上的帮助。 我的下一步是将其全部写下来、他们尝试通过映像设置 DCSM OTP、而不是使用 UniFlash、以便更轻松地进行生产编程。

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

    您好!

    [引用]这有点烦人、我不记得在文档中指定了它的位置、但您需要等待取消保护。 [/报价]

    TRM 的"3.13.1.1仿真代码安全逻辑(ECSL)"部分中提到了这一点。

    跟进密码锁定。 对于我来说、它看起来像是一个值0xFFFFFFFE 的工作方式。 [/报价]

    是的、这应该起作用。

    此致、

    Vivek Singh

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

    您好!

    有关密码。 密码锁定不会涉及区域安全、它只会锁定 密码 OTP 读取! 因此、密码锁定中的任何值都应该对您有效、它不会影响区域安全、您需要解锁密码才能重新编程。 但从 0x78000处的位置读取密码会怎么样呢?

    正如 Z1_OTPLOCK 寄存器说明中所述、PSWDLOCK 域从 Z1_PSWDLOCK[7:4]位加载。 被告知、当所有四个位都为1时、 1111 CSM 密码位置不受保护并且不能从调试器中读取。  由于您的 BALUE 0xFFFFFFFE 已设置所有四个位、因此您应在未解锁密码的情况下在等待引导模式下看到密码。 关于我说的不正确、我是说只清除四位中的一位。 我曾尝试过将密码锁值编程为0xFFFFFFEF 后、如果区域受到保护、您可以在附加图片中看到、用户密码片段可见、则会使用 MS Paint 隐藏。 之后、我始终将密码锁定编程为0x00000000、至少 应清除所有四个位[7:4]、我确定。

    此致