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不对应.
请问是原因什么导致的?
我没有用过0025
我是在28388D上我用VCU计算的CRC16
不过我想应该是类似的
你说的正确的结果 是不是找的第三方工具计算的 比如现在有很多在线crc工具
你检查下
1.crc seed值
2.字节校验顺序,是先校验低字节 还是高字节
3.有没有reflect,就是没有掉换msb和lsb
基本检查这三点
https://mp.weixin.qq.com/s/RBHNHbrkdD43E5kPhuQO1w
这个链接是我总结的28388 vcu做校验 你可以参考一下
我觉得他是把那段代码复制出来用的
按照注释理解 这段代码是做了4个字节的crc校验吧 而不是12个字节
而且注意
这种计算 输入 输出都做了反转
工具默认就是反转的 而且不能更改
我在做校验对比验证的时候 用的是这种校验方式
把要校验的数据 以16bit为单位 按照低字节在前 高字节在后的顺序 输入到这个工具输入框里
在388里 选择crc16 poly2 0x1021 也是按照低字节在前 高字节在后的顺序进行校验,不过这个无所谓 应为校验顺序可选的 哪个在前哪个在后都行 只要验证工具和388设置的方式一致就可以 因为我的系统里要和430单片机通许,所以我才选择低字节在前
你是已经用查表法实现校验了对吗 那是不是就不比一定要用文档里的汇编了呢
至于这个“那我要用VCRC单元做如下图的校验需要调用那个汇编例程?”
C2000ware 没有相关的280025的例程
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 ; .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时,j结果是:
CRC16resultP1 = 0x00005A00,CRC16resultP2 = 0x0000FD9B,
以上结果都与在线计算的结果不对应,正确结果应为DDBA
可用如下地址在线计算:
https://www.lddgo.net/en/encrypt/crc
当我使用VCU检验时,校验方式为CRC-16-MODBUS x16+x15+x2+1
是我使用的例程不对吗?该使用那个例程?
麻烦帮忙问一些,谢谢!
你好,根据回答的方法,
我将
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计算例程,
请问我需要怎么修改才能得到我想要的结果?
谢谢
当RefIn为True时,输入的原始数据的每个字节需要做个逆序的处理,注意:针对的每个字节,而不是整个数据,以一个4字节的原始数据为例:
当Refout为True,需要对输出数据做一次整个数据的逆序处理,注意:这里做的逆序和RefIn不同,它不是按字节逆序,而是整个逆序,以CRC-32为例来说明,最后的数据为32位,当Refout为True时,翻转如下: