Hallo, ich implementiere gerade einen Algorithmus auf einem STM32F103. Dabei müssen leider großen Integer verarbeitet werden. Sobald ich allerdings uint64_t statt uint32_t in meinem Programm verwende, läuft das ganze Programm nicht mehr! Selbst der Teil vor der ersten Verwendung von uint64_t wird nicht ausgeführt, der Mikrocontroller bleibt komplett still. Woran kann das liegen? Ich benutze den arm-none-eabi-gcc und im Anhang ist mein makefile. Vielen Dank für weiterführende Tipps.
Doran S. schrieb: > Ich benutze den arm-none-eabi-gcc und im Anhang ist mein makefile. Du meinst, der Bug steckt im Makefile?
Gast
#6078122
> Woran kann das liegen?
Am Makefile kann man das nicht erkennen.
Abgesehen davon: Der Dateiname sollte mit einem "M" beginnen, nicht "m".
Vermutlich steht in Zeile 42 des source codes oder linker scripts oder startup codes "if uint64_t, then fail"... Oliver
Hallo, hatte vermutet, dass eventuell eine Compiler-Option fehlerhaft sein könnte, daher das Makefile... Der Code, der Ärger macht sieht so aus:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
Die stdint.h ist natürlich eingebunden. Woran könnte der Fehler liegen?
Gast
#6078134
Doran S. schrieb: > Woran könnte der Fehler liegen? Kann man an diesem kleinen Schnipsel nicht sehen. Zur Ratekiste würde ich hinzufügen: Speicherüberlauf Eventuell hilft es, sich die Warnungen des Compilers anzuschauen.
Doran S. schrieb: > uint32_t FTW = (uint32_t)(((uint64_t)(0x100000000) * (uint64_t)(freq)) / > ((uint64_t)(125000))); Sicher daß deine DDS mit 125kHz läuft? Oder sind es nicht eher 125 MHz?
Hallo, Ja, der DDS läuft natürlich mit 125MHz. Ich rechne aber in kHz, daher passt das. Der Fehler muss aber in der gezeigten Zeile liegen, denn wenn ich diese Zeile z.B. durch
1 | |
ersetze, dann geht alles. Ich kann auch z.B. den Compiler-Output bereitstellen, oder den gesamten Quellcode, falls dies hilft? Was benötigt ihr?
Wie groß is freq?
Am C-Code iegt es in der Zeile nicht. Wenn Ram insgesamt knapp ist, könnten die 64-Bit-Routinen natürlich das Faß zum überlaufen bringen, aber so wirklich glaube ich da nicht dran. Oliver
Hallo, der RAM ist sehr gering ausgelastet, der Linker gibt folgendes aus:
1 | |
2 | |
3 | |
freq = 14000. Hat sonst noch jemand Tipps? So sieht die entsprechende Stelle disassembliert aus:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
Vielen Dank schon mal.
Gast
#6078223
Stefan F. schrieb: >> Woran kann das liegen? > > Am Makefile kann man das nicht erkennen. > > Abgesehen davon: Der Dateiname sollte mit einem "M" beginnen, nicht "m". Die meisten Windows-User haben noch nie davon gehört, dass Dateinamen case-sensitiv sein können. Bei Windows ist es egal, wie das (M/m)akefile heißt.
Gast
#6078231
Doran S. schrieb: > der RAM ist sehr gering ausgelastet Das sagt noch nichts darüber aus, wie viel RAM dynamisch zur Laufzeit belegt wird.
(4294967296 * 14000) / 12500 != 1546188227 (0x5C28F5C3)
Gast
#6078250
Doran S. schrieb: > 8000d2e: 4629 mov r1, r5 > 8000d30: 4620 mov r0, r4 > 8000d32: f7ff f9e3 bl 80000fc <__aeabi_uldivmod> Das ist sicher keine 64bit Operation. Aber dividiere mal freq und 125.000 vorher durch 1000, dann koennte es passen. leo
Vincent H. schrieb: > (4294967296 * 14000) / 12500 != 1546188227 (0x5C28F5C3) Das stimmt, aber: (4294967296 * 14000) / 125000 = 481036337 (0x1CAC0831). Und auch wenn ich
1 | |
durch
1 | |
ersetze, funktioniert es. Das Problem muss deshalb in der Berechnung liegen... Hat noch jemand einen Tipp?
Gast
#6078255
Doran S. schrieb: > der Mikrocontroller bleibt komplett still. Glaub ich nicht. Springt in eine Exception (Hard Fault,...)? Ich hatte mit uint64_t auf IAR EWARM nie Probleme mit dem F103.
Gast
#6078256
Springt er in eine Exception (Hard Fault,...)?
leo schrieb: > Das ist sicher keine 64bit Operation. Ich denke doch. r1:r0 /% r3:r2
1 | |
2 | |
vmtl steht an Adresse 8000d98 der Wert 125000
1 | |
2 | |
vmtl das Produkt von vorher
Frank M. schrieb: > Du meinst, der Bug steckt im Makefile? Vielleicht. Wenn er die falsche Lib erwischt.
An Adresse 080000fc steht:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
Leider kenne ich mich mit Assembler nicht so aus. Hilft dies weiter?
Mr.T schrieb: > Springt er in eine Exception (Hard Fault,...)? Habe versucht, eine LED im Hard Fault Handler blinken zu lassen, aber da kommt nichts...
Beitrag #6078295 wurde von einem Moderator gelöscht.
Doran S. schrieb: > 800011c: f000 f806 bl 800012c <__udivmoddi4> Dann mach da mal weiter. Der Code oben testet nur auf Division durch 0.
An Adresse 800012c steht eine sehr lange Funktion, siehe Datei anbei.
Gast
#6078308
Doran S. schrieb: > uint32_t FTW = (uint32_t)(((uint64_t)(0x100000000) * (uint64_t)(freq)) / > ((uint64_t)(125000))); schreibe doch mal statt dessen folgendes: uint32_t FTW = (uint32_t)(((uint64_t)(0x10000000) * (uint64_t)(freq)) /((uint64_t)(125000))); ...wenn es läuft: dann war ein Null zuviel dran
Vielleicht ist es das alte Stack-Alignment-Problem. Zeig mal das ganze Linkerscript und den Startupcode. Was sagt der Debugger zum Crash? Hard-Fault? Register-Inhalte, insb. SP? An welcher Stelle crasht es genau?
Was ist das "alte Stack-Alignment-Problem"? Das kenne ich nicht. Das Linker-Skript sieht so aus:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
Mit dem Debugger kann ich leider nicht ran, weil die Hardware nur einen UART-Anschluss hat (über den ich flashe). Gibt es Alternativen? Kann man das irgendwie simulieren?
Doran S. schrieb: > Was ist das "alte Stack-Alignment-Problem"? Das kenne ich nicht. Bei manchen Beispiel-Linker-Scripten von ST ist der initiale Stack-Pointer falsch gesetzt, sodass er ein falsches Alignment hat, und dann das Speichern von 64bit-Werten auf dem Stack scheitert. Das scheint hier aber nicht der Fall zu sein. Doran S. schrieb: > Mit dem Debugger kann ich leider nicht ran, weil die Hardware nur einen > UART-Anschluss hat Fehler Nr. 1 beim Hardware-Design... Doran S. schrieb: > Gibt es Alternativen? Kann man > das irgendwie simulieren? z.B. mit einem anderen STM32F103-Board. Keil µVision kann auch STM32 simulieren.
Wenn ich das gesamte Projekt als gepacktes Archiv hochlade, könnte dann jemand, der eine Hardware mit Debug-Möglichkeit hat, das mal bei sich ausprobieren? Vielleicht hat ja mein Controller einen Hardware-Schaden?
Gast
#6078352
Doran S. schrieb: > Wenn ich das gesamte Projekt als gepacktes Archiv hochlade, Ich schätze, der Betreiber des Forums würde sich freuen, wenn du das über Dropbox oder einen ähnlichen Dienst machst, wegen der Größe.
Hallo, habe noch so ein Board gefunden: https://www.reichelt.de/evaluationboard-stm32-value-line-discovery-stm32-vldiscov-p219361.html?&trstct=pos_14 Darauf habe ich das selbe Problem. Man kann also die Hardware ausschließen. Auf dem Board ist ja ein ST-Link. Kann ich damit debuggen?
Gast
#6078588
Doran S. schrieb: > Auf dem Board ist ja ein ST-Link. Kann ich damit debuggen? Ja
Hallo, ich komme einfach nicht weiter. In Keil uVision muss ich mich erst einarbeiten. Anbei jedoch das komplette Programm als Disassemble. Wer darin den Fehler findet und mir beibringen kann, was schief gelaufen ist, bekommt von mir ein 1X16 LCD als Weihnachtsgeschenk zugesendet.
Gast
#6078637
Doran S. schrieb: > ich komme einfach nicht weiter. Welche IDE benutzt du? Mache ein "clean" (allo *.obj, *.o, *.bin etc) und komprimiere dein Projekt in ein Zip-File, setze es hier rein, es findet sich sicher jemand der es nachprüfen kann. So gross kann dein Projekt nicht sein dass es nicht hier up- und downloadbar sein könnte.
Gast
#6078640
Doran S. schrieb: > Wer darin den Fehler findet ..... Ich werde mir das nicht antun, das vorher angebotene jedoch schon.
Hallo, anbei das komplette Projekt als ZIP-Archiv. Ich benutze keine IDE, sondern gebe im Terminal "make" ein.
Gast
#6078669
Doran S. schrieb: > Ich benutze keine IDE, > sondern gebe im Terminal "make" ein. Gut, ich baue ein Projekt daraus und melde mich dann. Vielleicht macht es jemand anders auch auf anderem Weg ....
Gast
#6078689
Doran S. schrieb: > anbei das komplette Projekt als ZIP-Archiv. Lässt sich leider nicht auf die Schnelle debuggen da ein Teil des Codes die Ports der SWD Schnittstelle umprogrammiert und man somit keinen Zugriff aufs Debuggen hat.
Hallo, oh, das habe ich übersehen. Im Anhang eine Version ohne Deaktivierung der Debug-Schnittstelle. Das Problem besteht trotzdem noch.
Gast
#6078697
Ist es ein BluePill Board das du verwendest? Wenn nicht, welchen Controller genau verwendest du?
Es ist eine selbst entwickelte Platine. Der Controller ist der STM32F103RCT6.
Gast
#6078704
Doran S. schrieb: > oh, das habe ich übersehen. Im Anhang eine Version ohne Deaktivierung > der Debug-Schnittstelle. Nein, ist immer noch der gleiche Code. Tut mir leid, ich bin raus.
Hallo, das tut mir Leid, ich habe aber tatsächlich in der letzten Version keine Deaktivierung der Debug-Schnittstelle mehr drin. Die Datei STM32F100.c ist entsprechend angepasst. Vielen Dank aber trotzdem für Deine Mühe. Bin eh ganz durcheinander, weil ich das heute den ganzen Tag versucht habe. Vielen Dank für die Tipps von allen Seiten. Das Angebot steht aber noch.
Gast
#6078729
Doran S. schrieb: > das tut mir Leid, ich habe aber tatsächlich in der letzten Version keine > Deaktivierung der Debug-Schnittstelle mehr drin. Diese Deaktivierung muss ja einen Sinn haben, wozu wird es überhaupt gemacht wenn man es auch weglassen kann?
Hallo, an PA13, PA14 und PA15 hängt Peripherie. Deshalb brauche ich diese als "normale" Ausgänge. Wenn ich es wieder aktiviere, dann funktioniert natürlich manche Peripherie nicht mehr, aber der Fehler, dass der Mikrocontroller kein Programm mehr ausführt, besteht immer noch.
1 | |
2 | |
3 | |
Diese Zeilen habe ich darum in der zweiten Version auskommentiert. Wenn Du noch weitere Infos brauchst, kann ich diese natürlich liefern. Viele Grüße!
Gast
#6078767
ändere mal eine Zeile im makefile zu LDFLAGS += -lgcc # more options, e.g. libraries in der libgcc sind die Routinen für uint64_t drin Gruss Dieter
Gast
#6078770
Gut, ich habe deine Sourcen in ein Projekt auf Basis des BluePill Boards (F103C8T6) eingebunden. Es compiliert einwandfrei, durchläuft die Initialisierung ohne Probleme, ebenso wird die Hauptschleife zyklisch abgearbeitet. Keine Hänger oder Hard Faults. Anbei das lauffähige Projekt für Embitz. Verwende das, du wirst sehen das geht relativ einfach und du hast den Debugger gleich mit eingebaut. Wenn es mit der Einstellung (F103C8T6) nicht gleich funktioniert musst du noch den richtigen Controller im Projekt einstellen. Im Code ist also kein prinzipieller Fehler enthalten, es muss dann wohl an deinem Linker Description File liegen, oder was anderem was ich beim Bau des Projekts nicht berücksichtigt habe.
Gast
#6078791
Was passiert, wenn FTW = 0 ist? Vielleicht entwickelt der Compiler (uint64_t)(0x100000000) zu Null? Im verbesserten Code steht auch: (uint64_t)(0x100000000ul)...
Gast
#6078794
OT512 schrieb: > Im verbesserten Code steht auch: (uint64_t)(0x100000000ul)... Das habe ich sicherheitshalber hinzugefügt. Sonst ist da nichts "verbessert".
OT512 schrieb: > Vielleicht entwickelt der Compiler (uint64_t)(0x100000000) zu Null? Dann wäre es kein C oder C++ Compiler. Oliver
Gast
#6078801
Doran S. schrieb: > (0x04 << 24); Wird das nicht 0?
Johannes S. schrieb: >> (0x04 << 24); > > Wird das nicht 0? Bei 16-Bittern schon. Aber nicht bei einem 32-Bitter.
Gast
#6078899
beim gcc auf einem F407 mit gcc kompiliert wird das richtig gerechnet:
1 | |
2 | |
3 | |
output: testvar: 1cac0831
Gast
#6079045
Stell mal den Datentyp von uint64_t auf int64_t um. Wenn ich mich recht erinnere, hatte ich schon mal Probleme bei der Division festgestellt.
Man könnte auch Räucherstäbchen anzünden, und einen Datentyp-Voodoo-Tanz aufführen. Oliver
Hallo, vielen Dank für die hilfreichen Antworten an alle. Also, wenn ich das EmBitz-Projekt von STM Apprentice kompiliere (und mit "stm32flash -w F103_uint64_Test.hex -v -R -i -dtr,rts,-rts:dtr,rts,-rts /dev/ttyUSB0") flashe, dann geht es! Es muss also irgendwie an den Einstellungen (Compiler, Linker) liegen.... Habe mal wie von Dieter Graef vorgeschlagen -lgcc bei den Linker-Flags hinzugefügt, aber das hat keine Änderung verursacht. Auch macht es keinen Unterschied ob ich uint64_t oder int64_t benutze.... Bin echt ratlos. Hat noch jemand eine Idee?
Johannes S. schrieb: > beim gcc auf einem F407 mit gcc kompiliert wird das richtig gerechnet: >
1 | |
2 | |
3 | |
4 | |
> output: > testvar: 1cac0831 Cool, wie hast Du compiliert? (Welche Compiler- und Linker-Einstellungen?)
Doran S. schrieb: > ich komme einfach nicht weiter. Hilf dir doch selbst. Reduziere das Programm auf ein Minimum, welches immer noch den Fehler hat - idealerweise nur eine main()-Funktion mit eine paar wenigen Zeilen, ganz ohne jegliche Ansteuerung externer Peripherie. Du kannst ja ggf. eine LED einschalten o.ä. um zu sehen ob es noch läuft, auf der tatsächlichen Hardware ohne Debug-Möglichkeit. Stelle sicher dass die Division tatsächlich zur Laufzeit durchgeführt wird, und nicht vom Compiler wegoptimiert. Eine Möglichkeit das zu tricksen wäre z.B.:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
Das Ergebnis-Programm mit Fehler spielst du dann auf ein STM32F103-Eval-Board, debuggst es mit einem ST-Link und gehst es Schritt für Schritt durch bis es abstürzt. Dieses Programm (Code+Kompilat/ELF-Datei) kannst du dann auch hier hochladen damit wir es auch ausprobieren können. Warum steht im Code eigentlich was von STM32F100 während es aber ein STM32F103 sein soll? Nicht dass der Takt oder Power-Management falsch initialisiert wird oder so. Das kann alle möglichen kuriosen Effekte haben.
Gast
#6079189
Doran S. schrieb: > Bin echt ratlos. Hat noch jemand eine Idee? Stack/heap? die keil/iar IDEs haben ja in den einstellungen angaben für die Stack/heapgrößen
Gast
#6079234
Doran S. schrieb: > Cool, wie hast Du compiliert? (Welche Compiler- und > Linker-Einstellungen?) ich habe das mit Mbed gemacht, den F407 habe ich gerade hier liegen und die Zeilen sind da schnell reinkopiert. Die Compileroptionen sind so gesetzt, hatte das debug Profil genutzt: https://github.com/ARMmbed/mbed-os/blob/master/tools/profiles/debug.json Gegenüber deinem Makefile sind hier wohl vor allem noch -WExtra wichtig für striktere Prüfung, mit -Og ist die Optmimierung reduziert. Wie die Vorredner glaube ich nicht das die long long Operationen das Problem sind, es wird nur hier sichtbar. So Spätfolgen passieren bei korupptem Stack oder Querschreibern, schreiben über Arraygrenzen hinweg oder Zeigerfehler. Auch die Newlib Nano kann long long rechnen, nur das printf ist da reduziert und kann die nicht ausgeben. Führt aber auch nicht zu Programmfehlern. Evtl. mal als C++ übersetzen, das ist ja pingeliger und so Sachen wie impliziete Funktionsdeklarationen sind Fehler und keine Warnungen.
Hallo, bin nun einen Schritt weiter: Wenn ich mein Linker-Skript (STM32F100.ld) und meinen Startup-Code (crt0.c) durch den vom Projekt von "STM Apprentice" ersetze, dann geht es. Mein Fehler ist also entweder im Startup-Code und/oder im Linker-Skript. Kann jemand erkennen, was im einem Startup-Code oder Linker-Skript fehlt?
Doran S. schrieb: > Kann jemand erkennen, was im > einem Startup-Code oder Linker-Skript fehlt? Im Linkerscript fehlt vor dem "_bss_section_start", dem "_bss_section_end", "_data_section_start", "_data_section_end", "__end__", "(*.stack)" jeweils ein ".=ALIGN(4)". Wo hast du das kaputte Linkerscript her? Warum nimmst du nicht eins von der IDE oder aus STM32Cube? Ist denn die Definition des Interrupt-Vektor im Startup-Code korrekt und für deinen Controller passend?
Hallo, also, das Problem war letztendlich das Linker-Skript. (Und als ich das korrekte von dem Projekt von "STM Apprentice" zusammen mit einem Startup-Code "crt0.c" verwendet hatte, hat es nicht funktioniert, weil ein paar Namen (von Sections) anders sind. Nachdem ich das korrigiert hatte, hat es funktioniert.) Um sowas in Zukunft besser zu können, möchte ich mehr über Linker-Skripte lernen. Kann mir jemand Literatur oder ein Tutorial dazu empfehlen? Außerdem ist mir nicht so ganz klar, was die einzelnen Sections bedeuten, also wozu der Prozessor diese benötigt. Was liegt in .init? Was in .fini? Was ist das .eh_frame? .ARM.extab und .ARM.exidx? Wo kann man diese Dinge lernen? Vielen Dank an alle für die vielen Tipps, die dann zur Lösung geführt haben. Ein Problem bleibt: Wem schicke ich nun das Display? ;-)
Gast
#6080169
Doran S. schrieb: > Ein Problem bleibt: Wem schicke ich nun das Display? Du hast dich bei mir schon bedankt indem du geschrieben hast wie es ausgegangen ist. Das wünschen sich alle die so einen Thread verfolgen, und du hast es dankenswerter Weise getan.
Gast
#6080418
Doran S. schrieb: > Ein Problem bleibt: Wem schicke ich nun das Display? ;-) Äh, mir natürlich. Was für eine seltsame Frage. ;))
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.