Hallo allerseits! Es geht um folgenden Gedanken: Ein Prüfgerät soll Prüflinge auf Hardwarefehler prüfen. Dazu müssen sämtliche IO's und analoge Eingänge getestet werden. Die Prüflinge können aber variieren, da sie modular aufgebaut sind. Das Prüfgerät soll in C programmiert und danach nicht wieder verändert werden. Das projektspezifische Prüfprogramm soll über eine Serielle Schnittstelle geladen werden und für eine unbegrenzte Anzahl Prüfungen im internen Flash abgelegt werden, bis es neu geladen wird. Das Prüfprogramm beschreibt die Reihenfolge der zu prüfenden IO's sowie die Prüfung der analogen Eingänge, sowie einige andere Details. Das Programm soll als txt-Datei übertragen werden. Das alles ist erst einmal unproblematisch. Aber: Die Prüfanweisungen könnten folgendermaßen aussehen: Test Analog_1.1 1.8V Test Analog_1.1 1.7V Test Analog_1.1 1.6V Test Digital_2.0 1 Test Digital_2.0 0 Test Digital_2.1 1 Test Digital_2.1 0 Nun zum Problem: Das Programm muss zur Laufzeit interpretiert werden. Ich habe eine hier große Wissenslücke, was das einlesen und verarbeiten der Datei angeht. Wie und wo finde ich Infos darüber? Wie parse ich so eine Datei, um daraus einen Programmablauf mit den zugehörigen Werten zu generieren? Wie gesagt der "Interpreter" läuft auf einem µC. Nix Python oder PERL, nur nacktes C. Nehmt es mir nicht übel, aber ich stehe auf dem Schlauch. Für Erklärungen und entsprechende Beispiele wäre ich sehr dankbar! Vielen Dank!
Hi! Ich hab ein wenig Erfahrung mit so Zeug. Zuerst ein paar Überlegungen: Welcher uC? Muss es ein bestimmter sein? Wenn ja, wie viel Speicher steht zur Verfügung? Oder geht’s eher darum, dass er zertifiziert wird? Kurz gefasst, wir sind nicht mehr in den 80-ern. Mittlerweile kann man neben der JVM schon einen Python Interpreter auf einem uC, oder ein ganzes Linux auf einem billigen SoC laufen lassen. Nur eine Überlegung. Möglich ist natürlich auch, dass 2 uCs verwendet werden: einen „Empfänger/Programmierer“ der maschinencode empfängt und einen „Slave“ jedes Mal flasht wenn ein neues Set kommt. Mehr darüber findest du unter dem Thema „In-System Programming (ISP)“ oder „In-Circuit Serial Programming“ All dies solltest du dir überlegen, wenn das System so skalierbar wie möglich sein sollte. Wenn (und aus Erfahrung ist das ein großes Wenn) du schon alle Anforderungen im Vorhinein kennst, oder es nicht so schwer ist die Maschine(n) neu bzw. nach zu flashen, kannst du dir überlegen einen Interpreter zu entwickeln (Ich denke, das ist das was du meinst das du willst). Je nach momentanen und erwarteten Anforderungen kannst du schnell einen kleinen Interpreter bauen, oder Full Retard gehen und das Eclipse Modeling Framework (EMF) heranziehen um den Interpreter, sowie eine Arbeitsumgebung für die end-User automatisch zu generieren. Aber nehmen wir mal an du brauchst (oder willst unbedingt, was auch ok ist, weil’s spaß macht! :) einen eigenen On Chip Interpreter. Die Arbeit hierfür besteht aus 2 wesentlichen Teilen: Sprachentwicklung, und Interpreter Programmierung. Sprache: Du hast schon ein paar Beispiele aufgelistet. Die sind prinzipiell nicht schlecht, aber ich würde dir Vorschlagen (wenn das ganze noch Wachsen sollte), dass du dir ein Beispiel, oder zumindest Inspiration an existierenden, ausgereiftenTest Frameworks nimmst (i.e. JUnit). Ich schlag dir mal eine Beispielsprache vor, die meiner Meinung nach einfach verständlich ist. Diese deckt schon mal einen großen Testbereich ab, und kann auch relativ leicht erweitert werden
1 | VORJEDEM: { |
2 | SETZE analog_1.1 0V, |
3 | SETZE analog_1.2 0V, |
4 | SETZE analog_1.3 0V, |
5 | } |
6 | NACHJEDEM: { |
7 | WARTE 1000ms |
8 | } |
9 | TEST 1: { |
10 | SETZE analog_1.1 1.8V, |
11 | FORDERE digital_2.1 == 0, |
12 | } |
13 | TEST 2: { |
14 | SETZE analog_1.1 1.7V, |
15 | FORDERE digital_2.0 == 1, |
16 | FORDERE digital_2.1 == 1, |
17 | } |
18 | TEST bodo: { |
19 | SETZE analog_1.1 1.7V, |
20 | FORDERE digital_2.1 == 0, |
21 | WARTE 4ms, |
22 | FORDERE digital_2.1 == 1, |
23 | FORDERE analog_1.1 <= 1.7V, |
24 | } |
Diese Sprache kann man nun als Grammatik definieren
1 | S | } -> VORJEDEM: | NACHJEDEM: | TEST |
2 | VORJEDEM: -> { |
3 | NACHJEDEM: -> { |
4 | TEST -> /([^:]+):/ -> { |
5 | { | , -> SETZE | FORDERE | WARTE | ERWARTE |
6 | SETZE -> /([^\s]+)/ -> /([^\s]+)/ -> , | } |
7 | WARTE -> /([^\s]+)/ ->, | } |
8 | … etc… |
Da du nun die Grammatik hast, kannst du nun den Interpreter bauen Nun ist es eine Überlegung wert, ob du nicht einen „Compiler“ baust, der die „menschenlesbare“ Sprache zuerst in Tokens zerlegt, bevor er sie zum uC schickt. String Manipulation in C ist nicht ganz so spaßig wie zb. In Python oder Javascript. Dieser Code kann natürlich auf dem PC laufen, der ja sowieso den String mittels Serial an die Maschine übergeben muss. … So, ich muss jetzt leider schaffen gehen, morgen kommt Teil 2 wenn du noch Interesse hast: Tokenizing, Speicher (wenn unbedingt C), und Ablauf. PS: bitte nicht das was ich dir beispielhaft hergewaschen habe als Gospel nehmen; so eine Entwicklung ist immer ein Prozess der verbessert werden kann!
Du solltest nochmal überlegen, weshalb das "Programm" als Textdatei übertragen und auf dem µC interpretiert werden soll. Das macht meiner Meinung nach keinen großen Sinn und alles sehr kompliziert. Ich würde einen Programmeditor/ -compiler für den PC bauen und in eine Binärdatei speichern. Diese dann auf den µC übertragen. Die Datei könnte aus serialisierten Structs bestehen: TestIF.h: #define TEST1 = 1; #define TEST2 = 2;
1 | struct Test1 { |
2 | short TestID; |
3 | int param11; |
4 | float param12; |
5 | };
|
6 | |
7 | struct Test2 { |
8 | short TestID; |
9 | float param21; |
10 | short param22; |
11 | };
|
auf dem µC speicherst du den Stream und interpretierst ihn dann so:
1 | int PC = 0; // Programmcounter |
2 | ...
|
3 | |
4 | while(!eos(s)) { // stream abarbeiten |
5 | switch( (short) s[PC] ) { // ID |
6 | case TEST1: |
7 | struct * Test1 = (Test1*) s[PC]; // cast auf struct Test2 |
8 | execTest1( Test1 ); |
9 | PC += sizeof(struct Test1); |
10 | break; |
11 | case TEST2: |
12 | struct * Test2 = (Test2*) s[PC]; // cast auf struct Test2 |
13 | execTest2( Test2 ); |
14 | PC += sizeof(struct Test2); |
15 | break; |
16 | ...
|
17 | |
18 | }
|
19 | }
|
20 | |
21 | void execTest1(struct * Test1 params) { |
22 | print (params.param11); |
23 | }
|
Ist natürlich nur Pseudocode. Die Headerdatei solltest du sowohl im Editor/Compiler als auch im µC verwenden, damit alles konsistent bleibt. Gruß M.
Matthias F. schrieb: > im internen Flash abgelegt werden, bis es neu geladen wird Da solltest du auf die Schreibzyklen achten. Vielleicht besser auf ein EEPROM ausweichen? Ich würde zusätzlich eine Prüfsumme über das Programm legen. Als kleinen Bonus könntest du das EEPROM steckbar machen, dann wandert das Prüfprogramm mit dem Testadapter mit, was Fehler ausschließt.
Es gibt genug Interpreter die man selber einfach erweitern und anpassen kann. Eventuell solltest du Syntax und Semantik deiner Testanweisungen dann an die von den Interpretern ohnehin benutzte Sprache anpassen. Diese Interpreter uebernehmen auch bereits die Tokenisierung, d.h. das Umsetzen des Quellprogramms in die interne Darstellung. Das ist dort schon alles fix und fertig und muss nur um eigene Befehle erweitert werden. Zum Beispiel das Basic der Maximite-Familie. Das enthaelt schon Routinen um Spannungen an den Analogeingaengen oder Frequenzen und Periodendauern zu messen. Programme und Daten koennen auf SD-Karten gespeichert und davon geladen werden.
Andre schrieb: > Als kleinen Bonus könntest du das EEPROM steckbar machen, dann wandert > das Prüfprogramm mit dem Testadapter mit, was Fehler ausschließt. Für mich gehört da ein mit jedem Endgerät beschreib- und auslesbarer "Standardspeicher" der zudem leicht nachbeschafft und getauscht werden kann zur Ablage der Prüfdaten rein. Zwingend. Jegliche proprietäre Bastelei wie "Übertragung per speziellem Programm über eine serielle Schnittstelle" sowie die "Umwandlung in ein proprietäres Format" samt "Speicherung auf einem proprietären Medium" wird sich in Zukunft als schlechte Idee herausstellen. Matthias F. schrieb: > Das projektspezifische Prüfprogramm soll über eine Serielle > Schnittstelle geladen werden > Das Programm soll als txt-Datei übertragen werden. Du könntest natürlich das Prüfprogramm auch gleich in Textform auf einer (micro)SD-Karte speichern. Dann könntest du, wenn es mal keine serielle Schnitte samt passendem "Dateiübertragungsprogramm" mehr gibt, einfach mit einem PC, dem Handy oder einem Tablet die Textdatei auf die SD-Karte kopieren. Und ggfs. die aktuell verwendete "Prüfdatei" einfach archivieren oder mal wieder vom Testgerät zurückholen. Und dann kanst du dir das Komprimieren und die Umwandlung in Tokens auch sparen, denn hier kommt es nicht primär auf die möglichst schnelle Ausführung der Schritte an (im Sinne von 1 Mio Schritte pro Sekunde müssen es schon sein). Wenn du da eine Speicherkarte mit ein paar GB hast, dann ist "Speicherplatz sparen" auch kein Argument mehr. Matthias F. schrieb: > Die Prüfanweisungen könnten folgendermaßen aussehen: > Test Analog_1.1 1.8V > Test Analog_1.1 1.7V > Test Analog_1.1 1.6V Die Definition dieser Testvektoren solltest du nochmal genau überdenken. Denn derzeit definierst du da augenscheinlich nur den Sollwert. Wäre es nicht geschickt, auch noch erwartete min. und max. Werte mit anzugeben? > Test Digital_2.0 1 > Test Digital_2.0 0 > Test Digital_2.1 1 > Test Digital_2.1 0 Und beim Digitaltest erscheint es mir sinnvoll, auch Seitenwirkungen mit anderen Signalen in den Test einzubeziehen zu können. Nur dann kannst du sicher Kurzschlüsse, Querschlüsse und Unterbrechungen feststellen. Und nur als grobe Richtung für den zu planenden Aufwand: bei uns kommen auf vier Steuerungsentwickler etwa drei Prüfgeräteentwickler, die schon parallel zur Steuerungsentwicklung das Prüfgerät anpacken und zusehen, dass es zum Serienanlauf funktionert.
Wie oben schon geschrieben, macht es Sinn einen fertigen Interpreter zu benutzen. Die gibt es natürlich auch für "kleine" Mikrocontroller. Was heißt hier klein? Wenn es ein Prüfgerät werden soll macht es doch überhaupt keinen Sinn zu sparen, das wird ja nicht in Stückzahlen gebraucht oder? Ein Cortex M4 mit 1MB Flash und 512K SRAM kostet doch heute auch schon fast nichts mehr. Als "Interpreter" z.B. "MicroPython" da gibt es sogar schon fertige Firmwaren für eine ganze Reihe an Evalboards (Inklusive SD-Karten und Dateisystem Support) https://github.com/micropython Wir haben auch gute Erfahrungen mit LUA gemacht, das braucht relativ wenig Resourcen: http://www.eluaproject.net/ So kann man dann auch das Testscript auch mit den Standard PC Interpretern verarbeiten und testen bevor man es in das Gerät lädt. Testscript kommt sinnigerweise SD Karte, alles andere ist viel zu kompliziert.
Wieso was eigenes entwickeln, warum nicht gleich ein Javascript oder LUA Interpreter nehmen, dann kannst Du deine Arveitszeit auf das wesentliche konzentrieren und der Benutzer muss nicht eine Unbekanntesprache mit schlechter Dokumenation/Beispielen erlernen. Javascript: http://www.espruino.com/ LUA: http://www.eluaproject.net/
Dazu musst Du das Prüfprogramm sehr stark modularisieren. Dann müssen praktisch alle Aktionen aus einer Tabelle ermittelt werden, die z.B. festlegt, dass Anschluss 1 ein 3,3V Eingang ist; Anschluss 2 ein offener Relaisanschluss oder Anschluss 3 ein 6,36V Ausgang ist. Usw. Natürlich kann es nicht schaden, wenn für alle Szenarien eine entsprechende Routine vorhanden ist, die dann bedarfsweise verwendet wird oder auch nicht (wenn der Anschluss nicht existiert). Es kann auch nicht schaden, wenn der Anwender den aktuellen Prüfling eindeutig auswählen kann. Ist nicht so doll, wenn ein im Grundgenommen fehlerfreies Gerät, durch die Prüfeinrichtung ins Nirwana geschickt wird. In dem Falle könnte dann allerdings ein Fehler gemeldet werden: Optisch mit einer LED oder olfaktorisch.
Ich vergaß! Für Freunde von C lautet das Stichwort hierzu Funktionszeiger (function pointer).
Kurt P. schrieb: > Welcher uC? Hier arbeitet ein Cortex M4 von Renesas. Mehr Infos über das Produkt darf ich leider nicht geben, ich weiß nicht was sonst passiert. Kurt P. schrieb: > Da du nun die Grammatik hast, kannst du nun den Interpreter bauen > Nun ist es eine Überlegung wert, ob du nicht einen „Compiler“ baust, der > die „menschenlesbare“ Sprache zuerst in Tokens zerlegt, bevor er sie zum > uC schickt. Ja, diese Überlegung hatte ich auch bereits, wobei hier schon das erste Mal der Text geparst (und natürlich auf Syntaxfehler etc kontrolliert) werden muss. dann hätte ich eine Art "Byte-Code", wenn ich da richtig liege. Kurt P. schrieb: > S | } -> VORJEDEM: | NACHJEDEM: | TEST > VORJEDEM: -> { > NACHJEDEM: -> { > TEST -> /([^:]+):/ -> { > { | , -> SETZE | FORDERE | WARTE | ERWARTE > SETZE -> /([^\s]+)/ -> /([^\s]+)/ -> , | } > WARTE -> /([^\s]+)/ ->, | } > … etc… Diese Auflistung habe ich jetzt nicht richtig verstanden. MikeH schrieb: > Du solltest nochmal überlegen, weshalb das "Programm" als Textdatei > übertragen und auf dem µC interpretiert werden soll. Das macht meiner > Meinung nach keinen großen Sinn und alles sehr kompliziert. Mein Hintergedanke war, den text im bedarfsfall ohne Verrenkungen wieder auslesen zu können. Was natürlich bei einem vorverarbeiteten text ebenfalls möglich wäre. Andre schrieb: > Da solltest du auf die Schreibzyklen achten. Vielleicht besser auf ein > EEPROM ausweichen? Ich würde zusätzlich eine Prüfsumme über das Programm > legen. > > Als kleinen Bonus könntest du das EEPROM steckbar machen, dann wandert > das Prüfprogramm mit dem Testadapter mit, was Fehler ausschließt. In beiden Überlegungen gast du natürlich recht. Die Anzahl Schreibzyklen ist wahrscheinlich unkritisch, die Sicherheitsmechanismen kommen später natürlich auch noch dazu. geoff schrieb: > Es gibt genug Interpreter die man selber einfach erweitern und anpassen > kann. Danke für den Hinweis. Die Idee ist sicherlich Zielführend, allerdings möchte ich selber auch verstehen, was dort abläuft. Auch weil es spaß macht. Lothar M. schrieb: > Du könntest natürlich das Prüfprogramm auch gleich in Textform auf einer > (micro)SD-Karte speichern. Das funktioniert leider nicht, da dieses Gerät eigentlich eine Steuerung ist, die mit anderer Software gleichartige Geräte testen soll. Dort ist leider keine Möglichkeit, eine SD-Karte o.ä. einzusetzen. Lothar M. schrieb: > Die Definition dieser Testvektoren solltest du nochmal genau überdenken. > Denn derzeit definierst du da augenscheinlich nur den Sollwert. Wäre es > nicht geschickt, auch noch erwartete min. und max. Werte mit anzugeben? Das waren natürlich nur grobe Beispiele. Andreas M. schrieb: > Was heißt hier klein? Wenn es ein Prüfgerät werden soll macht es doch > überhaupt keinen Sinn zu sparen, das wird ja nicht in Stückzahlen > gebraucht oder? Ein Cortex M4 mit 1MB Flash und 512K SRAM kostet doch > heute auch schon fast nichts mehr. Wie weiter oben geschrieben, die Hardware existiert bereits und ist 100% kompatibel zu den Prüflingen. Wie macht das eigentlich eine SPS, die hat einen fest implementiertes Betriebssystem und interpretiert auch nur die eingegebenen Befehle. Gibt es für so etwas Beispiele bzw. Open Source-Projekte, nach denen man sich richten kann? Kurt P. schrieb: > morgen kommt Teil 2 wenn du > noch Interesse hast Sehr gerne!
Matthias F. schrieb: > Ich habe eine hier große Wissenslücke, was das einlesen und verarbeiten > der Datei angeht. Wo ist das Problem. Das ist doch trivial. Du hast da eine (extrem primitive) Sprache, in der die Testanweisungen formuliert sind. Du brauchst also auch nur einen extrem primitiven Parser, um die Anweisungen in ihre semantischen Bestandteile zu zerlegen. DAS IST KINDERKRAM! Und weil das so ist, wirst du auch keine speziellen Infos dafür finden. Das ist einfach was, was jeder Programmierer in jeder beliebigen Sprache locker aus der Hüfte umsetzen kann, ohne groß darüber nachdenken zu müssen.
c-hater schrieb: "c-hater": ALLEINE WEGEN DEINES NAMENS BIST DU FÜR MICH DISQUALIFIZIERT! c-hater schrieb: > DAS IST KINDERKRAM! Für jemanden wie dich vielleicht. Windeln heute schon gewechselt? c-hater schrieb: > Wo ist das Problem. Das ist doch trivial. Du hast da eine (extrem > primitive) Sprache, in der die Testanweisungen formuliert sind. > > Du brauchst also auch nur einen extrem primitiven Parser, um die > Anweisungen in ihre semantischen Bestandteile zu zerlegen. Das ist das allgemeinste und dämlichste (jawohl, unMÄNNLICHSTE) Geschwätz ohne einen geringsten Anteil hilfreicher Informationen. Wenn ich mir deine bisherigen "Beiträge" (seit mindestens 5 Jahren) ansehe, beschränkt sich dein Horizont genau darauf. Vielleicht hast du ein Problem mit deinen Eiern (falls (noch) vorhanden), lernfähig scheinst du jedenfalls nicht zu sein; das beweist die immer gleiche Struktur deiner so genannten "Beiträge". Es scheint auch andere Faktoren zu geben, die das Nervensystem angreifen als nur Corona. Dafür bist du ein gutes Beispiel. Wenn ich so viel Zeit hätte wie du, würde ich mir ein anderes, lukrativeres Hobby suchen, als anderen Menschen mit der puren Existenz auf den Sack zu gehen. Geh an die Börse und spekulier mit CFDs oder Futures. Da kannst du zeigen was für ein toller Hecht du bist! Oder so richtig verscheißen wenn du dich verzockst. Zeig wer du bist, aber lass uns hier in Ruhe! Eine Hand voll Hilfe ist mehr wert, als eine Karre voll dummer Ratschläge!
Man kann so was wie du geschrieben hast schon sicher auswerten, aber ich würde einen einfachen Basic, c oder forth interpreter nehmen. Das hat den Vorteil das man recht einfach deine Listen in dem Code einbauen kann, schleifen und delays auch einfach einbauen kann. Ich habe so etwas an der Arbeit vor ein paar Jahren für die Produktion so gemacht und habe einen basic Interpreter genommen.
Wenn man einen Interpreter nimmt ist man mit Sicherheit am besten aufgestellt. Das parsen von Deinen Daten würde ich mir nicht antun. Es geht zwar aber dann noch nicht so einfach ist wie man sich das denkt. Und mit einem Interpreter hast Du alles din was man so brauch. Das kannst Du sogar auf dem PC mit entsprechender Umgebung vortesten. Klar die ganzen Routinen für I/O einstellen, lesen & setzen musst Du dann noch schreiben, aber das musst Du ja sowieso machen. Ausgaben sind dann auch kein Problem.
Matthias F. schrieb: > Das funktioniert leider nicht, da dieses Gerät eigentlich eine Steuerung > ist, die mit anderer Software gleichartige Geräte testen soll. Dort ist > leider keine Möglichkeit, eine SD-Karte o.ä. einzusetzen. Tja, das passiert halt wenn man zuerst die Hardware kauft und dann die Anforderungen festlegt. Dann muss halt das Testprogramm für alle zu testenden Geräte auf die Steuerung und per Schalter o.ä. umgeschalten werden. Matthias F. schrieb: > Wie macht das eigentlich eine SPS, die hat einen fest implementiertes > Betriebssystem und interpretiert auch nur die eingegebenen Befehle. Gibt Das kann man so pauschal nicht sagen, denn das ist nicht nur von Hersteller zu Hersteller sondern auch von Produkt zu Produkt unterschiedlich. Bei Siemens war es früher z.b. tatsächlich immer ein interpretierter Byte-Code. Deswegen konnte man auch die Speicherkarten von einer SPS meist ohne Probleme in einer neueren SPS einsetzten und alles lief wie vorher. Das ist heute nicht mehr immer so. 3S Codesys hat einen eingebauten Compiler und übersetzt das Programm in passenden Code für die Zielplatform. Es gibt auch Motion Controller mit FPGAs im Datenpfad. > es für so etwas Beispiele bzw. Open Source-Projekte, nach denen man sich > richten kann? Lol, genau darin steckt das meiste Gehirnschmalz von einer SPS, der Hersteller wäre schön blöd wenn er das für lau im Netz verteilt. Im Opensourcebereich hat das keine Relevanz, warum sollte sich jemand zum Spaß ne VM für Bytecode ausdenken, da gibts schon zig Varianten.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.