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.

[参考译文] MSP430FR2476:尝试将由链接器生成的 CRC 表与 CRC 模块一起使用

Guru**** 2387830 points
Other Parts Discussed in Thread: MSP430FR2476, MSP430F2132
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/991256/msp430fr2476-trying-to-use-linker-generated-crc-tables-with-crc-module

器件型号:MSP430FR2476
主题中讨论的其他器件: MSP430F2132

您好!
我能够使用 MSP430FR2476的 CRC 模块验证 TLV CRC。  当我之前对该代码有疑问时、以下是该代码的链接:
https://e2e.ti.com/support/microcontrollers/msp430/f/msp-low-power-microcontroller-forum/972585/ccs-msp430fr2476-another-tlv-structure-checksum

现在、我正在尝试使用链接器生成 CRC 表、并使用 CRC 模块来验证它们。  该代码最初用于没有 CRC 模块的 MSP430F2132、因此它使用 C 函数检查链接器 CRC。  我希望我可以使用 CRC 模块、就像对 TLV 所做的那样。  遗憾的是、链接器和模块的 CRC 结果不匹配。

以下是链接器的相关部分:

...
    GROUP(ALL_FRAM)
    {
        GROUP(READ_WRITE_MEMORY)
        {
            .TI.persistent : {}              /* For #pragma persistent            */
            .cio           : {}              /* C I/O Buffer                      */
            .sysmem        : {}              /* Dynamic memory allocation area    */
        } PALIGN(0x0400), RUN_START(fram_rw_start) RUN_END(fram_rx_start)

        GROUP(READ_ONLY_MEMORY)
        {
            .cinit      : {}                   /* Initialization tables             */
            .pinit      : {}                   /* C++ constructor tables            */
            .binit      : {}                   /* Boot-time Initialization tables   */
            .init_array : {}                   /* C++ constructor tables            */
            .mspabi.exidx : {}                 /* C++ constructor tables            */
            .mspabi.extab : {}                 /* C++ constructor tables            */
            .const      : {}, crc_table(linkerCrcTable, algorithm=CRC16_802_15_4) /* Constant data */
        }

        GROUP(EXECUTABLE_MEMORY)
        {
            .text       : {}, crc_table(linkerCrcTable, algorithm=CRC16_802_15_4) /* Code */
            .text:_isr  : {}                   /* Code ISRs                         */
        }
    } > FRAM_APPL
    
...

    UNMI         : { * ( .int44 ) } > INT44 type = VECT_INIT
    SYSNMI       : { * ( .int45 ) } > INT45 type = VECT_INIT
    .reset       : {}               > RESET  /* MSP430 reset vector         */

    // CRC Table.  Don't put this in FRAM2, it will get warnings
    // because the memory addresses there are over 16 bits.
    .TI.crctab   : > FRAM_APPL
...

以下是 CRC 代码:

...
#define BYTES_PER_WORD  2       /**< Number of bytes in a word. */

// CRC16-CCITT parameters
#define CRC_INIT 0xFFFF

extern CRC_TABLE linkerCrcTable;        /**< Provides access to linker-generated CRC table. */
...

static bool POST_CRC_Code(void) {
  volatile CRC_TABLE  * linkerTable = &linkerCrcTable;
  volatile CRC_RECORD   codeCRCRecord;
  volatile uint16_t     crcResult   = 0x0000;
  uint8_t   loopCtrl1   = 0;
  uint16_t  loopCtrl2   = 0;
  uint16_t  numRecords  = linkerTable->num_recs;
  bool      retVal      = true;

  // Process each record of linker CRC table
  for (loopCtrl1 = 0; loopCtrl1 < numRecords; loopCtrl1++) {
    // Get the current CRC table record
    codeCRCRecord = linkerTable->recs[loopCtrl1];

    // Calculate the CRC
    // (example at e2e.ti.com/.../803317)
    CRC_setSeed(CRC_BASE, CRC_INIT);

    for ( loopCtrl2 = codeCRCRecord.addr;
          loopCtrl2 < codeCRCRecord.addr + codeCRCRecord.size;
          loopCtrl2 += BYTES_PER_WORD)
    {
        CRC_set16BitDataReversed(CRC_BASE, *(uint16_t*) loopCtrl2);
    };

    // Check if calculated CRC value matches linker record
    crcResult = CRC_getResult(CRC_BASE);
    if (crcResult != codeCRCRecord.crc_value) {
      // CRC check failed, return false and break
      retVal = false;
      break;
    }
  }


  #if 1 == POST_forceCrcPass
  // Debug flag set so force return to true
  retVal = true;
  #endif

  return retVal;
}

使用调试器、post_crc_Code 的第一个循环在 main 之前检查以下存储器:

GPIO_PORT_TO_BASE
0000	0200	0200	0220	0220	0240	0240	0260
0260	0280	0280	FFFF	FFFF	0320
$P$T0$1
0000	0000	0000	0000	0000	0000	0000	0000
$P$T0$1
0000	0000	0000	0000	0000	0000	0000
$P$T0$1
0000	0000	0000	0000	0000

将 crcResult 与 codeCRCRecord.CRC_value 进行比较时、 crcResult = 64786 (0xFD12)且 CRC_VALUE = 53469 (0xD0DD)时失败。

我使用的种子与 TLV 使用的种子相同、CRC 功能 也相同、CRC_set16BitDataReversed。  我尝试使用常规 CRC_set16BitData、但也失败了。

如果有人可以立即看到任何问题、请告诉我。  否则、我会感谢您提出任何调试建议...

谢谢!