www.mikrocontroller.net

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


Autor: Dietmar (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Dietmar (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der folgende Code aus einem Bootloader wird für eine 128KB ATMega 1284P 
mit einer Warnung übersetzt, die ich nicht verstehe:
// erase entire chip before first page is written

if (erased == false)
{
        uint8_t *erase;

        for (erase = NULL; erase < (uint8_t *)BOOTSTART; erase += SPM_PAGESIZE)
        {
                boot_page_erase((uint32_t)erase);

                boot_spm_busy_wait();

                boot_rww_enable();
        }

        erased = true;
}

../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?

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Dietmar (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die Antwort. Das ist ja schrecklich ;)

Autor: g457 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: g457 (Gast)
Datum:

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

Listigerweise wird der Flash tatsächlich byteweise adressiert.

</ingrid>

Autor: Andreas Ferber (aferber)
Datum:

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

Indirekt:
#include <stdint.h>

int
main(void)
{       
        static int a1[1-2*(sizeof(uint8_t *) <= 1)];
        static int a2[1-2*(sizeof(uint8_t *) <= 2)];
        static int a3[1-2*(sizeof(uint8_t *) <= 3)];
        static int a4[1-2*(sizeof(uint8_t *) <= 4)];
}

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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.