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.

[参考译文] LAUNCHXL-F280039C:有关通过闪存生成的 CRC 构建的问题

Guru**** 2588965 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1240157/launchxl-f280039c-questions-about-build-generated-crc-over-flash

器件型号:LAUNCHXL-F280039C

首先、我不熟悉 C2000产品和 CCS。 我正在探索针对闪存中构建生成的 CRC 值的选项、而且我想获得一些反馈。
我已经阅读了很多问题和指南、了解具有不同存储器布局和功能的不同 MCU 的类似行为。 我找到了从代码定义的存储器区域生成表的示例。 但是我还没有找到在所有闪存中创建值的示例。 闪存范围为80000:AFFFF。 由于执行限制、最后一行已被声明为"保留"、因此我认为 AFFF0行是 CRC 的重要存储位置。 我正在研究这是不是真正的"保留"还是只是代码不可用。

我一直在从一个基本示例项目中工作、试图让链接器使用其内置函数来生成 CRC。 该工程是使用闪存链接器文件配置的、我已经尝试使用 CRC 功能从存储器声明和使用 crc_table 的段声明中生成 CRC、但到目前为止链接器不合作。  在内存段中创建组时我遇到了问题、因为组范围与文件中定义的4K 闪存段重叠。 似乎我无法将组声明为范围引用。

关于如何让链接器针对此 MCU 上的整个闪存生成 CRC、有没有很好的示例?

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

    JJ、您好!

    由于指令预取逻辑的运行方式、最后一行被"保留"。 可以在此处存储 CRC 等数据字。

    请提供一份链接器命令文件的副本、以便我可以尝试找出出现问题的原因。

    此致、

    伊袋

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

    其他问题我也可能会问,因为我不会因我最初的问题的回答而分心。

    这些是对 CCS 示例中的2个示例工程的参考、这些示例针对使用 BGCRC 的 CRC 280003x:cpuinterrupt 和 cpubbasic (不是 CLA 示例)

    链接器文件为什么将闪存(组0扇区0)原始地址定义为0x80002而不是0x80000? 我无法在数据表或 TR 中找到答案、这是保留值位置吗?  

    这些示例工程包括 RAM 和闪存的链接器文件、在两个闪存中、闪存都拆分为存储体(0.1.2)和扇区(0-15)、大小最多为4K。
    我可以理解 为什么这在 管理 擦除闪存时很重要。 但不明白为什么它对链接器很重要。  原因是什么? 无法无问题地跨扇区访问存储器?

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

    谢谢你的答复,我写了一个后续的,因为你的答复。
    我了解了指令 预取、感谢大家确认、应该可以为 CRC 表数据找到它。   

    对于链接器命令文件、我一直在进行各种不同的尝试。 我真的没有任何有效的东西,所以我不知道这些猜测有多大帮助。  


    我害怕分享这是因为它只是几个蹩脚的黑客尝试,并得到一些工作. 唯一显示出任何承诺(但不起作用)的是段声明末尾的最后一行。  

    认真... 如果你看着这件事,请在你看完后立即忘记你看到的。
    我想值得注意的是、这是/bgcrc_ex1_cpuinterrupt  示例工程中的28003x_generic_flash_lnk.cmd  、它经过修改以测试生成 CRC。
     

    MEMORY
    {
       BEGIN            : origin = 0x00080000, length = 0x00000002
       BOOT_RSVD        : origin = 0x00000002, length = 0x00000126
    
       RAMM0            : origin = 0x00000128, length = 0x000002D8
       RAMM1            : origin = 0x00000400, length = 0x000003F8
       // RAMM1_RSVD       : origin = 0x000007F8, length = 0x00000008 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
    
       RAMLS0           : origin = 0x00008000, length = 0x00000800
       RAMLS1           : origin = 0x00008800, length = 0x00000800
       RAMLS2           : origin = 0x00009000, length = 0x00000800
       RAMLS3           : origin = 0x00009800, length = 0x00000800
       RAMLS4           : origin = 0x0000A000, length = 0x00000800
       RAMLS5           : origin = 0x0000A800, length = 0x00000800
       RAMLS6           : origin = 0x0000B000, length = 0x00000800
       RAMLS7           : origin = 0x0000B800, length = 0x00000800
    
       RAMGS0           : origin = 0x0000C000, length = 0x00001000
       RAMGS1           : origin = 0x0000D000, length = 0x00001000
       RAMGS2           : origin = 0x0000E000, length = 0x00001000
       RAMGS3           : origin = 0x0000F000, length = 0x00000FF8
       // RAMGS3_RSVD      : origin = 0x0000FFF8, length = 0x00000008 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
    
       BOOTROM          : origin = 0x003F8000, length = 0x00007FC0
       SECURE_ROM       : origin = 0x003F2000, length = 0x00006000
    
       RESET            : origin = 0x003FFFC0, length = 0x00000002
    
       /* Flash sectors */
       /* BANK 0 */
       FLASH_BANK0_SEC0  : origin = 0x080002, length = 0x000FFE
       FLASH_BANK0_SEC1  : origin = 0x081000, length = 0x001000
       FLASH_BANK0_SEC2  : origin = 0x082000, length = 0x001000
       FLASH_BANK0_SEC3  : origin = 0x083000, length = 0x001000
       FLASH_BANK0_SEC4  : origin = 0x084000, length = 0x001000
       FLASH_BANK0_SEC5  : origin = 0x085000, length = 0x001000
       FLASH_BANK0_SEC6  : origin = 0x086000, length = 0x001000
       FLASH_BANK0_SEC7  : origin = 0x087000, length = 0x001000
       FLASH_BANK0_SEC8  : origin = 0x088000, length = 0x001000
       FLASH_BANK0_SEC9  : origin = 0x089000, length = 0x001000
       FLASH_BANK0_SEC10 : origin = 0x08A000, length = 0x001000
       FLASH_BANK0_SEC11 : origin = 0x08B000, length = 0x001000
       FLASH_BANK0_SEC12 : origin = 0x08C000, length = 0x001000
       FLASH_BANK0_SEC13 : origin = 0x08D000, length = 0x001000
       FLASH_BANK0_SEC14 : origin = 0x08E000, length = 0x001000
       FLASH_BANK0_SEC15 : origin = 0x08F000, length = 0x001000
    
       /* BANK 1 */
       FLASH_BANK1_SEC0  : origin = 0x090000, length = 0x001000
       FLASH_BANK1_SEC1  : origin = 0x091000, length = 0x001000
       FLASH_BANK1_SEC2  : origin = 0x092000, length = 0x001000
       FLASH_BANK1_SEC3  : origin = 0x093000, length = 0x001000
       FLASH_BANK1_SEC4  : origin = 0x094000, length = 0x001000
       FLASH_BANK1_SEC5  : origin = 0x095000, length = 0x001000
       FLASH_BANK1_SEC6  : origin = 0x096000, length = 0x001000
       FLASH_BANK1_SEC7  : origin = 0x097000, length = 0x001000
       FLASH_BANK1_SEC8  : origin = 0x098000, length = 0x001000
       FLASH_BANK1_SEC9  : origin = 0x099000, length = 0x001000
       FLASH_BANK1_SEC10 : origin = 0x09A000, length = 0x001000
       FLASH_BANK1_SEC11 : origin = 0x09B000, length = 0x001000
       FLASH_BANK1_SEC12 : origin = 0x09C000, length = 0x001000
       FLASH_BANK1_SEC13 : origin = 0x09D000, length = 0x001000
       FLASH_BANK1_SEC14 : origin = 0x09E000, length = 0x001000
       FLASH_BANK1_SEC15 : origin = 0x09F000, length = 0x001000
    
      /* BANK 2 */
       FLASH_BANK2_SEC0  : origin = 0x0A0000, length = 0x001000
       FLASH_BANK2_SEC1  : origin = 0x0A1000, length = 0x001000
       FLASH_BANK2_SEC2  : origin = 0x0A2000, length = 0x001000
       FLASH_BANK2_SEC3  : origin = 0x0A3000, length = 0x001000
       FLASH_BANK2_SEC4  : origin = 0x0A4000, length = 0x001000
       FLASH_BANK2_SEC5  : origin = 0x0A5000, length = 0x001000
       FLASH_BANK2_SEC6  : origin = 0x0A6000, length = 0x001000
       FLASH_BANK2_SEC7  : origin = 0x0A7000, length = 0x001000
       FLASH_BANK2_SEC8  : origin = 0x0A8000, length = 0x001000
       FLASH_BANK2_SEC9  : origin = 0x0A9000, length = 0x001000
       FLASH_BANK2_SEC10 : origin = 0x0AA000, length = 0x001000
       FLASH_BANK2_SEC11 : origin = 0x0AB000, length = 0x001000
       FLASH_BANK2_SEC12 : origin = 0x0AC000, length = 0x001000
       FLASH_BANK2_SEC13 : origin = 0x0AD000, length = 0x001000
       FLASH_BANK2_SEC14 : origin = 0x0AE000, length = 0x001000
       FLASH_BANK2_SEC15 : origin = 0x0AF000, length = 0x000FF0
    
    // FLASH_BANK0_SEC15_RSVD     : origin = 0x0AFFF0, length = 0x000010  /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
    
    	FLASH_MEM_CRC32      : origin = 0x0AFFF0, length = 0x000010  /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
    
    // this crap just doesn’t work, ignore:
    //	GROUP(FlashTest)
    //	{
    //	  F: origin = 0x8A0000, length = 0x000FF0
    //	} crc(flash_CRC32, algorithm=CRC32_PRIME)
    }
    
    
    SECTIONS
    {
       codestart        : > BEGIN, ALIGN(8)
       .text            : >> FLASH_BANK0_SEC2 | FLASH_BANK0_SEC3 | FLASH_BANK0_SEC4,   ALIGN(8)
       .cinit           : > FLASH_BANK0_SEC1,  ALIGN(8)
       .switch          : > FLASH_BANK0_SEC1,  ALIGN(8)
       .reset           : > RESET,                  TYPE = DSECT /* not used, */
    
    // This was a hack to see if I could trick the linker to view all memory as one space, this should be ignored
       .all_flash		: >> FLASH_BANK0_SEC0 | FLASH_BANK0_SEC1 | FLASH_BANK0_SEC2 | FLASH_BANK0_SEC3 | FLASH_BANK0_SEC4 | FLASH_BANK0_SEC5 | FLASH_BANK0_SEC6 | FLASH_BANK0_SEC7 | \
       						 FLASH_BANK0_SEC8 | FLASH_BANK0_SEC9 | FLASH_BANK0_SEC10 | FLASH_BANK0_SEC11 | FLASH_BANK0_SEC12 | FLASH_BANK0_SEC13 | FLASH_BANK0_SEC14 | FLASH_BANK0_SEC15 | \
       						 FLASH_BANK1_SEC0 | FLASH_BANK1_SEC1 | FLASH_BANK1_SEC2 | FLASH_BANK1_SEC3 | FLASH_BANK1_SEC4 | FLASH_BANK1_SEC5 | FLASH_BANK2_SEC6 | FLASH_BANK1_SEC7 | \
       						 FLASH_BANK2_SEC8 | FLASH_BANK1_SEC9 | FLASH_BANK1_SEC10 | FLASH_BANK1_SEC11 | FLASH_BANK1_SEC12 | FLASH_BANK1_SEC13 | FLASH_BANK1_SEC14 | FLASH_BANK1_SEC15 | \
       						 FLASH_BANK2_SEC0 | FLASH_BANK2_SEC1 | FLASH_BANK2_SEC2 | FLASH_BANK2_SEC3 | FLASH_BANK2_SEC4 | FLASH_BANK2_SEC5 | FLASH_BANK2_SEC6 | FLASH_BANK2_SEC7 | \
       						 FLASH_BANK2_SEC8 | FLASH_BANK2_SEC9 | FLASH_BANK2_SEC10 | FLASH_BANK2_SEC11 | FLASH_BANK2_SEC12 | FLASH_BANK2_SEC13 | FLASH_BANK2_SEC14 | FLASH_BANK2_SEC15, TYPE = DSECT
       .stack           : > RAMM1
    
    #if defined(__TI_EABI__)
       .init_array      : > FLASH_BANK0_SEC1,  ALIGN(8)
       .bss             : > RAMLS5
       .bss:output      : > RAMLS3
       .bss:cio         : > RAMLS0
       .data            : > RAMLS5
       .sysmem          : > RAMLS5
       .const           : > FLASH_BANK0_SEC4,  ALIGN(8)
    #else
       .pinit           : > FLASH_BANK0_SEC1,  ALIGN(8)
       .ebss            : > RAMLS5
       .esysmem         : > RAMLS5
       .cio             : > RAMLS0
       .econst          : > FLASH_BANK0_SEC4,  ALIGN(8)
    #endif
    
        ramgs0 : > RAMGS0
        ramgs1 : > RAMGS0
    
        /*  Allocate IQ math areas: */
       IQmath           : > FLASH_BANK0_SEC1, ALIGN(8)
       IQmathTables     : > FLASH_BANK0_SEC2, ALIGN(8)
    
       .TI.ramfunc      : LOAD = FLASH_BANK0_SEC1,
                          RUN = RAMLS0,
                          LOAD_START(RamfuncsLoadStart),
                          LOAD_SIZE(RamfuncsLoadSize),
                          LOAD_END(RamfuncsLoadEnd),
                          RUN_START(RamfuncsRunStart),
                          RUN_SIZE(RamfuncsRunSize),
                          RUN_END(RamfuncsRunEnd),
                          ALIGN(8)
    // This is about the only thing which looked promising (ie didn’t crash the build), but it is not correct and doesn’t do anything
    // originally used the .data section instead of .all_flash
       .TI.crctab: > FLASH_MEM_CRC32
       .data_2b_checked: {bgcrc_ex1_cpuinterrupt.obj(.all_flash);} > FLASH_MEM_CRC32, crc_table(_linkerCrcTable, algorithm = CRC32_PRIME)
    //    .TI.memcrc > FLASH_CRC32
    }
    
    
    

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

    好的、我不太熟悉链接器 CRC 功能、因此我会让您联系我们的编译器工具团队来进一步解决这个问题。 但是从我在文档中可以知道的内容来看、分配的16个字节可能不足以包含表。 因此、这可能会给您带来这里的挑战。

    实际的链接器输出消息也会很有帮助。

    此致、
    伊袋

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

     整个闪存块的 CRC 表应该只有一个条目。 除非我在调整整个范围时遗漏了一些东西、否则应该允许、但可能不允许。 其他 C2000器件的文档和示例不清楚。 但我没有错过 Bank_0_SEC0的原点0x80002、不是0x80000会是问题、因为地址需要 与 128个字(0x80)对齐、0x80002会向上对齐到0x80080、而不是向下到0x80000。

    我期待编译器 对此提出建议。  

    难道这不是每个人都做的事情吗? 我很难相信设计中使用的这些器件不需要 对闪存进行完整性检查。 这似乎很奇怪。

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

    您好!

    正如 Itukun 所指出的那样、CRC 表会更长、并且不是一个单独的条目。 它 包含地址和大小信息以及 CRC 值

    此致、

    维纳

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

    "对不起,我也没想到会被你撞见的。"
    1) 1)这是关于将 CRC 记录结构拟合到闪存的最后一行吗? (即16个16位字?)
    2)我不明白为什么你说 CRC 表会"更长,而不是一个单一的条目"。 "你说什么?  如果我们将闪存视为一个连续的存储器块并对该存储器计算 CRC、那一个记录吗? 为什么我们需要的不仅仅是一个条目?

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

    您可以参考.map 文件以获取 CRC 表的实际大小。  

    在尝试将 crctable 放入最后保留的闪存区域时是否存在任何分配问题?

    此致、

    维纳  

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

    所以我没有 CRC 表... 还没有产生任何结果。 因此、不放置任何元素是因为我无法使链接器生成范围值、这是我未决的问题之一。

    我还有一个未解决的问题、即在何处获取闪存的 MCU 特定定义值、在哪里定义了基地址和大小? 我们将在 F280039C 的 LaunchPad 上生成代码、但我们的目标是 F280037。 我知道它们具有不同的存储器布局、那么获得闪存基址及其大小所需的代码定义是什么? 我找不到此文档。  

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

    您可以在器件数据表中找到每个器件型号的可用闪存组

    此致、

    维纳

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

    谢谢、但有人可以说 所有头文件中的每个目标特定定义、对吗?

     头文件定义的值的一个目的是能够从 TARGET_A 移动到 TARGET_B、并让编译器处理对地址的更改。 例如:GPIO_16是 Register_?和 Register_?的位 X 内存位置为 X 这些值可以在两个目标上不同、但如果代码使用定义的标签、则源代码不会在目标之间更改、编译器和链接器会解决 差异。  

    您说 TI 没有 定义 闪存基址和闪存存储器大小的标签吗? _headers_*。cmd 链接器文件看起来包含其中的一些信息、但并不是完全需要的信息。 我不了解 TI 组织此信息的方式、我只能搜索而无法找到所需的内容。  

    如果需要 M0 RAM、M1 RAM、GS0 RAM、LS0 RAM 或任何其他 RAM 的基地址、则使用 driverlib 名称(M0_RAM_BASE、M1_RAM_BASE、GS0_RAM_BASE、LS0_RAM_BASE 等)定义它们。 但闪存存储器的情况并非如此、或者至少我无法确定它们是否存在。 Flash_CTRL_regs 和 FLASH_ECC_REGS 也是如此。  为什么 没有闪存基址和大小的类似定义?

    这些在每个 MCU 上都是不同的、应由 TI 以传统方式进行定义 、以供开发人员使用。  如果这不正确、为什么?  

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

    要求跟进仍未解决的问题。

    我想指出、在这两年前的主题中有非常类似的问题:
    TMS320F280025:硬件 CRC 编程或代码- C2000微控制器论坛- C2000 ︎ 微控制器- TI E2E 支持论坛

    现在情况已不相同、我们将使用不同的 MCU (280037或280039C (用于 launchpad))。 但在该线程中提出的问题会并行运行、从而使其能够在最新版本的 CWare2000上运行。

    仍然开放、是否有针对引导加载程序(bootROM)的内置支持、以便在闪存引导时进行闪存 CRC 验证? 看起来是基本行为、即使对于 ECC 闪存也是如此。  

    如何配置链接器 cmd 文件以在整个闪存上生成一条记录? 默认 F28003x 链接器 cmd 文件的设计方法似乎是使用48个4K 字扇区(IIRC)。 该旧线程中记录的方法不是最新的、 现在还不清楚建议的过程是什么。

    如果我可以获得一个应放入闪存最后一行的条目 CRC 表、但如果有48条 CRC 记录、则需要一个较大的(不受保护)区域、这会带来额外的风险。

    仅需指出的是、在 VCRC 支持以及如何使用 VCRC 扩展方面、在论坛和网络上发现了很多不一致之处。  甚至许多在线(和 e2e 支持)链接也会断开(包括:TI 博客条目、TI 操作方法参考和 TI 培训资源)与 TI 内部 托管资源的连接。  但他们不再是可以访问的,因为事物已经被移动。  如果将 TI 服务器配置为在更改时自动重定向、那会很好)。 此外、上述 CRC 的数量和类型通常不再可用、或者 VCRC 具有内置支持。 我看到 C28_CHECKSUM_16被描述为链接器的"默认"CRC、但 CRC32_PRIME 也是如此。 crc_defines.h (至少对于28003x)没有列出 C28_CHECKSUM_16、那么该配置到底是什么? 我在 STL_CRC 中针对 CRC32看到的示例似乎使用了一种"非标准"设置。 至少使 IV 0xFFFFFFFF 没有反射和没有退出 XOR 至少是一个标准配置。 IV 为0x00000000时的配置不同。 今后、保持 一致的流程会有所帮助、因此任何新的支持 都将与之前在该 e2e 论坛上以及 google 知道的过时文档向后兼容、并且 TI 会继续 在其服务器上积极提供支持。

    开发人员是否确实确定不需要在启动时验证闪存? 对于 ECC (及其相关问题)适合安全关键型应用这一共识是否充分满足这一要求?

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

    我想我已经解决了我的大多数问题、需要注意的是、CRC32_PRIME 中的内置是一个作为 IV 0的"非标准"配置、不包括进入/退出和异或 退出。 则可以知道其自身的值。  

    可以使用 crc()函数在 MEMORY 区域中使用组来获取较小段的复合 CRC。 crc ()的输出 memrange_crc_table 在所有段中包含一个复合 CRC。 crc_table 不包含相同的复合 CRC。 虽然汇编器文档中有信息、但这不是一个明显的检查位置、信息可以得到更好的呈现。    

    生成的表 也有点奇怪、因为与数据流不同、表条目中的值是静态的、并且为开发人员所知。 这使人感觉有限内存资源的使用效率低下。