Funktionale Programmierung mit MCU(s)

Funktionale Sprachen wie Haskell, LISP oder Scheme ermöglichen es einem Programmierer, schnell mit dem Paradigma der funktionalen Programmierung zu arbeiten . Sie haben ihre Ineffizienzen , aber meine Anwendung legt mehr Wert auf die Effizienz des Programmierers als auf die Effizienz des Programms selbst.

Ich möchte die funktionale Programmierung auf einem Mikrocontroller verwenden, um Maschinensteuerung usw.

Welche Einschränkungen gibt es, z. B. Mindestsystemressourcen?
Welche Beispielimplementierungen dieser Sprachen sind verfügbar?

Wenn Ihre Frage lautet: "Ist es das nicht wert, jede Maschine mit der leistungsstärksten Programmiersprache zu programmieren, die Sie in die Finger bekommen können?", sollten Sie die C++- und Java - Fragen lesen (mehr über OOP als über funktionale Programmierung).
Ihr erster Absatz wirkt argumentativ, was Ihnen einige knappe Stimmen eingebracht hat. Erwägen Sie eine Umformulierung in etwas Passiveres ("Ich interessiere mich für die Verwendung funktionaler Programmierung für die Maschinensteuerung, welche Beispiele gibt es für Haskell/LISP/Scheme-Implementierungen für eingebettete Systeme") oder entfernen Sie sie vollständig.
Ich kaufe Ihre "ineffiziente" Aussage nicht. Sie scheinen eine extreme Tendenz zur Bastler-/Prototypenseite zu zeigen - geringe Lautstärke (auch bekannt als: 1). C/C++/asm führt zu kleinerem, schnellerem Code, der tausend- oder millionenfach verstärkt wird, wenn Sie Prozessoren mit gerade genug Geschwindigkeit und Speicherplatz verwenden können. Eingebettet ist eingebettet. Sie programmieren nicht auf einem universellen Betriebssystem.
@sheepsimulator, diese Frage ist sehr umstritten und es gibt nie eine eindeutig richtige Antwort. Dies ist nicht das, wofür SO verwendet werden soll.
@Kortuk - Machen wir es dann nicht argumentativ, anstatt es loszuwerden. Ich werde weitermachen und es bearbeiten und für eine Wiedereröffnung stimmen, es gibt bereits 2 Stimmen zur Wiedereröffnung und es wurden konstruktive Antworten wie die von Joby (die jetzt bearbeitet werden müssen) und die von Pingswept erhalten. Versuchen Sie nicht, Ihre ♦ Autorität an sich zu reißen, sondern versuchen Sie einfach zu helfen.
@reemrevnivek, ich tätige einen Anruf in dem Wissen, dass er wiedereröffnet werden kann, wenn die Community anders denkt, aber Diskussionen über Programmiersprachen sind von Natur aus emotional.
@Kortuk, reemrvnivek - der Hauptgrund, warum ich so gefragt habe, ist, dass ich wenig Diskussion über die Verwendung von Dingen jenseits von C/C++ zum Programmieren von MCUs sehe. Ich fand Jobys Antwort hilfreich. Nur so konnte ich es sagen; Wenn jemand einen Weg findet, der weniger aufrührerisch erscheint, dann tu es.
@sheepsimulator - Fertig!
@Kortuk - Natürlich sind sie das. Dies ist jedoch keine Diskussion über die Vorzüge verschiedener Programmiersprachen (oder sollte es zumindest nicht sein). Es geht (jetzt) ​​um Implementierungen von funktionalen Programmiersprachen.
@Nick T - "C/C++/asm führt zu kleinerem, schnellerem Code, der tausend- oder millionenfach verstärkt wird, wenn Sie Prozessoren mit gerade genug Geschwindigkeit und Speicherplatz verwenden können" - was ist mit der Wartung? Eine funktionale Sprache kann häufig in einer einzigen Zeile tun, wofür ein C-Programm 10 Sekunden benötigt, was bedeutet, dass weniger Raum für Fehler vorhanden ist. Außerdem können sie kompiliert (dh Haskell) und auf dem Ziel ausgeführt werden, was schneller als Interpreter ist. Ich wollte dieses Thema ein wenig untersuchen, da ein kompiliertes Haskell möglicherweise genauso schnell, aber schneller zu entwickeln ist als beispielsweise eine C-App. Wollte den Status quo ein wenig hinterfragen.
@Sheepsimulator Leider machen Kommentare wie Ihr letzter Fragen wie diese argumentativ.
@Sheepsimulator, ich kann leicht argumentieren, dass nur weil es weniger Code ist, es nicht weniger Fehler gibt. Ich hatte viele Male, in denen ich weniger darüber wusste, was tatsächlich passiert, dass ich einen Fehler verursachte, den ich nicht hätte, wenn ich mehr Codezeilen schreiben müsste.

Antworten (8)

ARMPIT SCHEME ist ein Interpreter für die Scheme-Sprache (lexikalischer Dialekt von Lisp), der auf RISC-Mikrocontrollern mit ARM-Kern läuft. Es basiert auf der Beschreibung im Revised Report on the Algorithmic Language Scheme (r5rs), mit einigen Erweiterungen (für E/A) und einigen Auslassungen (um in den MCU-Speicher zu passen). Es ist ferner darauf ausgelegt, Multitasking und Multiprocessing zu unterstützen. Es wird erwartet, dass Armpit Scheme gut für Bildungseinrichtungen geeignet ist, einschließlich Studentenprojekten in Kursen über Steuerung und Instrumentierung oder Capstone-Designkursen, in denen Mikrocontroller benötigt werden. Es soll das Spektrum der für MCUs verfügbaren interpretierten Sprachen (z. B. BASIC und FORTH) bereichern und kann eine Alternative zu MCU-basierten Bytecode-Interpretern (z. B. für Scheme oder Java) und zu kompilierten Sprachen (z. B. C) sein.

http://armpit.sourceforge.net/

Du sagst:

Die Verwendung von C, C++, Assembly usw. ist im Vergleich zu Sprachen wie Haskell, LISP oder Scheme ziemlich ineffizient

Die Verwendung von Hochsprachen ist eine effizientere Verwendung der Programmiererzeit, kann jedoch häufig eine weniger effiziente Verwendung von Computerressourcen sein. Bei in Serie hergestellten eingebetteten Systemen haben Kosten und Leistung oft eine höhere Priorität als der Entwicklungsaufwand.

Sie können auch AVR-Controller mit Haskell mit Atom/Copilot programmieren, zum Beispiel http://leepike.wordpress.com/2010/12/18/haskell-and-hardware-for-the-holidays/

Haskell ist wirklich gutes Zeug <3

C, C++ und Assembly sind der Maschinensprache sehr ähnlich. Durch die Verwendung einer Sprache auf höherer Ebene fügen Sie zusätzlichen Overhead im Austausch für eine schnellere/einfachere/usw. Entwicklung hinzu.

-1: Ich stimme dieser Antwort nicht wirklich zu. Obwohl Sie Recht haben, dass Assembly der Maschinensprache nahe kommt, sind C und C++ sehr unterschiedliche Hochsprachen.
@ BG100, ich würde die Linie "High Level / Low Level" tatsächlich irgendwo in C ziehen, anstatt sie einfach eine High-Level-Sprache zu nennen. Bei der Durchführung von Arithmetik-, Zeiger- (String-) Operationen und anderen allgemeinen grundlegenden Aufgaben lassen die Anweisungen, die Compiler im Allgemeinen erzeugen, die CPU die Daten direkt ohne Abstraktionsebenen manipulieren.
@ Nick T: Ich verstehe Ihren Standpunkt, aber bedenken Sie Folgendes: Wenn Sie eine Interrupt-Routine schreiben, die im Allgemeinen so schnell wie möglich ausgeführt werden muss, hätten Sie in C keine Ahnung, wie lange die Ausführung dauern würde, aber in Assembler könnten Sie zählen Sie einfach die Anweisungen. Ich denke, auf niedrigem Niveau ist zu wissen, GENAU was in Ihrem Programm vor sich geht, Sie wissen das nicht genau, wenn Sie C verwenden.
@ BG100: Derselbe Assembler-Befehl kann basierend auf Operanden und ihren Adressierungsmodi eine unterschiedliche Anzahl von Zyklen für die Ausführung benötigen. In C erhalten Sie jedoch nach dem Kompilieren statischen Code, der sich nicht ändert (nicht ändern kann). Stimmt, das ist ein etwas dürftiges Argument, aber wenn wir die Kleinigkeiten diskutieren wollen, um zu versuchen, eine große rote Linie zu ziehen ...

Ich habe kürzlich ein ARM-Board in Python programmiert und finde es großartig. Es ist nicht gut für die Echtzeitsteuerung, aber ich mache mehr webbezogene Sachen, was in einer Hochsprache weitaus angenehmer ist als in C.

Die Mehrheit der Mikrocontroller sind immer noch 8- und 16-Bit-Geräte (obwohl sich dies langsam ändert). Die beiden bisher in anderen Antworten erwähnten Instanzen höherer Sprachen (Scheme und Python) laufen beide auf 32-Bit-ARM-Kernen. Die kleineren 8- und 16-Bit-Geräte (die nur ein paar Dollar kosten können) haben nicht genug RAM, um die erwähnten Sprachen zu unterstützen – normalerweise haben sie nur ein paar KB RAM.

Außerdem sind diese höheren Sprachen nicht zum Schreiben von Interrupt-Handlern mit niedriger Latenzzeit und dergleichen ausgelegt. Es ist nicht ungewöhnlich, dass ein Mikrocontroller-Interrupt-Handler hundert- oder tausendmal pro Sekunde aufgerufen wird und jedes Mal seine Aufgabe in zehn Mikrosekunden oder weniger ausführen muss.

Scheme wurde Mitte der späten 70er und Anfang der 80er entwickelt. Auf keinen Fall benötigt Scheme einen 32-Bit-Prozessor oder Megabyte Speicher. Scheme war Mitte der 80er Jahre für PCs der AT-Klasse verfügbar. Jüngste Implementierungen sind möglicherweise für ressourcenreichere Umgebungen optimiert, aber es gibt klare Beispiele für Schemata, die auf heutigen "winzigen" Computerplattformen ausgeführt werden.
@ThePhoton Ich stehe korrigiert. Obwohl mir das BIT-Projekt bekannt war, das auf Prozessoren mit Dutzenden von KB Speicher abzielt (mehr als auf den meisten kleinen Mikrocontrollern verfügbar ist), habe ich gerade PICBIT entdeckt , das von einigen Studenten der Université de Montréal und der Université Laval entwickelt wurde. Dadurch können echte Scheme-Programme auf PIC-Prozessoren mit nur 2 KB RAM ausgeführt werden. Ziemlich erstaunlich.

Es ist möglich, mit der Lua-Sprache einige funktionale Programmierungen durchzuführen. Wirklich, Lua ist eine Multi-Paradigma-Sprache; Wikipedia behauptet, es sei eine „scripting, imperative, funktionale, objektorientierte, prototypbasierte“ Sprache. Die Sprache erzwingt kein einzelnes Paradigma, sondern ist flexibel genug, um es dem Programmierer zu ermöglichen, jedes Paradigma zu implementieren, das auf die Situation anwendbar ist. Es wurde von Scheme beeinflusst.

Zu den Features von Lua gehören erstklassige Funktionen , lexikalischer Geltungsbereich sowie Closures und Coroutines , die für die funktionale Programmierung nützlich sind. Sie können sehen, wie diese Funktionen im Lua-Benutzer-Wiki verwendet werden, das eine Seite hat, die der funktionalen Programmierung gewidmet ist . Ich bin auch auf dieses Google Code-Projekt gestoßen , aber ich habe es nicht verwendet (es behauptet, von Haskell beeinflusst zu sein, einer anderen Sprache, die Sie erwähnt haben).

eLua ist eine Implementierung, die für eine Reihe von Entwicklungsboards für die Architekturen ARM7TMDI, Cortex-M3, ARM966E-S und AVR32 konfiguriert verfügbar ist und Open Source ist, sodass Sie sie für Ihre eigene Plattform konfigurieren können. Lua ist in ANSI C implementiert und der gesamte Quellcode wiegt weniger als 200 kB, sodass Sie es für die meisten Plattformen mit einem C-Compiler erstellen können sollten. Mindestens 128 KB Flash und 32 KB RAM werden empfohlen. Ich arbeite derzeit an einem PIC32-Port dafür (allerdings noch in der Phase "Get the PIC32 Board").

Das Tolle an Lua ist, dass es als Glue-Sprache konzipiert wurde, sodass es sehr einfach ist, C-Erweiterungen für Dinge zu schreiben, die schnell sein müssen (wie Interrupts usw.), und die dynamischen, interpretierten Funktionen der Sprache zu nutzen, um schnell zu arbeiten Entwicklung in der Programmlogik.

Lua ist keine rein funktionale Sprache, aber Sie können darin eine Menge funktionaler Programmierung durchführen, es ist schnell und klein ( im Vergleich zu anderen Skriptsprachen ) und Sie müssen Ihr Gerät nicht neu flashen, um ein Programm auszuprobieren. Es gibt sogar einen interaktiven Dolmetscher!

"Gibt es Möglichkeiten, mit einer funktionalen Sprache auf einer MCU funktional zu programmieren, um schwierige Probleme zu lösen?"

Ja, es gibt Wege. Aber der Nachteil ist, dass Sie einen 32-Bit-Prozessor, MMU, 128 MB RAM, SSD, ein RTOS und $$$ benötigen.

Mikrocontroller sind anders als Mikroprozessoren. Der Mikrocontroller ist vielleicht nur eine 8-Bit-CPU, 1K RAM, 8K ROM, aber er hat einen eingebauten UART, PWM, ADC usw. Und er kostet nur 1,30 $.

Sie könnten also all diese Hochsprachen ausführen, aber es kostet viel mehr, sie zu erstellen.

Ich denke, Sie müssen Ihre Definition von Mikrocontrollern überdenken. Viele Mikrocontroller haben jetzt 128 KB oder mehr Flash und 64 KB oder mehr RAM, viel Platz, um einen Interpreter für einige kleinere Sprachen auszuführen. Es sieht so aus, als würden Sie Spezifikationen für ein eingebettetes Linux-Gerät angeben. Ich denke, das OP hat nach einem dedizierten Port gefragt.
Wenn Sie 1,30 $ für eine 8-Bit-MCU bezahlen, dann gibt es mehrere 32-Bit-MCUs, die billiger sind. Berücksichtigen Sie auch, dass die meisten 8-Bit-MCUs auf dem Markt schreckliche Code-ineffektive Architekturen sind, deren Designs aus den frühen 80er Jahren stammen.

Dieses Buch bietet eine Möglichkeit, mit einem leichten Gefühl von FP zu programmieren. http://www.state-machine.com/psicc2/

Echtes FP erfordert jedoch die Fähigkeit, Funktionen zur Laufzeit zu erstellen und sie über Ihr Programm zu übergeben. Hier haben wir ein Problem: Wie können wir diese konstruierte Funktion darstellen? und wie können wir diese Funktion effektiv ausführen? Auf einem großen System können wir dynamische Kompilierung verwenden, die echten Maschinencode auf einer ersten Funktionsanwendung generiert. Auf der MCU haben wir nur RAM, um sehr primitive Compiler wie den Forth-Sprachkern zu implementieren.

Die einzige Möglichkeit, FP oder OOP zu verwenden, wenn Sie dies bevorzugen, ist die Metaprogrammierung : Schreiben Sie komplexe Funktions-/OOP - Programme, die Programme für MCU generieren (z. B. C-Quellcode oder LLVM IL). Bei dieser Variante sind Sie nicht durch die Komplexität von Paradigmen oder Programmiermethoden eingeschränkt.