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**** 2524550 points


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

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

器件型号:TMS570LC4357

您好!

我正在测试 CRC 模块、并注意到、使用两个32位字的方法与在 SafeTI 诊断库中实现的64位方法之间的计算值不同。 我将结果与 Richard Burke 在该主题中发布的软件计算方法( https://e2e.ti.com/support/microcontrollers/hercules/f/312/p/104764/368714#368714 )进行了比较,但结果也与其他方法不同。

在每次使用 CRC 模块进行测试之前、我都会复位该模块、这样会将起始值设置为0、并将 CRC 单元设置为"完全 CPU 模式"。

以下是我的代码:

#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 手动实现示例*/
typedef uint64 crc_t;
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;

uint64 result_crc_manual = 0U;
uint64 result_crc_decure_ti_lib = 0U;
uint64 result_crc_decure_tid_mode_tid_crc*= 0U;uint64 result_crc_decure_mode_crc_decure_tru_mode_y*


= 0U;uint64 crcu = 0u_crcu = 0u;u_resume_tru_crcu = 0u_mode_resume_tru_crcu = 0u;uint64 crcu = 0u_mode_resume_tru_





未交换的字*/
crcInit();
crcREG1->PSA_SIGREGH1 =(UINT32)(CRC_TEST_VALUE >> 32);
crcREG1->PSA_SIGREGL1 =(UINT32) CRC_TEST_REG1_VALUE;
result_CRC_CRC_TEST_REG1(crcSG1)*(crcREG1=(crcREG1)32

)





;crcREG1*0_REST_REST_REST_REST_REST_REST_REST_REST_32 (crC24_RESTON_REST_REST_REST_REST_REST_REST_REST_REST_REST_REST_REST_REST_REST_RESTON_C32)*(cr32)*(crC12_REST_REST_REST_REST_REST_REST_REST_REST_REST_REST_REST_REST_REST_REST_REST_REST_REST_REST_RES

结果如下:

RESULT_CRC_MANUAL = 0x2646CED073922BFD
RESULT_CRC_SAFE_TI_lib = 0x2646CEB873922B5F
Result_CRC_test1 = 0x739225063C91C898
Result_CRC_test2 = 0x2646CBAC3105924B

我希望 Result CRC_MANUAL、Result_CRC_SAFE_ti_lib 和 Result_CRC_test1或...2应该相同、那么我的测试可能会出什么问题?


谢谢、此致、

Jens

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

    您好!

    是否有人知道我的软件计算 CRC 与硬件计算 CRC 有何不同?

    谢谢、此致、

    Jens

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

    我正在研究这一点、并尝试了解两个 C 函数和测试例程之间的差异。 我今天会回来。

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

    您好、Sunil、

    有任何有关这方面的新闻吗? 提前感谢!

    此致、

    Jens

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

    很抱歉、需要很长时间才能回答。

    我不确定 Richard Burke 的手动实施、因为我尚未对其进行测试。 我确信 pycrc (https://pycrc.org/) 会生成与 TMS570 CRC 模块的输出相匹配的结果。

    至于 CRC_test1和 CRC_test2、请注意、每当 CPU 写入这些寄存器时、PSA 寄存器都会根据由 PSA_SIGREGLx 和 PSA_SIGREGHx 寄存器组成的64位值的内容计算签名。 在测试中、您可以将两个单独的32位值写入这些单独的寄存器。 每次写入都会触发签名计算、该计算会覆盖签名寄存器的内容、从而覆盖刚刚写入特定寄存器的内容。 这就是您最终计算的签名与使用对 PSA 签名寄存器的64位写操作生成的签名完全不同的原因。

    此致、
    Sunil