STM32-Programmierung-Tipps und Fragen
Konnte ich nicht finden, eine gute Dokument im internet über STM32-Programmierung. STM eigenen Dokumente nicht erklären nichts mehr, als register Funktionen. Ich werde sehr dankbar, wenn jemand erklären kann, meine folgenden Fragen?
- Bemerkte ich, dass alle Beispiel-Programme, STM bietet, lokale Variablen für main() immer definiert, außerhalb der main () - Funktion (mit gelegentlicher Verwendung von static-Schlüsselwort). Gibt es einen Grund dafür? Sollte ich eine ähnliche Praxis? Sollte ich vermeiden, verwenden Sie lokale Variablen innerhalb der main?
- Ich habe eine gloabal Variablen, die aktualisiert wird, in der clock-interrupt behandeln. Ich bin mit der gleichen variable, die innerhalb einer anderen Funktion als Schleifenbedingung. Kann ich nicht zugreifen zu können, müssen Sie diese variable mit irgendeiner form von atomarer read-operation? Wie kann ich wissen, dass einen Uhr-interrupt nicht ändern Sie dessen Wert in der Mitte der Ausführung der Funktion? Sollte ich absagen müssen clock-interrupt jedes mal wenn ich diese variable innerhalb einer Funktion? (Dies scheint jedoch äußerst ineffektiv, um mich, wie ich es als Schleifenbedingung. Ich glaube, es sollte bessere Möglichkeiten, es zu tun).
- Keil fügt automatisch ein Startcode, die ist geschrieben in der Montage (d.h. startup_stm32f4xx.s). Dieser startup-code die folgende import-Anweisungen:
IMPORT SystemInit
IMPORT __main
.In "C", macht es Sinn. Aber in C++ werden beide Haupt-und system_init unterschiedliche Namen haben (z.B. _int_main__void). Wie können diese startup-code noch arbeiten können in C++ auch ohne Verwendung von "extern "C" " (ich habe versucht und es funktionierte). Wie kann der c++ - linker (armcc --cpp) aus und ordnen diese Aussagen mit den richtigen Funktionen?
Diese Fragen sind alle ziemlich unabhängig voneinander sind. Warum nicht brechen Sie in drei verschiedenen Fragen auf stackoverflow, so dass, wenn jemand weiß, die Antwort auf eine von Ihnen, aber nicht alle von Ihnen können Sie immer noch beraten?
Ich bin damit einverstanden. Als spät-coming-Leser, ich würde auch eher das Sie getrennt werden, so kann ich finden, was ich über Pflege effizienter zu gestalten.
Ich bin damit einverstanden. Als spät-coming-Leser, ich würde auch eher das Sie getrennt werden, so kann ich finden, was ich über Pflege effizienter zu gestalten.
InformationsquelleAutor tantuni | 2011-11-12
Schreibe einen Kommentar Antworten abbrechen
Du musst angemeldet sein, um einen Kommentar abzugeben.
können Sie lokale oder Globale Variablen, die mit local in embedded-Systeme, hat ein Risiko von Ihrem stack-Kollision mit Ihren Daten. mit globals, die Sie nicht haben, dass problem. aber dies ist wahr, egal wo Sie sind, eingebettet, mikrocontroller, desktop, etc.
Ich würde eine Kopie des globalen in der Vordergrund-task, der es verwendet.
und dann nur mit myg für den rest der Funktion. Im Grunde nehmen Sie einen Schnappschuss und mit dem snapshot. Sie möchten die gleiche Sache zu tun, wenn Sie das Lesen von einem register, wenn Sie wollen, um mehrere Dinge basiert auf einer Stichprobe von etwas nehmen, eine Probe von es und entscheiden, dass eine Probe, sonst kann der Gegenstand änderung zwischen den Proben. Wenn Sie mit einer globalen Kommunikation hin und her, um den interrupt-handler, naja ich möchte zwei Variablen einen Vordergrund zu unterbrechen, den anderen unterbrechen, in den Vordergrund. ja, es gibt Zeiten, in denen Sie benötigen, um sorgfältig zu verwalten, eine gemeinsame Ressource, wie normal es zu tun hat mit den Zeiten, wo Sie mehr tun müssen, als eine Sache, zum Beispiel, wenn Sie hatte mehrere Positionen, die alle brauchen, um zu ändern, als eine Gruppe, bevor der Hundeführer sehen können Sie ändern, dann müssen Sie zum deaktivieren der interrupt-handler auf, bis alle Elemente verändert haben. hier gibt es nichts besonderes zu embedded-mikrocontroller das ist alles grundlegende Dinge, die Sie sehen auf einem desktop-system mit einem ausgewachsenen Betriebssystem.
Keil weiß, was Sie tut, wenn Sie Unterstützung von C++, dann von der system-Ebene Sie haben diese ausgearbeitet. I dont use-Keil-ich benutze gcc und llvm für mikrocontroller wie dieser.
Edit:
Hier ist ein Beispiel von was ich spreche
https://github.com/dwelch67/stm32vld/tree/master/stm32f4d/blinker05
stm32 verwenden von timer-interrupts basiert, der interrupt-handler ändert eine variable, die gemeinsam mit der Aufgabe Vordergrund. Die Aufgabe Vordergrund, dauert eine einzelne Momentaufnahme von der shared variable (pro loop) und wenn es sein muss, nutzt die snapshot-mehr als einmal in der Schleife anstatt der freigegebenen variable, die sich ändern können. Das ist C, nicht C++ - ich verstehe das, und ich bin mit gcc und llvm nicht Keil. (Hinweis: llvm hat die bekannten Probleme, die Optimierung der engen while-Schleifen sehr alten bug, weiß nicht, warum Sie kein Interesse haben, zur Festsetzung, llvm funktioniert für dieses Beispiel).
Ich bin nicht einverstanden mit dwelch ersten Satz. Wenn Sie eine variable ändern von lokalen zu globalen, werden Sie die Steigerung Ihrer RAM-Nutzung, da eine Globale variable, nimmt den RAM die ganze Zeit, während eine lokale variable nur RAM, während die Funktion im Gültigkeitsbereich, und selbst dann könnte es sein, gespeichert in einem register statt im RAM. Da Sie die Erhöhung Ihrer Verwendung von RAM, das erhöht die chance, Ihren stack Kollision mit Ihren Daten (stack-overflow).
Sie haben die "Kontrolle" über die ram-Auslastung und es ist sehr deterministisch, wenn Sie Sie verwenden, globals, locals, braucht viel mehr Arbeit und können variieren mit subtilen Veränderungen. wenn Sie bereit sind zu tun, die Analyse, dann gehen Sie für es. Ich Stimme sicherlich zu, dass die einheimischen Sie "mehr ram" in dem Sinne, dass Sie es wiederverwenden, viel und bekommen viel mehr Variablen zur Verfügung, um Ihr Programm Dinge wie, dass.
Ich sollte erwähnt haben, dass die shared Variablen sollten deklariert als volatile zu versichern, dass der compiler tatsächlich liest es aus dem ram (es hängt alles davon ab, was dein code aussieht). Wenn Sie Lesen, a=b, und Sie versichern, dass b Lesen aus dem ram und nicht im Vordergrund register UND der Speicher ist etwas, das gelesen werden kann, in einem einzelnen transfer (32 bit oder weniger, vielleicht auch 64 bit, aber ich bezweifle, dass dieses Ding hat eine 64-bit-AXI/amba-bus), DANN sind Sie gehen, um ein vollständiges Beispiel der, dass die variable...
ja, könnte es sein, nachdem oder bevor der Hundeführer verpasst. Ob das wichtig ist oder nicht, hängt von Ihrer system-design. Wenn beide Benutzer der freigegebenen Ressource sind dabei read-modify-schreibt der Artikel ja dann müssen Sie beide verwenden eine Atomare operation, und Sie würde zu bewältigen haben, die durch standard-Methoden, ausschalten von interrupts sperren, etc. Wenn man liest und die anderen read-modify-writes dann können Sie nicht brauchen, hängt davon ab, wie Ihr code funktioniert. Wenn es eine Schleife, dann werden Sie fangen den neuen Wert das nächste mal um.
InformationsquelleAutor old_timer
Frage 1: Lokale Variablen
Den Beispielcode von ST ist nicht besonders effizient oder elegant. Es bekommt den job getan, aber manchmal gibt es keine gute Gründe für die Dinge, die Sie tun.
Im Allgemeinen verwenden Sie immer wollen, dass Ihre Variablen haben den kleinsten Bereich möglich. Wenn Sie nur eine variable in einer Funktion definieren, die Sie innerhalb dieser Funktion. Fügen Sie das "static" Schlüsselwort, um die lokalen Variablen, wenn-und nur wenn Sie Sie brauchen, um Ihren Wert behalten, nachdem die Funktion fertig ist.
In einigen embedded-Umgebungen, wie die PIC18-Architektur mit dem C18-compiler, lokale Variablen sind viel teurer (mehr Programm-Speicherplatz, langsamere Ausführungszeit) als global. Auf dem Cortex M3, das ist nicht wahr, so sollten Sie fühlen sich frei, verwenden Sie lokale Variablen. Überprüfen Sie die Liste der assembly und sehen Sie selbst.
Frage 2: Austausch von Variablen zwischen interrupts und der main-loop
Leute geschrieben haben, ganze Kapitel erläutert die Antworten zu dieser Gruppe von Fragen. Wann immer Sie teilen sich eine variable zwischen der main-loop und ein interrupt, sollten Sie auf jeden Fall verwenden Sie die
volatile
keywords auf. Variablen von 32 oder weniger bits zugegriffen werden kann atomar (es sei denn, Sie sind falsch).Wenn Sie brauchen, um auf eine größere variable oder zwei Variablen gleichzeitig aus der main-Schleife, so haben Sie zum deaktivieren der Uhr zu unterbrechen, während Sie den Zugriff auf die Variablen. Wenn dein interrupt nicht erfordert präzises timing, das wird kein problem sein. Wenn Sie re-aktivieren Sie den interrupt ein, wird es automatisch ausgelöst, wenn es nötig ist.
Frage 3: die main-Funktion in C++
Ich bin mir nicht sicher. Sie können
arm-none-eabi-nm
(oder was auch immernm
wird in Ihrem Namen toolchain) an Ihren Objekt-Datei, um zu sehen, welche symbol-name der C++ - compiler weistmain()
. Ich würde Wetten, dass der C++ Compiler verzichten mangeln die wichtigste Funktion für diesen genauen Grund, aber ich bin mir nicht sicher.InformationsquelleAutor David Grayson
STM-sample-code ist nicht ein exemplar der gute Codierung der Praxis, es soll lediglich exemplarisch für die Nutzung Ihrer standard peripheral library (vorausgesetzt, diese sind die Beispiele, die Sie sprechen). In einigen Fällen kann es sein, dass Variablen deklariert werden, die externe
main()
weil auf Sie zugegriffen wird, aus einem interrupt-Kontext (shared memory). Gibt es vielleicht auch eine Möglichkeit, dass es gemacht wurde, die Art und Weise bloß zu erlauben, die Variablen, die beobachtet werden in den debugger aus jedem Zusammenhang gerissen, aber das ist kein Grund zum kopieren der Technik. Meiner Meinung nach der STM ist der Beispiel-code ist, dass es allgemein ziemlich schlecht, selbst als Beispiel-code, geschweige denn von software-engineering-Sicht.In diesem Fall Ihre Uhr-interrupt-variable atomar ist, so lange, wie es ist (32bit oder weniger so lange, wie Sie nicht mit read-modify-write Semantik mit mehreren Autoren. Sie können sicher einen Schreiber und mehrere Leser unabhängig. Dies gilt für diese Besondere Plattform, aber nicht unbedingt universell; die Antwort kann unterschiedlich sein für die 8-oder 16-bit-Systeme, oder für multi-core-Systeme zum Beispiel. Die variable erklärt werden sollte
volatile
in jedem Fall.Bin ich mit C++ auf STM32 mit Keil, und es ist kein problem. Ich bin nicht sicher, warum Sie denken, dass der C++ - Eintrag Punkte sind anders, Sie sind nicht hier, (Keil ARM-MDK v4.22a). Die start-up-code ruft
SystemInit()
die Initialisierung der PLL-und Speicher-timing-zum Beispiel, dann ruft__main()
führt, die Globale statische Initialisierung ruft dann C++ Konstruktoren für Globale statische Objekte vor dem Aufrufmain()
. Wenn Sie Zweifel haben, Schritt für Schritt durch den code in den debugger. Es ist wichtig zu beachten, dass__main()
ist nicht diemain()
Funktion, die Sie schreiben, für Ihre Anwendung, es ist ein wrapper mit verschiedenen Verhalten für C und C++, aber letztendlich ruft Ihremain()
Funktion.InformationsquelleAutor Clifford