Re: [SLUG] BASH and a comm port

From: Ian Blenke (icblenke@nks.net)
Date: Tue Jan 24 2006 - 23:54:36 EST


Ron Youvan wrote:
> A bash question.
>
> My stupid LINUX books only say some special understanding (of some
> kind)
> is required to deal with comm. ports when using bash script files.
> (I can do anything with a few examples, but they are scarce in my books,
> I am just a user.)

One command to master is "setserial", to set various com port parameters:

    # setserial -a /dev/ttyS0
    /dev/ttyS0, Line 0, UART: 16550A, Port: 0x03f8, IRQ: 4
        Baud_base: 115200, close_delay: 50, divisor: 0
        closing_wait: 3000
        Flags: spd_normal skip_test

Realize that "/dev/cua" is deprecated in favor of "/dev/ttyS" when
referencing serial ports. If you find documentation talking about
/dev/cua, it's pretty old (and probably a bit inaccurate). Theodore Tso
has a good description of the difference between the two that can be
found in the mgetty user docs on your distribution (named "ttyS-cua.txt").

Another thing to realize is that a "com port" is just another Unix tty.
Just as your shells use posix psuedo-ttys (pty's) to interact with you,
your shell can interact with a tty using the same techniques.

Just as you would use the "stty" command to set your pty's baud rate,
duplex, etc... you may use "stty" to do the same with a serial tty.

    # tty
    /dev/pts/32
    # stty -a
    speed 38400 baud; rows 24; columns 80; line = 0;
    intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
    eol2 = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase
= ^W;
    lnext = ^V; flush = ^O; min = 1; time = 0;
    -parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts
    -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl
ixon -ixoff
    -iuclc -ixany -imaxbel
    opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0
bs0 vt0 ff0
    isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop
-echoprt
    echoctl echoke

and here's the same against /dev/ttyS0:

    # stty -a < /dev/ttyS0
    speed 9600 baud; rows 0; columns 0; line = 0;
    intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
    eol2 = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase
= ^W;
    lnext = ^V; flush = ^O; min = 1; time = 0;
    -parenb -parodd cs8 hupcl -cstopb cread clocal -crtscts
    -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl
ixon -ixoff
    -iuclc -ixany -imaxbel
    opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0
bs0 vt0 ff0
    isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop
-echoprt
    echoctl echoke

Note the stdin redirection from /dev/ttyS0.

> I have a project at work where I have DOS text strings constantly
> coming
> into a computer (it will be operating just LINUX with no X windows system
> at all) and I want to append a file (named with the current date) and
> also
> tee to the display (for confidence) to a virtual terminal.

Something as simple as:

    ( stty 9600 cs8 crtscts ; cat - ) < /dev/ttyS0 | tee somefile.txt

_Should_ work to do what you're looking to do (it's been a while, but
that sounds right).

Try a manpage on stty for more info on the options you can use.

I've generally noticed that you must stty with the _same_ filehandle you
use to read from the port. In other words, running stty with stdin
redirected from the port and following that with a separate command
doing the same (not in the same subshell) seems to end with the port not
being in the state you would think it would be left in. That's just
personal experience though, YMMV.

> At 0000 hrs a new file will be created and the string will be append
> that
> file. This is a "logging function," I am using a M$ DOS laptop
> currently,
> on a chair, but I need to use it elsewhere.
To rotate to different files, you might try something like:

    ( stty 9600 cs8 crtscts ; cat - ) < /dev/ttyS0 | while read line ;
do eval 'date=`date +%Y%m%d.txt`'; echo $line >> logfile-$date.txt; done

A bit heavy handed (as are most things with bash), but should work in
theory. Forking a date command for each line read does incur quite some
overhead if a huge volume of lines are to be processed.
> I can easily do all of this from a file, but I need to get the
> string from
> a comm. port. I don't want to run any comm. program. (as I am now:
> Telix)
> Can anyone point me to some reading that will help me along?
>
> Another related question:
> I think I want to start this program from int but I don't know how to
> assign the tee-ed output to a virtual console # (unless it would default
> to #1) which would be fine. Although everything is on a UPS, if the
> computer does reboot I need the computer to resume as soon as possible.

You just tee to /dev/tty12, for example. Then alt-F12 to see the output.

    ( stty 9600 cs8 crtscts ; cat - ) < /dev/ttyS0 | while read line ;
do eval 'date=`date +%Y%m%d.txt`'; echo $line | tee logfile-$date.txt;
done > /dev/tty12

That too will work in theory (I'd love to test this, would need to work
up a connection between two machines to test it though)...

> Using Slackware 2.4.26 kernel and a rack mounted old HP P-1 with a
> USB port
> and floppy. (the files vary between 148 k and 300 kb or so, so a
> floppy can
> be used to transport the files to the desktop confuser)

Fun. A classic pentium with a USB port? must be a card, or an embedded
device :)

-- 
- Ian C. Blenke <icblenke@nks.net>


----------------------------------------------------------------------- This list is provided as an unmoderated internet service by Networked Knowledge Systems (NKS). Views and opinions expressed in messages posted are those of the author and do not necessarily reflect the official policy or position of NKS or any of its employees.



This archive was generated by hypermail 2.1.3 : Fri Aug 01 2014 - 17:07:19 EDT