Forum: Mikrocontroller und Digitale Elektronik STM32F072 Disco + CooCox CoIDE + CubeMX


von Heinz M. (subi)


Lesenswert?

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
von pegel (Gast)


Lesenswert?

Was spricht gegen CubeMX + SW4STM32 ?

von Nop (Gast)


Lesenswert?

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.

von Heinz M. (subi)


Lesenswert?

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?

von Stefan F. (Gast)


Lesenswert?

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.

von STM Apprentice (Gast)


Lesenswert?

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.

von Heinz M. (subi)


Lesenswert?

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.

von STM Apprentice (Gast)


Lesenswert?

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.

von Stefan F. (Gast)


Lesenswert?

> 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.

von Johannes S. (Gast)


Lesenswert?

Oder der Treiber liegt in einem anderen Verzeichnis und es fehlt der 
Includepfad.

von Nop (Gast)


Lesenswert?

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.

von pegel (Gast)


Lesenswert?

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"

von Heinz M. (subi)


Lesenswert?

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?

von pegel (Gast)


Lesenswert?

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.

von Nop (Gast)


Lesenswert?

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???

von Heinz M. (subi)


Lesenswert?

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
von Nop (Gast)


Lesenswert?

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! ^^)

von Heinz M. (subi)


Lesenswert?

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?

von Dr. Sommer (Gast)


Lesenswert?

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...

von Stefan F. (Gast)


Lesenswert?

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

von Stefan F. (Gast)


Lesenswert?

> 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.

von Heinz M. (subi)


Lesenswert?

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.

von Em bitz (Gast)


Lesenswert?

Embitz ist die alternative zu coocox. Funktioniert in der regel auf 
anhieb

von Johannes S. (Gast)


Angehängte Dateien:

Lesenswert?

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).

von Heinz M. (subi)


Lesenswert?

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
von Johannes S. (Gast)


Lesenswert?

'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.

von Heinz M. (subi)


Lesenswert?

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.

von Johannes S. (Gast)


Lesenswert?

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)

von Nop (Gast)


Lesenswert?

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.

von Heinz M. (subi)


Lesenswert?

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?

von pegel (Gast)


Lesenswert?

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 ....

von Johannes S. (Gast)


Lesenswert?

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.

von Stefan F. (Gast)


Lesenswert?

> 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.

von Heinz M. (subi)


Lesenswert?

pegel schrieb:
> In der main.h finden sich die #define ....

Danke, das habe ich gesucht.

von eagle user (Gast)


Lesenswert?

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.

von Heinz M. (subi)


Lesenswert?

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).

von Markus F. (mfro)


Lesenswert?

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...

von Nop (Gast)


Lesenswert?

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.

von Markus F. (mfro)


Lesenswert?

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?

von Nop (Gast)


Lesenswert?

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.

von Markus F. (mfro)


Lesenswert?

Ist der Hard-Fault bei Unterlauf eigentlich irgendwo in den ARM-Specs 
garantiert?

Könnte ja auch sein, daß der Stackpointer einfach "umklappt"?

von Nop (Gast)


Lesenswert?

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.

von Stefan F. (Gast)


Lesenswert?

Das finde ich sehr praktisch, kenne ich von den einfacheren AVR's nicht.

von Nop (Gast)


Lesenswert?

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.

von Johannes S. (Gast)


Angehängte Dateien:

Lesenswert?

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
Noch kein Account? Hier anmelden.