Hallo zusammen,
ich hoffe hier jemanden zu finden, der mit meiner Frage etwas anzufangen
vermag, wenn sie vielleicht auch "laienhaft" gestellt sein mag ;-)
Mein eigentliches Problem ist hier beschrieben:
Beitrag "CooCox problem mit memset"
Mittlerweile glaube ich aber nicht mehr, dass das Problem mit der
Einrichtung eines Heaps zu tun hat, da freeRTOS eine eigene
Speicherverwaltung implementiert die an malloc vorbei geht.
Im beigefügten Bild sieht man, dass der Program Counter vor dem Aufruf
von memset steht. Im Disassembly Window führt die Anweisung
blx 0x8002e2c <memset> (**)
dann zu einer Exception.
Die erste Frage
Im Cortex M4 Manual "PM0214 Programming manual" finde ich die BLX
Instruktion folgendermaßen beschrieben:
B{cond} label
BL{cond} label
BX{cond} Rm
BLX{cond} Rm
.
.
BLX Is branch indirect with link (register).
.
.
Also sollte ein BLX <label> (**) doch gar nicht existieren. Wieso setzt
mein Compiler diesen Befehl ab?
Die zweite Frage
Anderswo steht:
"if you generate a target address for a BX or BLX instruction, you must
ensure that bit[0]
of the address you generate is set to 1 for correct execution."
Bei mir ist die Target Adresse 0x8002e2c, also ist bit-0 nicht gesetzt.
Deshalb vermute ich mal ungeniert, dass das auch die Ursache für die
Exception ist, die ich erhalte, wenn das BLX ausgeführt wird. Trifft
diese Vermutung zu?
-> Falls ja, wie kann ich erreichen, dass der Compiler kein BLX absetzt,
bzw. was mache ich falsch und warum passiert das überhaupt?
Kann es sein, dass ich eine "falsche" c-Library verwende?
-> Falls ja, wo finde ich die richtige unter der arm-none-eabi-gcc-4_6
toolchain?
Ich wäre für eine Expertenantwort oder einen Tip sehr dankbar, da ich
schon zwei Tage an dieser Stelle hänge und nicht mehr weiß, was ich tun
soll ;-)
Liebe Grüße,
Michael
Denkst du daran, daß unterste Bit zu setzen in der Adresse ?
Der Cortex-Mx kann nur Thumb2 und das muß durch ein gesetztes Bit 0
signalisiert werden, sonst knallts.
Dennis Heynlein schrieb:> Denkst du daran, daß unterste Bit zu setzen in der Adresse ?> Der Cortex-Mx kann nur Thumb2 und das muß durch ein gesetztes Bit 0> signalisiert werden, sonst knallts.
Danke für die Antwort.
Mir ist klar dass es wohl aus diesem Grund knallt. Das Ergebnis ist aber
ein Code, den der c-Compiler abgesetzt hat. Wie kann ich das verhindern?
Dennis Heynlein schrieb:> Dein Memset-Problem ist wo anders, erhöhe mal die Granularität des Heaps> von FreeRTOS auf minimum 4.
und wo?
Ich finde nur im freeRTOSConfig.h:
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 40960 ) )
und das wird es ja wohl nicht sein, oder?
Übrigens: Was hat das mit dem nicht gesetzten Bit[0] zu tun?
ARM DDI 0403D (ARM ARMv7-M):
Branch with Link and Exchange calls a subroutine at an address and
instruction set specified by a register.
ARMv7-M only supports the Thumb instruction set. An attempt to change
the instruction execution state
causes the processor to take an exception on the instruction at the
target address.
ARM DDI 0406C.b (ARM ARMv7AR):
--------------
The BLX (immediate) instruction switches between ARM and Thumb states
and branches to the value written
to the PC. Its definition ensures that the value written to the PC is
correctly aligned for the new instruction
set state.
--------------
Hast Du den richtigen Core eingestellt?
irgendwo ist normalerweise ein
#define portBYTE_ALIGNMENT 8
Das Bit[0] ist eigentlich die Info für den Core daß er z.B. bei Bit[0]=0
ARM-Code oder bei Bit[0]=1 Thumb-Code ausführen muß.
Der Cortex-Mx hat aber nur Thumb(2)-Befehle und so ist ein Bit[0]=0 eine
Exception.
Dennis Heynlein schrieb:> welchen Heap nimmst du ?
Das ist das Problem aus dem ersten Posting: Ich habe keinen speziellen
Heap eingerichtet und weiß auch nicht, wie ich das tun soll, da ich
(noch) keine Linker Scripts schreiben kann.
Das ist jedenfalls das Default Script:
1
[cc] opened script file P:\CooCox\CoIDE\configuration\ProgramData\rtostest/arm-gcc-link.ld
[cc] /* .bss section which is used for uninitialized data */
50
[cc] .bss (NOLOAD) :
51
[cc] {
52
[cc] _sbss = . ;
53
[cc] *(.bss .bss.*)
54
[cc] *(COMMON)
55
[cc] . = ALIGN(4);
56
[cc] _ebss = . ;
57
[cc] } > ram
58
[cc]
59
[cc] /* stack section */
60
[cc] .co_stack (NOLOAD):
61
[cc] {
62
[cc] . = ALIGN(8);
63
[cc] *(.co_stack .co_stack.*)
64
[cc] } > ram
65
[cc]
66
[cc] . = ALIGN(4);
67
[cc] _end = . ;
68
[cc] }
Ich habe bisher noch nie einen expliziten Heap gebraucht. Wann braucht
man einen solchen und was hat das mit dem nicht gesetzten Bit[0] zu tun
?
Danke, Michael
Dennis Heynlein schrieb:> B / BL sind die direkt-adress-codierten Varianten.> BX / BLX sind die Varianten mit dem Register als Sprungziel.
Bitte nochmal bei ARM nachlesen!
X = Wechsel zwischen ARM und Thumb Mode!
Der Heap wird bei FreeRTOS immer durch Heap1.c - Heap4.c eingebunden. je
nach geschmack.
Es ist eine Eigenständige Allozierung an malloc vorbei.
Hast du den Core richtig auf Cortex-M3/4 eingestellt ?
Der OP hat vergessen den MCU Typ dem Linker mitzuteilen - der nimmt per
default den ARM statt Thumb Befehlssatz. Deshalb wird eine BLX
Instruktion generiert, denn das Ziel ist ARM Code.
Abhilfe ist die korrekte Angabe der Zielplatform auch für den Linker.
Dennis Heynlein schrieb:> Der Heap wird bei FreeRTOS immer durch Heap1.c - Heap4.c eingebunden. je> nach geschmack.> Es ist eine Eigenständige Allozierung an malloc vorbei.>> Hast du den Core richtig auf Cortex-M3/4 eingestellt ?
siehe den obigen Log aus der Console...
Ich verwende übrigens heap2.c
Jim Meba schrieb:> Der OP hat vergessen den MCU Typ dem Linker mitzuteilen - der nimmt per> default den ARM statt Thumb Befehlssatz. Deshalb wird eine BLX> Instruktion generiert, denn das Ziel ist ARM Code.>> Abhilfe ist die korrekte Angabe der Zielplatform auch für den Linker.
Hier ist doch der Linker mit -mcpu=cortex-m4 versorgt, oder?
Jim Meba schrieb:> Der OP hat vergessen den MCU Typ dem Linker mitzuteilen - der nimmt per> default den ARM statt Thumb Befehlssatz. Deshalb wird eine BLX> Instruktion generiert, denn das Ziel ist ARM Code.>> Abhilfe ist die korrekte Angabe der Zielplatform auch für den Linker.
Ausweislich seines Console Logs hat er das auch gemacht.
Michael: Bist Du Dir sicher, dass Du das richtige Image debuggst?
gopher schrieb:> Ändert trotzdem nix dran, dass "X" = exchange.
Ist es für dich nun klar, warum mein Fehler passiert?
Warum erzeugt der Compiler einen Change auf ARM ?
Kann es sein, dass die von mir verwendete lic.a für "ARM" statt "thumb"
generiert wurde, und der Compiler DESHALB den switch macht?
Michael W. schrieb:> gopher schrieb:>> Ändert trotzdem nix dran, dass "X" = exchange.>> Ist es für dich nun klar, warum mein Fehler passiert?> Warum erzeugt der Compiler einen Change auf ARM ?>
Nein, ist mir nicht. MMn machst Du alles richtig.
Lass' doch mal ein Listfile mit AssemblerOutput
erzeugen.
> Kann es sein, dass die von mir verwendete lic.a für "ARM" statt "thumb"> generiert wurde, und der Compiler DESHALB den switch macht?
Was ist lic.a? Oder sollte das libc.a heissen?
Nein, die Auswahl der richtigen Lib durch den Linker muss anhand der
-march oder -mcpu Option erfolgen.
gopher.
Wir können uns ja jetzt drüber Streiten. Aber der ARMv7-M versteht BLX
und er macht auch genau das was er soll.
Am untersten Bit der Sprungadresse bestimmt der ARM7 welcher
Instructionset an der Sprungadresse gilt.
Ein Bit[0]=ARM32, ein Bit[0]=Thumb(2).
Probiere es bitte selbst aus, ein Üblicher Cortex-M3/M4 reicht.
Und Michael, irgendwo hast du dem Compiler noch nicht klipp und klar
erklärt das es sich um einen Only-Thumb2 dreht.
Ein ARMv7-M muß ausgewählt werden, kein ARMv7-A oder -R.
gopher schrieb:> Ändert trotzdem nix dran, dass "X" = exchange.
Ist es für dich nun klar, warum mein Fehler passiert?
Warum erzeugt der Compiler einen Change auf ARM ?
Kann es sein, dass die von mir verwendete lic.a für "ARM" statt "thumb"
generiert wurde, und der Compiler DESHALB den switch macht?
gopher schrieb:> Was ist lic.a? Oder sollte das libc.a heissen?>> Nein, die Auswahl der richtigen Lib durch den Linker muss anhand der> -march oder -mcpu Option erfolgen.
Ich habe unter CooCox eine Link Maske (siehe Anhang).
Nehme ich die c-Library libc.a aus dem fpu Ordner des gcc lib
Vrzeichnisses, so habe ich mein aktuelles Problem.
Es gibt auch ein Verzeichnis "thumb", wo ebenfalls ein libc.a drin ist.
Das führt aber wieder zu einen Fehler (siehe Bild). Da gibt es aber
dutzende libc.a, libg.a, libnosys.a, etc... in verschiedensten
Verzeichnissen, sodass ich nicht weiß, welche die richtige ist...
Dennis Heynlein schrieb:> Und Michael, irgendwo hast du dem Compiler noch nicht klipp und klar> erklärt das es sich um einen Only-Thumb2 dreht.> Ein ARMv7-M muß ausgewählt werden, kein ARMv7-A oder -R.
Ok, das hat geholfen. Ich habe jetzt im Ordner armv7e-m/thumb eine
Version von libc.a gefunden, die kein BLX, sondern ein BL erzeugt. Nun
komme ich über den memset Befehl unbeschadet hinweg.
Was ist nun armv7e-m ? Ich habe nirgends eine Beschreibung gefunden und
nur nach Bauchgefühl gehandelt.
Wieso gibt es so viele verschiedene libc.a ? Mein vorheriges libc.a war
offenbar für einen ARM7 gedacht - sehe ich dies richtig?
Danke einmal!!!!
Dennis Heynlein schrieb:> |Cortex-M4 | -mthumb -mcpu=cortex-m4 | armv7e-m |> |(No FP) |--------------------------------------------| |> | | -mthumb -march=armv7e-m | |> |----------|--------------------------------------------|----------|> |Cortex-M4 | -mthumb -mcpu=cortex-m4 -mfloat-abi=softfp | armv7e-m |> |(Soft FP) | -mfpu=fpv4-sp-d16 | /softfp |> | |--------------------------------------------| |> | | -mthumb -march=armv7e-m -mfloat-abi=softfp | |> | | -mfpu=fpv4-sp-d16 | |> |----------|--------------------------------------------|----------|> |Cortex-M4 | -mthumb -mcpu=cortex-m4 -mfloat-abi=hard | armv7e-m |> |(Hard FP) | -mfpu=fpv4-sp-d16 | /fpu |> | |--------------------------------------------| |> | | -mthumb -march=armv7e-m -mfloat-abi=hard | |> | | -mfpu=fpv4-sp-d16 |>>> https://launchpadlibrarian.net/151487295/readme.txt
OK, das macht Sinn...
Im Nachhinein klar ;-) Wieder mal zwei Tage unnötig vergeudet...
Diese Tabelle kannte ich nicht.
Ich hoffe, dass das RTOS nun auch funktioniert und werde morgen gleich
testen. Was hat es mit der Aktivierung des Heaps auf sich? Ich habe
keinen expliziten Heap eingereichtet, da ich angenommen habe, dass ich
das bei Heap2.c nicht brauche (malloc wird nicht verwendet). Oder etwa
doch?
Danke !!!
FreeRTOS handhabt seine Speicheranforderungen über Heapx.c .
Mal ein Statisches Array, mal eine Wrapper (heap3)
Die Größe des Arrays gibste in der FreeRTOS-Config an.
Les es ruhig selbst :)
http://www.freertos.org/a00111.html
Ein Vorteil ist dann, der Speicher kann auch im CCM liegen.
Michael W. schrieb:> gopher schrieb:>> Ändert trotzdem nix dran, dass "X" = exchange.>> Es gibt auch ein Verzeichnis "thumb", wo ebenfalls ein libc.a drin ist.> Das führt aber wieder zu einen Fehler (siehe Bild). Da gibt es aber
Die Meldung "uses VFP..." ist auch ein Indiz, dass Cortex-Ax wirksam
ist,
Cortex-M4 hat zwar eine FPU, aber keinen VFP (Vector Floating Point)
> dutzende libc.a, libg.a, libnosys.a, etc... in verschiedensten> Verzeichnissen, sodass ich nicht weiß, welche die richtige ist...
....
>Ein ARMv7-M muß ausgewählt werden, kein ARMv7-A oder -R.
Das sollte aber eine zwangsläufige Folge von -mcpu=cortex-m4 sein...
Noch ein Tip:
Es gibt Tools wie (arm-none-eabi...)-objdump, -readelf, -nm etc. (die
auch bei einer Windows-Installation von GCC verfügbar sein sollten), die
über den Inhalt eines Objects oder eine Lib Auskunft geben...