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.

[参考译文] TMS320F280037:DCSM 使用闪存 API 对 ZxOTP_CSMPSWDx 位置进行编程

Guru**** 2535750 points
Other Parts Discussed in Thread: TMS320F280037, UNIFLASH

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1351707/tms320f280037-dcsm-programming-zxotp_csmpswdx-locations-using-flash-api

器件型号:TMS320F280037
主题中讨论的其他器件: UNIFLASH

您好!

我在为 TMS320F280037器件对 DCSM OTP 位置进行编程时遇到了一个非常奇怪的问题。 我正在使用我自己加载的代码并从 GSRAM 运行、同时使用 FlashAPI 进行编程。 我对较早的 TMS320器件有经验、认为安全位置上的编程值在复位后开始有效。 对于 TMS320F28003x、对 ZxOTP_CSMSWDx 位置( 由 ZxLINKPOINTERS 选择) 进行编程似乎会立即保护器件。 这实际上、在使用闪存 API 之后、  

 oReturnCheck = Fapi_issueProgrammingCommand (0x78020、Buffer、8、0、0、Fapi_Auto EccGeneration);      //此操作的结果是  Fapi_Status_Success  

我无法通过运行  

oReturnCheck = Fapi_doVerify (0x78020、8/2、Buffer32、&oFlashStatusWord);

 oReturnCheck 的返回值 始终为 Fapi_Error_Fail。 此外、在 Fapi_issueProgrammingCommand 之后、CCS 中的存储器浏览器也全部为零。 器件似乎在没有任何复位的情况下被锁定。

我已经 通过运行以下代码来检查 Fapi_issueProgrammingCommand 之后的 DCSM 状态:

oSecureCheck = DCSM_getZone1CSMSecurityStatus();

 oSecureCheck 成为值 DCSM_STATUS_SECURE。

现在、我尝试通过运行以下代码来解锁 DCSM:

            //dummy read
            DCSM_readZone1CSMPwd();

            // driverlib struct for csmKey.
            DCSM_CSMPasswordKey psCMDKey;

            psCMDKey.csmKey0 = (uint32_t)data[0] | ((uint32_t)data[1] << 16);
            psCMDKey.csmKey1 = (uint32_t)data[2] | ((uint32_t)data[3] << 16);
            psCMDKey.csmKey2 = (uint32_t)data[4] | ((uint32_t)data[5] << 16);
            psCMDKey.csmKey3 = (uint32_t)data[6] | ((uint32_t)data[7] << 16);

            // Unlock the zone 1, driverlib.
            DCSM_unlockZone1CSM(&psCMDKey);

            oSecureCheck = DCSM_getZone1CSMSecurityStatus();

但是  oSecureCheck 的 值也是 DCSM_STATUS_SECURE、而不是 DCSM_STATUS_UNSECURE (我期望是这个值)。 我确信 csmKey 具有正确的值。

当我使用 UniFlash 工具检查 DCSM 中的编程数据时、编程的 DCSM 存储器具有正确的 CSMPSWD 值。  

问题是:如何验证 CSMPSWD 位置上的编程值?

感谢您的任何帮助。

此致、

托马斯

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

    您好!

    没有人能帮忙吗?

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

    尊敬的 Tomas:

    当对 CSM 密码地址执行读取操作时、它会将密码加载到一个与 CSMKEY 进行比较的隐藏寄存器中。 这将确定区域是否已锁定。

    遗憾的是、这将导致 DCSM 在所有设置都在用户 OTP 中编程之前被锁定、并导致闪存编程错误。 为了解决这个问题、您需要在 CCS 片上闪存工具中禁用编程后验证。 如果您对如何执行此操作有任何疑问、请告诉我。

    只能通过指定一个被忽略的地址范围、在对应用程序进行编程时该地址范围包含用户 OTP 并使验证保持选中状态、来禁用对用户 OTP 编程的验证。 然后仅使用用户 OTP 设置再次编程、并取消选中验证。

    此外、还可以选择仅对将锁定区域的 CSMPSVD 进行编程。 然后、您可以解锁整个应用并对其进行编程、包括安全设置。 由于您已解锁、CSMKEYs 将与用户 OTP 中的密码匹配、因此读取 CSM 密码不会锁定区域。

    如果您有任何问题、请告诉我。

    谢谢!

    卢克

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

    忘记提一下、如果在设定密码或用户 OTP 中的某些设置时出现错误、请参阅 SECERRSTAT。 ERR 位将被置位。 您可以使用该位确定 OTP 设置是否已正确编程。

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

    Luke、您好!

    感谢您的答复。 好的、我添加到我的检查  SECERRSTAT 的代码中。 ERR 位、但我仍然不明白为什么下面的代码不起作用。 我附加了用于 对 CSMPSWD 位置进行编程的示例代码(0x78020 - x78027)。 对于值为0x3FFF 的 Z1LinkoPointers 的默认值、这个位置是有效的 ZoneSelectBlock1。

            uint16 au16DataBuffer[8] = {0x2222, 0x1111, 0xFFFF, 0x4D7F, 0x4444, 0x3333, 0x6666, 0x5555};
            uint32 u32Index = 0x78020;
    
            oSecureCheck = DCSM_getZone1CSMSecurityStatus();    //get status DCSM_STATUS_UNSECURE
            VerifyFlag = DCSM_getZone1ControlStatus();          //Get value 0x60
    
            oReturnCheck = Fapi_issueProgrammingCommand((uint32 *)u32Index,au16DataBuffer,8,0,0,Fapi_AutoEccGeneration);   //result aj Fapi_Status_Success
            while(Fapi_checkFsmForReady() == Fapi_Status_FsmBusy);
            if(oReturnCheck != Fapi_Status_Success){
                break;
            }
    
            dataval= DcsmCommonRegs.SECERRSTAT.all;     //Get value 0x0
            if ((dataval&0x1) == 1){
                oReturnCheck = Fapi_Error_NoActiveCommand;  //Set some error code to return
                break;
            }
    
            //DCSM_secureZone1();   //this command can be here or not
    
            // driverlib struct for csmKey.
            DCSM_CSMPasswordKey psCMDKey;
            psCMDKey.csmKey0 = (uint32_t) au16DataBuffer[0] | ((uint32_t) au16DataBuffer[1] << 16); //0x11112222
            psCMDKey.csmKey1 = (uint32_t) au16DataBuffer[2] | ((uint32_t) au16DataBuffer[3] << 16); //0x4D7FFFFF
            psCMDKey.csmKey2 = (uint32_t) au16DataBuffer[4] | ((uint32_t) au16DataBuffer[5] << 16); //0x33334444
            psCMDKey.csmKey3 = (uint32_t) au16DataBuffer[6] | ((uint32_t) au16DataBuffer[7] << 16); //0x55556666
            //dummy read
            DCSM_readZone1CSMPwd();
            // Unlock the zone 1, driverlib.
            DCSM_unlockZone1CSM(&psCMDKey);
    
            oSecureCheck = DCSM_getZone1CSMSecurityStatus();     //get status DCSM_STATUS_SECURE, I expect DCSM_STATUS_UNSECURE
            VerifyFlag = DCSM_getZone1ControlStatus();           //Get value 0x64
    
            oReturnCheck = Fapi_doVerify((uint32 *)u32Index, 8/2, Buffer32+(i/2), &oFlashStatusWord);   //get result Fapi_Status_Fail

    为什么不能将 DCSM 模块设置为不安全状态? 有什么问题吗?

    在对 DCSM"活动"CSMPSWD 位置进行编程后、是否需要复位器件? 那么、只有在执行此复位之后、器件才能处于不安全状态?

    谢谢!

    此致、

    托马斯

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

    尊敬的 Tomas:

    您能否验证您选择的密码是否已在地址为0x78020的存储器浏览器中进行编程?

    谢谢!

    卢克

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

    Luke、您好!

    我使用 UniFlash 工具从地址0x78020附加已读值的屏幕截图。 已使用设定的密码执行解锁。

    因此、根据上面 myu 回复中发布的代码成功编程密码。 有什么想法吗、为什么 DCSM 不是不安全的?

    谢谢!

    托马斯

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

    尊敬的 Tomas:

    可能 CSM键 未被正确编程。 您能否在 DCSM_unlockZone1CSM (&psCMDDKey)调用并检查 Z1_CSMKEY 寄存器之后设置断点?

    谢谢!

    卢克

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

    Luke、您好!

    对 CSM键 进行正确编程。 如果没有、我应该无法使用 UniFlash 读取内容、因为器件应该被阻止。 但是可以使用上述密钥来解锁器件(并且其他密钥仍会被器件阻止)。

    我在  csm_unlockZone1CSM (&psCMDKey)之后添加代码:

                // Unlock the zone 1, driverlib.
                DCSM_unlockZone1CSM(&psCMDKey);
    
                dataval= DcsmZ1Regs.Z1_CSMKEY0;     //read 0x11112222
                dataval= DcsmZ1Regs.Z1_CSMKEY1;     //read 0x4D7FFFFF
                dataval= DcsmZ1Regs.Z1_CSMKEY2;     //read 0x33334444
                dataval= DcsmZ1Regs.Z1_CSMKEY3;     //read 0x55556666    
    
                oSecureCheck = DCSM_getZone1CSMSecurityStatus();
                VerifyFlag = DCSM_getZone1ControlStatus();

    寄存器具有预期的值、但 DCSM_getZone1CSMSecurityStatus 仍具有 DCSM_STATUS_SECURE 状态 。

    有什么想法吗?

    托马斯

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

    尊敬的 Tomas:

    在 oSecureCheck = DCSM_getZone1CSMSecurityStatus()之后设置断点时,是否能够在 Memory Browser 中读取内存? 这将表明 Zone 已解锁。

    如果在 oSecureCheck = DCSM_getZone1CSMSecurityStatus()之前添加了延迟,它是否仍具有 DCSM_STATUS_SECURE 状态?

    谢谢!

    卢克

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

    Luke、您好!

    "当在 oSecureCheck = DCSM_getZone1CSMSecurityStatus()之后设置断点时,是否能够在内存浏览器中读取内存? 这将表明防区已解锁。"

    否、整个闪存 的值为0x0000。

    "如果您在 oSecureCheck = DCSM_getZone1CSMSecurityStatus ();之前添加了延迟、它是否仍具有 DCSM_STATUS_SECURE 状态?"

    多长时间? 1ms/1s/10s? II 认为这并不重要、因为当我调试代码时、我以几秒的步长在代码行中移动。

    重点是-密码编程成功、Uniflash 可以使用此密码解锁器件、但上面的代码不能解锁。 我提到、我从不安全的 GSRAM 运行我的代码...原因可能是这样吗?

    托马斯

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

    尊敬的 Tomas:

    您可以尝试翻转每个密钥的字节序吗? aka 会更改以下代码:

    psCMDKey.csmKey0 = (uint32_t) au16DataBuffer[0] | ((uint32_t) au16DataBuffer[1] << 16); //0x11112222
            psCMDKey.csmKey1 = (uint32_t) au16DataBuffer[2] | ((uint32_t) au16DataBuffer[3] << 16); //0x4D7FFFFF
            psCMDKey.csmKey2 = (uint32_t) au16DataBuffer[4] | ((uint32_t) au16DataBuffer[5] << 16); //0x33334444
            psCMDKey.csmKey3 = (uint32_t) au16DataBuffer[6] | ((uint32_t) au16DataBuffer[7] << 16); //0x55556666

    psCMDKey.csmKey0 = (uint32_t) au16DataBuffer[1] | ((uint32_t) au16DataBuffer[0] << 16); //0x11112222
            psCMDKey.csmKey1 = (uint32_t) au16DataBuffer[3] | ((uint32_t) au16DataBuffer[2] << 16); //0x4D7FFFFF
            psCMDKey.csmKey2 = (uint32_t) au16DataBuffer[5] | ((uint32_t) au16DataBuffer[4] << 16); //0x33334444
            psCMDKey.csmKey3 = (uint32_t) au16DataBuffer[7] | ((uint32_t) au16DataBuffer[6] << 16); //0x55556666

    谢谢!

    卢克

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

    Luke、您好!

    是的,我已经尝试过几次,你的帖子,但改变字节顺序没有任何效果。

    托马斯

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

    尊敬的 Tomas:

    明白了、我会自行测试您的代码以确定根本原因。 我会在本周回复您。

    谢谢!

    卢克

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

    Luke、您好!

    有新消息?

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

    尊敬的 Tomas:

    您的 GRABRAM 和 GRABSECT 位被设定为什么? 我自己重新创建了这个、并且能够使用您提供的代码解锁区域、但是只有在将所有 GRABSECT / GRABRAM 字段编程为"10"后。 这是因为如果一个区域被锁定并且一个 GRABSECT/GRABRAM 域被设定为缺省值11、那么相应的存储器区域将无法访问。

    您是否能够单步执行配置 CSM 密钥的代码并观察寄存器窗口中的变化?

    谢谢!

    卢克