Forum: Mikrocontroller und Digitale Elektronik LUA, C, PIC32, dynamischer Quelltext


von Thomas P. (daelectrictick)


Lesenswert?

Hallo,
ich möchte gerne dynamischen Quelltext auf einem eingebetteten System 
erzeugen und bin mir etwas unsicher in der Umsetzung.
Im Zusammenhang mit dynamischem Quelltext lese ich immer wieder was von 
LUA. Gibt es hier jemand der Erfahrung mit der Programmiersprache im 
Zusammenhang eingebetteter Systeme hat? Ich bevorzuge den PIC32 der 
Firma Microchip.
Es geht mir in erster Linie darum, ob es mit LUA möglich ist, während 
der Laufzeit Funktionen in C hinzuzufügen.

Ich denke das ganze wird in Richtung virtuelle Maschine gehen, aber wie 
gesagt habe ich leider keinerlei Erfahrung mit dynamischen 
Programmiersprachen.

Ich freue mich über jeden Hinweis, dynamischen Quelltext zu erzeugen.

Ich habe viel Erfahrung im Bereich der C Programmierung und 
Echtzeitbetriebssystemen, auch VHDL Kenntnisse sind vorhanden.

Mit freundlichem Gruß
Ich

von S. R. (svenska)


Lesenswert?

Um zur Laufzeit C-Quellcode hinzufuegen zu können, brauchst du einen 
C-Compiler (oder C-Interpreter) auf dem Target. Den enthält die 
Lua-Bibliothek nicht und ich bezweifle, dass du soetwas einbinden 
möchtest.

Vorkompilierte, positionsunabhängige Funktionen (also Binärcodeblöcke) 
kannst du einbinden, solange du dich an die Aufrufkonvention hältst; 
wobei ich nicht weiss, wie das in Lua gemacht wird. Die zu erzeugen ist 
aber nicht unbedingt einfach, und positionsabhängigen Code einzubinden 
wird vermutlich auch eher wenig Spass machen.

von Thomas P. (daelectrictick)


Lesenswert?

Danke für den Hinweis. Das ist richtig, ich möchte nicht unbedingt einen 
C-Compiler auf dem Controller implementieren.

Ich sollte vielleicht etwas genauer erklären, was mein Vorhaben ist:

Es gibt ein Hauptprogramm geschrieben in C. Dieses Hauptprogramm wird 
normal kompiliert.

Nach einer gewissen Zeit soll der Code erweitert werden, ohne dass eine 
neue Kompilierung des Hauptprogrammes erforderlich ist.
Als Erweiterung ist das hinzufügen von Funktionen gedacht.
Leider wird erst während der Laufzeit klar, welche individuellen 
Funktionen benötigt werden.

Ein anderer Gedanke war es, dynamisch gelinkte Bibliotheken zu 
verwenden. (Das wäre als Notlösung auch in Ordnung) Nur habe ich damit 
in C, wenn es überhaupt in C möglich ist, ebenso wie mit LUA keinerlei 
Erfahrungen..

von Daniel A. (daniel-a)


Lesenswert?

Thomas P. schrieb:
> Danke für den Hinweis. Das ist richtig, ich möchte nicht unbedingt
> einen
> C-Compiler auf dem Controller implementieren.

Ist auch nicht nötig. Ich habe keine erfahrung mit lua, aber ich weiss 
dass es eine Scriptingsprache ist (also normalerweise nicht compiliert 
werden muss) und man von C auf LUA funktionen zugreifen kann. Es ist 
zwar nicht möglich C-Quellcode hinzuzufügen, aber LUA Code auszufüren 
und so lua funktionen hinzuzufügen, die in C verwendet werden können.

> Ich sollte vielleicht etwas genauer erklären, was mein Vorhaben ist:
>
> Es gibt ein Hauptprogramm geschrieben in C. Dieses Hauptprogramm wird
> normal kompiliert.
>
> Nach einer gewissen Zeit soll der Code erweitert werden, ohne dass eine
> neue Kompilierung des Hauptprogrammes erforderlich ist.
> Als Erweiterung ist das hinzufügen von Funktionen gedacht.
> Leider wird erst während der Laufzeit klar, welche individuellen
> Funktionen benötigt werden.

Ich habe noch nie einen PIC verwendet, aber ein PIC benutzt eine 
modifizierte Harvard Architektur, es ist somit nich möglich Code 
Auszuführen ohne diesen zu flashen, da der ram in einem anderen 
Adressraum liegt als der flash. Es ist jedoch möglich Interpreter zu 
schreiben. Falls der PIC ein EMB hat und die Funktionen auf einem 
externes EEPROM, FLASH, etc. sind, können diese direckt ausgeführt 
werden.

Aber woher sollen die Zusatzfunktionen denn kommen? Falls der Controller 
den Code generieren soll den er Ausführen soll ist das Generieren von 
code auf demselben der falsche Ansatz. Andernfals ist die Optimale 
lösung von der Dynamic des zu lösenden Problems abhängig. Ist der code 
eine Benutzereingabe? Dann einen Interpreter nehmen. Wird ein 
dynamisches interface für unbekannte Componenten benötigt, sollte eine 
generische Datenstruktur und/oder ein passendes Protokoll verwendet 
werden. Baut man einen Gameboy und muss das Programm von einer cartridge 
ausführen, nimmt man einen PIC mit EMB, etc.

Kurz: Der Verwendungszweck und somit die Anforderungen sind unbekannt, 
nimand kann die Lösung auf ein Unbekanntes Problem wissen.

> Ein anderer Gedanke war es, dynamisch gelinkte Bibliotheken zu
> verwenden. (Das wäre als Notlösung auch in Ordnung) Nur habe ich damit
> in C, wenn es überhaupt in C möglich ist, ebenso wie mit LUA keinerlei
> Erfahrungen..

Hast du denn ein OS oder sonst was auf dem PIC welches solche libs laden 
kann?

von S. R. (svenska)


Lesenswert?

Thomas P. schrieb:
> Nach einer gewissen Zeit soll der Code erweitert werden, ohne dass eine
> neue Kompilierung des Hauptprogrammes erforderlich ist.

Die Frage ist: Soll der C-Code erweitert werden? Wenn ja, dann ist dein 
Ansatz hinfällig, weil das geht nicht ohne neu zu kompilieren.

Soll dagegen nur Lua-Code erweitert werden, dann ist das erstmal (also 
in der Theorie) ohne Probleme möglich. Allerdings kenne ich Lua dazu 
nicht gut genug. In Perl könnte man die Funktionen in Strings speichern 
und durch eval() aufrufen; Lua kennt ähnliche Mechanismen (loadstring, 
loadfile).

> Als Erweiterung ist das hinzufügen von Funktionen gedacht.
> Leider wird erst während der Laufzeit klar, welche individuellen
> Funktionen benötigt werden.

Erklär mal, was das überhaupt werden soll. Das Konzept klingt so erstmal 
etwas fischig. ;-)

> Ein anderer Gedanke war es, dynamisch gelinkte Bibliotheken zu
> verwenden. (Das wäre als Notlösung auch in Ordnung) Nur habe ich damit
> in C, wenn es überhaupt in C möglich ist, ebenso wie mit LUA keinerlei
> Erfahrungen..

Dynamisch gelinkte Bibliotheken sind eine Funktion des Betriebssystems, 
nicht der Programmiersprache (Windows selbst und viele DLLs sind in C 
programmiert). Du müsstest also einen Runtime-Linker in dein System 
einbauen. Der Haken dabei ist, dass du - um die Bibliotheken zu erzeugen 
- wieder einen vollwertigen Compiler brauchst. Dafür wäre die Ausführung 
schneller, weil zur Laufzeit nichts interpretiert wird.

Daniel A. schrieb:
> Ich habe noch nie einen PIC verwendet, aber ein PIC benutzt eine
> modifizierte Harvard Architektur, es ist somit nich möglich Code
> Auszuführen ohne diesen zu flashen, da der ram in einem anderen
> Adressraum liegt als der flash.

Es geht um den PIC32, und der benutzt einen MIPS-Kern. Da ist das kein 
Problem.

Das spielt aber auch keine Rolle, weil Lua interpretiert wird. Die 
hinzugefügten Funktionen liegen zwar immer im RAM, aber der Interpreter 
selbst liegt (vermutlich) im Flash.

von Axel S. (a-za-z0-9)


Lesenswert?

Thomas P. schrieb:
> Ich sollte vielleicht etwas genauer erklären, was mein Vorhaben ist:
>
> Es gibt ein Hauptprogramm geschrieben in C. Dieses Hauptprogramm wird
> normal kompiliert.
>
> Nach einer gewissen Zeit soll der Code erweitert werden, ohne dass eine
> neue Kompilierung des Hauptprogrammes erforderlich ist.
> Als Erweiterung ist das hinzufügen von Funktionen gedacht.
> Leider wird erst während der Laufzeit klar, welche individuellen
> Funktionen benötigt werden.

Dann können das schon mal keine C-Funktionen sein - denn die erfordern 
in jedem Fall einen Compilerlauf. Aber natürlich kannst du Lua- 
Funktionen zur Laufzeit hinzufügen. Aus Sicht des C-Programms ist ein 
Lua-Programm ein simpler String. Bzw. ein File - wofür du aber zumindest 
einen Teil der POSIX API implementieren mußt.

Aus dem C-Programm heraus kannst du dann einen oder auch mehrere Lua- 
Interpreter starten, denen du ihr Programm als String (oder File) 
vorgibst. Und dann kannst du Funktionen aus dem Programm eines laufenden 
Lua-Interpreters aufrufen. Genauso kannst du aus Lua C-Funktionen 
aufrufen, was allerdings voraussetzt daß du dem Lua-Interpreter zur 
Compilationszeit sagst, welche Funktionen das sind und welche Signatur 
sie haben.

von LuaUser (Gast)


Lesenswert?

schau mal hier:

Beitrag "Wie benutze ich uLua auf einem AVR?"

asdfasd schrieb:
> Lua ist für den
> typischen Mikrocontroller (ein paar Dutzend KB Flash, ein paar KB RAM)
> nicht geeignet - frag mal die NodeMCU-Leute

"Wobei bei NodeMCU der Compiler mit auf dem µC läuft, das ist schon eine
ganze Größenordnung mehr Aufwand."

von Thomas P. (daelectrictick)


Lesenswert?

Daniel A. schrieb:
> Ist auch nicht nötig. Ich habe keine erfahrung mit lua, aber ich weiss
> dass es eine Scriptingsprache ist (also normalerweise nicht compiliert
> werden muss) und man von C auf LUA funktionen zugreifen kann. Es ist
> zwar nicht möglich C-Quellcode hinzuzufügen, aber LUA Code auszufüren
> und so lua funktionen hinzuzufügen, die in C verwendet werden können.

Das ist auf jeden Fall sehr hilfreich! Damit kann ich mir ein paar 
Ansätze überlegen.

Daniel A. schrieb:
> Falls der PIC ein EMB hat und die Funktionen auf einem
> externes EEPROM, FLASH, etc. sind, können diese direckt ausgeführt
> werden.

Leider hat der PIC32 keinen externen Speicherbus.

S. R. schrieb:
> Soll dagegen nur Lua-Code erweitert werden, dann ist das erstmal (also
> in der Theorie) ohne Probleme möglich.

Genau in diese Richtung soll es gehen.

S. R. schrieb:
> Dynamisch gelinkte Bibliotheken sind eine Funktion des Betriebssystems,
> nicht der Programmiersprache (Windows selbst und viele DLLs sind in C
> programmiert).

Danke! Ich verwende als OS FreeRTOS. Leider sind dynamische Verlinkungen 
bei FreeRTOS nicht möglich, da es selber statisch gelinkt wird.

S. R. schrieb:
> Erklär mal, was das überhaupt werden soll. Das Konzept klingt so erstmal
> etwas fischig. ;-)

Ok :P

Es wird ein modulares System, dem unbekannte Module hinzugefügt werden 
können und diese der Hauptplatine(PIC32) mitteilen, welche Funktionen 
ausgeführt werden sollen, um mit ihnen zu arbeiten.

Das heißt: Auf der Hauptplatine wird eine Platine mit LED montiert. Die 
Platine mit LED liefert der Hauptplatine den Code zur Ansteuerung der 
LED.

Das Beispiel mit der LED ist nur zur simplen Erklärung gedacht...

Ich denke, ich sollte mit dem Gedanken spielen, das Hauptsystem mit C 
und FreeRTOS zu programmieren, das System auf mehrere Tasks unterteilen, 
um mehr oder weniger Template-Tasks aufzubauen, die dann anschließend 
LUA Funktionen ausführen, die wiederum den von den externen Modulen 
enthaltenen Funktionscode, sei es C oder LUA selbst, ausführt.

Vielleicht kann man das ganze soweit spinnen, dass zur Laufzeit Tasks 
erstellt werden, die dann den Funktionscode ausführen. Dadurch wäre eine 
Priorisierung möglich, was für mich von Vorteil wäre. Aber eins nach dem 
anderen..

Danke schon mal für das Interesse!

von Thomas P. (daelectrictick)


Lesenswert?

LuaUser schrieb:
> asdfasd schrieb:
>> Lua ist für den
>> typischen Mikrocontroller (ein paar Dutzend KB Flash, ein paar KB RAM)
>> nicht geeignet - frag mal die NodeMCU-Leute
>
> "Wobei bei NodeMCU der Compiler mit auf dem µC läuft, das ist schon eine
> ganze Größenordnung mehr Aufwand."

Es sollte klar sein, dass ich hier von eLUA spreche, da ich auf einem 
Embedded System arbeite, aber danke für den Hinweis.

von LuaUser (Gast)


Lesenswert?

"Es sollte klar sein, dass ich hier von eLUA spreche, da ich auf einem
Embedded System arbeite, aber danke für den Hinweis."

NodeMCU = Microcontroler = Embedded System

https://learn.adafruit.com/adafruit-huzzah-esp8266-breakout/overview

The ESP8266 processor from Espressif is an 80 MHz microcontroller with a 
full WiFi front-end (both as client and access point) and TCP/IP stack 
with DNS support as well.

von Thomas P. (daelectrictick)


Lesenswert?

LuaUser schrieb:
> NodeMCU = Microcontroler = Embedded System
>
> https://learn.adafruit.com/adafruit-huzzah-esp8266-breakout/overview
>
> The ESP8266 processor from Espressif is an 80 MHz microcontroller with a
> full WiFi front-end (both as client and access point) and TCP/IP stack
> with DNS support as well.

Du hast natürlich recht! Ich benutze den PIC32MX795F512L mit 128 KB 
SRAM-Speicher und 512 KB Programm-Speicher. Laut eLUA eine ausreichende 
Größe.

Ich freue mich auch über Alternativen. Ich muss nicht strikt eLUA 
verwenden. Es geht einfach erstmal nur darum, zu wissen, ob es möglich 
ist und wenn ja womit.

So wie ich das im Moment sehe, ist es mit eLUA möglich, aber nicht das 
tollste.. Viel Speicher, bedeutend langsamer als C-Code und und und.. 
(Falls ich falsch liege verbessert mich bitte!)

P.S.: Ich würde den Funktionscode gerne auf eine SD-Card oder einen 
USB-Stick auslagern und bei bedarf verwenden.


Mit freundlichem Gruß
ich

: Bearbeitet durch User
von X4U (Gast)


Lesenswert?

Thomas P. schrieb:
> Es wird ein modulares System, dem unbekannte Module hinzugefügt werden
> können und diese der Hauptplatine(PIC32) mitteilen, welche Funktionen
> ausgeführt werden sollen, um mit ihnen zu arbeiten.

Was ja bedeutet das die Funktionen auch vorkompiliert sein können und du 
Sie "nur" aufrufen musst. Ob du dafür nun eine Skriptsprache, Basic, 
Assembler oder Morsecode verwendest ist ja erst mal egal.

Da ja nicht bekannt ist was kommt musst du so oder so alles von deinem 
OS Kapseln (und feste Übergabepunkte vereinbaren).

HP hatte das anno dazumal in der Series 80 gemacht. Da konntest du 
externe Karten zustecken. Der "Treiber" war ein I/O Prozessor auf jeder 
Karte. Damit war jedes Gefummel mit den Treibern und die ganze Timing 
Problematik schlicht nicht vorhanden.

Evtl. Software war im ROM und das wurde in Assembler über sog. Hooks 
gemanaged. Das OS hat nachgeschaut ob n Hook da war und ihn angesprungen 
wenn ja.
Austausch lief über den Stack, das hat mehr als einer in etwas mehr als 
2 Wochen gebaut.

von Thomas P. (daelectrictick)


Lesenswert?

X4U schrieb:
> Was ja bedeutet das die Funktionen auch vorkompiliert sein können und du
> Sie "nur" aufrufen musst. Ob du dafür nun eine Skriptsprache, Basic,
> Assembler oder Morsecode verwendest ist ja erst mal egal.
>
> Da ja nicht bekannt ist was kommt musst du so oder so alles von deinem
> OS Kapseln (und feste Übergabepunkte vereinbaren).

Richtig!!! :)

X4U schrieb:
> HP hatte das anno dazumal in der Series 80 gemacht. Da konntest du
> externe Karten zustecken. Der "Treiber" war ein I/O Prozessor auf jeder
> Karte. Damit war jedes Gefummel mit den Treibern und die ganze Timing
> Problematik schlicht nicht vorhanden.

Sehr Interessant, ich werde mal schauen, ob ich dazu einige Datenblätter 
und andere Informationen bekomme. Danke!

X4U schrieb:
> Austausch lief über den Stack, das hat mehr als einer in etwas mehr als
> 2 Wochen gebaut.

Ich habe eine Zeitspanne von ca. 3 Monaten, á 8 Stunden pro Tag, 6 Tage 
die Woche. Da sollte doch einiges zu schaffen sein.

Mit freundlichem Gruß
ich

von X4U (Gast)


Lesenswert?

Thomas P. schrieb:
> Sehr Interessant, ich werde mal schauen, ob ich dazu einige Datenblätter
> und andere Informationen bekomme. Danke!

Schau mal im HP Museum, offiziell ist das schon lange obsolete. Aber es 
ist wirklich '80er. 80er Jahre 80er Prozessoren (8038 oder so) und 8 
Bit.

> Ich habe eine Zeitspanne von ca. 3 Monaten, á 8 Stunden pro Tag, 6 Tage
> die Woche. Da sollte doch einiges zu schaffen sein.

Kommt darauf an was es ist. Am besten ist wohl die Anforderungen 
schriftlich zu formulieren und dann ein (proof of) Konzept zu machen.

von S. R. (svenska)


Lesenswert?

Thomas P. schrieb:
> Es wird ein modulares System, dem unbekannte Module hinzugefügt werden
> können und diese der Hauptplatine(PIC32) mitteilen, welche Funktionen
> ausgeführt werden sollen, um mit ihnen zu arbeiten.

Also das PC-Prinzip: Das BIOS enthält nur sehr wenige Treiber, aber eine 
API ("Option ROMs"), mit der zusätzlich hinzugefügte Geräte ihre eigenen 
Treiber einbinden können. Sag das doch gleich. Die Treiber selbst müssen 
also nicht im Quelltext vorliegen, und müssen auch nicht zur Laufzeit im 
Quelltext eingefügt werden.

Um den Gedanken mal weiterzudenken: Am einfachsten definierst du dir 
bestimmte Modultypen, die du anschließen können möchtest (Unix 
unterscheidet zwischen "blockdev" und "chardev", plus ioctls) und eine 
dafür geeignete Schnittstelle. Der "Code", der dann von den 
angeschlossenen Modulen bereitgestellt wird, kann (sollte?) bereits 
vorkompilierter Bytecode sein, oder - ganz allgemein - 
positionsunabhängiger Maschinencode.

Vermutlich ist ein einfacher Bytecode die einfachste Lösung. Dein 
Hauptprogramm muss sowieso mit dem Modul kommunizieren können (um den 
Code auszulesen), also kann der Bytecode-Interpreter diese Primitiven 
auch anbieten. Der Code auf dem Modul selbst wäre dann sogar unabhängig 
von der Art des Anschlusses.

von WehOhWeh (Gast)


Lesenswert?

Daniel A. schrieb:
> Ich habe noch nie einen PIC verwendet, aber ein PIC benutzt eine
> modifizierte Harvard Architektur, es ist somit nich möglich Code
> Auszuführen ohne diesen zu flashen, da der ram in einem anderen
> Adressraum liegt als der flash.

Das ist nicht richtig.
Einige (alle?) PIC32 können auch Code aus dem RAM ausführen:

".... In addition, the data memory can be made executable, allowing
PIC32MX330/350/370/430/450/470 devices to execute from data memory..."

(Datenblatt PIC32MX470, page39)

Damit sollte man Maschinencode während der Laufzeit ins RAM schreiben 
und dann ausführen können.

von Alex (Gast)


Lesenswert?

Hier ist ein Lua-PIC32-Port:
https://github.com/FMMT666/PIC32Lua

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.