Forum: Mikrocontroller und Digitale Elektronik Hello World für den STM32


von Josef V. (Firma: e. GmbH) (htpem)


Lesenswert?

Hallo,

ich möchte gerne mein erstes Programm für den STM32 schreiben. Soll erst 
mal nicht viel können, eine LED blinken lassen reicht mir für das erste.
Für diese Aufgabe habe ich folgendes Arbeitsgerät zur Verfügung:

- IAR Embedded Workbench for ARM 6.21.1
- Evalboard (geschenkt bekommen)
  - STM32F103VE
  - EPC-XKIT05-STM-STM32F103
- Debugger ST-LINK

Ich bin die Sache einfach mal ganz blauäugig angegangen:

1. Entwicklungsumgebung gestartet
2. Neuen Workspace angelegt
3. Neues Projekt angelegt
   - C++ Programm mit main() ausgewählt
4. Unter den Projektoptionen
   General Options/Target/Processor variant
   Device ausgewählt und "ST STM32F10xxE" gewählt
5. In der main.cpp das Programm so abgeändert, dass es so aussieht:
1
int main()
2
{
3
  while(1);
4
  return 0;
5
}
   und übersetzt. Das klappt mit der Warnung:
   "Warning[Pe111]: statement is unreachable"
   was logisch ist und mich auch erst mal nicht weiter stört.
6. Unter den Projektoptionen
   Debugger/Driver
   "ST-LINK" eingestellt
7. Das Evalboard mit Spannung versorgt
8. Download und Debug gedrückt

Nun ist es so, dass ich schon den Eindruck habe, dass ich tatsächlich 
auf das Eval-board komme. Ich kann auch auf die while(1) Schleife einen 
Breakpoint ansetzen, nur erreiche ich diesen nicht.
Nun liegt die vermutung nahe, das schon vorher etwas schief geht. Nur 
was?

Grüße
htpem
von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Eine Warning ist immer schlecht, mach mal sowas:

int main()
{
  volatile int i = 0;
  while(1)
    i++;
  return 0;
}

Immer bei Warnings / Hints ist was schlecht und kann zu Problemen 
führen, also alle immer weg machen.
von (prx) A. K. (prx)


Lesenswert?

Jo, aber die Warnung sollte man wegbekommen, indem man das unerreichbare 
"return" in die Tonne befördert.
von htpem (Gast)


Lesenswert?

Hallo mmvisual,

die Warnung beziet sich darauf, dass bei einer Endlosschleife es nicht 
möglich ist die Zeile "return 0" zu erreichen.
Ich will jedoch nicht pampig werden und ändere kurz den Quellcode ab:
1
int main()
2
{
3
  volatile int i = 0;
4
  while (i > 2){
5
    i++;
6
    i = 0;
7
  }
8
  return 0;
9
}
Erwartungsgemäß mit dem gleichen Resultat, jetzt jedoch ohne Warnung.
Dein Vorschlag erzeugt übrigens logischerweise die selbe Warnung.

Grüße
htpem
von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Ich hab es auch grad das nicht compiliert / getestet.

Dennoch kommen bei der Übersetzung meist wegen Typecasts 
Warnungen/Hinweise, die man am besten immer weg macht. (Nur so als Tipp 
für die Zukunft)

Debuggen geht jetzt?
von Josef V. (Firma: e. GmbH) (htpem)


Lesenswert?

Hallo mmvisual,

um es nochmals deutlich zu sagen: das Ganze hat nichts mit dem Quellcode 
zu tun, ich erreiche main() ja schon gar nicht.
Die Ursache liegt in fehlenden Initialisierungen des SP oder ähnlich, so 
genau weis ich das jedoch nicht.
Ich dachte hald mal ich poste das vollständig, jemand wird mir schon auf 
die Sprünge helfen wie ich den STM32 richtig initialisiert bekomme in 
der IAR Workbench.
Also nix für ungut und trotzdem Danke für Deine Vorschläge.

Grüße
htpem
von heldvomfeld (Gast)


Lesenswert?

Servus,
ich kenne mich leider mit dem STM32 nicht aus und kenne auch die 
Kompilerspezifikationen nicht, allerdings ist es häufig so, dass die 
Kompiler eine leere Schleife einfach "wegoptimieren". Deswegen würde ich 
in einer leeren Schleife (Endlosschleife bspw.) zumindestens nen nop - 
Befehl tippen.

gruß~
von Peter (Gast)


Lesenswert?

>um es nochmals deutlich zu sagen: das Ganze hat nichts mit dem Quellcode
>zu tun, ich erreiche main() ja schon gar nicht.

Bist Du Dir da so sicher? Gut möglich dass Dir gleich das ganze main(0) 
wegoptimiert wird, weil der Code nichts bewirkt, jetzt probiere es doch 
endlich mit einem der Beispielen, die Dir hier gegeben wurden!!! 
Gaaaaaaanz wichtig, das Zauberwort "volatile" es verhindert, dass die 
Variable vom Optimizer wegrationalisiert wird!

Und benutze zum anfangen mal einfach ein C-Projekt und nicht gleich C++

Mein Vorschlag:
1
int main()
2
{
3
  volatile int i = 1;
4
  while(i)
5
    i++;
6
  return 0;
7
}
von (prx) A. K. (prx)


Lesenswert?

heldvomfeld schrieb:

> Kompilerspezifikationen nicht, allerdings ist es häufig so, dass die
> Kompiler eine leere Schleife einfach "wegoptimieren".

Nur wenn sie aus Sicht des Compilers wirkungslos ist. Eine 
Endlosschleife ist aber das exakte Gegenteil von garnix, darf also nicht 
wegoptimiert werden. Wobei jedoch ihr eventueller Inhalt verschwinden 
kann, wenn scheinbar wirkungslos, und dann nur die nackte Schleife 
bleibt.
von htpem (Gast)


Lesenswert?

Ich hab's probiert, sogar mit assembler NOP. Nur der Vollständikeit 
halber. Erwartungsgemäß gleiches Resultat.

Grüße
htpem
von Martin (Gast)


Lesenswert?

Markus Müller schrieb:
> Dennoch kommen bei der Übersetzung meist wegen Typecasts
> Warnungen/Hinweise

Ja genau. Casts führen häufig zu "statement unreachable".

Bevor du den OP anpflaumst, solltest du selbst erstmal die 
allereinfachsten Grundlagen lernen.

Oder halt höflich bleiben und sinnlose Entgegnungen vermeiden.
von htpem (Gast)


Lesenswert?

Also nochmal von vorne:

1. Ich wollte nicht unhöflich sein oder jemanden anpflaumen. 
Entschuldigung wenn sich jemand so angesprochen fühlte.
2. Wer oder was ist OP?
3. Wo gibt es einen cast?
4. Mit folgendem Programm erreiche ich ebenfalls nicht den Breakpoint in 
der Programmzeile i++:
1
int main()
2
{
3
  volatile int i = 0;
4
  i++;
5
  return 0;
6
}
Hier gibt es keinen cast, keine Schleife die wegoptimiert werden kann 
und auch keinen Fehler und keine Warnung.

Trotzdem, wie gesagt erreiche ich den Breakpoint nicht.

Grüße
htpem
von W.S. (Gast)


Lesenswert?

heldvomfeld schrieb:
> ...leere Schleife einfach "wegoptimieren"...

Ich halte den gewählten Programmierstil ohnehin für grottenschlecht. 
Irgendwann hat mal so ein selbst ernannter Guru den Kindern beigebracht, 
daß 'goto' etwas gaaaaanz schlechtes sei - und mangels eigener Fähigkeit 
zur besseren Einsicht halten die sich dann ein Leben lang sklavisch 
daran und umschreiben das Ganze mit while(true) blablabla;

Gerade in main() bei einem uC ist die Verwendung von goto sehr 
angemessen:

void main (void)    // jaa, guckt mal, ob euer Startupcode überhaupt
{                   // jemals ein Argument übergeben kann!
  InitMyDies();
  InitMyDas();
  InitMyBlaBla();

immerzu:
  hier alles hin
  was der uC immerzu
  erledigen muß

goto immerzu;
}
/* eof */


W.S.
von (prx) A. K. (prx)


Lesenswert?

htpem schrieb:

> 1. Ich wollte nicht unhöflich sein oder jemanden anpflaumen.
> Entschuldigung wenn sich jemand so angesprochen fühlte.

Damit warst nicht du gemeint ...

> 2. Wer oder was ist OP?

... aber damit.

> 3. Wo gibt es einen cast?

Nirgends.

> 4. Mit folgendem Programm erreiche ich ebenfalls nicht den Breakpoint in
> der Programmzeile i++:

Wenn wie hier wenig zielführende Resonanz kommt, dann sind entweder alle 
mit passendem Profil beim Essen oder es gibt davon zu wenige. IAR ist 
für praktische Anwendung a bissel teuer.
von (prx) A. K. (prx)


Lesenswert?

W.S. schrieb:

> Ich halte den gewählten Programmierstil ohnehin für grottenschlecht.

Nur dürfte das eigentliche Problem nichts mit der Schleife zu tun haben, 
lange Diskussionen über tote oder lebende Schleifen und gotos bringen 
ihn folglich nicht weiter.

Hier sind eher Leute mit Praxis beim IAR gefragt.
von htpem (Gast)


Lesenswert?

Danke prx, das trifft wohl den Nagel auf den Kopf.
von W.S. (Gast)


Lesenswert?

A. K. schrieb:
> Hier sind eher Leute mit Praxis beim IAR gefragt.

Ja, aber bei mir nicht mit ARM, sondern mit NEC. Die Anzeige von nicht 
erreichbarem Code ist bei original ARM genau so. Das ist keine 
IAR-spezifische Warnung. ich schreib's aber nochmal: Denkt bevor ihr den 
Editor benutzt. Im uC ist hinter main() normalerweise _garnix_:

               LDR     R0, =main
               BLX     R0
               B       .
               ENDP

also ist es eigentlich sinnlos, main als "int main (..)" zu deklarieren. 
Ja, ich weiß, man macht es der lieben Konvention zuliebe ja doch, weil 
ansonsten eine andere Warnung aufpoppt, aber ein return mit value 
hinzuschreiben, sollte man sich verkneifen.

W.S.
von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

A. K. schrieb:
> Hier sind eher Leute mit Praxis beim IAR gefragt.

Ich denke morgen, während normalen Bürozeiten sollten wieder Leute hier 
mitlesen die einen IAR vor sich haben und können sicher besser helfen.
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.