Forum: Compiler & IDEs Multi-Core LPC5410x: Compiler/Linker Einstellungen


von N. G. (newgeneration) Benutzerseite


Lesenswert?

Hallo Forum,

(wer sich Vorgeplänkel sparen will springt direkt zu Frage hinter den 
--- )

ich bin gerade am Mikrocontroller LPC54102 von NXP dran. Dieser ist vor 
allem ein Cortex-M4 mit FPU, hat aber im Unterschied zu anderen µCs 
noch einen Koprozessor, einen Cortex-M0+.

Stand aktuell:
Ich will den Chip nicht nur benutzten, sondern verstehen. Dazu gehört 
auch, nicht nur in irgendeiner IDE (z.B. LPCxpresso) ein Projekt 
zusammenzuklicken, das dann hoffentlich so funktioniert.

Deswegen wolle ich "barebones" fahren, also mit Makefile, Linkerscript 
und alles was dazugehört

Stand aktuell: Der Cortex-M4F funktioniert so wie er soll, nun soll es 
an den Koprozessor gehen.
NXP hat sich dazu ein relativ einfaches Konzept einfallen lassen: 3 
Register steuern die beiden Cores:
- CPUCTRL: Entscheidet, welcher Core Master ist (bei mir der M4) und 
legt fest, ob die Clocks zu den beiden Cores aktiv sind
- CPBOOT: legt fest, wo die Start-Adresse vom Koprozessor ist
- CPSTACK: legt den Stackbeginn vom Koprozessor fest.

So, nun habe ich mich dazu entschieden, den Slavecode in den SRAM1 zu 
legen und den Stack vom Koprozessor ans Ende vom SRAM1.

Nun zum eigentlichen Problem:
Wie stelle ich den Compiler ein?
Das Linkerscript habe ich um diesen Bereich erweitert:
1
.slave_code : {
2
    _slave_code_start = .;
3
    KEEP(*(._slave_code))
4
    KEEP(*(._slave_code*))
5
    KEEP(*(._slave_data))
6
    KEEP(*(._slave_data*))
7
    _slave_code_end = .;
8
/*  ASSERT(!(_slave_code_start == _slave_code_end), "No Slave code provided!"); */
9
} > SRAM1 AT > Flash
(Das assert ist noch auskommentiert, sonst bricht der Linker ab)

Jetzt wäre es mir am liebsten, wenn ich den Code für den M0+ "ganz 
normal" programmmieren, also wie eine normale Anwendung. Aktuell müsste 
ich ja jede Funktion und jede Variable mit 
__attribute__((section("._slave_code"))) resp. "._slave_data" 
kennzeichnen. Aber das gefällt mir ehrlich gesagt nicht.

NXP hat auch Erklärungen zum Thema "Mutlicore Design", aber leider wird 
dort nur das vorgehen der LPCXpresso IDE erläutert (Link: 
https://community.nxp.com/message/630715).

---

Die Frage eigentliche ist: wie kann ich ein fertiges .elf-File (oder 
etwas anderes was der Linker ausspuckt) an eine bestimmte Section legen?

Fehlende Infos reiche ich gerne nach.

Mit freundlichen Grüßen,
N.G.

Links:
- Datasheet: http://www.nxp.com/documents/data_sheet/LPC5410X.pdf
- User manual: http://www.nxp.com/documents/user_manual/UM10850.pdf
- Dual Core Usage: 
http://www.nxp.com/documents/application_note/AN11609.zip

von Jim M. (turboj)


Lesenswert?

N. G. schrieb:
> Die Frage eigentliche ist: wie kann ich ein fertiges .elf-File (oder
> etwas anderes was der Linker ausspuckt) an eine bestimmte Section legen?

Cortex-M0+ Projekt als eigenes Projekt auslagern und an vorgesehene 
Addresse Linken, zum Schluss nach .bin konvertieren.

Das bin verfüttert man an arm-none-eabi-objcopy (siehe: 
http://stackoverflow.com/a/328137/410847) um es nach .o zu konvertieren. 
Dabei werden ein paar Symbole für den Linker rangepappt.

Dieses .o wird dann im Linker Skript des Haupt Projekts in die 
entsprechene Stelle Eingebunden.

von N. G. (newgeneration) Benutzerseite


Lesenswert?

Hallo Jim Meba,

ich bin deinem Vorschlag gefolgt.
Der aktuelle Stand sieht so aus:

Es gibt einen Projektordner mit einem übergeordneten Makefile. Dieses 
baut die beiden "Unterprojekte" in den Ordnern cortex-m0+ und cortex-m4.
Das Regel sehen so aus, dass das cortex-m0+-Projekt erst komplett als 
.elf gelinkt (so dass es im SRAM1 liegt) wird und dann mittels
1
arm-none-eabi-objcopy -Obinary cm0_code.elf cm0_code.bin
 in eine Binärdatei konvertiert wird.
Das Makefile für das cortex-m4-Projekt enthält dann eine Konversion in 
ein object-File:
1
arm-none-eabi-objcopy -Ibinary $< --binary-architecture ARM \
2
--rename-section .data=._slave_data \
3
--rename-section .text=._slave_code \
4
-O elf32-littlearm $@
Dieses Object wird dann normal dazugelinkt. Damit der Linker dieses 
object dann auch an die richtige Stelle packt, habe ich das linkerscript 
auf das folgende geändert:
1
. = ALIGN(4);
2
3
._slave_code : {
4
    _slave_code_start = .;
5
    KEEP(*(._slave_code))
6
    KEEP(*(._slave_code*))
7
    KEEP(*(._slave_data))
8
    KEEP(*(._slave_data*))
9
    _slave_code_end = .;
10
    ASSERT(!(_slave_code_start == _slave_code_end), "No Slave code provided!"); 
11
} > SRAM1 AT > Flash

Der startup-Code muss natürlich noch die Datan vom Flash in das SRAM1 
kopieren.

Das ganze sollte eigentlich funktionieren, zumindest ist im finalen 
Binary alles nötige enthalten.
Den Coprozessor habe ich noch nicht erfolgreich starten können, aber 
dieses Problem liegt wahrschleinlich wo anders.

Danke für deine Hilfe,
N.G.

: Bearbeitet durch User
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.