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.

[参考译文] F28M35M52C:CSM 处于活动状态时、闪存编程失败

Guru**** 2472990 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1452283/f28m35m52c-flash-programming-fails-while-csm-is-active

器件型号:F28M35M52C

工具与软件:

您好!

我有一个引导加载程序、它通过 CAN 下载闪存映像以编程到闪存中。  CSM 通过以下方式处于活动状态:

Z1 CSMPSWD 设置为密码值

Z1 GRABSECT 0xFFF55555

Z1 GRABRAM 0xFFFFFFF5

所有其他安全设置均未设置(已擦除值)

启动时、闪存 API 加载到 C0 RAM 中。

闪存 API 似乎会针对扇区擦除和写入命令返回成功状态、但闪存未被擦除和写入。

如果我擦除密码(无论有无 GRABSECT 和 GRABRAM 设置)、一切都正常工作。  闪存按预期被擦除、并按预期写入、使用 CRC 进行验证。

尽管在给定 GRABSECT 和 GRABRAM 设置后、一切(闪存代码、RAM 代码、RAM、堆栈、 等)全部位于 Z1中。

我在这里遗漏了哪些建议或内容?

提前感谢、

——基思

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

    尊敬的 Keith:  

    让正确的专家知道。

    谢谢!

    Charles

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

    尊敬的 Keith:

    除了闪存 API 返回的状态外、似乎一切都按预期工作。 当你设定 CSM 密码并且已经将闪存分配至安全区域时、我认为闪存应该返回一个失败。

    您能否分享返回成功状态的屏幕截图? 我会将该线程重新分配给我们的闪存 API 专家、他可以更好地为您提供帮助。

    谢谢!

    Luke

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

    Luke、

    我感到困惑。 您说我必须解锁闪存才能对其重新编程吗? 这就是我首先将闪存 API 放置在安全 RAM 中的原因。

    如果我必须解锁器件以便从引导加载程序对闪存进行编程、这意味着我必须将密码放在引导加载程序中、这使得它很容易受到攻击、尤其是在通过引导加载程序下载进行编程期间。

    我将处理一个有意义的屏幕截图或返回代码的其他证据。  

    ——基思

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

    Keith、

    请注意、闪存 API 不会等待闪存操作完成。 它只是发出命令并返回。 因此、用户应用程序必须等待 FMC 完成操作、然后才能返回到任何类型的闪存访问。 有关更多详细信息、请参阅以下闪存 API 用户指南

    您还可以 使用 Fapi_getFsmStatus()函数检查 FMSTAT 值 并查看它们是否有错误吗?
    此致、
    Rajeshwary
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    对 Z1中的扇区执行擦除

    (如上所述:  

    Z1 CSMPSWD 设置为密码值

    Z1 GRABSECT 0xFFF55555

    Z1 GRABRAM 0xFFFFFFF5

    )

    等待 FSM 完成、然后使用 Fapi_getFsmStatus ()读取 FMSTAT 寄存器。

    寄存器值为0x00000410。

    Cstat = 1

    EV = 1

    不是特别有用。  我读取此信息是因为有错误、擦除未进行验证、但没有指示原因。

    您能否澄清 Luke 在其最后一条消息中表示的内容...我必须先解锁闪存、然后才能从位于同一安全区域内的内部代码重新编程?

    如果是这样、这是一个很大的限制、我在 CSM 或闪存 API 文档中找不到任何确认这一点的文档。

    ——基思

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

    Luke、根据后续帖子、我发现由于 FMSTAT Cstat = 1和 EV = 1、在密码锁定的情况下尝试擦除闪存失败。   

    您能否澄清一下以下说法:从内部引导加载程序(位于同一个安全区)重新编程之前、我必须解锁闪存?  这似乎是一个很大的限制、因为我必须将密码嵌入到引导加载程序代码中、然后闪存实际上在编程过程中不安全。

    在这方面、我真的可以使用一些帮助。

    谢谢!

    ——基思

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

    尊敬的 Keith:

    您如何在启动时将闪存 API 从安全闪存复制到安全 RAM?

    如果闪存 API 存储在安全存储器中、您应该能够对闪存进行编程。 我已经和卢克澄清了这一点。

    谢谢。此致、

    Charles

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

    感谢您澄清 Charles。

    闪存 API 在执行开始时被复制、并且看起来正常工作(在非安全环境中)、因为我可以毫无问题地擦除和写入闪存。

    在链接器文件中、我们建立了闪存 API 代码范围...

    C03SRAM (rwx):origin = 0x20000000、length = 0x00002000

    相关

    ramfuncs

    -l F021_API_CortexM3_LE.lib
    }
    }
    负载=闪存、
    运行= C03SRAM
    Load_start (RamfuncsLoadStart)、
    Load_End (RamfuncsLoadEnd)、
    Load_Size (RamfuncsLoadSize)、
    RUN_START (RamfuncsRunStart)、
    页= 0

    下面是映射文件中闪存 API 函数的映射:

    20000e81 Fapi_Block
    2000112d Fapi_Block
    20000e70 Fapi_Global 263it
    20000c5f Fapi_calculateEcc
    20000bb5 Fapi_calculateFletcherChecksum
    20000de9 Fapi_checkFsmForReady
    200001b5 Fapi_connectFlashPumpToCpu
    200002e7 Fapi_disableBanksForOtpWrite
    200002a7 Fapi_enableBanksForOtpWrite
    200001AD Fapi_getFsmStatus
    20000cd1 Fapi_initializeAPI
    20000d71 Fapi_isAddressEcc
    20000e55 Fapi_issueAsyncCommand
    20000e0d Fapi_issueAsyncCommandWithAddress
    20000221 Fapi_issueFsmSuspendCommand
    20000811 Fapi_issueProgrammingCommand
    20000b0b Fapi_issueProgrammingCommandForEccAddresses
    20000da1 Fapi_remapEccAddress
    200014a5 Fapi_serviceWatchdogTimer
    200007a5 Fapi_setActiveFlashBank
    20001405 Fapi_setupBankSectorEnable
    200012d1 Fapi_setupEepromSecorEnable
    20000c97 Fapi_waitDelay
    20000261 Fapi_writeEwaitValue

    在 main()中、

    memcpy (&RamfuncsRunStart、&RamfuncsLoadStart、(size_t)&RamfuncsLoadSize);

    当我保护器件时、我将 Z1_GRABRAM 寄存器设置为0xFFFFFFF5、这将使 C0和 C1 RAM 安全并位于我要擦除的闪存扇区相同的区域(Z1)中。

    Z1_GRABSECT =   0xFFF55555

    等待 FSM 完成、然后使用 Fapi_getFsmStatus ()读取 FMSTAT 寄存器。

    寄存器值为0x00000410。

    Cstat = 1

    EV = 1

    它只告诉我擦除失败、但没有告诉我原因。

    ——基思

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

    如果 memcpy 函数未存储在安全存储器中、结果是否相同?

    谢谢!

    Charles

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

    您好、Charles、

    memcpy 位于安全闪存中。  如果不是、那么复制到 RAM 会失败、对吧?  它必须正常工作、因为我可以在控制台上看到闪存 API 状态的输出。  我不确定您想通过这个问题实现什么目标。  您能解释一下吗?

    我还尝试了复位 GRABRAM 寄存器、这样闪存 API 现在就处于不安全的 RAM 中、却会遇到同样的故障。

    ——基思

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

    尊敬的 Keith:

    您能给我链接器 cmd 文件或整个项目用于评估吗?

    谢谢。此致、

    Charles

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

    尊敬的 Charles:

    在我发送工程之前、清除该工程并对其进行测试需要付出相当大的努力。  让我在此处包含链接器命令文件、以查看您是否可以首先检测到任何问题。

    谢谢!

    ——基思

    --------------------------------------------------------

    --retain=g_pfnVectors.

    -保留=dcsm_z1_secvalues.obj (.z1secvalues,.z1_csm_rsvd)
    --retain=dcsm_z2_secvalues.obj (.z2secvalues,.z2_csm_rsvd)

    小程序

    BootROM (RX):origin = 0x00000000、length = 0x00010000

    /*闪存块0、扇区0 Z1 CSM */
    CSM_ECSL_Z1:origin = 0x00200000、length = 0x00000024 //保留以避免永久锁定电路板
    CSM_RSVD_Z1:origin = 0x00200024、length = 0x0000000C //保留以避免永久锁定电路板

    /*重置后加载内存地址*/
    flash_boot (rwx):origin = 0x00200030、length = 0x00000004
    /*用于存储.exe 文件、全局变量和初始化数据*/
    Flash (RWX):origin = 0x00200034、length = 0x0000FF00 //保留用于引导加载程序(扇区 N 和扇区 M、L 的一部分)

    //使用 Flash_Api 数据写入和读取目的
    FLASH_C (rwx): origin = 0x00274000, length = 0x4000 /*16k*/
    FLASH_B (rwx): origin = 0x00278000, length = 0x4000 /*16k*/
    Flash_A (RWX):origin = 0x0027C000、length = 0x3fd0 /*~16k*//= 0x0027FFD0

    CSM_RSVD_Z2:origin = 0x0027FFD0、length = 0x0000000C //保留以避免永久锁定电路板
    CSM_ECSL_Z2:origin = 0x0027FFDC、length = 0x00000024 //保留以避免永久锁定电路板

    C03SRAM (RWX):origin = 0x20000000、length = 0x00002000 //仅使用 RAM C0扇区
    S01SHRAM (RWX):origin = 0x20008000、length = 0x00004000 //使用 SRAM S0和 S1扇区
    // S23SHRAM (rwx):origin = 0x2000c000、length = 0x4000

    MAC_OTP (R):origin = 0x680810、length = 0x8
    }

    部分中)

    /*分配方案领域:*/
    .text :>闪存
    :>闪存
    .cinit :>闪存
    . Pinit :>闪存

    /*初始化的段进入闪存中*/
    .const :> FLASH

    /*分配未初始化的数据段:*/
    .vtable:> C03SRAM //| S03SHRAM
    .data :>/*>C03SRAM |*/ S01SHRAM //任意一个 RAM
    . bss :>/* C03SRAM |*/ S01SHRAM.
    .dma :>/* C03SRAM |*/ S01SHRAM //任意一个 RAM
    .sysmem :>/* C03SRAM |*/ S01SHRAM.
    .stack:> C03SRAM | S01SHRAM
    .cio :>/* C03SRAM |*/ S01SHRAM.
    .neardata :>/* C03SRAM |*/ S01SHRAM.
    .rodata :>/* C03SRAM |*/ S01SHRAM.
    .args :>/*C03SRAM |*/ S01SHRAM.

    z1secvalues :> csm_ecsl_z1.
    .z1_csm_rsvd :> csm_rsvd_z1.
    z2secvalues:> csm_ECSL_z2.
    .z2_csm_rsvd :> csm_rsvd_z2.

    // ramfuncs:load = flash、/*将段加载到 Flash */
    // run = C03SRAM、/*从 RAM 中运行段*/
    // load_start (RamfuncsLoadStart)、
    // load_size (RamfuncsLoadSize)、
    // load_end (RamfuncsLoadEnd)、
    // run_start (RamfuncsRunStart)、
    // page = 0

    #ifdef __TI_Compiler_version__
    #if __TI_Compiler_version__>= 15009000
    相关

    ramfuncs

    -l F021_API_CortexM3_LE.lib
    }
    }
    负载=闪存、
    RUN = C03SRAM、//S47SHRAM、
    Load_start (RamfuncsLoadStart)、
    Load_End (RamfuncsLoadEnd)、
    Load_Size (RamfuncsLoadSize)、
    RUN_START (RamfuncsRunStart)、
    PAGE = 0//、ALIGN (4)
    #else
    相关

    ramfuncs

    -l F021_API_CortexM3_LE.lib
    }
    }
    负载=闪存、
    RUN = C03SRAM、//S47SHRAM、
    Load_start (RamfuncsLoadStart)、
    Load_End (RamfuncsLoadEnd)、
    Load_Size (RamfuncsLoadSize)、
    RUN_START (RamfuncsRunStart)、
    PAGE = 0//、ALIGN (4)
    #endif
    #endif


    .MACOTP :> MAC_OTP
    }

    __stack_top =__stack + 256;

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

    尊敬的 Keith:

    看起来你已经为 S0和 S1 SHRAM 分配了一些资源、这是非安全内存。 您能否尝试将所有内容分配给安全的 RAM (C0和 C1)?

    谢谢!

    Luke

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

    您好!

    我把东西移走了。  我无法在安全 RAM (C0/C1扇区)中容纳.vtable 段。  除此之外、一切都位于安全 RAM 中。  我一旦设置密码并更改 GRABRAM 和 GRABSECT 寄存器、就不能擦除或写入闪存。

    存储器配置

    名称源长度已使用未使用属性填充
    --------------- --- --- --- --- ---
    BootROM 00000000 00010000 00000000 00010000 R X
    CSM_ECSL_Z1 00200000 00000024 00000000 00000024 RWIX
    CSM_RSVD_Z1 00200024 0000000c 00000000 0000000c RWIX
    FLASH_BOOT 00200030 00000004 00000004 00000000 RW X
    闪存00200034 0000ff00 0000dc70 00002290 RW X
    FLASH_C 00274000 00004000 00000000 00004000 RW X
    FLASH_B 00278000 00004000 00000000 00004000 RW X
    FLASH_A 0027c000 00003fd0 00000000 00003fd0 RW X
    CSM_RSVD_Z2 0027ffd0 0000000c 00000000 0000000c RWIX
    CSM_ECSL_Z2 0027ffdc 00000024 00000000 00000024 RWIX
    MAC_OTP 00680810 00000008 00000000 00000008 R
    C03SRAM 20000000 00004000 00003e3a 000001c6 RW X
    S01SHRAM 20008000 00004000 000001b0 00003e50 RW X


    段分配映射

    Run origin load origin length init length attrs 成员
    --- --- --- --- --- ---
    00200030 00200030 0000a480 0000a480 r-x
    00200030 00200030 00000004 00000004 r-x .ti_catalog_arm_cortexm3_concerto Init_BEGIN
    00200034 00200034 000001ac 000001ac r--.resetVecs.
    002001e0 002001e0 0000a2d0 0000a2d0 r-x .text
    0020b7d0 0020b7d0 00002288 00002288 r--
    0020b7d0 0020b7d0 00002288 00002288 r--.const
    0020da98 0020da98 00000210 00000210 r--
    0020da98 0020da98 00000200 00000200 r--.cinit
    0020dc98 0020dc98 00000010 00000010 r--.binit
    20000000 20000000 000020f8 00000000 rw-
    20000000 20000000 000001ac 00000000 rw-.vecs.
    200001b0 200001b0 00001f48 00000000 rw-.bss
    200020f8 0020a4b0 00001320 00001320 RWX
    200020f8 0020a4b0 00001320 00001320 rwx ramfuncs
    20003418 20003418 000009ec 00000000 rw-
    20003418 20003418 000005ea 00000000 rw-.data
    20003a04 20003a04 00000400 00000000 rw-.stack
    20003e04 0020da58 0000003c 0000003c r-x
    20003e04 0020da58 0000003c 0000003c r-x .flashfuncs
    20008000 20008000 000001b0 00000000 rw-
    20008000 20008000 000001b0 00000000 rw-.vtable

    ——基思

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

    在再次通过 CSM 和寄存器进行读取后、我 尝试了改变 SECZONEREQUEST SEM 位来限制到闪存包装程序寄存器的访问只在区域1。  技术参考手册似乎意味着一个00值应该允许无限制的任何访问(非安全、区域1或2)、但是显然情况并非如此。

    无论如何、这解决了我眼前的问题。