TI中文支持网
TI专业的中文技术问题搜集分享网站

TMS320F280025: 使用SPRUHS1C文件内642页提供CRC例程输出结果不正确。

Part Number:TMS320F280025Other Parts Discussed in Thread:C2000WARE, CONTROLSUITE

创建的.asm文件如下:

调用汇编函数如下:

Uint16 inputdata[6]= {1,2,3,4,5,6};

mycrc.CRCData = inputdata;
mycrc.CRCLen = 12;

 CRC16P1(&mycrc);

返回结果为 0x8059  ,与正确结果0xDDBA不对应.

请问是原因什么导致的?

user78960159:

我没有用过0025

我是在28388D上我用VCU计算的CRC16

不过我想应该是类似的

你说的正确的结果 是不是找的第三方工具计算的 比如现在有很多在线crc工具

你检查下

1.crc seed值

2.字节校验顺序,是先校验低字节 还是高字节

3.有没有reflect,就是没有掉换msb和lsb

基本检查这三点

https://mp.weixin.qq.com/s/RBHNHbrkdD43E5kPhuQO1w

这个链接是我总结的28388 vcu做校验 你可以参考一下

,

Yale Li:

Hello,

可以参考一下楼上工程师的分享。

我也已经咨询了相关工程师:

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1260124/tms320f280025-incorrect-output-using-the-crc-routine-provided-on-page-642-of-spruhs1c

,

Yale Li:

xixi wu said:与正确结果0xDDBA不对应

这个结果是如何得出的?请提供一下计算的过程

,

xixi wu:

你好,多项式类型如下:

CRC-16-MODBUS

    x16+x15+x2+1

 在线计算器计算的正常结果是 0xDDBA。

,

user78960159:

我觉得他是把那段代码复制出来用的

按照注释理解 这段代码是做了4个字节的crc校验吧 而不是12个字节

而且注意

这种计算 输入 输出都做了反转

工具默认就是反转的 而且不能更改

我在做校验对比验证的时候 用的是这种校验方式

把要校验的数据 以16bit为单位 按照低字节在前 高字节在后的顺序 输入到这个工具输入框里

在388里 选择crc16 poly2 0x1021 也是按照低字节在前 高字节在后的顺序进行校验,不过这个无所谓 应为校验顺序可选的 哪个在前哪个在后都行 只要验证工具和388设置的方式一致就可以 因为我的系统里要和430单片机通许,所以我才选择低字节在前

,

xixi wu:

那我要用VCRC单元做如下图的校验需要调用那个汇编例程?具体怎么操作?另外我用查表方式校验的结果是和在线计算器校验的结果是一致的

,

xixi wu:

以下是查表校验程序

,

user78960159:

你是已经用查表法实现校验了对吗 那是不是就不比一定要用文档里的汇编了呢

至于这个“那我要用VCRC单元做如下图的校验需要调用那个汇编例程?”

C2000ware 没有相关的280025的例程

,

Yale Li:

感谢 user78960159参与讨论~

xixi wu said:CRC-16-MODBUS

    x16+x15+x2+1

 在线计算器计算的正常结果是 0xDDBA。

我把这些同步给相关的工程师看一下

,

xixi wu:

主要想用VCRC单元来实现,看计算速度快不快。查表方式占用空间比较大。

,

user78960159:

恩是的 应该还是用VCU算合理一些 VCU和C28是并行的结构 这也是我在用388时候校验选择VCU的原因

,

Yale Li:

xixi wu said:主要想用VCRC单元来实现,看计算速度快不快。查表方式占用空间比较大。

好的

,

user78960159:

其实你用cla用查表算crc也行 不占用c28的资源

,

Yale Li:

如果CLA没有被使用的话,这也是一个方法。

,

xixi wu:

CRC-16-MODBUS

    x16+x15+x2+1这种校验模式初始值是固定的为0xFFFF,

我试了下controlSUITE\libs\dsp\VCU\v110\source\C28x_VCU_LIB这里面的例程结果也是不对,.asm文件代码如下

; -------------------
; Calculate the CRC of a block of data
; This function assumes the block is a multiple of 2 16-bit words
;.if __TI_EABI__.asg getCRC16P1_vcu, _getCRC16P1_vcu.asg CRC16P1 , _CRC16P1.asg getCRC16P2_vcu, _getCRC16P2_vcu.endif;.def _getCRC16P1_vcu
;.defCRC16P1.global _CRC16P1.global _getCRC16P2_vcu.global	_getCRC16P1_vcu;.text_CRC16P1VCRCCLR; Clear the result registerMOVAL,*+XAR4[4]; AL = CRCLenASRAL,2; AL = CRCLen/4SUBBAL,#1; AL = CRCLen/4 - 1MOVLXAR7,*+XAR4[2]	; XAR7 = &CRCData.align 2NOP; Align RPTB to an odd addressRPTB _CRC16P1_done, AL; Execute block of code AL + 1 timesVCRC16P1L_1 *XAR7; Calculate CRC for 4 bytesVCRC16P1H_1 *XAR7++; ...VCRC16P1L_1 *XAR7; ...VCRC16P1H_1 *XAR7++; ..._CRC16P1_doneMOVLXAR7,*+XAR4[0]; XAR7 = &CRCResultVMOV32*+XAR7[0], VCRC; Store the resultLRETR; return to caller_getCRC16P2_vcu:PUSHXAR0PUSHXAR1MOVZAR0, *-SP[7]; load rxLenADDBSP, #4; allocate 4 words for localVMOV32*-SP[2], VCRC; Store current CRCVCRCCLRMOVL*-SP[4], ACCVMOV32VCRC,*-SP[4]; VCRC = Inital valueMOVAL,AR5; check the paritySBF_CRC16p2_loop_prep, EQVCRC16P2H_1 *XAR4++; if parity=1, calculate high byte firstDECAR0SBF_CRC16p2done, EQ
_CRC16p2_loop_prep:MOVAL, AR0MOVAH, AR0ANDAL, #0xFFF8; check to see if the length is greater than 8 bytesBF_CRC16p2_LSB,EQLSRAL, #3; loop in 8 bytesMOVAR1, ALSUBAR1, #1.align(2); align at 32-bit boundary to remove penaltyRPTB_CRC16p2_post, AR1; loop for the middle part of the packetVCRC16P2L_1 *XAR4VCRC16P2H_1 *XAR4++VCRC16P2L_1 *XAR4VCRC16P2H_1 *XAR4++VCRC16P2L_1 *XAR4VCRC16P2H_1 *XAR4++VCRC16P2L_1 *XAR4VCRC16P2H_1 *XAR4++
_CRC16p2_postLSLAL, #3; calculating remaining number of bytesSUBAH, ALSBF_CRC16p2done, EQ;branch to end on 0 remainderMOVAR0, AH
_CRC16p2_LSBVCRC16P2L_1 *XAR4; if parity=0, calculate the low byteDECAR0SBF_CRC16p2done, EQVCRC16P2H_1 *XAR4++DECAR0SBF_CRC16p2_LSB, NEQ
_CRC16p2doneVMOV32*-SP[4], VCRC; Store CRCMOVAL, *-SP[4]; return ALVMOV32VCRC, *-SP[2]; Restore VCRCSUBBSP, #4; restore stack pointerPOPXAR1POPXAR0LRETR_getCRC16P1_vcu:PUSHXAR0PUSHXAR1MOVZAR0, *-SP[7]; load rxLenADDBSP, #4; allocate 4 words for localVMOV32*-SP[2], VCRC; Store current CRCVCRCCLRMOVL*-SP[4], ACCVMOV32VCRC,*-SP[4]; VCRC = Inital valueMOVAL, AR5; check the paritySBF_CRC16p1_loop_prep, EQVCRC16P1H_1 *XAR4++; if parity=1, calculate high byte firstDECAR0SBF_CRC16p1done, EQ
_CRC16p1_loop_prep:MOVAL, AR0MOVAH, AR0ANDAL, #0xFFF8; check to see if the length is greater than 8 bytesBF_CRC16p1_LSB,EQLSRAL, #3; loop in 8 bytesMOVAR1, ALSUBAR1, #1.align(2); align at 32-bit boundary to remove penaltyRPTB_CRC16p1_post, AR1; loop for the middle part of the packetVCRC16P1L_1 *XAR4VCRC16P1H_1 *XAR4++VCRC16P1L_1 *XAR4VCRC16P1H_1 *XAR4++VCRC16P1L_1 *XAR4VCRC16P1H_1 *XAR4++VCRC16P1L_1 *XAR4VCRC16P1H_1 *XAR4++
_CRC16p1_postLSLAL, #3; calculating remaining number of bytesSUBAH, ALSBF_CRC16p1done, EQ;branch to end on 0 remainderMOVAR0, AH
_CRC16p1_LSBVCRC16P1L_1 *XAR4; if parity=0, calculate the low byteDECAR0SBF_CRC16p1done, EQVCRC16P1H_1 *XAR4++DECAR0SBF_CRC16p1_LSB, NEQ
_CRC16p1doneVMOV32*-SP[4], VCRC; Store CRCMOVAL, *-SP[4]; return ALVMOV32VCRC, *-SP[2]; Restore VCRCSUBBSP, #4; restore stack pointerPOPXAR1POPXAR0LRETR

函数调用代码如下:

typedef enum{CRC_parity_even = 0,CRC_parity_odd = 1
}CRC_parity_e;typedef struct {Uint32 *CRCResult;// Address where result should be storedUint16 *CRCData;// Start of dataUint16 CRCLen ;// Length of data in bytes
}CRC_CALC;
CRC_CALC mycrc;extern Uint32 CRC16P1(CRC_CALC *mycrc);
extern Uint16 getCRC16P1_vcu(Uint32 input_crc16_accum, Uint16 *msg, CRC_parity_e parity, Uint16 rxLen);
extern Uint16 getCRC16P2_vcu(Uint32 input_crc16_accum, Uint16 *msg, CRC_parity_e parity, Uint16 rxLen);Uint32 CRC16resultP1;
Uint32 CRC16resultP2;
Uint16 inputdata[6]= {0x01,0x02,0x03,0x04,0x05,0x06};
static const Uint16 CRC16inputdata[6] = {0x01,0x02,0x03,0x04,0x05,0x06};
void main(void)
{//mycrc.CRCResult = TESTresult;mycrc.CRCData = inputdata;mycrc.CRCLen = 6;while(1){CRC16P1(&mycrc);CRC16resultP1 = getCRC16P1_vcu(0xFFFF, (Uint16*)CRC16inputdata, (CRC_parity_e)CRC_parity_even, 6);CRC16resultP2 = getCRC16P2_vcu(0xFFFF, (Uint16*)CRC16inputdata, (CRC_parity_e)CRC_parity_even, 6);}

得到结果是:

*(CRCResult) = 0x00001800;

CRC16resultP1 = 0x00005AD8,CRC16resultP2  = 0x0000F38B,

当初始改为0x0000时,j结果是:

CRC16resultP1 = 0x00005A00,CRC16resultP2  = 0x0000FD9B,

以上结果都与在线计算的结果不对应,正确结果应为DDBA

可用如下地址在线计算:

https://www.lddgo.net/en/encrypt/crc

当我使用VCU检验时,校验方式为CRC-16-MODBUS   x16+x15+x2+1 

是我使用的例程不对吗?该使用那个例程?

麻烦帮忙问一些,谢谢!

,

Yale Li:

好的,我已经跟进过去了

,

xixi wu:

函数调用的程序好像没跟进过去。

,

Yale Li:

已补充

,

xixi wu:

你好,根据回答的方法,

我将

Uint16 inputdata[6]= {0x01,0x02,0x03,0x04,0x05,0x06};

Uint16 CRC16inputdata[3] ={0x01,0x02,0x03,0x04,0x05,0x06};

修改为

Uint16 inputdata[3]= {0x0201,0x0403,0x0605};

Uint16 CRC16inputdata[3] ={0x0201,0x0403,0x0605};

得到的结果是

*(CRCResult) = 0x00009E33;

CRC16resultP1 = 0x0000DA6F,

CRC16resultP2  = 0x0000D71C,

其中CRC16resultP2  = 0x0000D71C,符合多项式CRC-16-CCITT-FALSE   x16+x12+x5+1的结果,

但是我需要多项式CRC-16-MODBUS   x16+x15+x2+1 的VCU计算例程,

请问我需要怎么修改才能得到我想要的结果?

谢谢

,

Yale Li:

好的,我跟进过去了

赞(0)
未经允许不得转载:TI中文支持网 » TMS320F280025: 使用SPRUHS1C文件内642页提供CRC例程输出结果不正确。
分享到: 更多 (0)

© 2024 TI中文支持网   网站地图 鲁ICP备2022002796号-1