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.

[参考译文] MSP430FR5994:CRC 硬件实现

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1327325/msp430fr5994-crc-hardware-implementation

器件型号:MSP430FR5994
主题中讨论的其他器件:MSP430WARE

您好、我需要一个示例 CCS 工程、其中演示了如何使用由链接器生成的 CRC 表在 MSP430FR5994中使用 CRC 硬件模块在运行时计算 CRC。 我已访问以下来源以了解如何生成 CRC 表、  

MSP430汇编语言工具 v18.1.0.LTS 用户指南(修订版 R)(TI.com)

专家分享:使用由链接器生成的 CRC 表执行循环冗余校验- Tools Insider -存档- TI E2E 支持论坛

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

    您好、Peace、

    从 MSP430中找不到这方面的任何完整示例。  

    有相当多的旧线程讨论了在链接器中使用 CRC 表(请参阅此处: https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/898475/compiler-msp430f5438a-appending-crc-to-the-output-file)

    有关如何在 MSP430中使用内部 CRC 模块的示例、请查看 Resource Explorer (https://dev.ti.com/tirex/explore/node?node=A__AF7oKdOr-S4f69Qk8zW6KA__msp430ware__IOGqZri__LATEST&placeholder=true&search=MSP430FR5994)中的 CRC_16和 CRC_32示例

    此致、
    布兰登·费舍尔

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

    尊敬的 Brandon:感谢您提供的信息、我已经能够为代码段和常量数据段生成 CRC 表、链接器生成的表通过.map 文件中的两个 CRC 记录进行了确认。 但是、为了在应用程序代码中确认此 CRC 值、我在尝试访问将通过 CRC 硬件外设传递的值时遇到了问题。 我是否需要一个特定函数来访问存储器范围中的值、

    是否已生成初始 CRC 值?

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

    您只需要一个指向段开头和段大小的指针、两者都 包含在 crc_decord 中、在链接器为每个输出段生成的 crc_table 结构中被引用。 然后逐字节馈送到外设中。 您将需要创建自己的函数来种子 CRC 模块并将字节输入其中 、因为 TI 不提供这种函数。 例如、我使用的一个基本函数如下所示:

    //Calculate the CRC16 using the CRC32 module. Only
    //perform CRC16_802_15_4 (CRC16_CCITT). The linker
    //does this byte-wise, load only 1 byte at a time.
    uint8_t calcCRCOverMemRange(CRC_RECORD *crcRec)
    {
       uint8_t *i;
    
       //Size is in 8-bit addressable units
       uint8_t *lastAddress = (uint8_t*)crcRec->addr + (crcRec->size);
    
       //Set initial value for CRC Module per the
       //crc_defines.h Algorithm Specifiers
       CRC16INIRESW0 = 0x0000;
    
       for(i = (uint8_t*)crcRec->addr; i < lastAddress; i++)
       {
           CRC16DIRBW0_L = *i;
       }
    
       if(CRC16INIRESW0 != crcRec->crc_value)
           return 1;
    
       return 0;
    }

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

    谢谢 Seth、我有一个与您发送的实现类似的实现、但到目前为止、我使用如下所示的 driverlib 函数、这会产生错误、因为它总是返回错误的 CRC 值。 但是、当我切换到寄存器时、它会正常工作。 您能帮助我使用 driverlib 来看一看下面的代码吗、或许我调用了错误的函数

    uint16_t saf_crc::GetCRC(uint8_t *addr, size_t len)
    {
    
        uint16_t crc_result = 0;
        uint8_t *current_addr;
    
        // Reset the CRC signature and set the initial seed
        CRC_setSeed(CRC32_BASE, CRC_Init);
    
        // Calculate the ending address
        uint8_t *end_addr = addr + len;
    
        // Iterate over the memory region from the starting address to the ending address
        for (current_addr = addr; current_addr < end_addr; current_addr++)
        {
            // Add the value into the CRC signature
            CRC_set8BitData(CRC32_BASE, *current_addr);
        }
    
        // Get the CRC result
        crc_result = CRC_getResult(CRC32_BASE);
        return crc_result;
    }
     

    这是上述函数的示例调用

    crc_record crc_rec = p_crc_table->recs[0];

    SAF_CRC::s_crc_val.crc_cal_val = SAF_CRC::GetCRC ((uint8_t *) crc_rec.addr、crc_rec.size);


    如果(SAF_CRC::s_crc_val.crc_cal_val!= crc_rec.crc_value)
    {
    //做一些事情
    GPIO_toggleOutputOnPin (
    GPIO_PORT_P1、
    GPIO_PIN0);

    否则
    {
    //做一些事情
    GPIO_toggleOutputOnPin (
    GPIO_PORT_P1、
    GPIO_PIN1);

    __delay_cycles (100000);

    感谢您的帮助

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

    我不使用 DriverLib、因此无法100%确定。 不过、您可以通过查看 DriverLib 的.h 和.c 文件来解决问题。 只需将它们执行的操作与工作寄存器代码执行的操作进行比较即可。 源代码位于 [MSP430WARE_INSTALL_DIR]\driverlib\driverlib\MSP430FR5xx_6xx 中

    我发布的代码在 CRC16模式下使用 CRC32模块、字节以相反的位顺序输入。 我不相信您的代码在做同样的事情。

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

    正如您指出的那样、通过以相反的位顺序馈送字节、它现在可以正常工作。

    uint16_t saf_crc::GetCRC(uint8_t *addr, size_t len)
    {
            uint16_t crc_result = 0;
            uint8_t *current_addr;
    
            // Reset the CRC signature and set the initial seed
            CRC_setSeed(CRC_BASE, CRC_Init);
    
            // Calculate the ending address
            uint8_t *end_addr = addr + len;
    
            // Iterate over the memory region from the starting address to the ending address
            for (current_addr = addr; current_addr < end_addr; current_addr++)
            {
                // Add the value into the CRC signature
                CRC_set8BitDataReversed(CRC_BASE, *current_addr);
            }
    
            // Get the CRC result
            crc_result = CRC_getResult(CRC_BASE);
            return crc_result;
    
    }

    正如您所指出的、这也可以在16位模式中使用 CRC32

    uint16_t saf_crc::GetCRC(uint8_t *addr, size_t len)
    {
            uint16_t crc_result = 0;
            uint8_t *current_addr;
    
            // Reset the CRC signature and set the initial seed
            CRC32_setSeed(CRC_Init, CRC16_MODE);
    
            // Calculate the ending address
            uint8_t *end_addr = addr + len;
    
            // Iterate over the memory region from the starting address to the ending address
            for (current_addr = addr; current_addr < end_addr; current_addr++)
            {
                // Add the value into the CRC signature
                CRC32_set8BitDataReversed(*current_addr, CRC16_MODE);
            }
    
            // Get the CRC result
            crc_result = CRC32_getResult(CRC16_MODE);
            return crc_result;
    
    }

    感谢您的帮助。