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.
:
Bearbeitet durch User
Dein Memset-Problem ist wo anders, erhöhe mal die Granularität des Heaps von FreeRTOS auf minimum 4.
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 |
2 | [cc] using external linker script: |
3 | [cc] ================================================== |
4 | [cc] OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") |
5 | [cc] /* Internal Memory Map*/ |
6 | [cc] MEMORY |
7 | [cc] rom (rx) : ORIGIN = 0x08000000, LENGTH = 0x00100000 |
8 | [cc] { |
9 | [cc] ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00020000 |
10 | [cc] ram1 (rwx) : ORIGIN = 0x10000000, LENGTH = 0x00010000 |
11 | [cc] } |
12 | [cc] |
13 | [cc] _eram = 0x20000000 + 0x00020000; |
14 | [cc] /* Section Definitions */ |
15 | [cc] SECTIONS |
16 | [cc] { |
17 | [cc] .text : |
18 | [cc] { |
19 | [cc] KEEP(*(.isr_vector .isr_vector.*)) |
20 | [cc] *(.text .text.* .gnu.linkonce.t.*) |
21 | [cc] *(.glue_7t) *(.glue_7) |
22 | [cc] *(.rodata .rodata* .gnu.linkonce.r.*) |
23 | [cc] } > rom |
24 | [cc] |
25 | [cc] .ARM.extab : |
26 | [cc] { |
27 | [cc] *(.ARM.extab* .gnu.linkonce.armextab.*) |
28 | [cc] } > rom |
29 | [cc] |
30 | [cc] __exidx_start = .; |
31 | [cc] .ARM.exidx : |
32 | [cc] { |
33 | [cc] *(.ARM.exidx* .gnu.linkonce.armexidx.*) |
34 | [cc] } > rom |
35 | [cc] __exidx_end = .; |
36 | [cc] |
37 | [cc] . = ALIGN(4); |
38 | [cc] _etext = .; |
39 | [cc] _sidata = .; |
40 | [cc] |
41 | [cc] .data : AT (_etext) |
42 | [cc] { |
43 | [cc] _sdata = .; |
44 | [cc] *(.data .data.*) |
45 | [cc] . = ALIGN(4); |
46 | [cc] _edata = . ; |
47 | [cc] } > ram |
48 | [cc] |
49 | [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
B / BL sind die direkt-adress-codierten Varianten. BX / BLX sind die Varianten mit dem Register als Sprungziel.
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!
Hallo Michael, welche -march oder -mcpu Option wird in Deinem Fall verwendet (siehe Console Output)?
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 ?
gopher schrieb: > 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! Gern. -> http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0553a/BABEFHAE.html Da gibts ein Paar Besonderheiten die dir vielleicht entgangen sind bei ARMV7-M
:
Bearbeitet durch User
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.
gopher schrieb: > Hallo Michael, > > welche -march oder -mcpu Option wird in Deinem Fall verwendet (siehe > Console Output)? Hier mein Compileraufruf aus der Console: arm-none-eabi-gcc -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -Wall -ffunction-sections -g -O0 -DHSE_VALUE=8000000 -c -DSTM32F407VG -DSTM32F4XX -DUSE_STDPERIPH_DRIVER -D__ASSEMBLY__ -D__FPU_USED -ID:\controller\CoIDE_Workspace\workspace - ... ... [cc] Starting link [cc] arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -g -nostartfiles -Wl,-Map=rtostest.map -O0 -Wl,--gc-sections -Wl,--verbose -LP:\CooCox\CoIDE\configuration\ProgramData\rtostest -Wl,-TP:\CooCox\CoIDE\configuration\ProgramData\rtostest/arm-gcc-link.ld -g -o rtostest.elf '"C:\Program Files\arm-none-eabi-gcc-4_6\arm-none-eabi\lib\fpu\libc.a"' ..\obj\startup_stm32f4xx.o ..\obj\main.o ..\obj\stm32f4xx_rcc.o ..\obj\timers.o ..\obj\tasks.o ..\obj\stm32f4xx_gpio.o ..\obj\list.o ..\obj\system_stm32f4xx.o ..\obj\port.o ..\obj\queue.o ..\obj\croutine.o ..\obj\heap_1.o ..\obj\configuration.o "-LC:\Program Files\arm-none-eabi-gcc-4_6\arm-none-eabi\lib\fpu" -lm -lgcc -lc [cc] GNU ld (GNU Tools for ARM Embedded Processors) 2.21.1.20110908 [cc] Supported emulations:
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?
1 | [cc] Starting link |
2 | [cc] arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -g -nostartfiles |
3 | -Wl,-Map=rtostest.map -O0 -Wl,--gc-sections -Wl,--verbose |
4 | -LP:\CooCox\CoIDE\configuration\ProgramData\rtostest |
5 | -Wl,-TP:\CooCox\CoIDE\configuration\ProgramData\rtostest/arm-gcc-link.ld |
6 | -g -o rtostest.elf '"C:\Program |
7 | Files\arm-none-eabi-gcc-4_6\arm-none-eabi\lib\fpu\libc.a"' |
8 | ..\obj\startup_stm32f4xx.o ..\obj\main.o ..\obj\stm32f4xx_rcc.o |
9 | ..\obj\timers.o ..\obj\tasks.o ..\obj\stm32f4xx_gpio.o .. |
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.
Dein
> blx 0x8002e2c <memset> (**)
sieht aus, als ob -mcpu=cortex-A8 o.ä wirksam wäre...
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...
Michael: eher Thumb. Aber, woher weißt du was für ARMv7 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!!!!
|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
"Blindes Huhn, find auch mal 'n Korn würd ich sagen :)" ARM7 ist ein ARMv4. Der kann Thumb und ARM32, der BLX switcht da allerdings immer.
:
Bearbeitet durch User
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.
:
Bearbeitet durch User
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...
gopher: Kennst du "the definitive guide to the ARM Cortex-M3 second edition" ? http://haseebsohail.files.wordpress.com/2013/02/definitive-guide-to-arm-cortex-m3-2nd-edition.pdf#418
:
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.