Programmemory Byte für Byte abtasten?

Gast #609215
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...
#609225
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);
#609237
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.
Gast #609597
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
#609650
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.
Gast #609736
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;

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren