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.

[参考译文] TMS570LC4357:CRC 算法

Guru**** 2609995 points
Other Parts Discussed in Thread: TMS570LC4357

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/755466/tms570lc4357-crc-algorithm

器件型号:TMS570LC4357

您好!

我正在尝试找到一种软件算法、该算法计算的 CRC 与 TMS570LC4357中的 CRC 单元相同(请参阅此主题: http://e2e.ti.com/support/microcontrollers/hercules/f/312/p/716945/2749159#2749159)。

我在这个论坛上尝试了 Richard Burke 的一个实现、也尝试了 pycc 生成的基于表格的例程、pycc 是 Sunil Oak 在另一个主题中推荐的工具。

我看到的是:Richard Burk 和 pycrc 例程的实现返回的值完全相同、但它们与处理器中硬件 CRC 单元生成的 CRC 不同。

以下是我的测试代码、包括 pycrc 参数:

#define CRC_CTRL0 (*(volatile UINT32 *) 0xFE000000U)
#define CRC_CTRL2 (*(volatile UINT32 *) 0xFE000010U)
#define CRC_SIGREG (*(volatile uint64 *) 0xFE000060U)

/*来自 SafeTI 诊断库(sl_MISC.c)的函数*/
/* SAFETYMCUSW 61 D MR:8.10、8.11 Common_1*/
uint64 SL_CRC_Calculate (uint64* startAddr、const UINT32 count64)
{
volatile UINT32 count = 0U;/* volatile 以防止优化*/

CRC_CTRL0 |= 0x00000001U;//重置 CRC 模块*/
CRC_CTRL0 &= 0x3U* FFCTRL0
|= 0x00000001U;//将 CRC2000*配置为完整 CPU

| CRCTRF000UFFW*| CRC_FFW*| CRCTRF0XUFFW*| CRC2000UFFW* 12.2. 注释_5*/*SAFETYMCUSW
134 S MR:12.2 comment_5*/
for (count=0U;count < count64;count++){
/*SAFETYMCUSW 45 D MR:21.1 备注_2*/
/*SAFETYMCUSW 93 S MR:6.1、6.2、10.1、10.2、10.3、10.4 "LDRA 工具问题"*/
CRC_SIGREG =(uint64)(* startAddr);
/*SAFETYMCUSW 45 D MR:21.1 备注_2*/
/*SAFETYMCUSW 567 S MR:17.1,17.4 "需要指针增量"*/
startAddr++;
}
return (crc_SIGREG);
}

// Richard Burke 手动实现的示例*/
crc_t crc_update_word (crc_t crc、crc_t data)
{
int i、j;
crc_t nextCrc = 0;
//对于63到0环路中的 I
for (i = 63;i >=0;i---)
{
// next _CRC_VAL (0):= CRC_VAL (63) XOR data (I);
nextCrc =(nextCrc &(crc_t)0xfffffffffffffffffffffffe)|((CRC >> 63)^(data >> I));
//对于 j in 1到63循环
对于(j = 1;j < 64;j++)
{
//case j 为
//当1|3|4 =>时
if (j = 1 || j = 3 || j = 4)
{
// NEW_CRC_VAL (j):= CRC_VAL (j - 1) XOR CRC_VAL (63) XOR DATA (i);
nextCrc =(nextCrc &~((crc_t)1 << j))|((((CRC >>(j-1)))^(CRC >> 63)^(数据>> I))& 1)<< j);
}
其他
{//当其他人=>时
// next _CRC_VAL (j):= CRC_VAL (j - 1);
nextCrc =(nextCrc &~((crc_t)1 << j))|(((CRC >>(j-1))& 1)<< j);
}
//结束大小写;
} //结束循环;
CRC = nextCrc;
} //结束循环

返回 CRC;
}

void CRC_TEST (void)
{
uint64 CRC_TEST_VALUE = 0x8DF8A32C74B91F3E;

uint8 CRC_TEST_array1[8]={0x8D、0xf8、0xA3、0x2C、0x74、 0xB9、0x1F、0x3E};


uint64 Result_CRC_SAFE_ti_lib = 0U;
uint64 Result_CRC_Burke = 0U;
uint64 Result_CRC_Pycrc = 0U;

Result_CRC_SAFE_ti_lib = SL_CRC_Calculate (&CRC_TEST_VALUE、1U);crc_crc_py_crc = 0U

;crc_result = 0U*将 CRC_Wet/ CRC_WIT_DULE = 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 *


/*
*在2018年12月12日12:46:55日生成
*由 pycc v0.9.1, https://pycrc.org
*使用配置
:*-宽度 = 64
*-聚酯 = 0x00000000001b
*- XorIn = 0x0000000000000000
*-反射式 =错误
*- XorOut = 0x0000000000000000
*- ReflectOut = False
*-算法 =表驱动
**/
result_crc_pycrc = crc_init ();
result_crc_pycrc = crc_update (result_crc_pycrc、(unsigned char *)&crc_test_value、8);
result_crc_pycrc = crc_dfinalize (result_crc_pycrc);

while (1);
} 

结果:

RESULT_CRC_SAFE_TI_lib = 0x2646CEB873922B5F

RESULT_CRC_Bike = 0x2646CED073922BFD

Result_CRC_pycrc = 0x2646CED073922BFD

 基元多项式与处理器参考手册中提到的相同、并且我禁用了所有额外的反射和 XOR 值。

可能出什么问题了?

此致、

Jens

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

    我有一段时间没有运行 pycrc 例程。 我记得、它根据 TMS570上的 CRC 模块生成了正确的签名、正如几年前在本帖子中所述:
    e2e.ti.com/.../672434

    我将再次运行它并告知您。

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

    您好、Sunil、

    这是我用于生成例程的命令:

    Python pycrc.py --model CRC-64 --算法表驱动--refle-in False --refle-out False --generate h -o crc.h
    Python pycrc.py --model CRC-64 --algorithm table drived--refle-in False --refle-out False --generate c -o crc.c

    crc.h:

    /**
    *\file
    *用于 CRC 校验的函数和类型。
    *
    **在2018年12月13日13:29:54日生成
    *由 pycc v0.1.1、 https://pycrc.org
    *使用配置:
    *-宽度 = 64
    *-聚酯 = 0x00000000001b
    *- XorIn = 0x0000000000000000
    *-反射式 =错误
    *- XorOut = 0x0000000000000000
    *- ReflectOut = False
    *-算法 =表驱动
    *
    *该文件定义了函数 crc_init()、crc_update()和 crc_dfinal()。
    *
    * crc_init()函数返回初始\c CRC 值,并且必须在
    第一次调用 crc_update()之前调用*。
    *同样,在使用
    \c CRC 之前,必须在最后一次调用* crc_update()之后调用 crc_dfinal()函数。
    正在使用*。
    *
    * crc_update()函数可在
    crc_init()和 crc_delfinal()调用之间任意次数(包括零*次)调用。
    *
    *此伪代码显示了 API 的示例用法:
    *\code{.c}
    * crc_t crc;
    * unsigned char data[MAX_DATA_LEN];
    * size_t DATA_len;
    *
    CRC = crc_init ();
    * while (data_len = Read_data (data、MAX_DATA_LEN)))> 0){
    *} CRC = CRC_UPDATE (CRC、DATA、DATA_Len);
    *}
    * CRC = CRC_finalize (CRC);
    *\endcode
    */
    #ifndef CRC_H
    #define CRC_H
    
    #include 
    #include 
    
    #ifdef __cplusplus
    extern "C"{
    #endif
    
    
    /**
    *所用算法的定义。
    *
    *这不在生成的代码中的任何位置使用、但
    *应用程序代码可以使用它来调用算法特定的代码(如果需要)。
    */
    #define CRC_ALGO_TABLE 被驱动1/**
    
    
    
    * CRC 值的类型。
    *
    *此类型必须足够大、至少包含64位。
    */
    typedef uint_fast64_t crc_t;
    
    
    //
    *计算初始 CRC 值。
    *
    *\返回 初始 CRC 值。
    */
    静态内联 crc_tcrc_init (void)
    {
    返回0x0000000000000000;
    }
    
    
    /**
    *用新数据更新 CRC 值。
    *
    *\param[in] crc 当前 CRC 值。
    *\param[in]数据 指向\a data_len 字节的缓冲区的指针。
    *\param[in] data_len 数据缓冲区中的字节数。
    *\返回 更新的 CRC 值。
    //
    crc_t crc_update (crc_t crc、const void * data、size_t data_len);
    
    
    //*
    计算最终 CRC 值。
    *
    *\param[in] CRC 当前 CRC 值。
    *\返回 最终 CRC 值。
    */
    静态内联 crc_t crc_dfinalize (crc_t CRC)
    {
    返回 CRC;
    }
    
    
    #ifdef __cplusplus
    } /* extern "C"的右括号*/
    #endif
    
    #endif /* CRC_H */
    

    crc.c:

    /**
    *\file
    *用于 CRC 校验的函数和类型。
    *
    **在2018年12月13日13:29:54日生成
    *由 pycc v0.1.1、https://pycrc.org
    *使用配置:
    *-宽度 = 64
    *-聚酯 = 0x00000000001b
    *- XorIn = 0x0000000000000000
    *-反射式 =错误
    *- XorOut = 0x0000000000000000
    *- ReflectOut = False
    *-算法 =表驱动
    */
    #include "crc.h" /*包含使用 pycrc 生成的头文件*/
    #include 
    #include 
    
    
    
    /**
    *用于 table_driven 实现的静态表。
    */
    静态常量 crc_tcrc_table[256]={
    0x0000000000000000、0x000000000000001b、0x0000000000000036、0x00000000002d、
    0x00000000006c、0x000000000077、0x00000000005a、0x000000000041、
    0x0000000000d8、0x0000000000c3、0x0000000000ee、0x0000000000f5、
    0x0000000000b4、0x0000000000af、0x000000000082、0x000000000099、
    0x00000000000001b0、0x00000000000001ab、0x0000000000000186、0x000000000000019d、
    0x00000000000001dc、0x00000000000001c7、0x00000000000001ea、0x00000000000001F1、
    0x0000000000000168、0x0000000000000173、0x000000000000015e、0x0000000000000145、
    0x0000000000000104、0x000000000000011f、0x0000000000000132、0x0000000000000129、
    0x0000000000000360、0x000000000000037b、0x0000000000000356、0x000000000000034d、
    0x000000000000030c、0x0000000000000317、0x000000000000033a、0x0000000000000321、
    0x00000000000003b8、0x00000000000003a3、0x000000000000038e、0x0000000000000395、
    0x00000000000003d4、0x00000000000003CF、0x00000000000003e2、0x00000000000003f9、
    0x00000000000002d0、0x00000000000002cb、0x00000000000002e6、0x00000000000002fd、
    0x00000000000002bc、0x00000000000002a7、0x000000000000028a、0x0000000000000291、
    0x0000000000000208、0x0000000000000213、0x000000000000023e、0x0000000000000225、
    0x0000000000000264、0x000000000000027f、0x0000000000000252、0x0000000000000249、
    0x00000000000006c0、0x00000000000006db、0x00000000000006f6、0x00000000000006ed、
    0x00000000000006ac、0x00000000000006b7、0x000000000000069a、0x0000000000000681、
    0x0000000000000618、0x0000000000000603、0x000000000000062e、0x0000000000000635、
    0x0000000000000674、0x000000000000066f、0x0000000000000642、0x0000000000000659、
    0x0000000000000770、0x000000000000076b、0x0000000000000746、0x000000000000075d、
    0x000000000000071c、0x0000000000000707、0x000000000000072a、0x0000000000000731、
    0x00000000000007a8、0x00000000000007b3、0x000000000000079e、0x0000000000000785、
    0x00000000000007c4、0x00000000000007df、0x00000000000007f2、0x00000000000007e9、
    0x00000000000005a0、0x00000000000005bb、0x0000000000000596、0x000000000000058d、
    0x00000000000005cc、0x00000000000005d7、0x00000000000005fa、0x00000000000005e1、
    0x0000000000000578、0x0000000000000563、0x000000000000054e、0x0000000000000555、
    0x0000000000000514、0x000000000000050f、0x0000000000000522、0x0000000000000539、
    0x0000000000000410、0x000000000000040b、0x0000000000000426、0x000000000000043d、
    0x000000000000047c、0x0000000000000467、0x000000000000044a、0x0000000000000451、
    0x00000000000004c8、0x00000000000004d3、0x00000000000004fe、0x00000000000004e5、
    0x00000000000004a4、0x00000000000004bf、0x0000000000000492、0x0000000000000489、
    0x0000000000000d80、0x0000000000000d9b、0x0000000000000db6、0x0000000000000DAD、
    0x0000000000000dec、0x0000000000000df7、0x0000000000000dda、0x0000000000000dc1、
    0x0000000000000d58、0x0000000000000d43、0x0000000000000d6e、0x0000000000000d75、
    0x0000000000000d34、0x0000000000000d2f、0x0000000000000d02、0x0000000000000d19、
    0x0000000000000c30、0x0000000000000c2b、0x0000000000000c06、0x0000000000000c1d、
    0x0000000000000c5c、0x0000000000000c47、0x0000000000000c6a、0x0000000000000c71、
    0x0000000000000ce8、0x0000000000000CF3、0x0000000000000cde、0x0000000000000cc5、
    0x0000000000000c84、0x0000000000000c9f、0x0000000000000cb2、0x0000000000000ca9、
    0x0000000000000EE0、0x0000000000000efb、0x0000000000000ed6、0x0000000000000ecd、
    0x0000000000000e8c、0x0000000000000e97、0x0000000000000eba、0x0000000000000ea1、
    0x0000000000000e38、0x0000000000000e23、0x0000000000000e0e、0x0000000000000e15、
    0x0000000000000e54、0x0000000000000e4f、0x0000000000000e62、0x0000000000000e79、
    0x0000000000000f50、0x0000000000000f4b、0x0000000000000f66、0x0000000000000f7d、
    0x0000000000000f3c、0x0000000000000f27、0x0000000000000f0a、0x0000000000000f11、
    0x0000000000000f88、0x0000000000000f93、0x0000000000000fbe、0x0000000000000f5、
    0x0000000000000fe4、0x0000000000000fff、0x0000000000000fd2、0x0000000000000fc9、
    0x0000000000000b40、0x0000000000000b5b、0x0000000000000b76、0x0000000000000b6d、
    0x0000000000000b2c、0x0000000000000b37、0x0000000000000b1a、0x0000000000000b01、
    0x0000000000000b98、0x0000000000000b83、0x0000000000000bae、0x0000000000000bb5、
    0x0000000000000bf4、0x0000000000000bef、0x0000000000000bc2、0x0000000000000bd9、
    0x0000000000000af0、0x0000000000000aeb、0x0000000000000ac6、0x0000000000000add、
    0x0000000000000a9c、0x0000000000000a87、0x0000000000000aaa、0x0000000000000ab1、
    0x0000000000000a28、0x0000000000000a33、0x0000000000000a1e、0x0000000000000a05、
    0x0000000000000a44、0x0000000000000a5f、0x0000000000000a72、0x0000000000000a69、
    0x0000000000000820、0x000000000000083b、0x0000000000000816、0x000000000000080d、
    0x000000000000084c、0x0000000000000857、0x000000000000087a、0x0000000000000861、
    0x00000000000008f8、0x00000000000008e3、0x00000000000008ce、0x00000000000008d5、
    0x0000000000000894、0x000000000000088f、0x00000000000008a2、0x00000000000008b9、
    0x0000000000000990、0x000000000000098b、0x00000000000009a6、0x00000000000009bd、
    0x00000000000009fc、0x00000000000009e7、0x00000000000009ca、0x00000000000009d1、
    0x0000000000000948、0x0000000000000953、0x000000000000097e、0x0000000000000965、
    0x0000000000000924、0x000000000000093f、0x0000000000000912、0x0000000000000909
    };
    
    
    crc_t crc_update (crc_t CRC、 const void * data、size_t data_len)
    {
    const unsigned char * d =(const unsigned char *) data;
    unsigned int tbl_idx;
    
    while (data_len--){
    tbl_idx =((CRC >> 56)^* d)& 0xff;
    CRC =(crc_table[tbl_idx]^(CRC << 8))和0xffffffff;
    D++;
    }
    返回 CRC 和0xFFFFFFFFFFFF;
    } 

    此致、

    Jens

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

    TI CodeGen 工具能够为已初始化的段生成 CRC 表。 有关更多详细信息、请参阅此处的 ARM 汇编工具用户指南: downloads.ti.com/.../

    第8.9节专门介绍了此功能的用法。

    另请参阅此博客、了解如何使用此功能通过链接器生成的 CRC 表执行循环冗余校验:
    e2e.ti.com/.../from-the-experts-perform-cyclic-redundancy-checking-using-linker-generated-crc-tables

    其中包括演示操作的视频。 它特定于 C2000 MCU、但可轻松适用于 TMS570 MCU。 我还将创建一个特定于 TMS570 MCU 的示例。 希望这在平均时间内有所帮助。

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

    我想你弄错了。 我想使用 TMS570的硬件 CRC 单元进行数据一致性检查、因此我必须先计算 PC 上的 CRC 并将其附加到数据中、以便 TMS570能够检查数据。
    对于该用例、pycrc 似乎是一个很有争议的工具、感谢这一建议。 您告诉我 pycrc 已经获得了相同的结果、因此我只需知道我必须为 pycrc 设置哪些参数才能与结果 TMS570 HW CRC 例程相匹配。

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

    尊敬的 Jens:

    我必须重新进行实验、以重新了解验证签名的具体要求。 在输入到 CRC 模块之前、您需要交换输入字符串中的高32位和低32位值。 在本例中、将值0x74B91F3E8DF8A32C 传递为输入。 请参阅以下代码:

    int main (void)
    {
    /*用户代码 begin (3)*/
    
    uint64 crcSign、crcSign2 = 0;
    
    crcModConfig_t crcParam;
    
    uint64_t 数据模式= 0x74B91F3E8DF8A32C;
    
    crcparam.crc_channel = CRC_CH1;// CRC 通道0
    crcParam.mode = CRC_FULL_CPU; //全 CPU 模式操作
    crcParam.data_length = 1; //要分析的单个64位字
    crcParam.src_data_pat =&dataPattern;
    
    crcInit();
    crcSignGen (crcREG1、&crcParam);
    
    crcSign = crcGetPSASig (crcREG1、CRC_CH1);
    
    crcSign2 =((uint64)(crcREG1->PSA_SIGREGH1)<<32U)|(uint64)(crcREG1->PSA_SIGREGL1);
    
    while (1);
    
    /*用户代码结束*/
    
    返回0;
    }
    

    crcGetPSASig 会重新排序 CRC 签名的高32位和低32位、这是不需要的。

    使用此代码、我得到以下结果:

    pycrc 给出的结果与传递的64位输入值相同、如下所示:

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

    您好、Sunil、

    感谢您的测试、结果让我感到非常吃惊。 我始终使用生成的代码、因为我必须计算二进制数据的 CRC、而不是 ASCII 字符串或文本文件的 CRC。 如果我以您的方式进行测试、我将获得相同的结果。 但是、为什么使用完全相同参数的 pycrc 生成的代码不会产生相同的结果? 我真的很困惑。

    此致、

    Jens

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

    您的 CRC 测试值定义为:
    uint64 CRC_TEST_VALUE = 0x8DF8A32C74B91F3E;

    TMS570实现的一个特性是在调用 sl_CRC_Calculate ()函数之前需要交换高32位和低32位。 例如、将 CRC 测试值设置为0x74B91F3E8DF8A32C、以获得与 pycrc 例程相同的 CRC 值。

    Result_CRC_SAFE_ti_lib = sl_CRC_Calculate (&CRC_TEST_VALUE、1U);

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

    您好、Sunil、

    非常感谢、这是正确的提示。 我没有交换输入字或为两个例程交换输入字。 出于性能原因、我为 HW CRC 计算选择了直接版本、但没有换用、并将换用外部工具中的单词。

    如果它可能对其他人有所帮助、这是我对匹配校验和的最终测试:

    #define CRC_CTRL0 (*(volatile UINT32 *) 0xFE000000U)
    #define CRC_CTRL2 (*(volatile UINT32 *) 0xFE000010U)
    #define CRC_SIGREG (*(volatile uint64 *) 0xFE000060U)
    
    /*来自 SafeTI 诊断库(sl_MISC.c)的函数*/
    /* SAFETYMCUSW 61 D MR:8.10、8.11 comment_1*/
    uint64 SL_CRC_Calculate (uint64* startAddr、const UINT32 count64)
    {
    寄存器 UINT32 count = 0U;//为了防止优化而易失性*
    寄存器 uint64* pAddress = startAddr;
    
    CRC_CTRL0 |= 0x00000001U;//重置 CRC_RFU0 |
    0x0000CLC= 0x0000FFL0;//
    /*配置为完全 CPU 模式*/*SAFETYMCUSW
    
    134 S MR:12.2 注释_5*/*SAFETYMCUSW
    134 S MR:12.2 comment_5*/
    for (count=0U;count < count64;count++){
    /*SAFETYMCUSW 45 D MR:21.1 备注_2*/
    /*SAFETYMCUSW 93 S MR:6.1、6.2、10.1、10.2、10.3、10.4 "LDRA 工具问题"*/
    CRC_SIGREG =(uint64)(*pAddress);
    /*SAFETYMCUSW 45 D MR:21.1 备注_2*/
    /*SAFETYMCUSW 567 S MR:17.1,17.4 "需要指针增量"*/
    pAddress++;
    }
    return (CRC_SIGREG);
    }
    
    #define CRC_START_ADDRESS 0
    #define CRC_MEM_SIZE 0x80000
    
    静态内联 uint64 SwapWords64 (uint64 Data_u64)
    {
    return (uint64)((uint32) Data_u64)<< 32U)|(uint64)(Data_u64 >> 32U);
    }
    
    void CRC_test (void)
    {
    uint64 DataCrchw_u64*
    
    
    
    
    
    
    
    ;uint64* resum_u64* crc (u64_u64_u_uint64*)
    
    ;u64* resum_u64_u_u64* crcum_u_u64_u_u_u_u64*
    
    对于(I = 0;I < CRC_MEM_SIZE;I++)
    {
    DataSwapped_u64 = SwapWord64 (*pAddress);
    ResultCrcSw_u64 = crc_update (ResultCrcSw_u64、(unsigned char *)&DataSwaped_u64、8);
    pAddress++;
    }
    ResultCrcSw_u64 = CRC_finalize (ResultCrcSw_u64);
    ResultCrcSw_u64 = SwapWord64 (ResultCrcSw_u64);
    
    if (ResultCrcHw_u64 = ResultCrcSw_u64)
    {
    while (1);
    }
    else
    {
    while (1);
    }
    

    此致、

    Jens