Forum: Compiler & IDEs Programmemory Byte für Byte abtasten?


von tobiTob (Gast)


Lesenswert?

Hi, wink

ich suche nun nach einer Möglichkeit den gesamten Programmemory einmal 
durchzuklappern. Eine ganz einfache Checksummer soll es werden. Da 
dieser Bereich ja immer 16bit breit ist also eine Adresse immer 2 Byte 
enthält verwendet man wohl die Routinen die man in der "pgmspace.h>" 
findet.

Warum liest er mir das so nicht ein?
bytpgm ist immer 0 :-(
1
calc_pgm_sum(void)
2
{
3
  uint8_t sum,bytpgm;
4
  uint16_t i;
5
6
  sum = 0;
7
    for (i=0;i<0x7000;i++) 
8
    {
9
    bytpgm = pgm_read_byte(&i);
10
    sum = sum ^ bytpgm;
11
    }
12
}

Hat jemand einen Tip?
Ist der Ansatz denn so falsch?


Gruß Tobi...

von Thorsten (Gast)


Lesenswert?

du lässt pgm_read_byte dauernd versuchen von der addresse von i was aus 
dem flash zu laden. das dürfte nach hinten losgehen.

versuchs mal das i ohne das "&" zu übergeben.

von Karl H. (kbuchegg)


Lesenswert?

tobiTob wrote:

>     for (i=0;i<0x7000;i++)
>     {
>     bytpgm = pgm_read_byte(&i);

Du willst sicher nicht 0x7000 mal vom Flash von der Speicherzelle
lesen, die zufällig die gleiche Adresse hat, wie i im SRAM.

Du willst dass der Inhalt von i als Adresse aufgefasst wird,
von der im Flash gelesen werden soll. D.h. die Adresse steht
in i.

      bytpgm = pgm_read_byte(i);

Das wird aber so nicht gehen, da i ein uint16_t ist, während
pgm_read_byte eine Adresse haben möchte. Also
muss umgecastet werden

      bytpgm = pgm_read_byte((uint8_t*)i);

von Karl H. (kbuchegg)


Lesenswert?

Allerdings:

Dein i hat die Aufgabe die Adresse zu speichern, von der als
nächstes aus dem Flash gelesen werden soll. Eine Variable, die
eine Speicheradresse aufnimmt, nennt man gemeinhin einen
Pointer.

Daher sollte man das auch so ausdrücken:
1
calc_pgm_sum(void)
2
{
3
  uint8_t sum,bytpgm;
4
  uint8_t* i;
5
6
  sum = 0;
7
  for( i = (uint8_t*)0; i < (uint8_t*)0x7000; i++ ) 
8
  {
9
    bytpgm = pgm_read_byte(i);
10
    sum = sum ^ bytpgm;
11
  }
12
}

Die cast sind leider notwendig, da 0x7000 einen Integer
darstellt und keine Adresse. Daher muss man das umcasten.

von Rolf Magnus (Gast)


Lesenswert?

> (uint8_t*)0

Beim AVR-GCC wird das vermutlich kein Problem sein, aber eigentlich ist 
es nicht ganz korrekt. Das erzeugt einen Nullpointer, der nicht zwingend 
mit einem Pointer auf Adresse 0 übereinstimmen muß.

von Jörg X. (Gast)


Lesenswert?

>> (uint8_t*)0
zeigt auf das Byte an Adresse 0, das ist noch kein NULL-Pointer à la
1
uint8_t *ptr =NULL;
welchen konkreten Wert ein NULL-pointer hat ist doch höchstens von 
"akademischem" Interesse, da man den ja garNICHT DEreferenzieren DARF.
Wenn_ NULL ein konkreter Wert _wäre, könnte man ja grundsätzlich in C 
(mindestens) eine Adresse nicht nutzen - das wäre eher unpraktisch.

sry --Jörg

von Karl H. (kbuchegg)


Lesenswert?

Jörg X. wrote:
>>> (uint8_t*)0
> zeigt auf das Byte an Adresse 0, das ist noch kein NULL-Pointer

doch das ist er.
Für 0 gibt es eine Ausnahme.

>
1
> uint8_t *ptr =NULL;
2
>

NULL ist auch nichts anderes. Nur durch das Makro verborgen.

> welchen konkreten Wert ein NULL-pointer hat ist doch höchstens von
> "akademischem" Interesse,

Im Prinzip ja.

> da man den ja garNICHT DEreferenzieren DARF.

das macht nichts. Er existiert. Und auch ein Nullpointer muss
ja einen Wert haben. Der muss nicht notwendigerweise 0 sein,
es könnte auch jeder andere Zahlenwert hergenommen werden.
Nur muss der Compiler sicherstellen, dass bei einer Zuweisung

    pPtr = 0;

genau dieser eine Wert für den Nullpointer benutzt wird. Das
gilt auch für Fälle wie

   pPtr = 1 - 1;

oder sontige Ausdrücke, die als Ergebnis 0 haben.

Allerdings: Ich kenne keine Plattform, auf der der Nullpointer-Wert
nicht 0 wäre.

> Wenn_ NULL ein konkreter Wert _wäre, könnte man ja grundsätzlich in C
> (mindestens) eine Adresse nicht nutzen

Genauso ist es.

von Karl H. (kbuchegg)


Lesenswert?

> da man den ja garNICHT DEreferenzieren DARF.

Nicht dürfen ist übertrieben.
Du hast halt 'undefined behaviour', welches ja auch
'funktioniert wie erwartet' beinhaltet.

von Jörg X. (Gast)


Lesenswert?

OK,
Danke für die Aufklärung Karl heinz

thx --Jörg

von Rolf Magnus (Gast)


Lesenswert?

> Das gilt auch für Fälle wie
>
>   pPtr = 1 - 1;
>
> oder sontige

... konstante Integer- ...

> Ausdrücke, die als Ergebnis 0 haben.

In folgendem Fall ist es anders, weil p nicht mit einer Konstanten 
initialisiert wird:
1
int x = 0;
2
char* p = x;

von tobiTob (Gast)


Lesenswert?

Hallo,

danke für die Hilfe, habe meine Lösung dadurch gefunden, nun kann es 
munter weiter gehen. ;-)

Was man alles so auslösen kann... duck

Gruß und wink Tobi...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.