Hi Leute, also ich möchte mein Mikrocontroller mit einem Command Line Interface erweitern. Da gibt es die Variante 1) ich sende per UART den Befehl und erhalte danach dann die Antwort (z.B. über HTerm, cutecom). Und dann gibt es die Variante 2) da kann man wie in der Linux Shell direkt sehen was man eingibt und auch mit Backspace den Befehl vor Absenden noch editieren etc.. Das kenne ich in Zusammenhang mit putty und einigen Ethernet Switchen. Ich hoffe ihr wisst was ich meine. Gibt es für Variante 2) einen Namen? So ganz klar ist mir das nämlich noch nicht wie das funktioniert. Wahrscheinlich wird mit jedem tippen der ganze Output neu geschrieben?
Hallo, Beim esp32 esp-idf gibt es eine Console Komponente die sehr aufschlussreich ist. Im Grunde besteht diese aus linenoise(-ng) und argtable3. MfG
Moin, HappyNuYear schrieb: > Gibt es für Variante 2) einen Namen? Ich wuerd' sagen: Shell oder CLI (command line interface) Gruss WK
HappyNuYear schrieb: > Gibt es für Variante 2) einen Namen? Keinen genormten, aber local echo trifft es ganz gut. Bei einem ernstzunehmenden Terminal-Programm kann man das einstellen. Wenn der Empfänger die Daten als Antwort zurücksendet (was fast immer der Fall ist, z.B. bei einem Modem) sollte man das abschalten, damit man nicht alles doppelt sieht (das liegt dann nicht an Silvester). Georg
Bei 2 läuft zusätzlicher ein Zeileneditor auf dem Controller. Der sendet die empfangenen Zeichen zurück (echo) und interpretiert einige davon als Editierkommandos (z.B. Backspace = letztes Zeichen löschen). Hier mal ein einfaches Beispiel:
1 | static void getline(u8 *buf, u8 size) |
2 | {
|
3 | u8 c, n = strlen(buf); |
4 | |
5 | restart:
|
6 | buf[n] = 0; |
7 | putlit("> "); |
8 | putstr(buf); |
9 | for (;;) |
10 | {
|
11 | c = getch(); |
12 | if (c == '\n') // Return - Eingabe beenden |
13 | {
|
14 | putch('\n'); |
15 | buf[n] = 0; |
16 | return; |
17 | }
|
18 | else if (c == '\b') // Backspace - letztes Zeichen löschen |
19 | {
|
20 | if (n) |
21 | {
|
22 | putlit("\b \b"); |
23 | n--; |
24 | }
|
25 | }
|
26 | else if (c == 3) // CTRL-C - Eingabe löschen |
27 | {
|
28 | putlit("^C\n"); |
29 | n = 0; |
30 | goto restart; |
31 | }
|
32 | else if (c == '\f') // CTRL-L - Bildschirm löschen |
33 | {
|
34 | //putlit("\ec\e[H\e[2J");
|
35 | putlit("\ec"); |
36 | goto restart; |
37 | }
|
38 | else if (c >= ' ' && c <= '~' && n < size-1) // druckbares Zeichen |
39 | {
|
40 | putch(c); |
41 | buf[n++] = c; |
42 | }
|
43 | else // ignoriertes Zeichen - beepen |
44 | putch('\a'); |
45 | }
|
46 | }
|
Ich habe mal ein Beispiel angehängt. Es ist sogar möglich mit Cursortasten Menüpukte auszuwählen. Es muss irgendeinen Standard/Protokoll geben, welches da im Hintergrund läuft und genau dazu suche ich die Bezeichnung. Scheinbar wird der Output ständig refreshed also muss es irgendwelche Sonderkommandos geben die Putty empfängt und daraufhin refreshed.
Mit einem anderen Terminalprogramm (cutecom) sieht der Output so aus:
1 | <0x1b>[m<0x1b>[m<0x1b>[m<0x1b>[4;26H<0x1b>[4;26HSystem Parameter<0x1b>[m<0x1b>[m<0x1b>[6;26H<0x1b>[6;26HSwitch Security<0x1b>[m<0x1b>[m<0x1b>[8;26H<0x1b>[8;26HPort Configuration / Statistics<0x1b>[m<0x1b>[m<0x1b>[10;26H<0x1b>[10;26HDisable Learning<0x1b>[m<0x1b>[m<0x1b>[12;26H<0x1b>[12;26HConfiguration<0x1b>[m<0x1b>[m<0x1b>[14;26H<0x1b>[14;26HUpdate<0x1b>[m<0x1b>[7m<0x1b>[7m<0x1b>[16;26H<0x1b>[16;26HPassword<0x1b>[m<0x1b>[m<0x1b>[m<0x1b>[18;26H<0x1b>[18;26HPing<0x1b>[m<0x1b>[m<0x1b>[20;26H<0x1b>[20;26HSystem Reset<0x1b>[m<0x1b>[m<0x1b>[22;4H<0x1b>[22;4HLOGOUT<0x1b>[m<0x1b>[m<0x1b>[16;26H |
Also man sieht bestimmte Sonderbefehle, die nur PuTTY interpretieren kann.
Der "Standard" nennt sind ANSI-Escapesequenzen[1]. Ein Programm auf dem Controller malt die Menues, wertet die Cursurtasten aus, malt entsprechend neu, steuert den Cursor, usw, usf. Ein Paket, das einem das erleichtert, nennt sich ncurses[2]. Auf kleineren Mikrocontrollern wirst du das aber kaum zum Rennen bekommen. [1] https://de.wikipedia.org/wiki/ANSI-Escapesequenz [2] https://de.wikipedia.org/wiki/Ncurses
HappyNuYear schrieb: > Es muss irgendeinen Standard/Protokoll geben, welches da im Hintergrund > läuft und genau dazu suche ich die Bezeichnung. Meinst du Terminal Emulationen wie VT-100,VT200 oder VT-52? Dabei kann der Host das Terminal steuern inkl. Position, Farbe usw.
Suche doch mal nach "ANSI-Escape-Sequenzen". Da gab es früher für bestimmte Terminals diese Steuersequenzen, mit denen du auf dem Bildschirm verschiedene Sachen machen kannst.
HappyNuYear schrieb: > Es ist sogar möglich mit Cursortasten Menüpukte auszuwählen. > Es muss irgendeinen Standard/Protokoll geben, welches da im Hintergrund > läuft und genau dazu suche ich die Bezeichnung. Ansi Escape Sequenzen https://en.wikipedia.org/wiki/ANSI_escape_code
Beitrag #6532954 wurde vom Autor gelöscht.
foobar schrieb: > ANSI-Escapesequenzen Matthias S. schrieb: > VT-100 Ja, danke, das ist es. http://ascii-table.com/ansi-escape-sequences-vt-100.php Happy New Year!
HappyNuYear schrieb: > Scheinbar wird der Output ständig refreshed Nein, das wird da nicht gemacht. Wie aber bereits genannt, werden hier Escape-Sequenzen verwendet. Der von Dir beobachtete Refresh, erfolgt durch Cursorpositionierung und Überschreiben.
HappyNuYear schrieb: > also ich möchte mein Mikrocontroller mit einem Command Line Interface > erweitern. Da gibt es die Variante 1)... Ach wo. Es geht viel viel viel einfacher: Dein Terminalprogramm im PC sendet die Zeichen, die du eintippst, zum µC. Dort ist ein kleines Kommandoprogramm, das diese Zeichen in einen Puffer (üblich sind 80 Zeichen) einlaufen läßt und dabei einige wenige Sonderzeichen passend interpretiert. Zum Beispiel 8 (=BS), was das letzte Zeichen löscht. Und dieses Kommandoprogramm sendet die empfangenen Zeichen auch wieder zurück an den PC. Dort kannst du sie dann in deinem Terminalprogramm sehen. Und wenn die Zeile komplett ist (CR als Zeilenende), dann wird sie ausgewertet - je nachdem, was du da an Kommandos eingebaut hast. Viel mehr braucht es nicht, um eine Kommandozeile im µC zu implementieren.
1 | /* Kommandozeile hereinholen */
|
2 | int kzi; |
3 | |
4 | void Talk (word wo) |
5 | { char c; |
6 | |
7 | if (RxAvail(wo)) |
8 | { c = GetChar(wo); |
9 | if (c==10) return; |
10 | if (c==13) |
11 | { CRLF_Out(wo); |
12 | DoCommand (Kommandozeile, wo); |
13 | InitCmd(wo); |
14 | }
|
15 | else
|
16 | { if (kzi>=(sizeof(Kommandozeile)-1)) return; |
17 | if (c==8) |
18 | { Char_Out(8, wo); |
19 | Char_Out(' ', wo); |
20 | Char_Out(8, wo); |
21 | if (kzi) --kzi; |
22 | Kommandozeile[kzi]=0; |
23 | }
|
24 | else
|
25 | { Char_Out(c, wo); |
26 | Kommandozeile[kzi++] = c; |
27 | Kommandozeile[kzi] = 0; |
28 | }
|
29 | }
|
30 | }
|
31 | }
|
Und zur Auswertung dann so etwas:
1 | char Kommandozeile[80]; |
2 | char* Cpt; |
3 | |
4 | void DoCommand (char* Pzeile, word wo) |
5 | { char c; |
6 | |
7 | Cpt = Pzeile; |
8 | if (match("OTTOKAR",&Cpt)) { DoOttokar(wo); return;} |
9 | if (match("EMIL",&Cpt)) { DoEmil(wo); return;} |
10 | ...und so weiter |
11 | |
12 | if (!*Cpt) return; |
13 | String_Out("wat? ", wo); |
14 | String_Out(Cpt, wo); |
15 | CRLF_Out(wo); |
16 | }
|
Ist doch easy, oder? W.S.
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.