240 likes | 365 Vues
Explore the world of dynamic visualizations that illustrate non-canonical keyboard input and terminal escape sequences for visualization effects. This course covers how the Linux kernel sets up permanent kernel mappings and demonstrates CPU responses to device interrupts. Learn to customize terminal behavior beyond canonical mode using ANSI escape sequences to gain greater control over output, cursor visibility, and character attributes. Understand the tty interface and its modes, and gain practical skills through hands-on programming examples in C/C++.
E N D
Dynamic visualizations On ‘non-canonical’ keyboard-input and terminal escape-sequences for visualization effects
Our course’s theme Using the computer to study the computer
Two ‘dynamic visualizations’ • Showing the Linux kernel’s algorithm for setting up ‘permanent kernel mappings’ • Showing the dual-CPUs’ responses to device-interrupts and CPU-exceptions
Some application tools • We need to modify the terminal-console’s normal way of processing keyboard-input and of displaying its line-at-a-time output • ANSI terminal escape-sequences allow page-oriented output (i.e., left-and-right, up-and-down), control of cursor-visibility and of character-attributes (e.g., colors)
The ‘tty’ interface • ‘tty’ is an acronyn for ‘TeleTYpe’ terminal • Such devices have a keyboard and screen • Behavior emulates technology from 1950s • Usually a tty operates in ‘canonical’ mode: • Each user-keystroke is ‘echoed’ to screen • Some editing is allowed (e.g., backspace) • The keyboard-input is internally buffered • The <ENTER>-key signals an ‘end-of-line’ • Programs receive input one-line-at-a-time
‘tty’ customization • Sometimes canonical mode isn’t suitable (an example: animated computer games) • The terminal’s behavior can be modified! • UNIX provides a convenient interface: • #include <termios.h> • struct termios tty; • int tcgetattr( int fd, struct termios *tty ); • int tcsetattr( int fd, int flag, struct termios *tty );
How does the ‘tty’ work? application User space tty_driver c_lflag Kernel space input handling c_iflag c_cc output handling c_oflag SOFTWARE struct tty { c_iflag; c_oflag; c_cflag; c_lflag; c_line; c_cc[ ]; }; terminal_driver c_cflag HARDWARE TeleTYpe display device
The ‘c_lflag’ field • This field is just an array of flag bits • Individual bits have symbolic names • Names conform to a POSIX standard • Linux names match other UNIX’s names • Though actual symbol values may differ • Your C/C++ program should use: #include <termios.h> for portability to other UNIX environments
ICANON and ECHO • Normally the ‘c_lflag’ field has these set • They can be cleared using bitwise logic: tty.c_lflag &= ~ECHO; // inhibit echo tty.c_lflag &= ~ICANON; // no buffering tty.c_lflag &= ~ISIG; // no CTRL-C
The ‘c_cc[ ]’ array • ‘struct termios’ objects include an array • The array-indices have symbolic names • Symbol-names are standardized in UNIX • Array entries are ‘tty’ operating parameters • Two useful ones for our purposes are: tty.c_cc[ VMIN ] and tty.c_cc[ VTIME ]
How to setup ‘raw’ terminal-mode • Step 1: Use ‘tcgetattr()’ to get a copy of the current tty’s ‘struct termios’ settings • Step 2: Make a working copy of that object • Step 3: Modify its flags and control-codes • Step 4: Use ‘tcsetattr()’ to install changes • Step 5: Perform desired ‘raw’ mode input • Step 6: Use ‘tcsetattr()’ to restore the terminal to its original default settings
Input-mode needs five settings • tty.c_cc[ VMIN ] = 0; • so the ‘read()’ function will return -- even if there is not at least one new input-character available • tty.c_cc[ VTIME ] = 0; • so there will be no time-delay, after each new key pressed, until the ‘read()’ function returns • tty.c_lflag &= ~ECHO; // no input-echoing • tty.c_lflag &= ~ICANON; // no buffering • tty.c_lflag &= ~ISIG; // no <CTRL>-C
Demo program: ‘noncanon.cpp’ • This program may soon prove useful • It shows the keyboard scancode values • It demonstrates ‘noncanonical’ tty mode • It clears the ISIG bit (in ‘c_lflags’ field) • This prevents <CONTROL>-C from being used to abort the program: the user must ‘quit’ by hitting the <ESCAPE>-key; so default terminal-settings will get reinstalled
‘Noncanonical’ terminal i/o • We’ve now learned how to reprogram the terminal to allow “raw” keyboard input #include <termios.h> struct termios tty; tcgetattr( 0, &tty ); // get tty settings tty.c_lflag &= ~( ICANON | ECHO | ISIG ); tty.c_cc[ VMIN ] = 1; tty.c_cc[ VTIME ] = 0; tcsetattr( 0, TCSAFLUSH, &tty ); // install
ANSI command-sequences A look at some terminal emulation features utilized in the “console-redirection” mechanism
Clearing the screen • Here is an ANSI command-sequence that clears the terminal’s display-screen: char cmd[] = “\033[2J”; int len = strlen( cmd ); write( 1, cmd, len );
Reposition the cursor • Here is an ANSI command-sequence that moves the cursor to row 12, column 40: char cmd[] = “\033[12;40H”; int len = strlen( cmd ); write( 1, cmd, len );
ANSI color-codes 0 = black 1 = red 2 = green 3 = brown 4 = blue 5 = magenta 6 = cyan 7 = gray
Setting text attributes • Here is an ANSI command-sequence that sets foreground and background colors: char cmd[] = “\033[32;44m”; int len = strlen( cmd ); write( 1, cmd, len );
Cursor visibility commands • Here are ANSI command-sequences that will ‘hide’ or ‘show’ the terminal’s cursor: char hide[] = “\033[?25l”; // lowercase L char show[] = “\033[?25h”; // lowercase H
In-class exercise #1 • Modify this simple C++ program so that it will print its “Hello” message in colors and be located in the center of the screen: #include <stdio.h> int main( void ) { printf( “Hello, world! \n” ); }
In-class exercise #2 • Compile and install our ‘pkmaps.c’ module • Then download, compile and execute our ‘mapwatch.cpp’ visualization-application • While ‘mapwatch’ continues to run in one window of your graphical desktop, open a second window nearby and execute some common commands, for example: $ ls $ mmake pkmaps
In-class exercise #3 • Compile and install our ‘smpwatch.c’ LKM • Then download, compile and execute our ‘smpwatch.cpp’ visualization-application • In a nearby window, try hitting some keys and moving the mouse • Try executing the ‘ping’ command to see if another machine responds, for example: $ ping stargate