Forum: Compiler & IDEs Problem mit Division


von Olaf (Gast)


Lesenswert?

Ich hab hier einen nRF51 Bluetoohcontroller, also einen Cortex-M0

Verwendeter Compiler:
COLLECT_GCC=/usr/local/cross//bin/cross-arm-gcc
COLLECT_LTO_WRAPPER=/usr/local/cross/libexec/gcc/arm-none-eabi/4.7.4/lto 
-wrapper
Ziel: arm-none-eabi
Konfiguriert mit: ../gcc-4.7.4/configure --target=arm-none-eabi 
--prefix=/usr/local/cross --program-prefix=cross-arm- 
--enable-languages=c --with-gnu-as --with-gnu-ld --with-newlib 
--with-checking=release --enable-obsolete
Thread-Modell: single
gcc-Version 4.7.4 (GCC)

Ich kann damit relativ komplexe und umfangreiche Beispielsourcen 
uebersetzen die auch funktionieren. Also bluetoothverbindung, softdevice 
alles super.

Beim einbinden von eigenen Code zu Ansteuerung eine LCDs ist mir aber 
aufgefallen das sich das Programm sehr brutal und endgueltig weghaengt.
Das ist natuerlich insoweit doof weil ich mir dann auch keine Variablen
anzeigen lassen kann.

Ich konnte das soweit runterbrechen das ich den Fehler nun mit anderem 
Code an anderer Stelle reproduzieren kann:

int main(void)
{   volatile int rem;
    volatile int base;

    //LEDs initialisieren
    leds_init();

    rem = 6;
    base = 10;

    set_greenled();

    rem = rem % base; //Problem1
    rem = rem / base; //Problem2

    set_blueled();
}

Wenn sich eine der beiden Problemzeilen im Code befindet dann wird zwar 
meine gruene TestLED eingeschaltet, aber nicht mehr die blaue.

Das finde ich ja sehr erstaunlich das so eine einfache Sache 
fehlschlagen kann. Besonders weil die richtig dicken Beispielsourcen von 
Nordic funktionieren.
Jetzt waere ja der Moment gekommen mal den Debugger zu starten. Leider 
funktioniert der noch nicht richtig. (andere Baustelle) Ausserdem 
muesste ich mich dann wohl erstmal in den ARM-Assemblerdialekt 
einlesen.(seufz)

Seht ihr in den CFLAGS fuer den Cortex-M0 irgendeinen Fehler:

#flags common to all targets
CFLAGS  = -DSOFTDEVICE_PRESENT
CFLAGS += -DNRF51
CFLAGS += -DS110
CFLAGS += -DBOARD_PCA10031
CFLAGS += -DBLE_STACK_SUPPORT_REQD
CFLAGS += -mcpu=cortex-m0
CFLAGS += -mthumb -mabi=aapcs --std=gnu99
#CFLAGS += -Wall -Werror -O3
CFLAGS += -Wall  -O3
CFLAGS += -mfloat-abi=soft
CFLAGS += -ffunction-sections -fdata-sections -fno-strict-aliasing
CFLAGS += -flto -fno-builtin
CFLAGS += -DSPI_MASTER_0_ENABLE

LDFLAGS += -Xlinker -Map=$(LISTING_DIRECTORY)/$(OUTPUT_FILENAME).map
LDFLAGS += -mthumb -mabi=aapcs -L $(TEMPLATE_PATH) -T$(LINKER_SCRIPT)
LDFLAGS += -mcpu=cortex-m0
LDFLAGS += -Wl,--gc-sections
# use newlib in nano version
#LDFLAGS += --specs=nano.specs -lc -lnosys
LDFLAGS +=  -lc -lnosys

Ich hab die Flags im Prinzip so von Nordic uebernommen. Allerdings hab 
ich leider keine nanolib. Ich denke aber nicht das dies ein Problem
sein sollte oder? Ich denke jedenfalls nicht das ich derzeit ein Problem 
mit Ram oder Flashgroesse habe.

Kann es sein das mein Compiler fuer den Cortex-m0 einen bug mit soetwas 
banalem wie eine division hat? Das kann ich mir eigentlich garnicht 
vorstellen.

Olaf

von Olaf (Gast)


Angehängte Dateien:

Lesenswert?

Es ist mir doch noch gelungen den gdb zu nutzen. Der scheint probleme zu 
haben wenn man das softdevice nutzt, aber bei dem einfach zu 
repoduzierenden Problem benoetige ich das ja nicht.

  Anmerkung: Softdevice ist eine sehr grosse Libary von Nordic die nur 
als
             Binaerfile vorliegt.

So konnte ich gerade das mal im Debuger nutzen.

Bild1 zeigt den C-Source. Bei Zeile 90 schalte ich dann auf die 
Assemblerdarstellung um.
Beim ausfuehren des Befehlt an der Adresse 0x114e mit si gibt es dann 
wohl einen Fehler und ich lande in Bild3.

Wieso gibt es da eine undefined instruction an Adresse 0x12cc?

Sagt das jemanden etwas? Ab da gibt es dann naemlich einen hardfault.

Olaf

von Mathe (Gast)


Lesenswert?

Braucht er eine Mathe-Lib für die Division?
#include<math.h> ?

von Jim M. (turboj)


Lesenswert?

Nutzt Du "gcc" als Linker Frontend oder den LD direkt? In letzterem 
Falle wird die flashce C-Lib eingebunden - ARM ist ja Multi-Lib.

Das ist hier mit dem "_from_thumb" mit einiger Sicherheit der Fall, denn 
der Cortex-M0 Kern kann keinen ARM Code ausführen - was er aber laut 
Bild3 tun soll (bx pc ist die Umschaltsequenz).

Das ist eine fiese Falle bei den Cortex-M, die man am Einfachsten durch 
Verwendung von "-gcc" als Linker Frontend umschiffen kann.

von Olaf (Gast)


Lesenswert?

Hm...der Aufruf (fuer meine Testsoftware) sieht so aus:

Linking target: nrf51422_xxac.out
"/usr/local/cross//bin/cross-arm-gcc" -Xlinker 
-Map=_build/nrf51422_xxac.map -mthumb -mabi=aapcs -L ./toolchain 
-Tlcdtester_nrf51.ld -mcpu=cortex-m0 -e main  -Wl,--gc-sections -lc 
-lnosys -g _build/gcc_startup_nrf51.o _build/system_nrf51.o 
_build/spi_master.o _build/app_timer.o _build/app_timer_appsh.o 
_build/app_error.o _build/app_scheduler.o _build/lcdg.o _build/spi.o 
_build/uc1611.o _build/main.o _build/nrf_delay.o  -o 
_build/nrf51422_xxac.out

> Falle wird die flashce C-Lib eingebunden - ARM ist ja Multi-Lib.

Und das aeussert sich dann nur bei der Division?

Ich kann irgendein Beispiel von Nordic uebersetzen und dann ueber 
Bluettooth z.B den AD-Wandler auslesen oder LEDs umschalten und da 
werden zum Teil Dutzende von Sourcefiles angezogen und uebersetzt.

Ausserdem ist mein Makefile im Prinzip eine Kopie von Nordic. Ich hab 
lediglich ihren ausufernden Sourcebaum etwas zusammengestrichen.

Wobei ich jetzt nicht sagen will das du da nicht recht hast. Ich hab mir 
den Compiler selber uebersetzt und da mag es irgendeinen Sonderfall 
geben. Dafuer wuerde auch sprechen das ich jetzt erstmals Code fuer 
einen Cortex-M0 erzeuge, bisher waren das alles M3.

Wenn ich das aber oben richtig interpretiere dann nutze ich den gcc zum 
linken.

Olaf

von Olaf (Gast)


Lesenswert?

> Braucht er eine Mathe-Lib für die Division?
> #include<math.h> ?

Ich wuerde erwarten das es dann eine Fehlermeldung gibt.
Ich hab es aber trotzdem mal ausprobiert und auch noch libm dazugelinkt, 
keinen Unterschied.

Olaf

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Mathe schrieb:
> Braucht er eine Mathe-Lib für die Division?
> #include<math.h> ?

Das eine Header-Datei und keine Library.

Und da es nur um simple Integer-Arithmetik geht, ist math.h komplett 
überflüssig, denn das ist für komplexere Float-Operationen nötig, die 
über die Grundrechenarten hinausgehen.

von Olaf (Gast)


Lesenswert?

Es gab im uebrigen schonmal jemanden mit diesem Problem:

https://gcc.gnu.org/ml/gcc-help/2012-12/msg00021.html

..aber eine Loesung hab ich bisher auch nicht gefunden.

Meine Idee war eigentlich mir nochmal eine Testversion des Compilers zu 
uebersetzen und dann mit den Kommandozeilen-parameter zu spielen.
Interessantweise bekomme ich jetzt noch nichtmal den Crosscompiler 
uebersetzt obwohl ich die Befehle einfach von der der letzten 
Uebersetzung erneut ausfuehren lasse.

make[1]: Entering directory 
`/usr/src/CrossCompiler/Cross_arm/arm-elf-gcc/gcc'
gcc -c   -g -O2 -DIN_GCC -DCROSS_DIRECTORY_STRUCTURE  -W -Wall 
-Wno-narrowing -Wwrite-strings -Wcast-qual -Wstrict-prototypes 
-Wmissing-prototypes -Wmissing-format-attribute -pedantic -Wno-long-long 
-Wno-variadic-macros -Wno-overlength-strings -Wold-style-definition 
-Wc++-compat   -DHAVE_CONFIG_H -DGENERATOR_FILE -I. -Ibuild 
-I../../gcc-4.7.4/gcc -I../../gcc-4.7.4/gcc/build 
-I../../gcc-4.7.4/gcc/../include -I../../gcc-4.7.4/gcc/../libcpp/include 
-I../../gcc-4.7.4/gcc/../libdecnumber 
-I../../gcc-4.7.4/gcc/../libdecnumber/dpd -I../libdecnumber    \
        -o build/genconstants.o ../../gcc-4.7.4/gcc/genconstants.c

/usr/local/cross/arm-none-eabi/bin/as: unrecognized option '--64'

Irgendwie habe ich den Eindruck je aelter Linux wird umso mehr naehert 
es sich dem gequirlten Windwosmist an weil die Systeme immer fetter und 
fetter werden und es praktisch keiner mehr durchschaut. Seufz.

Olaf

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

arm-elf-gcc ist auch falsch.
Den nutzt man um ARM Programme für Linux zu bauen.

Eigentlich nutzt man den arm-none-eabi-gcc für embedded.
Was dein cross-arm-gcc ist weis ich nicht, den hab ich noch nie 
verwendet.

Irgendwie sieht das so aus als würde er die falsche libgcc.a einbinden.
Nämlich eine für "vollwertige ARM Befehle" statt Thumb Befehle.

Gib doch daher mal einen festen Pfad zur libgcc an, die passende libgcc 
für thumb liegt im thumb Ordner wo deine libgcc sich tummeln.
(Bei mir unter \lib\gcc\arm-none-eabi\7.2.1\thumb\v6-m)
Wie Jim Meba schon anmerkte sieht das "from thumb" SEHR verdächtig aus.

: Bearbeitet durch User
von Olaf (Gast)


Lesenswert?

Das Problem hab ich geloest:

/usr/local/cross/arm-none-eabi/bin/as: unrecognized option '--64'

War ein falscher $PATH. Dadurch wurde beim compilieren der falsche as 
aufgerufen.

> arm-elf-gcc ist auch falsch.

Guter Hinweis! Das muss ich gestern schon mal versehentlich gerade 
gebogen haben. arm-elf-gcc ist noch ein anderer Compiler der hier gar 
nicht benutzt werden sollte.

> Was dein cross-arm-gcc ist weis ich nicht, den hab ich noch nie
> verwendet

Nun ja, das ist halt meine Bezeichnung. Bei mir heissen alle 
Crosscompiler so.
Nachdem compilieren wieder klappt hab ich gestern Abend mal einen 
Testcompiler komplett neu erzeugt. Ich hab da mal ein kleines bisschen 
aufgeraeumt. Der Aufruf zum compiler sieht so aus:


[olaf] ~/sources/nRF51822/source/lcd_tester: crosstest-arm-gcc -v
Es werden eingebaute Spezifikationen verwendet.
COLLECT_GCC=crosstest-arm-gcc
COLLECT_LTO_WRAPPER=/usr/local/cross/libexec/gcc/arm-none-eabi/4.7.4/lto 
-wrapper
Ziel: arm-none-eabi
Konfiguriert mit: ../gcc-4.7.4/configure --target=arm-none-eabi 
--build=x86_64-redhat-linux --host=x86_64-redhat-linux 
--prefix=/usr/local/cross --program-prefix=crosstest-arm- 
--enable-languages=c --with-newlib --with-checking=release 
--enable-interwork --enable-multilib
Thread-Modell: single
gcc-Version 4.7.4 (GCC)

Das Problem ist geblieben, sieht aber etwas anderes aus. Ich muss da 
gleich noch ein paar Bilder machen die das zeigen...

Olaf

von Olaf (Gast)


Angehängte Dateien:

Lesenswert?

Ich hab noch mal ein paar Bilder der Debugsession gemacht. Ich denke da
sieht man mehr als wenn ich hier nur text reinkopiere.

Bild4.gif Zeigt noch den C-Source kurz bevor ich auf Assembler 
umschalte.

Bild5.gif Zeigt wie der Compiler die Register mit den Werten fuer die 
Division füllt und dann zur Divisionsroutine springt.

Bild6.gif Das ist jetzt in der Divisionsroutine. Und bereits hier steht
          meiner Meinung nach totaler Unsinn.

Bild7.gif Und weil das Unsinn ist gibt es nun einen Hardfault
Bild8.gif aber man bekommt einen Hinweis wo der Code herbekommt!


Bild9.gif zeigt den Source vom gcc, oder besser der gcclib wo Code 
angeblich
          herstammt. Ich finde der Source sieht gut aus, aber das was 
der
          compiler daraus macht ist totaler Quatsch.

Wieso wird aus cmp r1,#0 im Source ein movs r0,r0 im Debugger?

Es kann doch im Leben kein Bug im Compiler sein. Eine Defekte 
Divisionsroutine waere doch niemals durch irgendwelche Tests vor der 
Veroeffentlichung gekommen und selbst wenn, drei Minuten nach der 
Veroeffentlichung haette das ganze Internet aufgeschrien.

An einen falschen Parameter bei mir wuerde ich ja gerne glauben. Aber er 
betrifft auschliesslich nur cortex-m0 und nur die Division? Ich kann ja 
richtig komplexen Code fuer den m0 erzeugen solange ich niemals 
dividiere und ich kann mit dem selben Compiler problemlos laufende 
Programme fuer m3 (Gecko,STM32F103) erzeugen wo dann auch dividiert 
wird.

Olaf

von Olaf (Gast)


Lesenswert?

Ich hab gerade nochmal kontrolliert das der Compiler wirklich die 
richtige libgcc.o reinpackt und das dies auch wirklich eine beim letzten 
compilieren neu erzeugte Version ist. Alles korrekt.

Dann hab ich die Libary mal ausgepackt und mir den Assemblercode 
angeschaut:

_divsi3.o:     file format elf32-littlearm


Disassembly of section .text:

00000000 <__divsi3>:
   0:   e3510000        cmp     r1, #0
   4:   0a000043        beq     118 <.divsi3_skip_div0_test+0x110>

00000008 <.divsi3_skip_div0_test>:
   8:   e020c001        eor     ip, r0, r1
   c:   42611000        rsbmi   r1, r1, #0
[..]

Das sieht gut und richtig aus. Ehrlich gesagt jetzt bin ich ratlos.

Schaut man sich jetzt mal die Bytes im Debugger an:
(gdb) x 0x115c
0x115c <__divsi3>:      0xe3510000
(gdb) x 0x115e
0x115e <__divsi3+2>:    0x0043e351

Sieht das gut aus. Aber wie kann es sein das der Debugger daraus...

0x115c <__divsi3>       movs   r0, r0
0x115e <__divsi3+2>     b.n    0x1804

..macht. movs und cmp sind doch total unterschiedliche Befehle!
Und auch der Sprungbefehl im Debugger ist ganz anders.

Olaf

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Das sieht doch schon besser aus.
Deim Debuggen darfste -O2 nicht angeben.
Optimiert debuggen geht einfach nicht ;)

Ein mov ->S<- setzt auch die Statusflags des ARM Kerns, dadurch erkennt 
er auch ob r0 0 ist oder nicht.
Das sogenannte S-Bit.
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0204j/Cihcdbca.html
Aber er darf nicht einfach das Register ändern und dann dauerhaft 
branchen.

Aber Debugge doch erstmal ohne -O2.

Kannste mal das elf von da oben in den Anhang packen?

von Kai (Gast)


Lesenswert?

Hi,

Ich denke, Dein Problem mag hiermit zusammenhängen (wie auch immer):
http://infocenter.arm.com/help/topic/com.arm.doc.faqs/ka12545.html

Wenn ich es richtig verstehe, gibt man im bit[0] der Adresse an, ob ARM 
oder Thumb instruction set.

Der M0 schmiert mit INVSTATE ab, wenn ARM ausgeführt werden soll.

Auf Deinen Fall angewendet, sollte der Sprung 115d sein, und nicht 115c.

Also geht etwas schief:
 * Beim Compilieren mit Thumb
 * Beim Linken mit Thumb
 * Eine Lib, die nicht für Thumb compiliert wurde, und Du diese dazu 
linkst
 * Bei LTO

Schalt mal LTO aus. Punkt 3 glaub ich nicht.

Schon mal einen nicht selbt compilierten armgcc genommen ?

Gruß N2

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

@Kai
Das abstrahiert der Debugger weg.
Wenn das das Problem wäre, dann würde der Programmablauf ja nichtmal zum 
"divsi3+2 b.n" kommen.

von Olaf (Gast)


Lesenswert?

> Aber Debugge doch erstmal ohne -O2.

Die Beispiele hier sind mit -O0 uebersetzt. Ich hatte das wohl ganz oben 
kurz nach dem ersten Post selbst bemerkt.

So sieht der compileaufruf fuer main.c aus:

Compiling file: main.c
"/usr/local/cross//bin/cross-arm-gcc" -DNRF51 -DBOARD_PCA10031 
-DBSP_DEFINES_ONLY -mcpu=cortex-m0 -mtune=cortex-m0 -mthumb -mabi=aapcs 
--std=gnu99 -Wall  -O0 -g -mfloat-abi=soft -ffunction-sections 
-fdata-sections -fno-strict-aliasing -flto  -fno-gcse 
-DSPI_MASTER_0_ENABLE -I./toolchain -c -o _build/main.o main.c

> Kannste mal das elf von da oben in den Anhang packen?

Wovon genau? main.o?

> Schalt mal LTO aus. Punkt 3 glaub ich nicht.

Hab ich gerade mal auskommentiert. Macht keinen Unterschied.

> Wenn ich es richtig verstehe, gibt man im bit[0] der Adresse an, ob ARM
> oder Thumb instruction set.

Du meinst das hier:
 -mthumb-interwork
 Generate code that supports calling between the ARM and Thumb 
instruction
 sets. Without this option, on pre-v5 architectures, the two instruction
 sets cannot be reliably used inside one program. The default is
 -mno-thumb-interwork, since slightly larger code is generated when
  -mthumb-interwork is specified. In AAPCS configurations this option
 is meaningless.

Das Flag hab ich beim Compilerbau gesetzt. Liest sich auch irgendwie als 
wenn man das haben sollte und es nicht schaden koennte.

Ich wollte eigentlich als naechstes dasselbe Testprogramm fuer einen 
cortex-m3 uebersetzen wo ich weiss das es dort funktioniert und dann mal 
vergleichen....
Und eigentlich muesste man sich mal die Doku vom ARM-Assembler 
reinziehen. Meine Faehigkeiten sind leider bei Z80,68k und MCS51 
stehengeblieben. Wer denkt denn auch das man dies nach dem Jahr 2000 
noch mal brauchen wuerde. :-D

Was ich nicht verstehe, wenn es solche Basisprobleme gibt, wie kann es 
sein das alles funktioniert bis auf die Division.

Olaf

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Der m3 hat ja meist ne Hardware Division.
Was jetzt genau auf dem m0 schiefgeht seh ich noch nicht, da muss noch 
weiter gebohrt werden.

Die elf Datei ist das was aus dem Linker rausfällt.
Ich will mir das mal im dump angucken was da rauskommt.

Häng doch noch nen bissel mehr hier ran:
Makefile und die C Datei auchnoch.
Dann compilier ich das auch mal bei mir.

DIe Quickreference sollte erstmal reichen für ARM:
http://infocenter.arm.com/help/topic/com.arm.doc.qrc0001m/QRC0001_UAL.pdf

von Olaf (Gast)


Lesenswert?

> Der m3 hat ja meist ne Hardware Division.

Ja, ist mir gerade auch aufgefallen:

0x34a6 <main+34>        ldr    r2, [r7, #4]
0x34a8 <main+36>        ldr    r3, [r7, #0]
0x34aa <main+38>        sdiv   r3, r2, r3
0x34ae <main+42>        str    r3, [r7, #4]
0x34b0 <main+44>        mov.w  r0, #1
0x34b4 <main+48>        bl     0x30a8 <led_2>

Da wird die Routine garnicht erst angesprungen.

> Die elf Datei ist das was aus dem Linker rausfällt.
> Ich will mir das mal im dump angucken was da rauskommt.

Ich leg es gleich bei mir auf den Server. Als Anhang vielleicht etwas 
dick.

> Dann compilier ich das auch mal bei mir.

Hm..problem ist das dieses Projekt etwas dicker ist. Das benutze ich 
zwar jetzt alles nicht weil ich direkt am Anfang des main bin, aber ich 
muss das erst noch etwas eindampfen. Ich melde mich gleich...

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Ich dacht das wär alles schon eingedampft?
Deine kleine main sieht jedenfalls danach aus.

Wenn man sowas ekeligem auf der Spur ist, dann immer ein Minimalbeispiel 
bauen.

von Olaf (Gast)


Angehängte Dateien:

Lesenswert?

So, hab es doch mal hochgeladen.

Hab dabei alles aus dem Code geworfen was unoetig ist.

Das Problem laesst sich damit genauso reproduzieren, habe ich gerade
noch getestet. Allerdings springt jetzt der Sprung in der divsi Routine 
in anderen wilden code rein und brauchst dort 5-6Befehle laenger bis zum 
hardfault.

Das Verzeichnis ist so wie bei mir direkt nach dem make. Alles 
objektfiles, mapfile usw liegt in _build.

Der Sourcecode in toolchain sollte bis auf startup nicht genutzt werden, 
aber das ist alles nordic-standardkram.

Olaf

von Olaf (Gast)


Lesenswert?

Fuer eigene Versuche wird man im makefile mindestens das hier anpassen 
muessen:

GNU_INSTALL_ROOT := /usr/local/cross/
GNU_VERSION := 4.7.4
GNU_PREFIX := cross-arm

Olaf

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Angehängte Dateien:

Lesenswert?

GNU_VERSION muss ich nicht angeben, das wird nirgends benutzt.
Warum auch immer das Makefile nen absoluten Pfad zu den GCC bins 
braucht, dafür gibts die PATH Variablen im OS.

Die "nrf51422_xxac.out" ist bei dir das elf welches man sich mit dem 
objdump ansehen kann.
DivisionsProblem\_build> arm-none-eabi-objdump -d nrf51422_xxac.out > 
disasm.s
Also häng mal deine "kaputte" nrf51422_xxac.out hier an.

Der Anfang von __divsi3 sieht bei mir auch ganz anders aus, der springt 
nämlich nicht gleich ins nirvana, siehe Anhang disasm.s.

Im Anhang mal mein compilat zum Testen.

edit:
ich seh ja grade, dass die alte .out schon dabei war.

Deine libgcc ist immernoch falsch, aber anders falsch.
Alle Befehle sind 32Bit breit, also ist es immernoch nicht das thumb 
__divsi3.

haste kein thumb Ordner in den Libs und kannst dem gcc mal dazu zwingen 
den zu nutzen?

haste beim gcc bauen das hier angegeben?
MULTILIB_OPTIONS     += marm mthumb
MULTILIB_DIRNAMES    += arm thumb

: Bearbeitet durch User
von Olaf (Gast)


Lesenswert?

> Im Anhang mal mein compilat zum Testen.

Werde ich gleich machen. Kann aber noch was dauern....

> ich seh ja grade, dass die alte .out schon dabei war.

Sollte alles dabei sein. Ich hatte ein

make clean
make

gemacht und dann mit dem was ich dir geschickt habe den Fehler 
ueberprueft.

> Deine libgcc ist immernoch falsch, aber anders falsch.
> Alle Befehle sind 32Bit breit, also ist es immernoch nicht das thumb
> __divsi3.

Ich hatte geprueft was der Compiler nimmt. Er zieht beim uebersetzen 
dieses File hier an:
l /usr/local/cross/lib/gcc/arm-none-eabi/4.7.4/thumb/libgcc.a
-rw-r--r--. 1 root 5,0M  2. Apr 08:01 
/usr/local/cross/lib/gcc/arm-none-eabi/4.7.4/thumb/libgcc.a

Du siehst es liegt im Thumb-verzeichnis und wurde heute morgen erst 
erstellt als ich den Compiler uebersetzt habe.

Ich habe dann genau diese Libary auch zerlegt und _divsi3.o 
disassembliert. Das Ergebnis davon hast du als divsi.dis.txt in dem 
Verzeichnis von mir.

> haste beim gcc bauen das hier angegeben?
> MULTILIB_OPTIONS     += marm mthumb
> MULTILIB_DIRNAMES    += arm thumb

Sowas hab ich hier nicht. So hab ich den Compiler heute morgen 
configuriert:

../gcc-4.7.4/configure          --target=arm-none-eabi \
    --build='x86_64-redhat-linux'  --host='x86_64-redhat-linux' \
    --prefix='/usr/local/cross' \
    --program-prefix='cross-arm-' \
    --enable-languages=c,c++ \
    --with-newlib --disable-nls \
    --with-checking=release \
    --enable-interwork \
    --enable-multilib

Aber wie du oben siehst liegt die Libary ja in einem thumb 
Unterverzeichnis. Es gibt ausserdem noch eine weitere libgcc.a die eine 
Ebene hoeher liegt. Ich bin bisher davon ausgegangen das eine fuer thumb 
ist und die auch verwendet wird und eine andere.

Jetzt will ich ja auch SEHR gerne glauben das ich am Compiler noch was 
falsch konfiguriert habe. Genauer gesagt vor dem Hintergrund das die 
gcclib ja auch zum Compiler gehoert, liegt der Gedanke ja geradezu nahe. 
Aber sollte der Compiler dann nicht alles falsch uebersetzen?

Ich melde mich nachher nochmal sobald ich mit der Datei von dir gespielt 
habe.

Olaf

von Jim M. (turboj)


Lesenswert?

Olaf schrieb:
> Aber wie du oben siehst liegt die Libary ja in einem thumb
> Unterverzeichnis. Es gibt ausserdem noch eine weitere libgcc.a die eine
> Ebene hoeher liegt. Ich bin bisher davon ausgegangen das eine fuer thumb
> ist und die auch verwendet wird und eine andere.

Da müssen vieeel mehr Dateien rumfliegen.

Hier z.B. gibt es extra Unterverzeichnisse "armv6-m" für Cortex-M0 neben 
"armv7-m" und "armv7e-m", letzteres hat dann noch 2 Unterverzeichnisse 
für FPU und SoftFP.

Ist vielleicht Deine Version zu alt? Mein Gnu ARM Embedded - das vom 
Silabs Simplicity Studio - liefert Version 4.9.3. Müsste es IIRC auch 
für Linux geben.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Nur der Unterdner thumb ist falsch, es muss wie Jim Meba sagt noch 
weiter runter gehen, weiter oben hatte ich ja schonmal nen passenden 
Pfad gepostet.
Für den m0 wäre es dieser Ordner:
\lib\gcc\arm-none-eabi\7.2.1\thumb\v6-m
Wie man sieht nutz ich auch schon einen viel neueren GCC, ka wieso du 
noch die alte 4.7er Gurke nutzt ;)

interessanterweise habe ich unter \thumb auch eine libgcc.a
Disassembliert hat die auch ein __divsi3 welches ausschließlich 32Bit 
Befehle nutzt (interessant).
Ein __modsi3 wiederum ist thumb.
Da verlässt mich so langsam meine Kenntniss, aber diese libgcc ist wohö 
für ARM Kerne die 32Bit ARM und thumb können.

In \thumb\v6-m die disassemblierte libgcc.a nutzt dann ausschließlich 
thumb.


Ist jetzt die Frage:
Gibt es denn v6-m Unterordner bei dir nicht oder nimmt der GCC diesen 
nur einfach nicht.

von Olaf (Gast)


Lesenswert?

Also zunaechst mal, deine Version geht. Ich hab zwar nur assembler 
gesehen, aber es ist zu sehen wie er erst die gruene LED einschaltet, 
fehlerlos durch die Divisionsroutine laeuft und danach die blaue LED 
einschaltet.

Aber eigentlich wissen wir jetzt nur das mein Compiler da irgendeinen 
Mist baut und deiner nicht. :)

> Da müssen vieeel mehr Dateien rumfliegen.

Ach? Ich dachte eine Libary von 5MB ist schon was fettes.

So sieht das hier aus:

[olaf] /usr/local/cross/lib/gcc/arm-none-eabi/4.7.4: du
8       ./install-tools/include
20      ./install-tools
20      ./include/ssp
556     ./include
76      ./plugin/include/c-family
132     ./plugin/include/config/arm
164     ./plugin/include/config
8       ./plugin/include/ada/gcc-interface
8       ./plugin/include/ada
280     ./plugin/include/cp
4       ./plugin/include/java
4       ./plugin/include/objc
4132    ./plugin/include
4764    ./plugin
5088    ./thumb
5104    ./fpu
12      ./include-fixed
20632   .

> Hier z.B. gibt es extra Unterverzeichnisse "armv6-m" für Cortex-M0 neben
> "armv7-m" und "armv7e-m", letzteres hat dann noch 2 Unterverzeichnisse
> für FPU und SoftFP.

Sowas gibt es hier nicht. Aber das mag sich ja bei neueren 
Compilerversionen auch mal geaendert haben.

> Müsste es IIRC auch für Linux geben.

Ich wuerde schon gerne was eigenes verwenden weil ich den Compiler auch 
fuer ein halbes Dutzend weitere Controller verwende und es nett ist wenn 
der Compiler auf demselben Versionsstand ist.

Ich hab heute Vormittag auch mal probiert einen neueren zu uebersetzen.
Genauer gesagt einen 4.8.5er. Was neueres wollte ich nicht verwenden 
weil der System-GCC bei redhat ebenfalls ein 4.8.5er ist. Und auch das 
ist schon
daran gescheitert das mich der Compiler mit hunderten von eigenartigen 
Fehlermeldungen beworfen hat.

Grundsaetzlich sollte es aber moeglich sein einen 4.7.4er zu verwenden.

Hier beschreibt im uebrigen jemand anderes wie er so einen compiler 
erzeugt:

https://xathrya.id/2015/12/11/building-gcc-arm-toolchain-cross-compiler-bare-metal/

Ich hab das mal mit meiner Generierung verglichen und sehe da keinen 
signifikanten Unterschied. Insbesondere wird dort ausser multilib und 
interworks nichts spezielles fuer arm gemacht. Also thumb und m0 wird 
wohl schon automatisch erzeugt. Auch der von mir erzeugte Compiler kennt 
ja prinzipiell den cortex-m0

Ich hab aber gerade noch was anderes gefunden:

https://gcc.gnu.org/ml/gcc-help/2010-09/msg00009.html

Da scheint noch jemand mit m0 Probleme gehabt zu haben. Ich probier 
gleich noch mal einen anderen Compiler zu uebersetzen....

Letztlich bestaetigt das meine seit langem gehegte Theorie das Arm 
ueberschaetzter Murks ist. Die Verarschen die Leute seit Jahren damit 
das ihre Controller alle SOOOOOO kompatibel sind. In Wahrheit ist die 
Peripherie sowie immer komplett anders und der Core ist so kompatibel 
wie Nutella und Leberwurst. :)

Olaf

von Olaf (Gast)


Lesenswert?

> Wie man sieht nutz ich auch schon einen viel neueren GCC, ka wieso du
> noch die alte 4.7er Gurke nutzt ;)

Weil das hier der Systemcompiler von meinem Redhat ist:

[olaf] ~: gcc -v
gcc-Version 4.8.5 20150623 (Red Hat 4.8.5-16) (GCC)

Glaubst du ich bekomme damit einen 7.x.xer uebersetzt?
Kann ich gerne gleich mal probieren. Aber ich hab so meine Zweifel.

Und so alt ist mein 4.7.4er auch nicht:

gcc-4.7.4/  2014-06-12 14:36

Er halt halt nur nicht die neuesten Bells&Whistles eingebaut, aber 
darauf koennte ich eigentlich verzichten.

Ich probier es aber gleich mal...

Olaf

von Μαtthias W. (matthias) Benutzerseite


Lesenswert?

Hi

Warum kämpfst du mit der Toolchain? Wenn man nicht sicher weiß was man 
da tut beim GCC bauen dann empfehle ich was fertiges zu nehmen. Z.B. das 
da

https://developer.arm.com/open-source/gnu-toolchain/gnu-rm

Matthias

von Olaf (Gast)


Lesenswert?

> Warum kämpfst du mit der Toolchain?

Vielleicht einfach weil ich nicht dumm bleiben will. :-)

Es gibt aber natuerlich auch noch andere Gruende. Hab ich aber schon 
erklaert.


Ich weiss jetzt warum es die Probleme gibt.

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60464

https://stratifylabs.co/embedded design 
tips/2016/03/13/Tips-Building-and-Installing-a-Cortex-M-Compiler/

Scheint mir letztlich eine Kombination aus Konfiguration und Bug im 
Compiler zu sein.

Olaf

von Johannes S. (Gast)


Lesenswert?

Erzeugt die Division auf dem M0 eigentlich viel Code? Ich hatte ein 
printf durch itoa ersetzt, das wurde aber immer noch recht groß. Dann 
das itoa durch eine einfache Version in Source ersetzt und da hat das 
meiste die Integer Division gekostet. Habe das aber noch nicht weiter 
verfolgt und kann gerade keine Zahlen dazu liefern.

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.