NXP ARM7 CRC-Berechnung; C-Problem?

30/04/2010 - 20:06 von Roland Kuhn | Report spam
Hallo zusammen,

benötige wieder mal die Hilfe eines ARM7 bzw. C-Experten:
Ich arbeite mit dem Keil Evakuation-Board mit dem 2368 von NXP
und der Keil MDK Version 4.03.
In meiner Software habe ich die Wahl, aus Kompatibilitàtsgründen Daten über den
I2C-Bus in ein externes RAM oder in den FLASH des Controllers zu schreiben. Das Schreiben
und Lesen ins RAM funktioniert einwandfrei, der CRC wird richtig berechnet.

Das Speichern und Auslesen ins und aus dem FLASH funktioniert anscheinend ebenfalls
einwandfrei, nur bei der Berechnung des CRC nach dem Auslesen erhalte ich ein falsches Ergebnis und weiß
nicht, weshalb. Die Daten werden richtig geschrieben und auch wieder ausgelesen (jedenfalls lt. Debugger).

Wenn ich den CRC (ohne erneutes Schreiben oder Auslesen der Daten) 5 mal berechnen lasse, erhalte ich 3 unterschiedliche Ergebnisse.
Ich benutze haargenau die gleiche Routine und die gleichen Buffer wie bei der Berechnung über I2C.

Es werden im Flash keine Daten versehentlich überschrieben oder gelöscht.
Auch stehen sie im Memory-Bereich an der richtigen Adresse.
(Sie werden ja richtig ausgelesen.)

Wo ist der sch... Fehler?

Hat jemand eine Idee? Bin für jeden Hinweis oder Tip dankbar!


Freundlicher Gruß


Roland Kuhn


Hier mein Code (Auszüge):

//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#define START_ADRESS_DATA 0x00010000 // Startadresse Flashdaten

#define numFlash 512 // Blockgröße, Anzahl Bytes zum Schreiben

int i;

unsigned char rec_buf[numFlash];
unsigned char send_buf[numFlash];
long crc, crc_read;



for (i=0;i<236;i++) // den Sendebuffer zum Testen schreiben
{
send_buf[i]=(unsigned char) i;
}

send_buf[236]=0x00;

crc=crc32i(&send_buf[1],236); // CRC bis Byte 235 berechnen, Anmerkung: Routine ist i.o. und funktioniert
send_buf[237]=(char)((crc >> 24)& 0xFF); // CRC anhàngen
send_buf[238]=(char)((crc >> 16)& 0xFF); // statt char > unsigned char einstellen bringt nichts
send_buf[239]=(char)((crc >> 8)& 0xFF);
send_buf[240]=(char)(crc & 0xFF);


// hier die Daten über den I2C-Bus ins RAM schreiben, funktioniert einwandfrei
send_to_ram(send_buf); // Daten ins RAM schreiben
read_from_ram (rec_buf); // Daten aus RAM in rec_buf schreiben

crc=crc32i(&rec_buf[1],236); // CRC vom 1. Wert (nicht vom 0ten!) über 235 Bytes
// berechnen
crc_read= rec_buf[237];
crc_read=(crc_read<<8) | rec_buf[238];
crc_read=(crc_read<<8) | rec_buf[239];
crc_read=(crc_read<<8) | rec_buf[240];

// Beim echten Vergleich stimmen die CRCs überein, alles i.o.
if(crc!=crc_read) // wenn CRCs stimmen nicht übereinstimmen
{
// Fehlerroutine
}



// Jetzt die Routine zum Schreiben ins Flash

void write_flash(unsigned long FLASH_adr,unsigned char *buf)
{
prepare_sector(GetSecNum (FLASH_adr),GetSecNum (FLASH_adr+numFlash));
if(result[0]!=CMD_SUCCESS)
while(1);
command[0] = 51;
command[1] = FLASH_adr;
command[2] = (unsigned long)buf;
command[3] = numFlash;
command[4] = cclock;
dis_interrupt(); // Interrupts disablen
iap_entry(command,result);
en_interrupt();
}

void write_parm_to_flash() //
{
erase_sector(GetSecNum (START_ADRESS_DATA),GetSecNum (START_ADRESS_DATA+numFlash));
write_flash(START_ADRESS_DATA, send_buf);
}


// und die Daten wieder einlesen
for(i=0; i<241; i++) // aus Flash auslesen
{
rec_buf[i]=*((unsigned char*)START_ADRESS_DATA+i); // ab Adresse
}

// Die eingelesenen Werte im rec_buf stimmen mit denen im Sendepuffer überein

// Und jetzt kommts!

crc=crc32i(&rec[1],236); // Hier wird der CRC falsch berechnet!!!!!!!!!!

// Wenn ich den CRC 5 mal berechnen lasse, erhalte ich 3 unterschiedliche Werte

crc_read= rec_buf[237]; // Werte im Buffer sind in Ordnung!!!
crc_read=(crc_read<<8) | rec_buf[238];
crc_read=(crc_read<<8) | rec_buf[239];
crc_read=(crc_read<<8) | rec_buf[240];


if(crc!=crc_read) // hier stimmen die CRCs dann nicht überein
{
// Fehlerroutine
}

// Die Werte in crc_read sind die gleichen, wie die ins Flash geschriebenen
// wurden. Die sind mit den Werten in der Routine zum Schreiben ins RAM
// absolut identisch. Der CRC wird am Anfang also richtig berechnet.



// Hier die Routine zum Brechnen des CRC; ich habe bereits eine andere
//Routine verwendet, das Ergebnis ist das gleiche.

unsigned long crc32i(unsigned char *txt,int l) // Berechnung der Checksumme
{
int i,j;
int hbit,bit;
unsigned long crc32=0xffffffff;

for (i=0;i<l;i++)
{
for (j=0x01;j<=0x80;j=j<<1)
{
bit =(txt[i] & j) ? 1 :0;
hbit=(crc32 & 0x01) ? 1 : 0;
if (hbit != bit) crc32=(crc32>>1) ^ CRC32POLY;
else crc32=crc32>>1;
}
}
return (crc32^0xffffffff);
}

//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 

Lesen sie die antworten

#1 Dirk Ruth
01/05/2010 - 14:23 | Warnen spam
Roland Kuhnschrieb:
"
Hallo zusammen,

benötige wieder mal die Hilfe eines ARM7 bzw. C-Experten:
Ich arbeite mit dem Keil Evakuation-Board mit dem 2368 von NXP
und der Keil MDK Version 4.03.
In meiner Software habe ich die Wahl, aus Kompatibilitàtsgründen Daten über den
I2C-Bus in ein externes RAM oder in den FLASH des Controllers zu schreiben. Das Schreiben
und Lesen ins RAM funktioniert einwandfrei, der CRC wird richtig berechnet.

Das Speichern und Auslesen ins und aus dem FLASH funktioniert anscheinend ebenfalls
einwandfrei, nur bei der Berechnung des CRC nach dem Auslesen erhalte ich ein falsches Ergebnis und weiß
nicht, weshalb. Die Daten werden richtig geschrieben und auch wieder ausgelesen (jedenfalls lt. Debugger).

Wenn ich den CRC (ohne erneutes Schreiben oder Auslesen der Daten) 5 mal berechnen lasse, erhalte ich 3 unterschiedliche Ergebnisse.
Ich benutze haargenau die gleiche Routine und die gleichen Buffer wie bei der Berechnung über I2C.

Es werden im Flash keine Daten versehentlich überschrieben oder gelöscht.
Auch stehen sie im Memory-Bereich an der richtigen Adresse.
(Sie werden ja richtig ausgelesen.)

Wo ist der sch... Fehler?

Hat jemand eine Idee? Bin für jeden Hinweis oder Tip dankbar!



[...]

Ich hab das besagte Board nicht und kann deshalb den Code so auch
nicht nachvollziehen.

Warum machst du nicht mal beides parallel?
1. Daten ins Flash und ins RAM schreiben.
2. Ein Byte aus dem Flash lesen und mit crc() brerechnen.
3. Ein Byte von I2C lesen und mit crc1() (wie crc() ) berechen.
4. Die Ergebnisse von crc() und crc1() vergleichen und bei
Ungleichheit abbrechen. Weiter mit 6.
5. Weiter mit 2.
6. Debuggen.


Dirk

Ähnliche fragen