/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
Checksums beregning i DLL
Fra : Søren


Dato : 19-03-02 16:38

Jeg skal have lavet et program til at snakke med noget hardware i VB6. Til
formålet skal der beregnes CRC 16 checksum af hver kommunikationsstreng
sendt mellem hardwaren og softwaren. Jeg har fået at vide at de funktioner
der benyttes virker bedst, når de laves i C++ og jeg håber derfor at en C++
programmør vil hjælpe mig med at få lavet en DLL jeg kan bruge fra VB6.

Jeg har følgende beskrivelse og pseudo kode til beregningen :

The CRC16 calculation is done from id no to the ETX, excl. the ETX.
This routine generates a CRC-16 forward remainder of ASCII
characters of 7 bit contained in 8 bit register.
CRCR is a 16 bit register which contains the result dynamically.
CRCP is a 16 bit register which contains the polynomium for the
standard X^16 + X^15 + X^2 + 1 = 1 1000 0000 0000 0101 binary.
The first bit is implicitly given in the carry, CRCP = 8005 hex.
CRCRhig = MSB CRCPhig = MSB = 80 hex
CRCRlow = LSB CRCPlow = LSB = 05 hex


Pseudo code for calculation:
Character string
start: SET CRCR = 0
>>>> Char. start: SET COUNTER = 7
SET TEMP = CHARACTER * 2
SET CRCRhig = CRCRhig <XOR> TEMP
>>> shift crcr: SET CRCR = CRCR * 2
IF no carry JUMP count shift >>
SET CRCR = CRCR <xor> CRCP
>> Count shift: SET COUNTER = COUNTER - 1
IF counter not zero JUMP shift crcr >>>
SET CHARACTER = next character
IF no end of string JUMP char. start >>>>


Kommunikationen mellem hardware og software, ser således ud :

Tx: <SOH>11<GS>003<GS>0<ETX>30206<EOT>
Rx: <SOH>11<STX>3<GS>000003227020310G 15042209503251002430000970000000
0000000000000003450000<ETX>64283<EOT>
Tx: <SOH>11<GS>003<GS>0<ETX>30206<EOT>
Rx: <SOH>11<STX>3<GS>000003227020310G 15042209503251002430000970000000
0000000000000003450000<ETX>64283<EOT>
Tx: <SOH>11<GS>003<GS>0<ETX>30206<EOT>
Rx: <SOH>11<STX>3<GS>000003228020310G 15042209503251002430000970000000
0000000000000003450000<ETX>64292<EOT>
Tx: <SOH>11<GS>003<GS>0<ETX>30206<EOT>
Rx: <SOH>11<STX>3<GS>000003228020310G 15042209503235002520000970000000

Checksummen beregnes ud fra decimal-ASCII værdien af hver karakter dvs.
1=049, 2=050 osv.
<STX> betyder Start of text og har værdien 002, så vidt jeg kan se.
<GS> står for tegnet group separator og har værdien 029.
Generelt er de tegn, som er omsluttet af "<>" oversat for at kunne vises.

Checksummen beregnes kun af noget af strengen, fra ID til ETX
dvs. I denne streng : <SOH>11<GS>003<GS>0<ETX>30206<EOT>
Beregnes checksummen af : <GS>003<GS>0
Tallet efter <SOH> (11) er ID'et.

Håber på hjælp.
Mvh.
Søren



 
 
Byrial Jensen (19-03-2002)
Kommentar
Fra : Byrial Jensen


Dato : 19-03-02 18:34

Søren <soren@FJERN_DETTEelisiussen.dk> skrev:
> Jeg skal have lavet et program til at snakke med noget hardware i VB6. Til
> formålet skal der beregnes CRC 16 checksum af hver kommunikationsstreng
> sendt mellem hardwaren og softwaren. Jeg har fået at vide at de funktioner
> der benyttes virker bedst, når de laves i C++ og jeg håber derfor at en C++
> programmør vil hjælpe mig med at få lavet en DLL jeg kan bruge fra VB6.

Jeg kan ikke se hvorfor det skulle virke bedre ved at være skrevet
i C++ end i andre sprog. Jeg bruger f.eks. jævnligt CRC-beregninger
som er skrevet i C, og det virker ganske udmærket.

Der er stort set 2 måder at kode det på: Den simple og direkte
beregning, og en hurtigere, men mere pladskrævende metode som
baserer sig på tabelopslag. Med lidt held vil du kunne finde frie
implementationer af begge slags på internettet.

Søren (19-03-2002)
Kommentar
Fra : Søren


Dato : 19-03-02 23:14


"Byrial Jensen" <bjensen@nospam.dk> wrote in message
news:slrna9etlb.2tp.bjensen@ask.ask...
> Der er stort set 2 måder at kode det på: Den simple og direkte
> beregning, og en hurtigere, men mere pladskrævende metode som
> baserer sig på tabelopslag. Med lidt held vil du kunne finde frie
> implementationer af begge slags på internettet.

Tjah, nu er mit problem imidlertid bare at jeg ikke selv ved nok om bit's
and byte's på det niveau til selv at lave det. Jeg synes jeg har ledt over
alt på nettet, men jeg kan ikke komme frem til en version, der fungerer i
dette tilfælde. Der er jo en hel masse forskellige variationer af CRC16
beregninger, men jeg håbede egentlig på at den rette mand - ud fra pseudo
koden ville kunne kode det i C++.

Mvh.
Søren



bop (22-03-2002)
Kommentar
Fra : bop


Dato : 22-03-02 21:48


"Søren" <soren@FJERN_DETTEelisiussen.dk> wrote in message
news:3c975b6f$0$60175$edfadb0f@dspool01.news.tele.dk...
> CRC 16

Tag et kig på

http://www.mit.edu/~yandros/doc/crc-intro

Teksten er en pragmatisk, grundig og letlæselig gennemgang af CRC og den er
sågar underholdende.

--
BopBopBop



Søren (22-03-2002)
Kommentar
Fra : Søren


Dato : 22-03-02 23:52

Tak for tippet, det vil jeg prøve.

Mvh.
Søren
"bop" <bop@bop.dk> wrote in message news:a7g59c$204t$1@news.cybercity.dk...
>
> "Søren" <soren@FJERN_DETTEelisiussen.dk> wrote in message
> news:3c975b6f$0$60175$edfadb0f@dspool01.news.tele.dk...
> > CRC 16
>
> Tag et kig på
>
> http://www.mit.edu/~yandros/doc/crc-intro
>
> Teksten er en pragmatisk, grundig og letlæselig gennemgang af CRC og den
er
> sågar underholdende.
>
> --
> BopBopBop
>
>



bop (23-03-2002)
Kommentar
Fra : bop


Dato : 23-03-02 12:43

"Søren" <soren@FJERN_DETTEelisiussen.dk> wrote in message
news:3c975b6f$0$60175$edfadb0f@dspool01.news.tele.dk...
> Pseudo code for calculation:
> Character string
> start: SET CRCR = 0
> >>>> Char. start: SET COUNTER = 7
> SET TEMP = CHARACTER * 2
> SET CRCRhig = CRCRhig <XOR> TEMP
> >>> shift crcr: SET CRCR = CRCR * 2
> IF no carry JUMP count shift >>
> SET CRCR = CRCR <xor> CRCP
> >> Count shift: SET COUNTER = COUNTER - 1
> IF counter not zero JUMP shift crcr >>>
> SET CHARACTER = next character
> IF no end of string JUMP char. start >>>>

Hej Søren,

Har du fået kigget lidt i crc_v3?

Funktionen kunne se sådan ud i c:

unsigned short int CRC16(char* data, int len)
{
unsigned short int crc;
int s;
int t;
for (s=len, crc=0; s-->0;)
{
for (t=7, crc ^= *data++ << 9; t-->0;)
crc = (crc & 0x8000) ? crc << 1 ^ 0x8005 : crc << 1;
}
return crc;
}

Funktionen adskiller sig fra en "almindelig CRC16" ved at
operere på 7-bit karakterer. Forskellen er linien

for (t=7, crc ^= *data++ << 9; t-->0;)

som ellers ville have set sådan ud

for (t=8, crc ^= *data++ << 8; t-->0;)


> Checksummen beregnes kun af noget af strengen, fra ID til ETX
> dvs. I denne streng : <SOH>11<GS>003<GS>0<ETX>30206<EOT>
> Beregnes checksummen af : <GS>003<GS>0
> Tallet efter <SOH> (11) er ID'et.

Med funktionen bliver checksummen af

11<GS>003<GS>0

beregnet til

30206

hvad strengen mellem <etx> og <eot> indikerer er korrekt. Du skal altså have
ID'et med i beregningen. Sådan fortolker jeg den engelske beskrivelse og det
giver da også mening.

Her følger en vejledning i at få lavet en DLL med funktionen.

- Put funktionen i en fil som du kalder (f.eks.) "crc16.c".

- Lav en fil samme sted som du kalder (f.eks.) "crc16.def" med følgende
indhold:

EXPORTS CRC16

- Hent Borlands BCC55 fra deres hjemmeside. Den er gratis, men du skal vist
lige registreres først. Installer og put bcc32.exe i stien.

- Kør denne kommandolinie:

bcc32 -p -WD -LC:\progra~1\borland\bcc55\lib crc16.c

-p er for at bruge pascal kaldekonvention. Hvad bruger VB? Du skal måske
bruge en anden. Det kommer du nok til at rode lidt med selv Her er dine
muligheder:

-p Use Pascal calling convention
-p- Use C calling convention
-pc Use C calling convention (Default: -pc, -p-)
-pm Functions without an explicit calling convention to use __msfastcall.
-pr Use fastcall calling convention for passing parameters in registers
-ps Use stdcall calling convention

-WD er for at fortælle linkeren at den skal lave en DLL.

-L... er for at fortælle linkeren hvor den kan finde filer til at linke en
DLL med. Hvis din installation er anderledes, så skal der seføli stå noget
andet i stien.

Hvis DLL'en skal bruges fra Delphi kan den importeres således:

function CRC16(s: PChar; len: Integer): Word; pascal; external 'crc16.dll';

forudsat kaldekonventionen stadig er pascal.

DLL'en skal naturligvis ligge i stien før programmet kan køres.

Importering i VB og resten af applikationen må du få nogen andre til at
lave. Rigtigt god fornøjelse med uddelegeringen af arbejde

--
BopBopBop



Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408925
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste