Changes between Version 16 and Version 17 of serial


Ignore:
Timestamp:
09/05/2019 12:29:37 AM (5 years ago)
Author:
Tim Harvey
Comment:

added section about serial console

Legend:

Unmodified
Added
Removed
Modified
  • serial

    v16 v17  
    663663
    664664
     665
     666
     667[=#console]
     668= Serial Console
     669
     670== Serial Console Window Size
     671console applications running inside Linux virtual terminal applications (xterm, rxvt etc) will receive SIGWINCH after a resize operation has taken place and adjust accordingly.
     672
     673When using a serial console there is no such mechanism and you can see the affect of this by connecting to a serial console (ie jtag_com/jtag_gang) and showing your size either via env vars or via the 'stty size' app:
     674{{{#!bash
     675~# echo $LINES $COLUMNS
     67624 80
     677~# stty size
     67824 80
     679}}}
     680
     681No matter how you resize that virtual terminal window (ie xterm), the above commands will always report the same size.
     682
     683It is possible for the application to actively ask for the current console window size so the second best thing is to do this every time a command prompt is printed by the shell. This can be achieved by sending a ANSI code to position the cursor to 999,999 then request the cursor position.
     684
     685The 'resize' app from the 'xterm' package does this, but here is also a cleaner version with less dependencies:
     686{{{#!bash
     687wget http://web.archive.org/web/20081224152013/http://www.davehylands.com/gumstix-wiki/resize/resize.c
     688gcc resize.c -o /usr/local/bin/resize
     689}}}
     690
     691You can also do this with shell scripts that do the same thing:
     692{{{#!bash
     693resize() {
     694  old=$(stty -g)
     695  stty raw -echo min 0 time 5
     696  printf '\0337\033[r\033[999;999H\033[6n\0338' > /dev/tty
     697  IFS='[;R' read -r _ rows cols _ < /dev/tty
     698  stty "$old"
     699  #echo "size:${cols}x${rows}"
     700  stty cols "$cols" rows "$rows"
     701}
     702}}}
     703
     704you could add this and the following to your /etc/bash.bashrc:
     705{{{#!bash
     706[[ "$(tty)" =~ "/dev/ttymxc" ]] && { resize; }
     707}}}
     708
     709some people also opt to use the 'trap' shell function to execute it on every command:
     710{{{#!bash
     711[[ "$(tty)" =~ "/dev/ttymxc" ]] && { trap resize DEBUG; }
     712}}}
     713
     714Notes:
     715 - 'tty' shows the name of the terminal device (ie /dev/ttymxc1 if on a Ventana serial console)
     716 - 'stty size' outputs the current terminal size based on what the kernel thinks
     717 - this has nothing to do with terminal type (TERM)
     718 - when remotely connected to a board via ssh for example, this isn't an issue as that can use SIGWINCH
     719orts 24 80
     720 - the COLUMNS and LINES env variables reflect the size of the tty
     721 - resizable terminals are the result of NAWS 'Negotiate About Window Size' from RFC 1073 Telnet Window Size Option
     722
     723References:
     724- https://unix.stackexchange.com/questions/16578/resizable-serial-console-window
     725- http://web.archive.org/web/20081224152013/http://www.davehylands.com/gumstix-wiki/resize/resize.c
     726{{{#!c
     727/* resize.c */
     728
     729#include <stdio.h>
     730#include <ctype.h>
     731#include <stdlib.h>
     732#include <unistd.h>
     733#include <sys/types.h>
     734#include <string.h>
     735#include <termio.h>
     736#include <termios.h>
     737
     738
     739#include <signal.h>
     740#include <pwd.h>
     741
     742#define ESC "\033"
     743
     744
     745#define TIMEOUT         10
     746
     747
     748char *myname;
     749
     750char getsize[] = ESC "7"  ESC "[r" ESC "[999;999H" ESC "[6n";
     751char restore[] = ESC "8";
     752
     753struct termios tioorig;
     754
     755char size[] = ESC "[%d;%dR";
     756
     757int tty;
     758FILE *ttyfp;
     759
     760static void onintr (int sig);
     761static void resize_timeout (int sig);
     762static void Usage (void);
     763static void readstring (FILE *fp, char *buf, char *str);
     764
     765char *
     766x_basename(char *name)
     767{
     768   char *cp;
     769
     770   cp = strrchr(name, '/');
     771   return (cp ? cp + 1 : name);
     772}
     773
     774
     775/*
     776  tells tty driver to reflect current screen size
     777 */
     778
     779int
     780main (int argc, char **argv)
     781{
     782
     783       int rows, cols;
     784       struct termios tio;
     785       char buf[BUFSIZ];
     786       struct winsize ws;
     787       char *name_of_tty;
     788
     789       myname = x_basename(argv[0]);
     790
     791       if (argc > 1) Usage();
     792
     793       name_of_tty = "/dev/tty";
     794
     795       if ((ttyfp = fopen (name_of_tty, "r+")) == NULL) {
     796           fprintf (stderr, "%s:  can't open terminal %s\n",
     797                    myname, name_of_tty);
     798           exit (1);
     799       }
     800       tty = fileno(ttyfp);
     801
     802       tcgetattr(tty, &tioorig);
     803       tio = tioorig;
     804       tio.c_iflag &= ~ICRNL;
     805       tio.c_lflag &= ~(ICANON | ECHO);
     806       tio.c_cflag |= CS8;
     807       tio.c_cc[VMIN] = 6;
     808       tio.c_cc[VTIME] = 1;
     809       signal(SIGINT, onintr);
     810       signal(SIGQUIT, onintr);
     811       signal(SIGTERM, onintr);
     812       tcsetattr(tty, TCSADRAIN, &tio);
     813
     814       write(tty, getsize, strlen(getsize));
     815       readstring(ttyfp, buf, size);
     816       if(sscanf (buf, size, &rows, &cols) != 2) {
     817               fprintf(stderr, "%s: Can't get rows and columns\r\n", myname);
     818               onintr(0);
     819       }
     820       write(tty, restore, strlen(restore));
     821
     822       if (ioctl (tty, TIOCGWINSZ, &ws) != -1) {
     823           /* we don't have any way of directly finding out
     824              the current height & width of the window in pixels.  We try
     825              our best by computing the font height and width from the "old"
     826              struct winsize values, and multiplying by these ratios...*/
     827           if (ws.ws_col != 0)
     828               ws.ws_xpixel = cols * (ws.ws_xpixel / ws.ws_col);
     829           if (ws.ws_row != 0)
     830               ws.ws_ypixel = rows * (ws.ws_ypixel / ws.ws_row);
     831           ws.ws_row = rows;
     832           ws.ws_col = cols;
     833           ioctl (tty, TIOCSWINSZ, &ws);
     834       }
     835
     836       tcsetattr(tty, TCSADRAIN, &tioorig);
     837       signal(SIGINT, SIG_DFL);
     838       signal(SIGQUIT, SIG_DFL);
     839       signal(SIGTERM, SIG_DFL);
     840
     841       exit(0);
     842}
     843
     844
     845static void
     846readstring(register FILE *fp, register char *buf, char *str)
     847{
     848       register int last, c;
     849
     850       signal(SIGALRM, resize_timeout);
     851       alarm (TIMEOUT);
     852       if ((c = getc(fp)) == 0233) {   /* meta-escape, CSI */
     853               *buf++ = c = ESC[0];
     854               *buf++ = '[';
     855       } else {
     856               *buf++ = c;
     857       }
     858       if(c != *str) {
     859               fprintf(stderr, "%s: unknown character, exiting.\r\n", myname);
     860               onintr(0);
     861       }
     862       last = str[strlen(str) - 1];
     863       while((*buf++ = getc(fp)) != last)
     864           ;
     865       alarm (0);
     866       *buf = 0;
     867}
     868
     869static void
     870Usage(void)
     871{
     872       fprintf(stderr,
     873        "Usage: %s\n"
     874        "   sets size via ioctl\n", myname);
     875       exit(1);
     876}
     877
     878static void
     879resize_timeout(int sig)
     880{
     881       fprintf(stderr, "\n%s: timeout occurred\r\n", myname);
     882       onintr(sig);
     883}
     884
     885/* ARGSUSED */
     886static void
     887onintr(int sig)
     888{
     889       tcsetattr (tty, TCSADRAIN, &tioorig);
     890       exit(1);
     891}
     892
     893}}}