主题中讨论的其他器件:controlSUITE、 C2000WARE
大家好、
以下是客户可能需要您的帮助的问题:
下面显示了客户创建的.asm 文件:

被称为汇编函数:

Uint16 inputdata[6]= {1,2,3,4,5,6};
mycrc.CRCData = inputdata;
mycrc.CRCLen = 12;
CRC16P1(&mycrc);
返回的结果为 0x8059 ,它不对应于正确的结果 0xDDBA 。
原因是什么?
--
谢谢、此致
耶鲁
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.
大家好、
以下是客户可能需要您的帮助的问题:
下面显示了客户创建的.asm 文件:

被称为汇编函数:

Uint16 inputdata[6]= {1,2,3,4,5,6};
mycrc.CRCData = inputdata;
mycrc.CRCLen = 12;
CRC16P1(&mycrc);
返回的结果为 0x8059 ,它不对应于正确的结果 0xDDBA 。
原因是什么?
--
谢谢、此致
耶鲁
您好、Vivek、
客户反馈:
此检查模式的初始值是固定的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
; .def CRC16P1
.global _CRC16P1
.global _getCRC16P2_vcu
.global _getCRC16P1_vcu
; .text
_CRC16P1
VCRCCLR ; Clear the result register
MOV AL, *+XAR4[4] ; AL = CRCLen
ASR AL, 2 ; AL = CRCLen/4
SUBB AL, #1 ; AL = CRCLen/4 - 1
MOVL XAR7, *+XAR4[2] ; XAR7 = &CRCData
.align 2
NOP ; Align RPTB to an odd address
RPTB _CRC16P1_done, AL ; Execute block of code AL + 1 times
VCRC16P1L_1 *XAR7 ; Calculate CRC for 4 bytes
VCRC16P1H_1 *XAR7++ ; ...
VCRC16P1L_1 *XAR7 ; ...
VCRC16P1H_1 *XAR7++ ; ...
_CRC16P1_done
MOVL XAR7, *+XAR4[0] ; XAR7 = &CRCResult
VMOV32 *+XAR7[0], VCRC ; Store the result
LRETR ; return to caller
_getCRC16P2_vcu:
PUSH XAR0
PUSH XAR1
MOVZ AR0, *-SP[7] ; load rxLen
ADDB SP, #4 ; allocate 4 words for local
VMOV32 *-SP[2], VCRC ; Store current CRC
VCRCCLR
MOVL *-SP[4], ACC
VMOV32 VCRC,*-SP[4] ; VCRC = Inital value
MOV AL,AR5 ; check the parity
SBF _CRC16p2_loop_prep, EQ
VCRC16P2H_1 *XAR4++ ; if parity=1, calculate high byte first
DEC AR0
SBF _CRC16p2done, EQ
_CRC16p2_loop_prep:
MOV AL, AR0
MOV AH, AR0
AND AL, #0xFFF8 ; check to see if the length is greater than 8 bytes
BF _CRC16p2_LSB,EQ
LSR AL, #3 ; loop in 8 bytes
MOV AR1, AL
SUB AR1, #1
.align (2) ; align at 32-bit boundary to remove penalty
RPTB _CRC16p2_post, AR1 ; loop for the middle part of the packet
VCRC16P2L_1 *XAR4
VCRC16P2H_1 *XAR4++
VCRC16P2L_1 *XAR4
VCRC16P2H_1 *XAR4++
VCRC16P2L_1 *XAR4
VCRC16P2H_1 *XAR4++
VCRC16P2L_1 *XAR4
VCRC16P2H_1 *XAR4++
_CRC16p2_post
LSL AL, #3 ; calculating remaining number of bytes
SUB AH, AL
SBF _CRC16p2done, EQ ;branch to end on 0 remainder
MOV AR0, AH
_CRC16p2_LSB
VCRC16P2L_1 *XAR4 ; if parity=0, calculate the low byte
DEC AR0
SBF _CRC16p2done, EQ
VCRC16P2H_1 *XAR4++
DEC AR0
SBF _CRC16p2_LSB, NEQ
_CRC16p2done
VMOV32 *-SP[4], VCRC ; Store CRC
MOV AL, *-SP[4] ; return AL
VMOV32 VCRC, *-SP[2] ; Restore VCRC
SUBB SP, #4 ; restore stack pointer
POP XAR1
POP XAR0
LRETR
_getCRC16P1_vcu:
PUSH XAR0
PUSH XAR1
MOVZ AR0, *-SP[7] ; load rxLen
ADDB SP, #4 ; allocate 4 words for local
VMOV32 *-SP[2], VCRC ; Store current CRC
VCRCCLR
MOVL *-SP[4], ACC
VMOV32 VCRC,*-SP[4] ; VCRC = Inital value
MOV AL, AR5 ; check the parity
SBF _CRC16p1_loop_prep, EQ
VCRC16P1H_1 *XAR4++ ; if parity=1, calculate high byte first
DEC AR0
SBF _CRC16p1done, EQ
_CRC16p1_loop_prep:
MOV AL, AR0
MOV AH, AR0
AND AL, #0xFFF8 ; check to see if the length is greater than 8 bytes
BF _CRC16p1_LSB,EQ
LSR AL, #3 ; loop in 8 bytes
MOV AR1, AL
SUB AR1, #1
.align (2) ; align at 32-bit boundary to remove penalty
RPTB _CRC16p1_post, AR1 ; loop for the middle part of the packet
VCRC16P1L_1 *XAR4
VCRC16P1H_1 *XAR4++
VCRC16P1L_1 *XAR4
VCRC16P1H_1 *XAR4++
VCRC16P1L_1 *XAR4
VCRC16P1H_1 *XAR4++
VCRC16P1L_1 *XAR4
VCRC16P1H_1 *XAR4++
_CRC16p1_post
LSL AL, #3 ; calculating remaining number of bytes
SUB AH, AL
SBF _CRC16p1done, EQ ;branch to end on 0 remainder
MOV AR0, AH
_CRC16p1_LSB
VCRC16P1L_1 *XAR4 ; if parity=0, calculate the low byte
DEC AR0
SBF _CRC16p1done, EQ
VCRC16P1H_1 *XAR4++
DEC AR0
SBF _CRC16p1_LSB, NEQ
_CRC16p1done
VMOV32 *-SP[4], VCRC ; Store CRC
MOV AL, *-SP[4] ; return AL
VMOV32 VCRC, *-SP[2] ; Restore VCRC
SUBB SP, #4 ; restore stack pointer
POP XAR1
POP XAR0
LRETR
函数调用代码如下:
typedef enum{
CRC_parity_even = 0,
CRC_parity_odd = 1
}CRC_parity_e;
typedef struct {
Uint32 *CRCResult; // Address where result should be stored
Uint16 *CRCData; // Start of data
Uint16 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、结果为
CRC16resultP1 = 0x00005A00,CRC16resultP2 = 0x0000FD9B、
上述结果与在线计算结果不对应、正确结果应为0xDDBA。

https://www.lddgo.net/en/encrypt/crc
当我使用 VCU 进行验证时、验证方法是 CRC-16-MODBUS x16+x15+x2+1 。
我使用的例程是否错误? 我应该使用哪种例程?
--
谢谢、此致
耶鲁
耶鲁大学
uint16 inputdata[6]={0x01、0x02、0x03、0x04、0x05、0x06};
最终这个值为0x0001、0x0002、0x0003、0x0004、0x0005、 0x0006
然后、当您对6个字节计算 CRC 时、将按照以下顺序 LSB-MSB-LSB-MSB 进行计算、因此您正在计算0x01-0x00-0x02-0x00-0x03-0x00上的 CRC。
如果您希望在0x01-0x02-0x03-0x04-0x05-0x06上计算它、那么您的输入缓冲区需要定义为
uint16 inputdata[3]={0x0201、0x0403、0x0605};
谢谢。
Sira
尊敬的 Sira:
感谢您的答复。
根据您提供的方法、我的客户改变了
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 计算例程。
我的客户需要如何修改才能获得所需的结果?
--
谢谢、此致
耶鲁
尊敬的 Sira:
当 REFIN 为真时、每个 字节 需要以相反的顺序处理输入原始数据。 请注意:对于每个字节而不是整个数据,以4字节的原始数据为例:

当 REFOUT 为 True 时、输出数据的处理顺序与 整个 数据 。 请注意:此处执行的反向顺序操作与 REFIN 不同、它不是字节反向顺序、而是整个反向顺序。 以 CRC-32为例、最终数据为32位。 当 REFOUT 为 true 时、 反向如下:

--
谢谢、此致
耶鲁
耶鲁大学
那么在计算 CRC 时是否使用相应的设置、即通过 VSETCRCMSGFLIP 指令位反转输入字节、通过位反转输出(例如通过_flip32 ()内在函数)。
C2000Ware 有一个示例可提供帮助、它既具有常规计算、也具有位反向计算(称为"反射")。
C:\ti\cc2000\C2000Ware_5_00_00\libraries\dsp\VCU\c28\examples\crc\28003x_vcrc_crc_16
谢谢。
Sira