Forum: Compiler & IDEs Adresse einer Funktion / eines Programmteils festlegen?


von Sebastian Voitzsch (Gast)


Lesenswert?

Hallo,

wie kann ich in C den Beginn einer Funktion bzw. eines ganzen
Programmteils festelgen? In Assembler gibt's dafür ja .org (in welcher
Syntax nun auch immer).

Konkret: ich möchte einen Bootloader schreiben. Da ich aber gerne die
Firmware von CF laden möchte, komme ich mit dem Bootloader alleine
nicht aus (FAT & Dir in 2K wird mir etwas eng). Idee dazu: die Firmware
selbst holt sich die von der Datei firmware.bin belegten Cluster, legt
diese im Ram ab und springt den Bootloader an. Dieser lädt die
entsprechenden Cluster und flashed die Firmware. Der Bootloader muß
dann nur noch die Routine readSector(ulong lba) enthalten - das paßt
wunderbar in 2K.

Also muß ich

- den Bootloader-Teil an Adresse 0x1C00 (z.B.) verschieben (ATmega162)
- die readSector(ulong lba) mag ich nicht zweimal im Flash haben. Wenn
ich deren Adresse fixieren kann, können beide Firmware-Teile die
Funktion benutzen. Wie geht dieses?

Danke,
Sebastian

von Joerg Wunsch (Gast)


Lesenswert?

Du weißt, daß der AVR eine Harvward-Architektur hat?

von Matthias (Gast)


Lesenswert?

Hi

schau mal in die Doku der AVR Libc. Da stehts drin wie man das macht.
(Stichwort section) Das Problem bei deiner Idee ist nur das der
Bootloader auf eine funktionierende Hauptapplikation angewiesen ist. Ob
das eine so gute Idee ist?

@Joerg
Wo da die Harvard-Architektur mit reinspielt ist mir unklar. Wenn man
seine Frage allerdings so interpretiert das die Firmware bei jedem
Start von der CF kommen soll machen die möglichen Schreibzyklen evtl.
Probleme.

Matthias

von Sebastian Voitzsch (Gast)


Lesenswert?

@Matthias:

Wenn savannah.gnu.org nur endlich wieder vernünftig laufen würde... Die
GNU Menneken sollten mal über ein vernünftiges Mirror-Konzept
nachdenken. 4 Wochen Downtime ist eindeutig zuviel! Mal gucken, ob ich
irgendwo noch eine lokale Kopie der libc-Doku habe. Aber danke für das
Stichwort "section"!

Das mit der funktionierenden Firmware ist wahr, aber das ist kein
Riesenproblem. Ich benutze das für eine Bastelei (MP3-Player, die
1023ste ;O)). Wenn die Firmware vollends schrott ist, kann ich den
Player noch immer aufschrauben und ein ISP-Kabel dranpappen. Da ich
aber 2 Player habe, ist die CF-Methode schon ganz nett - sobald einer
funktioniert, kann der zweite ohne Aufschrauben geupdatet werden.

@Jörg:

<Harvard-Architektur: getrennte Daten- und Programmspeicher> Ich
verstehe Deinen Hinweis offensichtlich nicht. Der AVR bietet
Unterstützung für einen Bootloader, dieser kann über alle erdenklichen
Quellen die Firmware beziehen und ins Flash schreiben; meist (auch in
der Atmel-AN) passiert das per serieller Schnittstelle. Ich will die
Daten nun einfach aus der CF holen. Wo soll das Problem sein? Da ich
nicht die ganze Firmware ins RAM bekomme, und auch keinen kompletten
Bootloader incl. FAT und Directory-Zugriff in 2K (Bootloader-Bereich),
wollte ich einen Mittelweg gehen und die FAT- und Directory-Routinen in
der (Haupt)-Firmware unterbringen. Was habe ich Deiner Meinung nach
übersehen?

Danke,
Sebastian

von Joerg Wunsch (Gast)


Lesenswert?

Wenn Du WinAVR hast, hast Du die Doku ohnehin lokal.

Sorry, ich hatte das mit dem RAM so verstanden, daß Du die Firmware
aus dem RAM abarbeiten willst.  Dem ist wohl nicht so, aber das war
mir nicht gleich verständlich.

von Sebastian Voitzsch (Gast)


Lesenswert?

Hallo nochmal,

die Doku habe ich gefunden, den Abschnitt in der FAQ auch. Entsprechend
habe ich meine CF-Routinen deklariert:

unsigned char CFReadSector(unsigned long lba) _attribute_
((section(".bootloader")))

Im Makefile habe ich --section-start zugefügt:
LDFLAGS=-Wl,--section-start=.bootloader=0x3C00,-Map=mymp3.map

Der komplette Aufruf des Linkers sieht so aus:
avr-gcc -mmcu=atmega162
-Wl,--section-start=.bootloader=0x3C00,-Map=mymp3.map -o mymp3.out *.o

Mache ich jetzt aber ein
avr-objdump -d mymp3.out | grep CFRead

bekomme ich:
000001a0 <CFReadSector>:
000003bc <CFReadAdr>:
000003da <CFRead>:

Hmm, weiß jemand, was da schiefgelaufen ist?

Danke,
Sebastian

von Sebastian Voitzsch (Gast)


Lesenswert?

Hab' den Fehler gefunden. Ich hatte die Deklaration im .c-File
geändert, die im .h-File aber nicht. Jetzt funktionierts und meine
CF-Routinen landen im bootloader-Bereich.

Sebastian

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.