Forum: Mikrocontroller und Digitale Elektronik 128KB-ATMegas: Adressierung anders?


von Dietmar (Gast)


Lesenswert?

Benutzen ATMegas mit 128KB Flash (z.B. ATMega 1284P) im Vergleich zu den 
64KB-Versionen (z.B. pinkompatibler ATMega 644) eine 24bit- oder 32-bit 
Adressierung statt 16bit - weil mit 16 bit nur 0-64K dargestellt werden 
können? Werden Binaries grösser? Oder ist der Speicher wortweise 
organisiert und Byte-Zugriff in C wird von gcc organisiert, so dass sich 
gar nichts ändert?

von (prx) A. K. (prx)


Lesenswert?

Das Flash wird wortweise adressiert, jedenfalls was Programmspeicher 
angeht. Daher wird es für den Code erst jenseits 128KB interessant. 
16-bit adressierte Daten sind natürlich nur in den ersten 64KB möglich, 
darüber sind schlicht andere Zugriffsfunktionen zuständig - transparent 
war das in avr-gcc ja sowieso nie.

Bei den 256KB Typen sorgt der Compiler dafür, dass alle Codeadressen, 
die irgendwie in Pointern landen könnten, in den ersten 128KB liegen. 
Notfalls steht da bloss ein Sprung nach hinten.

von Dietmar (Gast)


Lesenswert?

Der folgende Code aus einem Bootloader wird für eine 128KB ATMega 1284P 
mit einer Warnung übersetzt, die ich nicht verstehe:
1
// erase entire chip before first page is written
2
3
if (erased == false)
4
{
5
        uint8_t *erase;
6
7
        for (erase = NULL; erase < (uint8_t *)BOOTSTART; erase += SPM_PAGESIZE)
8
        {
9
                boot_page_erase((uint32_t)erase);
10
11
                boot_spm_busy_wait();
12
13
                boot_rww_enable();
14
        }
15
16
        erased = true;
17
}

../main.c:458: warning: cast from pointer to integer of different size

(das ist die Zeile mit boot_page_erase((uint32_t)erase)

Wenn man den Cast testweise durch boot_page_erase((uint16_t)erase) 
ersetzt (was keinen Sinn ergibt, da man in 16 bit keine Byte-Adressen in 
der Gegend von 128KB spezifizieren kann), ist die Warnung weg.

Jetzt frage ich micht: Was ist hier sizeof(uint8_t *)? Kann ich mir das 
vom Compiler irgendwie ausgeben lassen?

von (prx) A. K. (prx)


Lesenswert?

Dietmar schrieb:

> Jetzt frage ich micht: Was ist hier sizeof(uint8_t *)? Kann ich mir das
> vom Compiler irgendwie ausgeben lassen?

Pointer sind bei avr-gcc immer gleich gross, unabhängig vom Typ und 
unabhängig vom Controller. Bei AVR 2 Bytes. Auch bei 128K und 256K 
Versionen.

Ich würde mir eher Sorgen um den Vergleich
  erase < (uint8_t *)BOOTSTART
machen. "erase" kann nicht mehr als 64KB adressieren.

Umgang mit Flash-Adressen jenseits der ersten 64KB ist ein Minenfeld. 
Kann sein man kommt durch, kann sein es geht eine hoch. Der Compiler 
wird mit seinen Warnungen nur eine eher begrenzte Hilfe sein.

von Dietmar (Gast)


Lesenswert?

Danke für die Antwort. Das ist ja schrecklich ;)

von g457 (Gast)


Lesenswert?

> Jetzt frage ich micht: Was ist hier sizeof(uint8_t *)? Kann ich mir das
> vom Compiler irgendwie ausgeben lassen?

Das ist hier unerheblich, weil Du im Flash arbeiten willst. Theoretisch 
sollte boot_page_erase() hier auf __boot_page_erase_extended() umgebogen 
werden (und das wiederum auf das passende Assemblerfragment, das mit 
$viel Flash umgehen kann) - das will einen uint32_t (keinen Zeiger! und 
schon gar nicht auf einen uint8_t!). Ergo solltest Du auch nicht mit 
uint8_t* hantieren sondern mit uint32_t.

Lass doch mal den Präprozessor drüberlaufen um zu sehen, was der 
tatsächlich ersetzt. Wenn der nämlich __boot_page_erase_normal() nimmt, 
dann klappt das (natürlich) nicht, und das würde zur angeführten 
Fehlermeldung passen.

HTH

von g457 (Gast)


Lesenswert?

Nachtrag: 's? und schon gar nicht auf einen uint8_t!??g;'

Listigerweise wird der Flash tatsächlich byteweise adressiert.

</ingrid>

von Andreas F. (aferber)


Lesenswert?

Dietmar schrieb:
> Jetzt frage ich micht: Was ist hier sizeof(uint8_t *)? Kann ich mir das
> vom Compiler irgendwie ausgeben lassen?

Indirekt:
1
#include <stdint.h>
2
3
int
4
main(void)
5
{       
6
        static int a1[1-2*(sizeof(uint8_t *) <= 1)];
7
        static int a2[1-2*(sizeof(uint8_t *) <= 2)];
8
        static int a3[1-2*(sizeof(uint8_t *) <= 3)];
9
        static int a4[1-2*(sizeof(uint8_t *) <= 4)];
10
}

Kompilieren und schauen, bei welcher Zeile er sich als erstes beschwert, 
dass die Grösse des Arrays negativ ist (bei AVR: a2). In dieser Zeile 
steht dann die Grösse des Datentyps als Vergleichswert hinter dem "<=" 
(also hier dann 2). Aufsteigende Reihenfolge der Werte beachten!

Andreas

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.