以下安全 PDU 的代码给出 了一个关于如何计算安全 PDU CRC 的示例。 尾随的 3 个 0 已 经考虑
在内。
****************************************************************
** Parameter : psPacket - FSCP12 / 1 Safety PDU
** startCrc - Startvalueof CRC Calculatoin
** seqNo - SeqNo
**
oldCRC - CRC _ 0 ofthelastreceived / send SafetySlave PDU
**
bRcvDir - bRcvDir=True : calcof CRCsofthereceived Frame
**
bRcvDir=False : calcof CRCsforthesend Frame
**
size
-sizeofSafety PDU
**
** Return :
bSuccess- TRUE : CRCkorrekt
**
*************************************************************** /
UINT8 CalcCrc ( SAFETY _ PDU * psPacket , UINT16 startCrc , UINT16 * seqNo , UINT16 oldCrc , UINT8 bRcvDir ,
UINT8size )
{
UINT8 bSuccess=FALSE ;
UINT16 w1 , w2 ;
// temporaryvalues
UINT16 crc ;
UINT16 crc _ common ;
// commonpartof CRCcalculation ,
// includes CRC _ 0 , Conn-ID , Sequence-No. , Cmd
UINT8 * pCrc= &psPacket->au8Data [ 2 ]; // pointerto CRC Low-Byte
UINT8 * pSafeData
// pointerto SafeData Low-Byte
if ( size > 6 )
// that means2 ora multipleoftwosafetydata
pCrc++ ;
// →Crc0 Low-Byteat Byteoffset3insteadof2
do
{
crc=0 ;
// resetcrc
// Sequenceforcalcultaion :
// old CRC-Lo , old CRC-Hi , ConnId-Lo , ConnId-Hi , SeqNo-Lo , SeqNo-Hi , Command ,
// ( Index ,) Data
// CRC-Lo
w1=aCRCTab1 [(( UINT8 * ) &crc )[ HI _ BYTE ]];
// lookatthe CRC-table
w2=aCRCTab2 [(( UINT8 * ) &startCrc )[ 0 ]];
// lookatthe CRC-table
w1=w1 XOR w2 ;
(( UINT8 * ) &crc )[ HI _ BYTE ] = (( UINT8 * ) &w1 )[ HI _ BYTE ] XOR (( UINT8 * )
&crc )[ LO _ BYTE ];
(( UINT8 * ) &crc )[ LO _ BYTE ] = (( UINT8 * ) &w1 )[ LO _ BYTE ];
// CRC-Hi
w1=aCRCTab1 [(( UINT8 * ) &crc )[ HI _ BYTE ]];
w2=aCRCTab2 [(( UINT8 * ) &startCrc )[ 1 ]];
w1=w1 XOR w2 ;
(( UINT8 * ) &crc )[ HI _ BYTE ] = (( UINT8 * ) &w1 )[ HI _ BYTE ] XOR (( UINT8 * )
&crc )[ LO _ BYTE ];
(( UINT8 * ) &crc )[ LO _ BYTE ] = (( UINT8 * ) &w1 )[ LO _ BYTE ];
// ConnId-Lo
w1=aCRCTab1 [(( UINT8 * ) &crc )[ HI _ BYTE ]];
w2=aCRCTab2 [ psPacket->au8Data [ size-2 ]];
w1=w1 XOR w2 ;
(( UINT8 * ) &crc )[ HI _ BYTE ] = (( UINT8 * ) &w1 )[ HI _ BYTE ] XOR (( UINT8 * )
&crc )[ LO _ BYTE ];
(( UINT8 * ) &crc )[ LO _ BYTE ] = (( UINT8 * ) &w1 )[ LO _ BYTE ];
// ConnId-Hi
w1=aCRCTab1 [(( UINT8 * ) &crc )[ HI _ BYTE ]];
w2=aCRCTab2 [ psPacket->au8Data [ size-1 ]];
w1=w1 XOR w2 ;
(( UINT8 * ) &crc )[ HI _ BYTE ] = (( UINT8 * ) &w1 )[ HI _ BYTE ] XOR (( UINT8 * )
&crc )[ LO _ BYTE ];
(( UINT8 * ) &crc )[ LO _ BYTE ] = (( UINT8 * ) &w1 )[ LO _ BYTE ];
// SeqNo-Lo
w1=aCRCTab1 [(( UINT8 * ) &crc )[ HI _ BYTE ]];
w2=aCRCTab2 [(( UINT8 * ) seqNo )[ LO _ BYTE ]];
w1=w1 XOR w2 ;
(( UINT8 * ) &crc )[ HI _ BYTE ] = (( UINT8 * ) &w1 )[ HI _ BYTE ] XOR (( UINT8 * )
&crc )[ LO _ BYTE ];
(( UINT8 * ) &crc )[ LO _ BYTE ] = (( UINT8 * ) &w1 )[ LO _ BYTE ];
// SeqNo-Hi
w1=aCRCTab1 [(( UINT8 * ) &crc )[ HI _ BYTE ]];
w2=aCRCTab2 [(( UINT8 * ) seqNo )[ HI _ BYTE ]];
w1=w1 XOR w2 ;
(( UINT8 * ) &crc )[ HI _ BYTE ] = (( UINT8 * ) &w1 )[ HI _ BYTE ] XOR (( UINT8 * )
&crc )[ LO _ BYTE ];
(( UINT8 * ) &crc )[ LO _ BYTE ] = (( UINT8 * ) &w1 )[ LO _ BYTE ];
// Command
w1=aCRCTab1 [(( UINT8 * ) &crc )[ HI _ BYTE ]];
w2=aCRCTab2 [ psPacket->au8Data [ OFFS _ COMMAND ]];
w1=w1 XOR w2 ;
(( UINT8 * ) &crc )[ HI _ BYTE ] = (( UINT8 * ) &w1 )[ HI _ BYTE ] XOR (( UINT8 * )
&crc )[ LO _ BYTE ];
(( UINT8 * ) &crc )[ LO _ BYTE ] = (( UINT8 * ) &w1 )[ LO _ BYTE ];
// CRCpartthatiscommonforallothercrc-calculationsissaved
crc _ common=crc ;
// Data [ 0 ]
w1=aCRCTab1 [(( UINT8 * ) &crc )[ HI _ BYTE ]];
w2=aCRCTab2 [ psPacket->au8Data [ OFFS _ DATA ]];
w1=w1 XOR w2 ;
(( UINT8 * ) &crc )[ HI _ BYTE ] = (( UINT8 * ) &w1 )[ HI _ BYTE ] XOR (( UINT8 * )
&crc )[ LO _ BYTE ];
(( UINT8 * ) &crc )[ LO _ BYTE ] = (( UINT8 * ) &w1 )[ LO _ BYTE ];
// if2 Byte Safetydata→calculatenext Byteintothecrc
if ( size > 6 )
{
// Data [ 1 ]
w1=aCRCTab1 [(( UINT8 * ) &crc )[ HI _ BYTE ]];
w2=aCRCTab2 [ psPacket->au8Data [ OFFS _ DATA+1 ]];
w1=w1 XOR w2 ;
(( UINT8 * ) &crc )[ HI _ BYTE ] = (( UINT8 * ) &w1 )[ HI _ BYTE ] XOR (( UINT8 * )
&crc )[ LO _ BYTE ];
(( UINT8 * ) &crc )[ LO _ BYTE ] = (( UINT8 * ) &w1 )[ LO _ BYTE ];
}
// UPDATE _ SEQ _ NO
seqNo [ 0 ] ++ ;
if ( seqNo [ 0 ] = =0 )
seqNo [ 0 ] ++ ;
} while ( crc = =oldCrc && ( bRcvDir & NEW _ CRC ) ! =0 ) ;
// aslongasresultingcrcisthesamelikeoldCrc
if ( bRcvDir )
// forreceivedirection
{
if ( (( UINT8 * ) &crc )[ HI _ BYTE ] = =pCrc [ OFFS _ CRC _ HI-OFFS _ CRC _ LO ]
&& (( UINT8 * ) &crc )[ LO _ BYTE ] = =pCrc [ 0 ] )
{
// forreceivedirection
// CRCiscorrect
bSuccess=TRUE ;
}
}
else
// forsenddirection
{
// insert Checksum
pCrc [ OFFS _ CRC _ HI-OFFS _ CRC _ LO ] = (( UINT8 * )
&crc )[ HI _ BYTE ];
pCrc [ 0 ] = (( UINT8 * )
&crc )[ LO _ BYTE ];
}
// if morethan2 Byte Safety Dataaretransferred ,
// CRC _ 1 andsoforth mustbecalculated
if ( size > 10 )
{
UINT16i =1 ;
pSafeData =pCrc+2 ;
// setpSafeDatatothe SafeData Low-Byte
// ofthenextpart=SafeData [ 2 ]
pCrc +=4 ;
// setpCrcto CRC _ i Low-Byte
size-=7 ;
// substractfirstpartoftheframe
while ( size >=4 )
// aslongasotherpartsfollow
{
// Start-CRC
crc=crc _ common ;
// this partisalreadycalculatedabove
// i ( Bit0-7 )
// calculateindex
w1=aCRCTab1 [(( UINT8 * ) &crc )[ HI _ BYTE ]];
w2=aCRCTab2 [(( UINT8 * ) &i )[ LO _ BYTE ]];
w1=w1 XOR w2 ;
(( UINT8 * ) &crc )[ HI _ BYTE ] = (( UINT8 * ) &w1 )[ HI _ BYTE ] XOR (( UINT8 * )
&crc )[ LO _ BYTE ];
(( UINT8 * ) &crc )[ LO _ BYTE ] = (( UINT8 * ) &w1 )[ LO _ BYTE ];
// i ( Bit8-15 )
w1=aCRCTab1 [(( UINT8 * ) &crc )[ HI _ BYTE ]];
w2=aCRCTab2 [(( UINT8 * ) &i )[ HI _ BYTE ]];
w1=w1 XOR w2 ;
(( UINT8 * ) &crc )[ HI _ BYTE ] = (( UINT8 * ) &w1 )[ HI _ BYTE ] XOR (( UINT8 * )
&crc )[ LO _ BYTE ];
(( UINT8 * ) &crc )[ LO _ BYTE ] = (( UINT8 * ) &w1 )[ LO _ BYTE ];
// Data2*i
w1=aCRCTab1 [(( UINT8 * ) &crc )[ HI _ BYTE ]];
w2=aCRCTab2 [ pSafeData [ 0 ]];
w1=w1 XOR w2 ;
(( UINT8 * ) &crc )[ HI _ BYTE ] = (( UINT8 * ) &w1 )[ HI _ BYTE ] XOR (( UINT8 * )
&crc )[ LO _ BYTE ];
(( UINT8 * ) &crc )[ LO _ BYTE ] = (( UINT8 * ) &w1 )[ LO _ BYTE ];
// Data2*i+1
w1=aCRCTab1 [(( UINT8 * ) &crc )[ HI _ BYTE ]];
w2=aCRCTab2 [ pSafeData [ 1 ]];
w1=w1 XOR w2 ;
(( UINT8 * ) &crc )[ HI _ BYTE ] = (( UINT8 * ) &w1 )[ HI _ BYTE ] XOR (( UINT8 * )
&crc )[ LO _ BYTE ];
(( UINT8 * ) &crc )[ LO _ BYTE ] = (( UINT8 * ) &w1 )[ LO _ BYTE ];
if ( (( UINT8 * ) &crc )[ HI _ BYTE ] = =pCrc [ 1 ]
&& (( UINT8 * ) &crc )[ LO _ BYTE ] = =pCrc [ 0 ] )
{
// CRCiscorrect
}
else
{
bSuccess=FALSE ;
if ( bRcvDir = =0 )
// forsenddirection
{
// insert Checksum
pCrc [ 1 ] = (( UINT8 * )
&crc )[ HI _ BYTE ];
pCrc [ 0 ] = (( UINT8 * )
&crc )[ LO _ BYTE ];
}
}
size
-=4 ;
// substractthis partoftheframe
pSafeData +=4 ;
// setto nextSafeData Low Byte
pCrc0
+=4 ;
// setto next CRC _ i Low Byte
i++ ;
// incrementIndex
}
}
returnbSuccess ;
}
aCrcTab1 : ARRAY [ 0..255 ] OF WORD : =
16#0000 , 16#39B7 , 16#736E , 16#4AD9 , 16#E6DC , 16#DF6B , 16#95B2 , 16# AC05 , 16#F40F , 16#CDB8 ,
16#8761 , 16#BED6 , 16#12D3 , 16#2B64 , 16#61BD , 16#580A , 16#D1A9 , 16#E81E , 16# A2C7 , 16#9B70 ,
16#3775 , 16#0EC2 , 16#441B , 16#7DAC , 16#25A6 , 16#1C11 , 16#56C8 , 16#6F7F , 16#C37A , 16#FACD ,
16#B014 , 16#89A3 , 16#9AE5 , 16# A352 , 16#E98B , 16#D03C , 16#7C39 , 16#458E , 16#0F57 , 16#36E0 ,
16#6EEA , 16#575D , 16#1D84 , 16#2433 , 16#8836 , 16#B181 , 16#FB58 , 16#C2EF , 16#4B4C , 16#72FB ,
16#3822 , 16#0195 , 16# AD90 , 16#9427 , 16#DEFE , 16#E749 , 16#BF43 , 16#86F4 , 16#CC2D , 16#F59A ,
16#599F , 16#6028 , 16#2AF1 , 16#1346 , 16#0C7D , 16#35CA , 16#7F13 , 16#46A4 , 16#EAA1 , 16#D316 ,
16#99CF , 16# A078 , 16#F872 , 16#C1C5 , 16#8B1C , 16#B2AB , 16#1EAE , 16#2719 , 16#6DC0 , 16#5477 ,
16#DDD4 , 16#E463 , 16# AEBA , 16#970D , 16#3B08 , 16#02BF , 16#4866 , 16#71D1 , 16#29DB , 16#106C ,
16#5AB5 , 16#6302 , 16#CF07 , 16#F6B0 , 16#BC69 , 16#85DE , 16#9698 , 16# AF2F , 16#E5F6 , 16#DC41 ,
16#7044 , 16#49F3 , 16#032A , 16#3A9D , 16#6297 , 16#5B20 , 16#11F9 , 16#284E , 16#844B , 16#BDFC ,
16#F725 , 16#CE92 , 16#4731 , 16#7E86 , 16#345F , 16#0DE8 , 16# A1ED , 16#985A , 16#D283 , 16#EB34 ,
16#B33E , 16#8A89 , 16#C050 , 16#F9E7 , 16#55E2 , 16#6C55 , 16#268C , 16#1F3B , 16#18FA , 16#214D ,
16#6B94 , 16#5223 , 16#FE26 , 16#C791 , 16#8D48 , 16#B4FF , 16#ECF5 , 16#D542 , 16#9F9B , 16# A62C ,
16#0A29 , 16#339E , 16#7947 , 16#40F0 , 16#C953 , 16#F0E4 , 16#BA3D , 16#838A , 16#2F8F , 16#1638 ,
16#5CE1 , 16#6556 , 16#3D5C , 16#04EB , 16#4E32 , 16#7785 , 16#DB80 , 16#E237 , 16# A8EE , 16#9159 ,
16#821F , 16#BBA8 , 16#F171 , 16#C8C6 , 16#64C3 , 16#5D74 , 16#17AD , 16#2E1A , 16#7610 , 16#4FA7 ,
16#057E , 16#3CC9 , 16#90CC , 16# A97B , 16#E3A2 , 16#DA15 , 16#53B6 , 16#6A01 , 16#20D8 , 16#196F ,
16#B56A , 16#8CDD , 16#C604 , 16#FFB3 , 16# A7B9 , 16#9E0E , 16#D4D7 , 16#ED60 , 16#4165 , 16#78D2 ,
16#320B , 16#0BBC , 16#1487 , 16#2D30 , 16#67E9 , 16#5E5E , 16#F25B , 16#CBEC , 16#8135 , 16#B882 ,
16#E088 , 16#D93F , 16#93E6 , 16# AA51 , 16#0654 , 16#3FE3 , 16#753A , 16#4C8D , 16#C52E , 16#FC99 ,
16#B640 , 16#8FF7 , 16#23F2 , 16#1A45 , 16#509C , 16#692B , 16#3121 , 16#0896 , 16#424F , 16#7BF8 ,
16#D7FD , 16#EE4A , 16# A493 , 16#9D24 , 16#8E62 , 16#B7D5 , 16#FD0C , 16#C4BB , 16#68BE , 16#5109 ,
16#1BD0 , 16#2267 , 16#7A6D , 16#43DA , 16#0903 , 16#30B4 , 16#9CB1 , 16# A506 , 16#EFDF , 16#D668 ,
16#5FCB , 16#667C , 16#2CA5 , 16#1512 , 16#B917 , 16#80A0 , 16#CA79 , 16#F3CE , 16# ABC4 , 16#9273 ,
16#D8AA , 16#E11D , 16#4D18 , 16#74AF , 16#3E76 , 16#07C1 ;
aCrcTab2 : ARRAY [ 0..255 ] OF WORD : =
16#0000 , 16#7648 , 16#EC90 , 16#9AD8 , 16#E097 , 16#96DF , 16#0C07 , 16#7A4F , 16#F899 , 16#8ED1 ,
16#1409 , 16#6241 , 16#180E , 16#6E46 , 16#F49E , 16#82D6 , 16#C885 , 16#BECD , 16#2415 , 16#525D ,
16#2812 , 16#5E5A , 16#C482 , 16#B2CA , 16#301C , 16#4654 , 16#DC8C , 16# AAC4 , 16#D08B , 16# A6C3 ,
16#3C1B , 16#4A53 , 16# A8BD , 16#DEF5 , 16#442D , 16#3265 , 16#482A , 16#3E62 , 16# A4BA , 16#D2F2 ,
16#5024 , 16#266C , 16#BCB4 , 16#CAFC , 16#B0B3 , 16#C6FB , 16#5C23 , 16#2A6B , 16#6038 , 16#1670 ,
16#8CA8 , 16#FAE0 , 16#80AF , 16#F6E7 , 16#6C3F , 16#1A77 , 16#98A1 , 16#EEE9 , 16#7431 , 16#0279 ,
16#7836 , 16#0E7E , 16#94A6 , 16#E2EE , 16#68CD , 16#1E85 , 16#845D , 16#F215 , 16#885A , 16#FE12 ,
16#64CA , 16#1282 , 16#9054 , 16#E61C , 16#7CC4 , 16#0A8C , 16#70C3 , 16#068B , 16#9C53 , 16#EA1B ,
16# A048 , 16#D600 , 16#4CD8 , 16#3A90 , 16#40DF , 16#3697 , 16# AC4F , 16#DA07 , 16#58D1 , 16#2E99 ,
16#B441 , 16#C209 , 16#B846 , 16#CE0E , 16#54D6 , 16#229E , 16#C070 , 16#B638 , 16#2CE0 , 16#5AA8 ,
16#20E7 , 16#56AF , 16#CC77 , 16#BA3F , 16#38E9 , 16#4EA1 , 16#D479 , 16# A231 , 16#D87E , 16# AE36 ,
16#34EE , 16#42A6 , 16#08F5 , 16#7EBD , 16#E465 , 16#922D , 16#E862 , 16#9E2A , 16#04F2 , 16#72BA ,
16#F06C , 16#8624 , 16#1CFC , 16#6AB4 , 16#10FB , 16#66B3 , 16#FC6B , 16#8A23 , 16#D19A , 16# A7D2 ,
16#3D0A , 16#4B42 , 16#310D , 16#4745 , 16#DD9D , 16# ABD5 , 16#2903 , 16#5F4B , 16#C593 , 16#B3DB ,
16#C994 , 16#BFDC , 16#2504 , 16#534C , 16#191F , 16#6F57 , 16#F58F , 16#83C7 , 16#F988 , 16#8FC0 ,
16#1518 , 16#6350 , 16#E186 , 16#97CE , 16#0D16 , 16#7B5E , 16#0111 , 16#7759 , 16#ED81 , 16#9BC9 ,
16#7927 , 16#0F6F , 16#95B7 , 16#E3FF , 16#99B0 , 16#EFF8 , 16#7520 , 16#0368 , 16#81BE , 16#F7F6 ,
16#6D2E , 16#1B66 , 16#6129 , 16#1761 , 16#8DB9 , 16#FBF1 , 16#B1A2 , 16#C7EA , 16#5D32 , 16#2B7A ,
16#5135 , 16#277D , 16#BDA5 , 16#CBED , 16#493B , 16#3F73 , 16# A5AB , 16#D3E3 , 16# A9AC , 16#DFE4 ,
16#453C , 16#3374 , 16#B957 , 16#CF1F , 16#55C7 , 16#238F , 16#59C0 , 16#2F88 , 16#B550 , 16#C318 ,
16#41CE , 16#3786 , 16# AD5E , 16#DB16 , 16# A159 , 16#D711 , 16#4DC9 , 16#3B81 , 16#71D2 , 16#079A ,
16#9D42 , 16#EB0A , 16#9145 , 16#E70D , 16#7DD5 , 16#0B9D , 16#894B , 16#FF03 , 16#65DB , 16#1393 ,
16#69DC , 16#1F94 , 16#854C , 16#F304 , 16#11EA , 16#67A2 , 16#FD7A , 16#8B32 , 16#F17D , 16#8735 ,
16#1DED , 16#6BA5 , 16#E973 , 16#9F3B , 16#05E3 , 16#73AB , 16#09E4 , 16#7FAC , 16#E574 , 16#933C ,
16#D96F , 16# AF27 , 16#35FF , 16#43B7 , 16#39F8 , 16#4FB0 , 16#D568 , 16# A320 , 16#21F6 , 16#57BE ,
16#CD66 , 16#BB2E , 16#C161 , 16#B729 , 16#2DF1 , 16#5BB9 ;
|