Hallo, Ich nutze für ein Projekt mit einem dsPIC den C30-Compiler von Microchip, welcher auf dem GCC basiert. Folgendes Problem habe ich: Ich möchte etwas Code (I/O-Initialisierungen usw.) vor der RAM-Initialisierung ausführen. Wie kann ich hier am einfachsten vorgehen? Folgendes habe ich bereits versucht: 1. Ich habe eine eigene Section im Linker-Script geschaffen "io_init" und versucht eine Methode in diese Section per Attribut abzulegen. Dies funktioniert auch soweit, scheitert allerdings daran, dass der Compiler zum Ende der Methode einen "return"-Befehl erzeugt. Das Programm kann dadurch nicht funktionieren, da der Stack zu diesem Zeitpunkt noch gar nicht verfügbar ist. Ich habe keine Möglichkeit gefunden, den Compiler an der Erzeugung dieses Befehls zu hindern. (Eine Möglichkeit wie "naked" beim avr-gcc scheint es beim C30 nicht zu geben.) 2. Ich habe versucht meine I/O-Initialisierung direkt in Maschinensprache selbst zu schreiben. Dabei kann ich natürlich nach Belieben Befehle weglassen. Aber hier kommt das nächste Problem: Der Assembler erlaubt nur ".section .text". Schreibe ich jedoch ".section .io_init" gibt er mir zu verstehen, dass er Code nicht im Datenbereich ablegen könne. Wer weiß Rat? Am besten würde es mir gefallen, wenn ich die Initialisierung selbst auch gleich in C schreiben könnte und nur die Erzeugung des "return"-Befehls irgendwie umgangen würde. Microchip hat eine Section "user_init" vorgesehen. Diese ist allerdings Unsinn, da sie unmittelbar vor "main" aufgerufen wird. Die ganzen statischen Variablen usw. sind dann allerdings schon initialisiert. Liebe Grüße, Michael
Soweit erinnert (kenne C30 nur aus Dokumentation) wird der Quellcode der Startupsequenz mitgeliefert. Diesen Quellcode (in crt0.S?) als Vorlage nehmen um den Aufruf der eigenen Initialisierung ergänzen. Falls Initialisierung in C geschrieben ist, vor dem Aufruf zumindest Stackpointer setzen. Eigene Startupdatei in Projekt/Makefile aufnehmen, assemblieren und linken. In der Map-Datei nachsehen, ob tatsächlich der eigene Startupcode gelinkt wurde und nicht der aus einer Library. Falls eigener nicht gelinkt wurde, Linkerreihenfolge und Linkeroptionen prüfen.
Hallo Martin, Vielen Dank für deinen Tipp! Der ist echt Gold wert. In der Datei "crt0_standard.s", welche sich im ZIP-Archiv "libpic30.zip" im Unterverzeichnis "src" des C30-Installationsverzeichnises befindet, steht folgender Code:
1 | mov #__has_user_init,w0 |
2 | cp0 w0 ; user init functions? |
3 | bra eq,1f ; br if not |
4 | call __user_init ; else call them |
5 | 1: |
Diesen habe einfach von seiner bisherigen Stelle kurz vor dem Aufruf von "main" unmittelbar hinter die Initialisierung des Stack-Pointers verschoben, zum Projekt hinzugefügt, assembliert und neu gelinkt. Funktioniert wunderbar! Durch die Abfrage davor gibt es noch nicht einmal einen Linkerfehler wenn die Methode im C-Code nicht existiert. Und am Linker-Script muss auch nichts geändert werden. Die Methode muss dafür natürlich in der richtigen Section stehen:
1 | __attribute__((section(".user_init"))) void init(void) |
So habe ich es mir vorgestellt. Nochmals Danke. Liebe Grüße, Michael
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.