Hallo, ich versuche das STM32F072RBT6 Discovery mit der CoIDE und CubeMX zum Laufen zu bekommen. Leider musste ich feststellen, dass es zu diesem Board absolut keine Tutorials gibt und auch die bisher getesten IDEs kennen dieses Board nicht. Mit SiSy STM32 hat das Board funktioniert. Möchte jedoch wegen der besseren Kompatibilität und hoffentlich einfacherer Konfiguration der Peripherie auf CoIDE umsteigen. CoIDE ist in der aktuellen Version 2.0.06 installiert. CoFlash wurde ebenfalls in den entsprechenden Ordner nachgeschoben. Als Anleitung verwende ich (momentan) diese: https://stm32geek.wordpress.com/2013/04/04/hello-world-stm32-coocox-coide-and-gcc-arm/ Es scheitert jedoch bereits daran, dass es in den Repositorys kein GPIO gibt. Weder für den dort genannten Mikrocontroller, noch für den STM32F072. Demzugolge findet er keine stm32f0xx_gpio.h. Im Internet ist das Problem bekannt, aber nirgends steht eine Lösung. Sämtliche Anleitungen die ich im Internet gefunden habe sind entweder für die alte Version wo es eine Repository GPIO gibt oder für ein anderes Discovery Board ohne jegliche Erklärung, wie man das anpassen müsste. Heinz
:
Bearbeitet durch User
Heinz M. schrieb: > CoIDE ist in der aktuellen Version 2.0.06 installiert. Alles nach 1.78 ist nicht wirklich beliebt geworden, u.a. wegen der Online-Problematik. CoIDE wird auch nicht mehr gepflegt. Die Treiber gibt es nicht in signiert, was mit Win10 zu weiteren Klimmzügen führen wird. Das Forum ist vollkommen verwahrlost. Für neue Projekte würde ich nicht mehr empfehlen, auf CoIDE aufsetzen.
Danke für den wichtigen Hinweis. Deswegen passen die ganzen Anleitungen nicht. Wenn ich durch bin werde ich mal die STM32 Seite im Wiki daraufhin aktualisieren. Dann probiere ich doch mal SW4STM32. Auch wenn ich bei den Telefon und Adress Pflichtfeldern schon die Schnauze voll hatte. Ich lade gerade die Target Firmware mit 260 b/s. Geht das bei euch auch so langsam?
Ich habe da einfach Quatsch eingegeben. Hauptsache sie sind nicht leer. Nur die Email Adresse muss funktionieren, weil du eine Verifikations-Mail bestätigen musst.
Heinz M. schrieb: > Dann probiere ich doch mal SW4STM32. Tja ........ und dann nicht zu vergessen: embitz Ein geniales Teil, je länge ich es verwende desto doller. Da hat sich wirklich ein kleiner Haufen Entwickler (oder war's nur einer?) Gedanken gemacht.
So ich hänge jetzt wieder an der gleichen Stelle wie bei den anderen IDEs: Das Kompilieren erzeugt Fehler wegen fehlenden Komponenten:
1 | fatal error: tsl_conf_stm32f0xx.h: No such file or directory tsl_acq_stm32f0xx.h /SW4STM32_2/STMTouch_Driver/inc line 35 C/C++ Problem |
2 | make: *** [STMTouch_Driver/src/tsl.o] Error 1 SW4STM32_2 C/C++ Problem |
Ich bin strickt nach Anleitung vorgegangen: http://www.openstm32.org/Getting+started+with+System+Workbench+for+STM32 Habe lediglichen den Touch Treiber dazu gewählt. Programmcode habe ich keinen eingegeben.
Heinz M. schrieb: > fatal error: tsl_conf_stm32f0xx.h: No such file or directory Diese Source ist nicht Bestandteil der Standard Libraries, du must sie selbst zum Projekt beitragen, woher auch immer. Heinz M. schrieb: > Möchte jedoch wegen der > besseren Kompatibilität und hoffentlich einfacherer Konfiguration der > Peripherie auf CoIDE umsteigen. Da hilft die beste IDE nix.
> So ich hänge jetzt wieder an der gleichen Stelle wie bei den > anderen IDEs Warum hast du denn um den heißen Brei geschrieben, und nicht das konkrete Problem beschrieben? Selbst Schuld. Als erstes würde mal die fehlende Datei auf der gesamten Festplatte suchen. Vielleicht musst du nur irgendwo den Pfad zur Library hinzufügen. Und dann noch ein Heißer Tip: Google mal nach dem Dateinamen "tsl_acq_stm32f0xx.h". Dann findest du das "STMTouch driver user maual" (welche Überraschung!) und dort wird die Datein Kapitel 2.5.2 aufgelistet. Ergo: Du hast die Library nicht richtig installiert. Wie man das macht, steht in genau diesem Dokument ausführlich beschrieben.
Oder der Treiber liegt in einem anderen Verzeichnis und es fehlt der Includepfad.
Wenn man das mit Buildscripten von der Kommandozeile aufsetzt, muß man sich nicht damit befassen, in welchem der Dutzenden Dialoge man ein Häkchen setzen soll.
Heinz M. schrieb: > Dann probiere ich doch mal SW4STM32. Auch wenn ich bei den Telefon und > Adress Pflichtfeldern schon die Schnauze voll hatte. Würde ich auch nicht machen. Deshalb nimmt man auch das eclipse Plugin: Beitrag "Re: STM32F7 Discovery Board"
Stefan U. schrieb: > Warum hast du denn um den heißen Brei geschrieben, und nicht das > konkrete Problem beschrieben? Selbst Schuld. Siehe erster Post: Heinz M. schrieb: > Als Anleitung verwende ich (momentan) diese: > https://stm32geek.wordpress.com/2013/04/04/hello-world-stm32-coocox-coide-and-gcc-arm/ > > Es scheitert jedoch bereits daran, dass es in den Repositorys kein GPIO > gibt. Weder für den dort genannten Mikrocontroller, noch für den > STM32F072. Demzugolge findet er keine stm32f0xx_gpio.h. Im Internet ist > das Problem bekannt, aber nirgends steht eine Lösung. Woher soll ein Anfänger wissen, dass er nach der übergeordneten Datei suchen muss und nicht nach der Datei, die nicht gefunden werden kann? Das Dokument habe ich gefunden und nach 2.2 sah es vollständig aus. Bis auf die Datei, die er nicht finden konnte. Ist erst mal egal, ich habe ein neues Projekt erstellt ohne Touch. Damit läuft es jetzt. Die LED blinkt. Jetzt probiere ich das mit CubeMX. @pegel & NOP: Ist nicht böse gemeint, aber genau das ist das Problem für Anfänger wie mich. Zich Varianten werden präsentiert und jede soll die Beste sein. Da weiß man dann gar nicht mehr was man machen soll. Da führt die einfachste Variante eher zum Ziel, als die Beste ;-) Was hat das F7xx mit dem F072 zu tun?
Heinz M. schrieb: > Was hat das F7xx mit dem F072 zu tun? Es geht nur um das Plugin. Wenn eclipse neon installiert ist, das Plugin aus den link installieren, fertig.
Heinz M. schrieb: > @pegel & NOP: Ist nicht böse gemeint, aber genau das ist das Problem für > Anfänger wie mich. Also Tips für den Anfang, so habe ich das jedenfalls gemacht: Ich hab mir erstmal CoIDE gezogen. Interessant war dabei für mich erstens das Startup-File und zweitens das Linkerscript. Das sind schonmal halbwegs annehmbare Vorlagen, von denen man ausgehen kann. Daß das Linkerscript selber schon bedenklich ist (Stack wächst von oben auf den ganzen Rest zu - WTF), ist am Anfang erstmal egal. Dann verstehen, was genau diese Dinge denn tun. Wo im Source ist der Einsprungspunkt im Binary, also wo läuft der Kram los? Wie kriegt man den Stack alloziert? Wie sagt man das dem Linker? Wo findet die Initialisierung des Speichers statt? Was geht sonst noch alles vor dem Aufruf der main() vor sich? Und wie wird die Systick-Routine mit der Interrupttabelle verhakt? Das sind alles Fragen, die scheinbar erstmal nur im Weg stehen. Aber wenn man sich die Mühe macht, das erstmal zu verstehen, dann kennt man das System auch gut genug, daß man danach weniger Probleme hat. Die anfängliche Fragestellung bei mir war gar nicht, wie ich das schnell ans Laufen kriege, sondern wie das funktioniert, das ist der Punkt an der Sache. Etwas, das funktioniert, aber ich weiß nicht exakt wieso, das hätte für mich keinen Wert gehabt. Dann habe ich zwei Tricks gemacht: Zum einen mir die Standard Peripheral Library von ST gezogen, um eine grobe Orientierung zu bekommen, was man tun könnte, und zum anderen mir das Reference Manual des Chips gezogen, um rauszukriegen, was man WIRKLICH tun muß. Leider zwei Paar Schuhe. Übrig vom Coide-Code ist nichts mehr, und den ST-Code kann man echt nur zur groben Referenz gebrauchen. Ich hab mir am Ende meine ganzen Register und Bitmasken dann selber in nem Headerfile definiert, direkt nach Vorlage des Reference Manuals. Man findet dabei aber auch immer wieder höchst interessante Dinge - das Reference Manual liest sich fast wie ein Krimi. Das wird noch besser mit dem Programming Manual, wo man dann z.B. drauf kommt, wie man Mindest-Delays unterhalb des Systemticks hinbekommt. Und dann die gesamte Initialisierung mit Clock-Einstellungen, Taktfrequenz usw. nach Datenblatt in entsprechenden selbstgeschriebenen Routinen gemacht. Das Ergebnis: sicher hat es erstmal länger gedauert, da nen Griff dranzukriegen. Aber dafür verstehe ich jetzt auch sehr genau, was im System passiert. Zum Abschluß und zur allgemeinen Erheitung noch zwei fiese Bugs, die mir in Erinnerung geblieben sind: 1) Ich hatte den Stack ins CCM gelinkt - und dann im Startupcode aus Versehen das CCM auf unpowered gesetzt. Das ist dann in der ersten etwas komplexeren Routine abgestürzt, aber da die Beziehung herstellen hat etwas gedauert. 2) Es gibt eine Instruktion, mit der man die Interrupts sperren kann. "CPSID i" nennt die sich. Schön, aber der Systick ist ja schließlich kein Interrupt, sondern eine Exception, also läuft der auch weiter. Nicht???
LEDs blinken jetzt auch mit CubeMX+SW4STM32. Danke für den Hinweis diese IDE zu verwenden. Morgen gehts weiter mit Timer. @NOP: Wenn man so weit ist, dass man sich das alles selbst basteln kann ist das sicher schön. Wenn man aber bei fast 0 steht, nimmt man lieber Tutorials, wo man Stück für Stück sieht, dass man auf dem richtigen Weg ist. Die Hardware Datenblätter von ST sind gut. Die Software Datenblätter setzen doch einiges an Grundwissen voraus.
:
Bearbeitet durch User
Heinz M. schrieb: > Wenn man aber bei fast 0 steht, nimmt man lieber > Tutorials Ja gut, das mag natürlich ein Unterschied sein. Ich hatte zu dem Zeitpunkt zwar keinen Plan von Cortex-M, aber schon viele Jahre embedded auf dem Buckel, und C ist sowieso meine zweite Muttersprache. Das ist natürlich was anderes, als wenn man erstens mit C und zweitens mit embedded nicht vertraut ist. Trotzdem würde ich Dir empfehlen, lieber auf kapieren als auf kopieren zu setzen. Meine Erfahrung ist, daß man damit länger braucht (außer man ist ein Genie), aber damit besser fährt. Klar ist es ein Erfolgserlebnis, wenn's blinkt. Aber ist es denn keines, wenn Du verstehst, wie z.B. Stack, Linkerscript und Startupcode zusammen funkktionieren? Muß es wirklich auf dem Board blinken, oder tut's nicht auch das Licht, was Dir aufgeht? ;-) (Come to the dark side.. we've got cookies! ^^)
Du hast keines Falls unrecht. Es ist aber immer eine Frage, wie tief man rein will. Man kann nicht bei jedem Hobby alles wissen ;-) Ich ziehe bei mir die Grenze bei der IDE inkl. Librarys. Ich weiß grob was sie im Hintergrund macht. Auch die drei von dir genannten Begriffe, obwohl ich damit bisher nicht in Berührung kam. Die IDE ist für mich ein Werkzeug, also zum Benutzen und nicht dran rumschrauben. Wenn man sich später auskennt kann man immer noch sein Werkzeug optimieren. Was ich an Code eingebe, das möchte ich verstehen. Da war das SiSy Tutorial sehr hilfreich. Aus dem Tutorial geht nicht hervor, wie man die weitere Peripherie (ohne Tutorial) nutzen kann. Außerdem scheinen die vorgefertigten Klassen nicht mit dem STM32F072 zu funktionieren. Deswegen immer das richtige Werkzeug für den richtigen Zweck. Noch eine Frage zum SW4STM32 allgemein: Wenn ich ein anderes Programmfenster wähle (z.B. Internet Explorer) und dann auf das SW4STM32 Fenster klicke(irgendwo auf den Quellcode), dann springt er manchmal vom Programmierbildschirm in den Startbildschirm. Ist das ein Bug oder gibt es da ne Einstellung?
Nop schrieb: > Stack wächst von oben auf den ganzen Rest zu - WTF Na, da beim ARM der Stack immer nach unten wächst, hat er am meisten Platz zu wachsen, wenn er ganz oben anfängt...
Ich würde noch einen Schritt weiter zur Wurzel gehen und nicht mit der veralteten Standard Library anfangen, sondern nur mit der CMSIS. Die besteht aus so wenig Dateien, daß man prima nachvollziehen kann, was genau nach dem System Reset passiert. Nop, du hast eine Menge gute Fragen zum Startvorgang gestellt, mir ist nicht klar, welche Davon du bereits selbst klären konntest und welche npch offen sind. Ich möchte Dir gerne helfen. Ich bin selbst totaler Anfänger im ARM Umfeld, aber ich habe viel Erfahrung mit zahlreichen 8bit Mikrocontrollern. Deswegen habe ich mich zuerst mit den Grundlagen beschäftigt - so wie du das vernünftigerweise auch machst. > aber der Systick ist ja schließlich kein Interrupt, > sondern eine Exception, also läuft der auch weiter. Das ist (soweit ich herausfinden konnte) technisch das selbe. Die ersten 15 werden vom ARM Kern ausgelöst und heissen Exceptions. Die anderen werden von Hardware ausgelöst, die der Chiphersteller um den Kern drumherum gebaut hat und heissen Interrupts. > den ST-Code kann man echt nur zur groben Referenz gebrauchen Sehe ich auch so. Mein erstes Testprogramm mit HAL stürzte bei der Initialisierung des Taktes ab, weil dieses blöde Tool fehlerhaften Initialisierungscode erzeugt hat. Dabei wollte ich "nur" eine LED blinken lassen! (Dieser Bug ist inzwischen behoben worden). Wenn man schon diesem Code nicht trauen kann, dann mache ich gleich alles möglichst selbst. > Wo im Source ist der Einsprungspunkt im Binary, also wo läuft der > Kram los? Je nach Boot-Jumper liegt die Interrupt-Vektor-Tabelle entweder am Anfang des RAM oder am Anfang des Flash Speichers. In beiden Fällen wird der Bott-Speicher auf Adresse 0x00000000 gemappt. Das erste Wort in der Interrupt-Vektor-Tabelle ist ein Zeiger auf die Startadresse des Programms. Der Code, der dort steht, stammt üblicherweise aus einer Quelltextdatei in Assembler (startup_stm32.s). In dieser Datei befindet sich übrigens auch die Interrupt-Vektor-Tabelle, wo ein paar wenige Interrupts vordefiniert sind. Weite kann man selbst ergänzen - ist kein Hexenwerk auch wenn man gar kein Assembler beherrscht. Das Assembler Startup-Code kopiert Daten vom Flash Speicher ins RAM (hauptsächlich Initialisierungswerte von Variablen) und füllt die Restlichen variablen mit 0x00 auf. Dann ruft er die C-Funktion "SystemInit" auf, falls vorhanden. Dann ruft er die Funktion "__libc_init_array", welche Bestandteil der C-Library newlib ist. Dann ruft er die "main" Funktion auf. Die SystemInit Funktion ist optional. Dort initialisiert man überlicherweise den Sytsemtakt. Kann man aber auch weglassen, wenn man erstmal mit dem Standard-Taltgeber (8Mhz R/C) zufrieden ist oder den Takt später in main() einstellt. Wenn man die Standard Lobrary oder Cube HAL verwendet, dann ist dort eine SystemInit Funktion enthalten. > Und wie wird die Systick-Routine mit der > Interrupttabelle verhakt? Im Startup Code werden mit ".weak" schwache Referenzen auf Interrupt-Handler definiert. Was es damit genau auf sich hat, habe ich noch nicht herausgefunden. Offensichtlich sind das Zeiger auf optionale Funktionen. Beispiel:
1 | void SysTick_Handler(void) |
2 | {
|
3 | systick_count++; |
4 | }
|
Im Gegensatz zu AVR braucht die Funktion keine speziellen Schlüsselwörter, welche sie als Interruptroutine kennzeichnet. Man muss allerdings aufpassen, daß man keinen Interrupt auslöst, für den die ISR fehlt. Die meisten Interrupts haben in der vorgegebenen Tabelle noch keine Namen und als Zeiger steht dort einfach nur eine 0. Anhand der wenigen vordefinierten Fälle (SystTick_Handler ist einer davon) kann man aber abgucken und die Tabelle ggf. ergänzen. > Die gesamte Initialisierung mit Clock-Einstellungen, > Taktfrequenz usw. nach Datenblatt in entsprechenden > selbstgeschriebenen Routinen gemacht Ich weiß gar nicht, warum viele Leute dies so schwierig finden. Ok, die Nötigen Infos sind im Datenblatt über mehrere nicht zusammenhängende Kapitel verstreut. Aber wenn man sich den Code anschaut, den CubeMx generiert und mal mit dem Datenblatt vergleicht, dann lernst man ganz schnell, worauf es ankommt. Und danach genügt das Datenblatt alleine. Bit in Registern setzen ist wahrlich kein Hexenwerk, wenn man Schrittweise voran geht. > Stack wächst von oben auf den ganzen Rest zu - WTF Warum "WTF?", das ist bei den meisten anderen Mikrocontrollen nicht anders. So kannst du ein und denselben Initialisierungscode für unterschiedliche Programme verwenden. Das RAM wird dadurch zur Laufzeit zwischen HEAP und STACK aufgeteilt. Nur tatsächich in der Mitte treffen sollten sie sich besser nicht. Aber wenn man das RAM anders aufteilen würde, wäre nichts gewonnen. So oder so führt ein Stack Überlauf zum Absturz, wenn man das nicht vorher erkennt und abfängt. > Zich Varianten werden präsentiert und jede soll die > Beste sein. Da weiß man dann gar nicht mehr was man machen soll. Da > führt die einfachste Variante eher zum Ziel, als die Beste ;-) In der Tat. In Zusammenhang mit dem ESP8266 habe ich erstmalig dazu herag gelassen, Arduino auszuprobieren und das hat im gegensatz zu allen anderen Varianten auf Anhieb geklappt. Ich habe auch andere ans Laufen bekommen, jedoch mit Fluchen und gereizten Nerven. Als danach zum ersten mal einem STM32 benutzt hatte, war es wieder die Arduino mgebung, die auf Anhieb funktionierende Ergebnisse brachte. Was soll ich sagen: Ich mag Arduino inzwischen. Zu AVR Zeiten sah das noch ganz anders aus. Daß man mit Arduino nicht alle Features voll ausreizen kann, sollte klar sein. Man muss sich nur Fragen, ob das für's jeweilige Projekt wirklich ein Hindernis ist, oder nicht. Für einen LED Blinker oder ein "Hello World" ist Arduino jedenfalls optimal. Das und mehr habe ich hier beschrieben: http://stefanfrings.de/stm32/index.html
> Wenn ich ein anderes Programmfenster wähle (z.B. Internet Explorer) > und dann auf das SW4STM32 Fenster klicke(irgendwo auf den Quellcode), > dann springt er manchmal vom Programmierbildschirm in den > Startbildschirm. Ist das ein Bug oder gibt es da ne Einstellung? Bei mir tritt dieser Effekt nicht auf. Hast du eventuell Skype laufen? Bei mir auf der Arbeit löst Skype manchmal solche Effekt auch in anderen IDE's aus.
Skype ist hier nicht installiert. Ist Windows 7 Pro. Außerer CubeMX und SW4STM32 sind gerade nur Windows Explorer, LibreOffice und Waterfox offen. Es ist gerade auch aufgetreten, als ich die main.c von einem anderen Projekt geschlossen habe.
Embitz ist die alternative zu coocox. Funktioniert in der regel auf anhieb
Heinz M. schrieb: > Ich ziehe bei mir die Grenze bei der IDE inkl. Librarys. Wenn du dabei einen Komfort wie bei Arduino haben möchtest kannst du dir auch mal mbed ansehen. Da gibt es einen Online Compiler, die Libs und Tools um auch Offline arbeiten zu können. Die Lib ist für viele Cortex-M fertig und wenn man nicht den kleinsten M0 nimmt ist mittlerweile auch ein RTOS integriert. Ein kleiner Haken: das 072 Disco wird nicht direkt unterstützt, nur das Nucleo. Diese sind sowieso besser für eigene Projekte weil da direkt Arduino oder ST Morpho Shields draufpassen. Beim Disco sind viele Dinger on Board verdrahtet und man muss mit ext. Peripherie aufpassen das die Pins nicht schon intern belegt sind. Aber da der Prozessor gleich ist mit dem Nucleo kannst du probieren ein Projekt für den Nuclieo zu erzeugen und auf dem Disco testen, sollte gehen wenn die Takterzeugung gleich ist. So ein Online angelegtes Projekt kann exportiert und in einer IDE weiterverwendet werden. Ich habe das mal für den Nucleo gemacht, wenn die die SW4STM32 installiert hast sollte sich das angehängte Projekt importieren lassen (ungetestet, habe diese IDE noch nicht auf dem Rechner).
Arduino habe ich nie probiert. Schields verwende ich keine, da am Ende Projekte mit langer Laufzeit entstehen sollen: -Universal Akkulader -CAN Bus Bewegungsmelder -Kellerlüftung -GPS und Kompass -... Mit Schields und Entwicklungsboards wird das etwas teuer. Die Discovery Boards haben trotzdem noch mehr freie GPIOs, als MSP430G2 oder Atmega 8, welche wir beim Studium hatten ;-) Bei SW4STM32 wird das STM32F072 unterstützt. Timer funktioniert mit von CubeMX erzeugtem Code. Frage: CubeMX erzeugt diesen Code:
1 | /*Configure GPIO pin Output Level */
|
2 | HAL_GPIO_WritePin(GPIOC, NCS_MEMS_SPI_Pin|EXT_RESET_Pin|LD3_Pin|LD6_Pin |
3 | |LD4_Pin|LD5_Pin, GPIO_PIN_RESET); |
4 | |
5 | /*Configure GPIO pins : NCS_MEMS_SPI_Pin EXT_RESET_Pin LD3_Pin LD6_Pin
|
6 | LD4_Pin LD5_Pin */
|
7 | GPIO_InitStruct.Pin = NCS_MEMS_SPI_Pin|EXT_RESET_Pin|LD3_Pin|LD6_Pin |
8 | |LD4_Pin|LD5_Pin; |
9 | (...)
|
10 | HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); |
Manuell war immer diese Deklaration (richtiger Begriff?) angegeben:
1 | GPIO_InitStruct.Pin = C9_Pin; |
Das heißt irgendwo muss eine Zuweisung erfolgen. Wo findet diese statt?
:
Bearbeitet durch User
'shields' ist nur ein Begriff für Erweiterungsplatinen der mit den Arduinos eingeführt wurde. Da die in Massen hergestellt werden sind die eigentlich spottbilig (wenn man die beim Chinesen bestellt). Eine leeres Lochrasterboard mit Klemmen ist da billiger als hier die Einzeilteile zu kaufen, oft sogar billiger als das Porto der Versender hier. Heinz M. schrieb: > Das heißt irgendwo muss eine Zuweisung erfolgen. Wo findet diese statt? Da wird eine Struktur mit Parametern gefüllt und in HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); wird die ausgewertet. Bei 'Komfort wie bei Arduino' meinte ich aber eher das man ein API hat das schon Unterstützung für wesentlich Dinge wie GPIO, UART, SPI, I2C, CAN, Timer, Interrupts usw. hat, weniger die fertigen Shields. Falls das so verstanden wurde.
Johannes S. schrieb: > Da wird eine Struktur mit Parametern gefüllt und in > HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); > wird die ausgewertet. Das ist klar. Ich suche die Zuordnung: Pin C9 = "LD3_Pin". Das muss ja irgendwo hinterlegt sein.
Heinz M. schrieb: > Das ist klar. Ich suche die Zuordnung: Pin C9 = "LD3_Pin". Das muss ja > irgendwo hinterlegt sein. Im Schaltplan oder im User Manual zu dem Board, http://www.st.com/content/ccc/resource/technical/document/user_manual/3b/8d/46/57/b7/a9/49/b4/DM00099401.pdf/files/DM00099401.pdf/jcr:content/translations/en.DM00099401.pdf (für den Link ist evtl. eine Registrierung bei ST nötig)
Dr. Sommer schrieb: > Nop schrieb: >> Stack wächst von oben auf den ganzen Rest zu - WTF > > Na, da beim ARM der Stack immer nach unten wächst, hat er am meisten > Platz zu wachsen, wenn er ganz oben anfängt... Richtig, und dann wächst er auf andere Daten zu. Das war übrigens beim Toyota Camry seinerzeit eines der Probleme, die letztlich zum Desaster geführt haben. Deswegen lege ich den Stack an den Anfang eines RAM-Bereiches, damit ich im schlimmsten Fall einen Hardfault kriege. Das ist wesentlich leichter zu erkennen, als wenn das System im undefinierten Zustand trotzdem noch irgendwie weiterläuft. Aber für den Anfang, das meinte ich ja auch schon, kann man das erstmal ignorieren.
Da habe ich mich missverständlich ausgedrückt. Initialisierung: LD3_Pin Ausführung(LED Einschalten): GPIOC, GPIO_PIN_9 Das steht in ein und dem selben Projekt und funktioniert auch. Woher weiß der Kompiler, dass es sich dabei um ein und das Selbe handelt?
Heinz M. schrieb: > Ich suche die Zuordnung: Pin C9 = "LD3_Pin". Das muss ja > irgendwo hinterlegt sein. Das wird schon in CubeMX festgelegt. Kannst auch deine eigenen Bezeichnungen für die Pins angeben. In der main.h finden sich die #define ....
Jetzt habe ich es auch gemerkt... Wenn es um die Deklaration von 'LD3_Pin' geht: mit Maus auf Symbol klicken und 'F3' drücken oder rechte Maustaste + 'open declaration'. Das mischen der Symbolnamen ist natürlich kein guter Stil und da kann man herrlich lange Fehler suchen.
> Deswegen lege ich den Stack an den Anfang eines RAM-Bereiches
Inwiefern ist das besser? Bei Stack Überlauf schmiert das System ebenso
ab. Und er läuft warscheinlich noch schneller über, da er ja nun eine
feste Maximalgröße hat.
Stefan U. schrieb: >> Stack wächst von oben auf den ganzen Rest zu - WTF > > Warum "WTF?", das ist bei den meisten anderen Mikrocontrollen nicht > anders. (...) Das RAM wird dadurch zur Laufzeit zwischen HEAP und > STACK aufgeteilt. Nur tatsächich in der Mitte treffen sollten sie > sich besser nicht. Aber wenn man das RAM anders aufteilen > würde, wäre nichts gewonnen. So oder so führt ein Stack Überlauf > zum Absturz, wenn man das nicht vorher erkennt und abfängt. >> Deswegen lege ich den Stack an den Anfang eines RAM-Bereiches > > Inwiefern ist das besser? Bei Stack Überlauf schmiert das System > ebenso ab. Nein, ganz anders, viel sauberer. Wenn der Stack "nur" den Heap überschreibt, läuft das Programm erstmal mit falschen Daten weiter. Im anderen Fall wird verhindert, dass irgendwelche Daten überschrieben werden -- schon per Definition: der Stack liegt am Anfang des RAM, davor ist nichts. Schreiben ins Nichts gibt einen Bus error oder einen Memory management fault. Damit kann man einfach einen Reset auslösen oder einen halbwegs geordneten Nothalt. Aber auf keinen Fall wird mit falschen Daten weiter gearbeitet. Mit Multitasking könnten sogar alle nicht betroffenen Tasks weiter laufen. > Und er läuft warscheinlich noch schneller über, da er ja nun eine > feste Maximalgröße hat. Die hat er doch immer, wir reden doch vom Cortex-M? Oder kannst du es steuern, dass der Heap rechtzeitig schrumpft wenn mehr Stack gebraucht wird? Überhaupt vermeidet man malloc() doch lieber. Und wenn, benutzt man kein free(), der Heap kann also nur im Extremfall schrumpfen. Aber eigentlich ist doch nur wichtig, dass der Stack rechtzeitig überläuft und nicht erst beim Kunden.
eagle user schrieb: > Aber eigentlich ist doch nur wichtig, dass der Stack rechtzeitig > überläuft und nicht erst beim Kunden. Welcher Kunde? Ich programmiere für mich selbst (Wink mit dem Zaunspfahl).
Nop schrieb: > Deswegen lege ich den Stack an den Anfang eines RAM-Bereiches, damit ich > im schlimmsten Fall einen Hardfault kriege. Das ist wesentlich leichter > zu erkennen, als wenn das System im undefinierten Zustand trotzdem noch > irgendwie weiterläuft. Der Einwand erscheint mir etwas akademisch. Was der Stack überschreibt, wenn er was überschreibt, ist doch eigentlich ziemlich wurscht: jedenfalls läuft das Programm dann nicht mehr so, wie's soll. Wenn er in die Vektortabelle reinwächst, fangen irgendwann mal die (wahrscheinlich seltener genutzten) "hinteren" ISRs an zu spinnen (und laufen vielleicht sogar noch - irgendwie, weil der Stack Return-Addressen enthält und damit auf "irgendwie lauffähigen" Code zeigt). Das ist sicher nicht einfacher zu debuggen als falsche Daten im Heap...
Stefan U. schrieb: >> Deswegen lege ich den Stack an den Anfang eines RAM-Bereiches > > Inwiefern ist das besser? Bei Stack Überlauf schmiert das System ebenso > ab. Richtig, und besser definiert abschmieren als undefiniert für wer weiß wie lange fehlerhaft weiterlaufen. Man kann ja außerdem im Hardfault-Handler auch noch z.B. Debugausgaben machen oder etwas ins Backup-RAM loggen. > Und er läuft warscheinlich noch schneller über, da er ja nun eine > feste Maximalgröße hat. Die Größe ist dann zwar fest, aber konfigurierbar. Man läßt sich hierzu mit dem Compiler seiner Wahl einfach den Stackbedarf seiner Funktionen ausgeben, ermittelt den tiefsten Callpath, addiert noch alle Interrupts drauf und kennt den worst-case-Bedarf. Und natürlich noch Marge, damit man das nicht dauernd neu machen muß. Oder wie garantiert man sonst, daß der Stack nicht im ungünstigsten Moment in den Heap reinwächst? Prinzip Hoffnung? Zumal man den Heap ohnehin meistens nicht benutzt, weil malloc sehr problemträchtig ist und dann noch mehr Arbeit für die Analyse erfordern würde. Ohne Heap wächst der Stack dann direkt auf die globals zu. Markus F. schrieb: > Der Einwand erscheint mir etwas akademisch. Nein: http://embeddedgurus.com/state-space/2014/02/are-we-shooting-ourselves-in-the-foot-with-stack-overflow/ So machen das die Profis (bzw.: so hätten sie es machen sollen). Allein schon zu Lernzwecken finde ich es auch bei Hobbyprojekten interessant, sich damit zu befassen, wie man das professioneller machen würde. Insofern ist es fatal, daß das Demo-Linkerscript meistens den Stack so legt, daß man sich absehbar in den Fuß schießt. Ich will gar nicht wissen, wieviele kommerzielle Produkte (außer dem Camry seinerzeit) noch so gemacht sind, weil das Problem nicht einmal bekannt ist. > Wenn er in die Vektortabelle reinwächst Tut er nicht, die liegt ja im ROM. Und wenn man sie ins RAM legt, kann man die ja auch hinter den Stack legen, an irgendeine durch 512 teilbare Adresse.
Einverstanden, daß man daß so machen kann (und durchaus auch einverstanden, daß das eine ganz clevere Lösung ist). Daß man das so machen muß, das akzeptiere ich aber trotzdem nicht ;). Jedes_ Stück einigermaßen komplexer Software _muß sicherstellen, daß im Feld kein Stacküberlauf entsteht. Wie man das macht, ist wurscht. Nachteilig erscheint mir, daß wenn ich im Laufe der Entwicklung feststelle, daß der Stackspace nicht mehr reicht, anschließend u.U. nix mehr da ist wo's vorher war?
Markus F. schrieb: > Jedes_ Stück einigermaßen komplexer Software muß sicherstellen, daß > im Feld kein Stacküberlauf entsteht. Wie man das macht, ist wurscht. Der Charme besteht halt darin, daß man noch eine Vorkehrung hat, wenn die Analyse falsch war. > Nachteilig erscheint mir, daß wenn ich im Laufe der Entwicklung > feststelle, daß der Stackspace nicht mehr reicht, anschließend u.U. nix > mehr da ist wo's vorher war? Wie, wo es vorher war? Ist doch egal, der Linker verteilt die Variablen sowieso automatisch, dann rücken die eben etwas nach oben. Ein Problem hat man nur, wenn man am Linker vorbei RAM-Bereiche direkt betut, die nicht sowieso eigene Adreßbereiche haben.
Ist der Hard-Fault bei Unterlauf eigentlich irgendwo in den ARM-Specs garantiert? Könnte ja auch sein, daß der Stackpointer einfach "umklappt"?
Markus F. schrieb: > Ist der Hard-Fault bei Unterlauf eigentlich irgendwo in den > ARM-Specs garantiert? Wenn unterhalb des RAM nichts ist, wo man hinschreiben/rauslesen kann, dann gibt's nen Hardfault, Busfehler oder sowas in der Art. Der SP ist ein 32bit-Register und klappt daher nur von 0x00000000 auf 0xffffffff um.
Stefan U. schrieb: > Das finde ich sehr praktisch, kenne ich von den einfacheren AVR's > nicht. Wenn man sich etwa beim F405 mal die memory map anschaut: CCM geht von 0x1000000 - 0x1000FFFF (64 kB). Darunter ist aber von 0x0810000 - 0x0FFFFFF ein reservierter Bereich, das sind 8 MB. Unterhalb davon wiederum endet gerade das Flash. Wenn man also den Stack ins CCM linkt, dann kriegt man ganz zuverlässig einen Fehler bei Overflow. Verfrachtet man ihn dagegen an den Anfang der beiden kontinuierlichen SRAM-Bereiche, dann reichen die zusammengenommen von 0x2000000 - 0x2001FFFF. Unterhalb ist von 0x1FFFC008 - 0x1FFFFFFF ein reservierter Bereich von 16 kB, darunter gehen die Option Bytes los.
Das mbed Projekt das ich hier Beitrag "Re: STM32F072 Disco + CooCox CoIDE + CubeMX" gepostet hatte lässt sich nicht mit SW4STM32 kompilieren, der mbed Exporter hat noch zwei Schönheitsfehler. Im Anhang ist ein manuell gefixtes Projektfile, das Originale aus ersten Post im workspace mit dem neuen ersetzen, dann sollte es ordentlich compilieren. Nur das Disco 072 Board habe ich nicht, das kann ich nicht testen.
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.