Forum: Mikrocontroller und Digitale Elektronik Putty und Backspace


von dotm (Gast)


Lesenswert?

Hallo
Ich möchte meinen MCU über ein Terminal bedienen. Das haut jetzt auch 
mit Tastatureingaben gut hin.
Backspace hab ich bei Putty mit 0x08 eingestellt. Mein MCU echot jedes 
Signal brav zum Terminal.
Das Terminal reagiert aber auf ein Backspace nicht so wie ich will.
Ich hätte gerne dass es nach hinten geht und das Zeichen löscht.
Stattdessen wird aber einfach nur nach hinten gegangen. Das Zeichen 
bleibt stehen.
Ich hab also ein anderes Terminalprogramm probiert (TeraTerm) und das 
verhält sich genauso.
Muss ich tatsächlich als Echo für das Backspacezeichen einmal Backspace 
dann einen Nullchar und dann wieder Backspace senden? Das wäre doch 
absurd!
Oder gibt es irgendein Terminalprogramm dass das für mich richtig 
interpretiert?
M.

von Karl H. (kbuchegg)


Lesenswert?

dotm schrieb:

> Stattdessen wird aber einfach nur nach hinten gegangen. Das Zeichen
> bleibt stehen.

Ja, das ist auch normal.
Lass dich nicht vom 'SPace' in 'Backspace' ins Boxhorn jagen. Damit ist 
nicht automatisch die Ausgabe eines Leerzeichens verbunden. Druckende 
Terminals können das zb überhaupt nicht. Was einmal am Papier steht, 
bleibt auch dort.

> Muss ich tatsächlich als Echo für das Backspacezeichen einmal Backspace
> dann einen Nullchar

nicht ein 'Nullchar'. Du willst das Zeichen das dort steht mit einem 
Leerzeichen überschreiben. Also sendest du auch genau das: ein 
Leerzeichen. Die Antwort auf einen Backspace ist also in den meisten 
Fällen die Sequenz Backspace, Leerzeichen, Backspace.

> und dann wieder Backspace senden? Das wäre doch
> absurd!

Keineswegs.
Die Dinge werden noch komplizierter, wenn deine Eingabe über mehrere 
Zeilen geht. Denn dann wird es unter Umständen richtig aufwändig, wenn 
der Cursor dann vom linken Zeilenende ans rechte Zeilende muss, während 
das legtzte Zeichen gelöscht wird.

von dotm (Gast)


Lesenswert?

Um GOTTES WILLEN!!!
gibt es kein Terminalprogramm mit entsprechender Funktion?

von Karl H. (kbuchegg)


Lesenswert?

Mein Gott. Mach dir doch nicht ins Hemd.
Was ist denn so schlimm an
1
  puts( "\b \b" );
so funktioniert das nun mal. Ist doch kein Drama.

von Bernd N (Gast)


Lesenswert?

google mal escape Sequenzen.

Backspace einfach mit prinf ausgeben '\b'

von Bernd N (Gast)


Lesenswert?


von dotm (Gast)


Lesenswert?

so einfach ist das bei mir nicht.
Ich muss halt eine Erkennung für jedes zeichen reinmachen vor dem Echo.
Bzw das Echo zu jedem unterschiedlichen Characterhandling dazuschreiben.
Eventuell nicht so arg, dennoch mühsam.

von Karl H. (kbuchegg)


Lesenswert?

Ja, das soll vorkommen, dass man in der Empfangsroutine ein paar if 
drinnen hat, die je nachdem eine spezielle Reaktion hervorrufen.
zb für Backspace
zb für das leidige Return/Newline Thema
zb für XON/XOFF

Da sich derartige Dinge aber auf unterster Ebene abspielen, ist das 
normalerweise alles halb so wild und nur auf diese Ebene beschränkt.

von dotm (Gast)


Lesenswert?

Vorallem lästig ist dass ich das lokale echo im einzelfall so machen 
kann:
1
if (echo_local == ENABLE)
2
{
3
USART_SendData(com_usart[params->COM], received_char);
4
}

jetzt aber if/thens UND vorallem abwarten bis das Zeug auch wirklich 
draussen ist!
1
if ((received_char == 0x08) && (params->handle_backspace == ENABLE))
2
          {
3
          if (char_counter > 0) char_counter--;
4
          params->buffer[char_counter] = 0x00;
5
          if (echo_local == ENABLE)
6
            {
7
            // send backspace-space-backspace for terminal
8
            USART_SendData(com_usart[params->COM], 0x08);
9
            while (USART_GetFlagStatus(com_usart[params->COM], USART_FLAG_TXE) == RESET)
10
              ;
11
            USART_SendData(com_usart[params->COM], 0x20);
12
            while (USART_GetFlagStatus(com_usart[params->COM], USART_FLAG_TXE) == RESET)
13
              ;
14
            USART_SendData(com_usart[params->COM], 0x08);
15
            while (USART_GetFlagStatus(com_usart[params->COM], USART_FLAG_TXE) == RESET)
16
              ;
17
            }
18
          }

von Karl H. (kbuchegg)


Lesenswert?

dotm schrieb:

> jetzt aber if/thens UND vorallem abwarten bis das Zeug auch wirklich
> draussen ist!

Dann wirds Zeit für ein paar Hilfsfunktionen.
1
   if ((received_char == 0x08) && (params->handle_backspace == ENABLE))
2
   {
3
     if (char_counter > 0)
4
     {
5
       char_counter--;
6
       params->buffer[char_counter] = 0x00;
7
8
       if (echo_local == ENABLE)
9
         USART_SendString( com_usart[params->COM], "\b \b" );
10
     }
11
   }

Die Hälfte des Codes ist sowieso notwendig, egal ob dein Terminal einen 
Backspace so ausführt, wie du das erwartest oder nicht. Und den Rest, 
die Ausgabe selbst, kapselst du in eine Stringausgabefunktion, die man 
in einem ordentlichen Programm sowieso braucht.
Mach nicht das Terminal dafür verantwortlich, wenn du nicht erkennst 
oder zu faul dazu bist, dir immer wieder gebrauchte Funktionalität in 
Funktionen zu kapseln.
Ob da jetzt als Antwort auf einen Tastendruck vom Benutzer 2 Zeichen 
mehr als Echo über die Leitung gehen, ist zeittechnisch aber sowas von 
egal. Kein Mensch tippt so schnell, dass man das je bemerken wird.

von dotm (Gast)


Lesenswert?

Karl Heinz schrieb:
> Und den Rest, die Ausgabe
> kapselst du in eine Stringausgabefunktion, die man in einem ordentlichen
> Programm sowieso braucht.

Hab ich sowieso.
Aber die Funktion wegen höherer Priorität im Task den Scheduler aufhält 
verwende ich lieber die schnellere variante und das ist dreimal 
USART_SendChar().
Schaut scheisse aus im Code ist aber performanter.

von Karl H. (kbuchegg)


Lesenswert?

dotm schrieb:

> Schaut scheisse aus im Code ist aber performanter.

Dreh wenigstens die Reihenfolge um. Es gibt keinen Grund, warum ma nauf 
das letzte Backspace warten müsste. (Zumindest nicht normalerweise).

Im Regelfall wartet man darauf, dass die UART soweit fertig ist, dass 
sie ein neues Zeichen versenden kann und stellt dann das Zeichen in die 
UART rein.

Also so rum
1
            while (USART_GetFlagStatus(com_usart[params->COM], USART_FLAG_TXE) == RESET)
2
              ;
3
            USART_SendData(com_usart[params->COM], 0x08);

das kapselt man sich in eine Funktion oder ein Makro und landet wieder 
bei
1
       if (echo_local == ENABLE)
2
       {
3
         USART_SendDataChecked( com_usart[params->COM], '\b' );
4
         USART_SendDataChecked( com_usart[params->COM], ' ' );
5
         USART_SendDataChecked( com_usart[params->COM], '\b' );
6
       }
und dann siehts gleich gar nicht mehr so Scheisse aus. Alles nur eine 
Frage der Codeorganisation.

von dotm (Gast)


Lesenswert?

Karl Heinz schrieb:
> Dreh wenigstens die Reihenfolge um. Es gibt keinen Grund, warum ma nauf
> das letzte Backspace warten müsste. (Zumindest nicht normalerweise).

ja. GUT! gefällt mir!

von dotm (Gast)


Lesenswert?

Dass bei
1
  while (USART_GetFlagStatus(com_usart[params->COM], USART_FLAG_TXE) == RESET)
2
              ;
3
            USART_SendData(com_usart[params->COM], 0x08);
das eine Semikolon in einer neuen Zeile ist liegt übrigens dran dass der 
Eclipse Code-Formatter so gut er auch ist es nicht schafft einen while 
Loop mit leerem Body als solchen zu erkennen und den Strichpunkt in der 
Zeile zu lassen.
Kann man ihm auch nicht beibringen.
Kack.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

dotm schrieb:
> Dass bei
>
1
>   while (USART_GetFlagStatus(com_usart[params->COM], USART_FLAG_TXE) == 
2
> RESET)
3
>               ;
4
>             USART_SendData(com_usart[params->COM], 0x08);
5
>
> das eine Semikolon in einer neuen Zeile ist liegt übrigens dran dass der
> Eclipse Code-Formatter so gut er auch ist es nicht schafft einen while
> Loop mit leerem Body als solchen zu erkennen und den Strichpunkt in der
> Zeile zu lassen.

Du irrst vermutlich und der Code-Formatter ist besser als Du denkst. Er 
will so dem Programmierer explizit zeigen, dass es sich hier um einen 
leeren Block handelt.

Ich selber bin sogar noch schlimmer und schreibe zusätzlich noch 
geschweifte Klammern um das Semikolon, also so:

   while (....)
   {
       ;
   }

Gund:

Wer hat nicht schon mal in seinem Leben hinter das while(...) aus 
Versehen ein Semikolon gehängt und sich gewundert, dass der nachfolgende 
Block nicht bzw. nur noch einmal ausgeführt wird?

von Karl H. (kbuchegg)


Lesenswert?

dotm schrieb:

> das eine Semikolon in einer neuen Zeile ist liegt übrigens dran dass der
> Eclipse Code-Formatter so gut er auch ist es nicht schafft einen while
> Loop mit leerem Body als solchen zu erkennen und den Strichpunkt in der
> Zeile zu lassen.

Warum sollte er auch.
Die Syntax lautet
1
  while( expression )
2
    statement

d.h. konsequenterweise kommt das Statement in die nächste Zeile und am 
Ende der Zeile mit dem while gibt es keinen ;

Ob das Statement jetzt eine Zuweisung ist
1
  while( expression )
2
    i = 5;

oder eine leere Anweisung (ja, so etwas gibt es!)
1
  while( expression )
2
    ;

ist ja egal. Statement ist Statement. Und das kommt in die nächste 
Zeile.

Wenn ich hingegen so etwas sehe
1
   if (char_counter > 0) char_counter--;
kommt mir das kalte Grausen und ich frage mich, wo noch überall du dich 
nicht an Formatiergepflogenheiten hältst.

von Peter D. (peda)


Lesenswert?

dotm schrieb:
> Vorallem lästig ist dass ich das lokale echo im einzelfall so machen
> kann:
> if (echo_local == ENABLE)
> {
> USART_SendData(com_usart[params->COM], received_char);
> }

Bei manueller Eingabe mag das gehen.
Aber aus einer Datei oder von einem Programm schießt Du Dir damit ins 
Knie, sobald im FIFO noch ein Zeichen ist.

Jedes empfangene Zeichen muß erstmal gespeichert werden, um es als Echo 
zu senden und dann auch noch zu parsen.

von dotm (Gast)


Lesenswert?

Karl Heinz schrieb:
> kommt mir das kalte Grausen und ich frage mich, wo noch überall du dich
> nicht an Formatiergepflogenheiten hältst.

seit wann darf ich ifs mit nur einer Anweisung nicht in nur eine Zeile 
schreiben?

Peter Dannegger schrieb:
> Bei manueller Eingabe mag das gehen.
> Aber aus einer Datei oder von einem Programm schießt Du Dir damit ins
> Knie, sobald im FIFO noch ein Zeichen ist.

In dem Fall brauch ich aber auch kein Echo.

von Karl H. (kbuchegg)


Lesenswert?

dotm schrieb:
> Karl Heinz schrieb:
>> kommt mir das kalte Grausen und ich frage mich, wo noch überall du dich
>> nicht an Formatiergepflogenheiten hältst.
>
> seit wann darf ich ifs mit nur einer Anweisung nicht in nur eine Zeile
> schreiben?

Du darfst alles, wonach dir der Sinn steht. Es ist schliesslich deine 
Zeit, die du mit sinnloser Fehlersuche verplemperst.

Sobald du mal mit anderem in einem Team arbeitest, werden die dir schon 
sagen, wie die Formatierung sein muss.

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.