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.

[参考译文] TMS320F2.8069万M:使用VCU进行CRC-16计算:如何获得标准结果?

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/656757/tms320f28069m-using-vcu-for-crc-16-calculation-how-to-get-standard-results

部件号:TMS320F2.8069万M
主题中讨论的其他部件:controlSUITEMOTORWARE

大家好,

我想在C2000 MCU上实施CRC-16计算,用于与其他器件通信,因此我想使用一种现有标准,这种标准在其他地方易于实施。

我已成功实施controlSUITE示例中的CRC计算。 为了确认结果是否正确,我尝试使用一些广泛可用的在线CRC计算器。 但没有一个计算出与我的MCU相同的输出!

以 http://crccalc.com/ 为例-大多数其他生成器显示相同的结果。 查看这些设置,我会看到 0xE97B (或可用选项中的任何其它选项)的输出。  但VCU模块提供了0x9331 -请参见下面的详细信息以验证此实验。

我的CRC对象已初始化为:

CRC.seedValue = INIT_CRC16;
crc.nMsgBytes = nbytes;
crc.parity = crc_parity_偶 数;
crc.crcResult = 0;
crc.pMsgBuffer =(uint16_t *)&testInput[0];
crc.pCrcTable = NULL;
CRC.init =(void (*)(void *)) crc_init16Bit;
CRC.run =(void (*)(void *)) crc_run16BitPoly1; 

输入矢量如下所示:

静态连接uint16_t testInput[NWORDS]={
0x4001,0x8002,0xC003,0x0004,0x4005, 0x8006,0xC007,0x0008,
0x4009,0x800A,0xC00B,0x000C,0x400D, 0x800E,0xC00F,0x0010,
0x4011,0x8012,0xC013,0x0014,0x4015, 0x8016,0xC017,0x0018,
0x4019,0x801A,0xC01B,0x001C,0x401D, 0x801E,0xC01F,0x0020,
0x4021,0x8022,0xC023,0x0024,0x4025, 0x8026,0xC027,0x0028,
0x4029,0x802A,0xC02B,0x002C,0x402D, 0x802E,0xC02F,0x0030,
0x4031,0x8032,0xC033,0x0034,0x4035, 0x8036,0xC037,0x0038,
0x4039,0x803A,0xC03B,0x003C,0x403D, 0x803E,0xC03F,0x0040,
}; 

或者采用在线计算器可接受的形式(仅为十六进制值流):

4001.8002万C003000440058006C00700084009800AC00B000C400D800EC00F001040118012C013001440158016C01700184019801AC01B001C401D801EC01F002040218022C023002440258026C02700284029802AC02B004080100030030C03340300303230030C3032403003230323032300C334033300323003240300C3032300C33303230323032303230323032300C3340300C334033323032303230323032300C33323033</s>30.0044万 5.8006万007000840098000.104万11.8012万130.0144万15.8016万017001840198010.204万21.8022万230.0244万25.8026万0270028402980240.801万3.003万3.3403万0.3032万3.003万30.324万30.0323万3.230323亿334033300323003240300303.23万33.3032万30.323万32.3032万30.323万3.23万334030033.4033万32.3032万30.323万3.230323亿3332.3033万

具体问题包括:

1) VCU使用哪些参数,是否有任何现有算法? 我找不到关于所用XOR值或输出位反转的任何信息(“Poly1Reflected”文档仅说明输入位)。

2)我应该更改哪些设置(以及如何更改)以获得与在线计算器相同的结果?

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

    你好,Jakub,

    您是否尝试使用了“CRC_run16BitTableLookupC”,而不是使用CRC_run16BitPoly1。

    [报价用户="Jakub Klein"]

    我的CRC对象已初始化为:

    CRC.seedValue = INIT_CRC16;
    crc.nMsgBytes = nbytes;
    crc.parity = crc_parity_偶 数;
    crc.crcResult = 0;
    crc.pMsgBuffer =(uint16_t *)&testInput[0];
    crc.pCrcTable = NULL;
    CRC.init =(void (*)(void *)) crc_init16Bit;
    CRC.run =(void (*)(void *)) crc_run16BitPoly1; 

    [/引述]

    请参阅 http://www.ti.com/tool/C2000WARE \libraries\DSP\VCU\c28\Examples\CRC\2837x_vcu2_CRC_16\main.c以检查CRC对象的初始化。

    如果您仍然遇到相同的错误,请告知我们。

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

    感谢您的回复。

    我做了一个实验-将示例中的代码复制并粘贴到我的项目中,这样所有设置都完全相同。 而"查找版本"的结果仍然与我使用在线计算器获得的结果完全不同。 它是否更适合您?

    但我注意到了一件事。 该示例运行两个初始化函数:VCU2_initSystemClocks()VCU2_initEpie(),我没有包含这两个函数,因为我使用的是带有不同MCU的Motorware API (示例适用于F2837)。

    PIE和系统时钟是否有特定于VCU的设置?

    如果是,我应该从 instaSpine_labs示例中设置的值更改hal.c中的哪些内容?

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

    Jakub,

    我不会在在线计算器中投入太多的库存。 至少不是从"标准答案"的角度来看。 实际上,没有用于CRC的标准,使得变体非常多(初始化矢量,字节交换,位反向,输出异或等)。 您可以找到使用相同CRC poly但给出不同答案的在线计算器。 但是,我可以帮您解决问题。

    使用使用VCU指令的简单实验(在线组装到.c文件中-警告,此块地址为0x8000,因此不要执行此操作,只能作为简单实验):

    ASM (" VCRCCLR");
    ASM (" MOVL XAR4,#0x0.8万");
    ASM (" MOV * XAR4,#0x1234");
    ASM (" VCRC16P1H_1 * XAR4");
    ASM (" VCRC16P1L_1 *XAR4");
    ASM (" ESTOP0");

    以上给出了0xECBB的结果(您可以在CCS的“Registers”(注册)选项卡中检查VCRC寄存器), 这就是crccalc.com的CRC-16/BUYPASS行给出的结果。 因此,您的困惑在于库c代码,而不是说明本身。 您可以获得与您正在报价的网站相同的价值。

    看着库代码,它出现了(至少在我的代码版本中,我假设我们有相同的代码),VCRC16P1L_1指令位于VCRC16P1H_1指令之前,这意味着它将处理高位字节(在我的上例中为0x34)之前的低位字节(上面为0x12)。 这没有什么问题,只要这也是您在发送端执行的方式。 但是,您引用的网站是先对高字节执行CRC计算,然后对低字节执行CRC计算(说实话,这可能是更合乎逻辑的方式-但正如我所说,对于如何输入数据没有标准)。 我怀疑,如果您颠倒了库代码中两个VCRC说明的顺序,您将得到您要寻找的答案。 或者相反,在数据表中,切换每16位字的两个字节。

    此致,

    Dave Foley

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

    谢谢你,David,

    我知道CRC本身是针对具体实施的,但我认为命名算法(例如, CCITT或ARC)非常明确-它们不仅定义了所使用的多项式,还定义了您提到的其他参数。 毕竟,多个程序员和设备(包括其他MCU和PC或移动应用程序)应使用相同的CRC,我们需要通用算法。

    问题似乎与TI如何将数据保存在内存中有关:使用ex. “0x8001”提供“0x01;0x80”,而不是任何其他8位寻址计算机将使用的预期“0x80;0x01”(可能包括这些联机计算器)。 事实上,在输入向量中将MSB与LSB切换会产生预期结果。 同时,我实施了一些C代码(可在Web上找到)来计算CRC,并遇到了相同的问题。

    是否有任何类型的内部编译器可以自动反转一组字中的LSB和MSB顺序,或者我是否必须用C语言手动编写?

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

    很抱歉回复延迟。 所有受支持的内部函数都在TMS320C28x优化C/C++编译器v 18.1 .0.LTS用户指南(www.ti.com/.../spru514p.pdf)的第151页开始列出。 没有特定的内在过程可以执行整个交换字节操作,但是有几个字节内在过程可以帮助您手动执行,如"int &__byte( int *array, unsigned int byte_index )"。

    此致,
    Dave Foley