Forum: Compiler & IDEs Umsetzung: String in Befehl


von Edgar (Gast)


Lesenswert?

Hallo,

ein echt aufschlussreiches Forum hier. Habe schon einiges verwenden 
können. Nun zu meiner Frage: Ich habe einen ATmega2561, der über die 
serielle Schnittstelle mit mein PC Interruptgetriggert kommmuniziert. 
Gibt es in C irgendeine Möglichkeit wie man einen String, z.B. 
"SetPortA(0xaf);" in einen direkten Befehl an den Mikrocontroller 
umwandeln kann.
Bisher ist mir nur eingefallen beim Empfang eines Strings, diesen dann 
zu decodieren.

mfg Edgar

von Edgar (Gast)


Lesenswert?

noch als kleine Info: Der String wird vom PC an den Mikrocontroller 
gesendet und steht im Anschluss in einem Buffer, über den ich auf den 
String zugreifen kann. Danke schon mal im Voraus über die hoffentlich 
zügigen Antworten.:-)

von Sven P. (Gast)


Lesenswert?

Das gibts bei interpretierten Sprachen als "eval" (PHP, Perl, 
JavaScript). In C funktioniert das so net. Da wirst du wohl mit 
Tabellen mit Funktionszeigern schaffen müssen, was aber wiederum schnell 
und elegant ist.

von Edgar (Gast)


Lesenswert?

Danke für die schnelle Antwort. Du meinst, dass ich den abhängig von dem 
String in eine Tabelle verzweige, in der die Funktionen aufgelistet 
sind. Wie  soll ich denn dann auf meinen Übergabewert kommen, ohne 
Decodierung?

mfg

von Hans (Gast)


Lesenswert?

Ein Standard wäre RPC (Remote Procedure Call). Aber für einen kleinen 
Microcontroller dürfte das weit überdimmensioniert sein.

Ich denke Du kommst um das decodieren des empfangenen Strings nicht 
herum - auch um zu prüfen, ob überhaupt ein gültiger String angekommen 
ist.

Was verstehst Du unter "decodieren" bzw. warum möchtest Du das 
vermeiden?

Ich verstehe unter decodieren folgendes:

Eim gültiger String könnte mit einer Marke z.B. $ beginnen und mit einer 
Marke enden. Parameter werden z.B. über ; abgetrennt. Der String um Port 
A den Wert 0xff zuzuweisen könnte dann so aussehen $p;A;0xff$

Auf dem Microconroller liest Du die empfangenen Bytes solange ein, biss 
ein $ -Zeichen kommt. Dann speicherst Du die darauffolgenden Zeichen, 
bis ein ;-Zeichen kommt, ... bis das abschließende $-Zeichen kommt. Dann 
rufst Du die Entsprechenden Funktionen auf.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Du brauchst letztlich eine Art Interpreter für eine Programmiersprache.

Da du mit einem ATmega2560 über relativ viel Platz verfügst, wäre
es eine Möglichkeit, einen ,,richtigen'' Scanner/Parser zu schreiben.
Dafür gibt es teilweise auch Werkzeuge.  Die bekanntesten sind lex
und yacc.  Für deren Opensource-Derivate flex und byacc könnte ich
dir Patches geben, mit denen man sie AVR-GCC-passend so verbiegt, dass
die relativ großen Tabellen, die für diese Werkzeuge typisch sind,
im Flash-ROM statt im SRAM abgelegt werden.

Exemplarisch habe ich damit mal einen einfachen BASIC-Interpreter
gezimmert, der aber mehr schlecht als recht funktioniert.

von Edgar (Gast)


Lesenswert?

@Hans

So ungefähr habe ich das gemeint. Der Unterschied ist nur, dass der 
String(also der Befehl), den ich an den µC sende, genau so aussehen 
soll, wie       die auszuführende Funktion im µC, z.B. SetPort(A, 0xF3);
Aber du hast wohl Recht. Ich werde vermutlich decodieren müssen.

von Edgar (Gast)


Lesenswert?

@Jörg Wunsch

Scheint eine gute Möglichkeit zu sein. Bei Bedarf melde ich mich bei 
dir. Danke.

von Hans (Gast)


Lesenswert?

Wenn Du natürlich die Möglichkeit hast einen Parser-Generator (yacc 
etc.) zu verwenden ist das tausendmal besser, als die decodierung von 
Hand zu machen.

Der von diesen Tools generierte Code ist in der Regel fehlerfrei (kommt 
wirklich ganz ganz selten vor, dass man da 'nen Bug entdeckt). Bei von 
Hand geschriebenem Code ist das - aus Erfahrung - ganz anders :-(

Vielleicht findest Du bei google ja schon eine fertige Grammatik für 
Basic, Pascal, C, ... oder der Sprache in der Du die Befehle senden 
möchtest.

Natürlich geben die Tools dann kein fertiges Programm aus. Ein bisschen 
dazuprogrammieren muss man schon.

von John S. (student)


Lesenswert?

Jörg Wunsch wrote:
> Du brauchst letztlich eine Art Interpreter für eine Programmiersprache.
>
> Da du mit einem ATmega2560 über relativ viel Platz verfügst, wäre
> es eine Möglichkeit, einen ,,richtigen'' Scanner/Parser zu schreiben.
> Dafür gibt es teilweise auch Werkzeuge.  Die bekanntesten sind lex
> und yacc.  Für deren Opensource-Derivate flex und byacc könnte ich
> dir Patches geben, mit denen man sie AVR-GCC-passend so verbiegt, dass
> die relativ großen Tabellen, die für diese Werkzeuge typisch sind,
> im Flash-ROM statt im SRAM abgelegt werden.
>
> Exemplarisch habe ich damit mal einen einfachen BASIC-Interpreter
> gezimmert, der aber mehr schlecht als recht funktioniert.

Hallo Jörg,

das Thema würde mich stark interessieren, das ich aus übertragenen 
Funktelegrammen (mit Befehlen) Abläufe programmieren möchte. Kannst Du 
mir bitte da mit Deinen Routinen helfen? Es geht nur um ein paar 
Befehle. Wieviel Speicher verliere ich denn durch den Parser ?

Grüsse

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Angehängte Dateien:

Lesenswert?

Charly Grosse wrote:

> Kannst Du
> mir bitte da mit Deinen Routinen helfen?

"Routinen" in dem Sinne habe ich nicht.

Ich hänge mal meine Patches für den flex-2.5.33 und byacc-20050813
an.  Die originalen Quellen gibt's im Internet, die Patches schieben
die generierten Tabellen in den Flash-ROM und greifen mit pgm_read_...
darauf zu.

Folgende Optionen habe ich im flex-File noch genutzt (teilweise sind
diese notwendig, damit der Scanner überhaupt compilierbar wird):

%option  noyywrap
%option  always-interactive
%option  case-insensitive
%option  nounistd

> Es geht nur um ein paar
> Befehle.

Dafür ist eine komplette formale Sprache sicher Overkill.

> Wieviel Speicher verliere ich denn durch den Parser ?

Verlieren wirst du keinen, denn er wird ja benutzt. ;-)

Das Ganze ist kein Leichtgewicht, aber für den ATmega256x des OPs
sicher nicht tragisch.  Das ,,Grundrauschen'' einer derartigen
Scanner/Parser-Kombination ist recht hoch, ich erinnere mich an
ca. 12 KiB ROM-Verbrauch (der RAM-Verbrauch bleibt in Grenzen).
Der Vorteil ist nur, dass der Verbrauch für eine tatsächlich
implementierte Sprache dann nur ganz allmählich anwächst.  Der
besagte BASIC-Interpreter hat es am Ende auf irgendwas um die 30 KiB
gebracht, aber das war mit kompletter Gleitkommaarithmetik und einer
einfachen Stringverarbeitung.  Außerdem sind deartige Parser relativ
schnell.

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.