Hallo zusammen, ich habe in der UNI ein Projekt bei dem wir den Controller STM32F103 benutzen sollen. Ich habe den zu verwendenden Code bereits auf dem PC in Visual Studio getestet und möchte ihn jetzt auf den Controller bringen. Leider klappt dies wie nicht anders zu erwarten war. Beim Aufrufen einer Funktion springt der Controller in einen Fehlerzustand. --------------- .section .text.Default_Handler,"ax",%progbits Default_Handler: Infinite_Loop: b Infinite_Loop .size Default_Handler, .-Default_Handler --------------- Meine Vermutung ist das es mit dem Stack oder den Speicher des Controllers zu tun hat. Als IDE benutze ich die "System Workbench" Kann mir jemand sagen wie ich den benutzen Programmspeicher mir anzeigen lassen kann? Und wie kann ich mir im Debugging den aktuellen Zustand des Stack-Pointers ausgeben? [Register -> SP ] zeigt mir die aktuell auf den Stack liegende Adresse? Vielen Dank für eure Hilfe
Sieht so aus als verwendest du einen Interrupt dessen Vektor nicht an die eigentliche Funktion sondern an einen Default-Handler springt - hast du ein Startup File für den STM32F103?
Ist die Funktion eine Interrupt Service Routine? Oder wird in der Funktion irgendwas von der Hardware so initialisiert, dass ein Interruptvector eingeschaltet wird, der aber keine zugewiesene ISR hat?
https://community.st.com/docs/DOC-1644-sw4stm32-full-user-training SW4MCU_User_Training-full-v1.1.pdf schon gelesen ?
Meinst du nicht, dass du mindestens den fragwürdigen Code vorzeigen solltest? Stack und Heap sind normalerweise 1) so angelegt, dass sie beide aufeinander zu wachsen. Dann ist die Menge an freiem Heap gleich der Menge an freiem Stack. Mit der Funktion malloc() kannst du zyklisch ausprobieren, wie viel Speicher maximal an einem Stück belegbar ist 2) und diese Zahl dann als Trace Meldung ausgeben. So bekommst du ein grobes Gefühl dafür, wie viel Speicher noch frei ist. Du solltest Dich diesbezüglich auch über das Thema "Heap Fragmentierung" informieren. 1) Aber das kann in deinem uns unbekannten Projekt auch völlig anders sein! 2) Entsprechende Code-Beispiele findest du mit Google. > Und wie kann ich mir im Debugging den aktuellen Zustand > des Stack-Pointers ausgeben? > [Register -> SP ] zeigt mir die aktuell auf den Stack liegende Adresse? Ja sicher doch. Aber ohne Kenntnis der aktuellen Größe des Heap nützt Dir das nicht viel. Wenn du den Heap untersuchen willst, musst du erstmal heraus finden, wie die von Dir verwendete C Library damit umgeht und wo sie ihre Pointer und Größen speichert.
@ Max MMM: Startup File liegt im Anhang bei. @Mr. Big: Danke für deinen Post. @Viktor B.: Die Funktion heisst inv_l() und stammt aus der Library flint.c Ist somit keine eigene Funktion. In der Funktion werden nur Berechnungen durchgeführt und keine Hardware angesprochen. @dasrotemopped: Danke für das Dokument. Kannte ich noch nicht und werde ich mir mal durchlesen. Stefanus F.: Ich benutzte die Bibliothek flint.h und dabei taucht der Fehler beim aufruf der Funtion inv_l() auf. In dem Projekt soll eine Implementierung eines RSA zu testzwecken auf einen Controller umgesetzt werden. Der Programmcode funktioniert soweit auf dem PC. Somit sollte es da kein Problem mit dem Syntax geben. Ich bin mit dem Controller und der IDE noch nicht so vertraut. Hab von euch aber schon ein paar Ansätze um ein Stückchen voran zu kommen.
Nils X. schrieb: > Ich habe den zu verwendenden Code bereits auf dem PC in Visual Studio > getestet und möchte ihn jetzt auf den Controller bringen. > > Leider klappt dies wie nicht anders zu erwarten war. Tja. Was hast du denn da auf dem PC getestet? Dir sollte klar sein, daß es auf einem µC etwas anders zugeht als auf deinem PC. Ich vermute mal, daß du auf dem PC so einiges an dortigen Bibliotheksfunktionen benutzt hast, für die du auf deinem µC keine Basis hast. Beispiel ist sowas wie malloc oder printf, wenn man nicht die passenden Lowlevel-Treiber für das tatsächliche RAM-Verwalten oder die tatsächliche Ausgabe vorgehalten hat. Auf dem PC macht sowas das BS, aber auf dem µC eben nicht, da gibt's kein BS. Also laß erst mal deinen "vorgetesteten" Code links liegen und fange zunächst ganz klein an mit einem Minimal-Programm. Gerade für die STM32F103C8T6 hab ich hier schon des öfteren was gepostet, mit dem du zunächst mal einen funktionablen Programm-Rumpf für diese µC hast, der per seriell oder usb-cdc mit dem PC kommunizieren kann, ne Systemuhr hat, ne Reihe von an µC's angepaßten Hilfsroutinen usw. hat, kurzum dir eine funktionierende Infrastruktur bietet. Die Unterschiede in der HW bei den verschiedenen Geschmacksrichtungen innerhalb der STM32F103xxxx Familie sind nicht groß, aber vorhanden. Also schreibe wenigstens, mit welchem konkreten Typ du in deiner Uni basteln willst. Irgendwo hab ich auch noch etwas für den STM32F103ZET6 herumliegen, so etwa aus 2013. W.S.
@W.S.: Wir sollen eine RSA Verschlüsselung auf einem Mikrocontroller umsetzen. Als ersten Schritt haben wir eine Umsetzung der Funktionalität auf dem PC getestet. --- Die genaue Controllerbezeichnung lautet: STM32F103R8T6 --- Ich werde mal deinen Rat annehmen und im ganz kleinen beginnen. Kannst du eventuell deine Codebeispiele hier kurz als Link posten. Dann hab ich schonmal eine Basis? thx
Der Code für die Verschlüsselung müsste auf den µC prinzipiell der selbe sein, wie auf dem PC. Spannend wird hier allerdings der Umgang mit dem knapperen Arbeitsspeicher. Also solltest du zuerst mal analysieren, wie dein Code auf dem PC mit dem Arbeitsspeicher umgeht. Dann schaust du, ob das zum viel kleineren Speicher des µC passt. Wenn nicht (womit ich rechne), schreibst du den Code um. Ein fertiges Beispiel wird Dir bei deiner Aufgabe nichts nützen. Du würdest damit vielleicht ein funktionierendes Programm erstellen können, aber das Ergebnis wäre mit Sicherheit völlig an der Aufgabe vorbei. Denn der Weg ist hier das Ziel. Dein Lehrer will sehen, wie du die Unterschiede zwischen den beiden Computern ermittelt hast und sicher wirst du deine Anpassungen am Code auch begründen müssen. > Ich benutzte die Bibliothek flint.h und dabei taucht der Fehler > beim aufruf der Funtion inv_l() auf. Es liegt nahe, sich den Quelltext dieser Funktion anzuschauen und insbesondere hinsichtlich der Verwendung von Arbeitsspeicher zu untersuchen. Eventuell muss man auch die Stellen betrachten, wo die Funktion aufgerufen wird.
@Stefanus F.: Danke für die Tipps. Ich denke mittlerweile auch, dass es anfangs etwas blauäugig war einfach nach dem Prinzip "copy and past" - Verfahren vorzugehen. Ich werde dann mal den Code stückweise analysieren. Wenn ich was essenzielles rausgefunden habe poste ich das mal hier.
Was mir ab und zu mal passiert: Ich schreibe Code unter der schlechten Annahme, dass eine Integer Variable eine bestimmte Größe (z.B. 32bit oder 64bit) hat. Wenn man das dann auf eine andere Architektur überträgt, kommt es Rechenfehlern oder gar fehlerhaften Speicherzugriffen in Kombination mit Pointern und type-casting.
Warum verwendest du dann nicht von anfang an Typen wie uint32_t + stdint.h etc.?
> Warum verwendest du dann nicht von anfang an Typen wie > uint32_t + stdint.h etc.? Weil ich blöd bin. Ich weiß ja längst, dass man es so machen soll. Aber man bessert sich im Laufe der zeit.
Nils X. schrieb: > Kannst du eventuell... Ja. Beitrag "Re: STM32 USART mit falscher Baudrate" war ein Beitrag zum Thread "STM32 USART mit falscher Baudrate". Und was kriegst du damit: Ne Basis für die STM32F103, passend zum Keil-MDK. Wer nen GCC benutzen will, muß sich das halt umschreiben. Also: - Startupcode (aber ohne Vorbelegungen im RAM) - Config-Unit zum Konfigurieren der Pins und zum Aufsetzen der Takte etc. - Conv I/O-Konvertierungen Zum Vermeiden von Ballast a la printf und so, aber auch zu Eingabe-Konvertierungen - Cmd eine einfache Kommandozeile - Events eben die Event-Verwaltung. Letztlich zum Organisieren von Zeitabläufen und zum Entkoppeln von lowlevel- und hilevel-Schichten im Programm - Gio zum Vereinheitlichen von seriellen Strömen (reals und virtuelle UARTs, usw.) - main eben für die Grundschleife, quasi der Idle-Zustand in der ganzen Firmware - serial eben die UART's - Systick die System-Uhr - Usb noch ne serielle Schnittstelle, diesmal als USB-VCP (Headerdatei lesen!) ... und das Ganze braucht nur 11508 Bytes. Da kann man mit dem Keil (frei bis 32K) noch ne Menge dazufügen. - EAGLE-Files für die Hardware. Die ist im Übrigen weitgehend kompatibel zu den ST-Link's gehalten, so daß man bei Bedarf nen ST-Link-Lader draufladen kann, dann mit dem Utility von ST daraus einen eigentlichen ST-Link machen kann. Ist nicht mein Fall, ich benutze lieber den eingebauten Bootlader. Dazu gibt's (auch von mir) ein kleines Delphi-Brennprogramm, das auch ein Terminalfenster eingebaut hat. Damit kann man nach dem Flashen sogleich mit dem µC über dieselbe serielle Schnittstelle kommunizieren, über die man ihn programmiert hat. Passende Usb-Seriell-Adapter mit TTL-Pegel sollten ja keine Hürde sein. Klaro? Stefanus F. schrieb: > Was mir ab und zu mal passiert: > > Ich schreibe Code unter der schlechten Annahme, dass eine Integer > Variable eine bestimmte Größe (z.B. 32bit oder 64bit) hat. Ja, das ist eine ganz schlechte Angewohnheit - und sie ist von hause aus fehlerhaft. Von einem int mehr als 16 Bit zu erwarten, ist grob fahrlässig - auch dann, wenn sowas auf einem ARM in der CPU mit 32 Bit gerechnet wird. Also: - wenn du mit 16 Bit für ne globale Variable auskommst, dann nimm int - wenn es eine lokale Variable ist, dann nimm lieber long - für alles, was mehr als 16 Bit zu brauchen scheint, nimm immer long - für alles darüber nimm int64 oder (falls dein Compiler das nicht kennt, schreibe long long) W.S.
W.S. schrieb: > - wenn du mit 16 Bit für ne globale Variable auskommst, dann nimm int Bei int16_t ist klarer was gemeint ist. Sonst aber richtig. W.S. schrieb: > - wenn es eine lokale Variable ist, dann nimm lieber long Was hat der Speicherort damit zu tun? Wenn 16 Bit oder Mehr reichen, nimmt man int_least16_t. Da wird automatisch was effizientes genommen. W.S. schrieb: > - für alles, was mehr als 16 Bit zu brauchen scheint, nimm immer long Warum nicht int(_least)32_t? Ist auch wieder klarer. Diese komplizierten Regeln kann man sich sparen. Das geht einfacher: 1. Überlegen wir viele Bits man braucht 2. Auf 2er-Potenz aufrunden 3. Überlegen ob der Algorithmus mit mehr Bits auch noch geht (Überlauf also nicht wichtig ist) 4. (u)intXX_t bzw (u)int_leastXX_t nehmen Dann muss man sich nicht mehr merken, wie viele Bits short, int, long, long long, und Hersteller spezifische Erweiterungen jetzt haben. W.S. schrieb: > falls dein Compiler das nicht kennt, Nimmt man einen der nicht auf dem Stand von vor 20 stehen geblieben ist.
Dr. Sommer schrieb: > Was hat der Speicherort damit zu tun? Ach unser Forums-Beckmesser ist mal wieder mit seinem Regel-Buch unter'm Arm unterwegs. Aber du kapierst es trotzdem nicht, sonst hättest du eben diese Frage nicht gestellt. Ach ja, da du schon gefragt hast, erklär ich's dir: Der Beckmesser ist der Versager in Wagners Oper von den Nürnberger Meistersingern. Die Meister können meisterlich singen und Lieder komponieren, da möchte Beckmesser gern mitmischen - aber er hat dafür halt nicht die Eier in der Hose. Also rennt er im Forum herum, mit dem Vorschriften-Buch unter'm Arm und versucht jedem Meister irgendwelche angeblichen Regelverstöße anzukreiden. Selbst als er dem Hans Sachs nen Quellcode (vom Junker geschrieben) geklaut hatte, war er zu doof, damit ein schönes Lied zu singen und hat sich vor dem Auditorium blamiert. Aber als der Junker eben diesen Quellcode vor versammeltem Auditorium nochmal vorsang, da erstrahlte die schöne Melodie - eben meisterlich. So, nun weißt du, warum du der Beckmesser dieses Forums bist. Schau mal, dieses Forum lebt von positiven Beiträgen. Deshalb habe ich dir vor geraumer Zeit dringend angeraten, von solchen scheuklappigen Kritteleien abzulassen und hier in diesem Forum etwas Eigenes vorzutragen, also irgend ein Werk, das weinigstens ein bißchen deines eigenen Entwicklerschweißes gekostet hat. Das nützt dem Forum und auf lange Sicht nützt es auch dir selber. Deshalb wiederhole ich hier meinen damaligen Rat an dich. W.S.
Hahaha, du bist also ein Meister, ja? Wohl eher der Frickelmeister! In der Mathematik und Informatik sind Regeln nun mal das ein und alles. Ignoriert man die, kommt's zum Chaos. Programmieren ist halt doch was anderes als Singen. Da kommt's auf Korrektheit an, nicht was du mit deiner Wirth-Brille "schöner" findest. W.S. schrieb: > und hier in diesem Forum etwas Eigenes vorzutragen, also irgend ein > Werk, das weinigstens ein bißchen deines eigenen Entwicklerschweißes > gekostet hat. Wie bereits gesagt habe ich das, aber eben nicht unter diesem Namen (du dozierst hier ja auch anonym!). Natürlich hast du es dir nicht nehmen lassen völlig unqualifiziertes und unbegründetes Geläster darunter abzulassen; nach Widerlegen desselben kam keine Antwort mehr. Peinlich für einen Meister!
W.S. schrieb: > So, nun weißt du, warum du der Beckmesser dieses Forums bist. Deine Beiträge zum Thema C sind regelmäßig von Halbwissen geprägt, oftmals auch schlichtweg falsch. Insofern solltest gerade Du Dich bei diesem Thema nicht soweit aus dem Fenster lehnen.
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.