====== Serial Consoles with picocom and screen ======
Notes for talking to the VAX (and anything else on a serial line) from Linux.
Verified on ''picocom v3.1'' and ''GNU Screen 5.0.1''.
===== Quick Reference =====
^ Task ^ Command ^
| Connect (simple) | ''picocom -b 9600 /dev/ttyS0'' |
| Leave picocom | ''Ctrl-A'' then ''Ctrl-X'' |
| Connect (shareable, logged) | ''screen -dmS {session_name} -L -Logfile ~/session.log /dev/ttyS0 9600'' |
| Join a screen session | ''screen -x {session_name}'' |
| Leave screen, keep it running | ''Ctrl-A'' then ''d'' |
| Kill a screen session | ''screen -S {session_name} -X quit'' |
| List screen sessions | ''screen -ls'' |
| Who is holding the port | ''fuser -v /dev/ttyS0'' |
===== Permissions =====
**# The serial port is owned by a group, not by you:**
ls -l /dev/ttyS0
Typically ''crw-rw---- root uucp''. On Debian/Ubuntu the group is ''dialout''.
**# Check you are in that group:**
id
**# Add yourself if not (log out and back in afterwards):**
sudo usermod -aG uucp $USER
If you get "Permission denied" opening the port, this is why. Do not reach for
''sudo picocom'' — fix the group instead.
===== picocom =====
The simple choice. One terminal, one session, no multiplexing.
**# Connect at 9600 baud:**
picocom -b 9600 /dev/ttyS0
**# Connect with explicit settings (8N1, no flow control):**
picocom -b 9600 -d 8 -p 1 -y n -f n /dev/ttyS0
**# Log the whole session to a file:**
picocom -b 9600 --logfile session.log /dev/ttyS0
**# Connect without taking an exclusive lock:**
picocom -b 9600 --no-lock /dev/ttyS0
==== picocom keys ====
Every command is prefixed by **Ctrl-A**. Press ''Ctrl-A'' then the second key.
^ Keys ^ Action ^
| ''Ctrl-A Ctrl-X'' | Exit, and reset the serial port |
| ''Ctrl-A Ctrl-Q'' | Exit **without** resetting the port |
| ''Ctrl-A Ctrl-H'' | Show this help |
| ''Ctrl-A Ctrl-V'' | Show current port settings |
| ''Ctrl-A Ctrl-C'' | Toggle local echo |
| ''Ctrl-A Ctrl-B'' | Set baud rate (prompts) |
| ''Ctrl-A Ctrl-U'' | Baud up |
| ''Ctrl-A Ctrl-D'' | Baud down |
| ''Ctrl-A Ctrl-F'' | Cycle flow control |
| ''Ctrl-A Ctrl-Y'' | Cycle parity |
| ''Ctrl-A Ctrl-I'' | Cycle data bits |
| ''Ctrl-A Ctrl-J'' | Cycle stop bits |
| ''Ctrl-A Ctrl-P'' | Pulse DTR (drop it 1 sec, raise it) |
| ''Ctrl-A Ctrl-T'' | Toggle DTR |
| ''Ctrl-A Ctrl-G'' | Toggle RTS |
| ''Ctrl-A Ctrl-\'' | Send BREAK |
| ''Ctrl-A Ctrl-W'' | Write raw hex bytes |
| ''Ctrl-A Ctrl-S'' | Send (upload) a file |
| ''Ctrl-A Ctrl-R'' | Receive (download) a file |
**# To send a literal Ctrl-A to the far end, press it twice:**
Ctrl-A Ctrl-A
**# Change the escape key if Ctrl-A clashes (here, to Ctrl-O):**
picocom -b 9600 --escape o /dev/ttyS0
===== screen =====
Use this instead of picocom when you want any of:
* the session to **survive** closing the terminal window
* **two people** (or a person and a script) on the same session at once
* an automatic **log** of everything
**# Start a detached, logging session called "vax":**
screen -dmS vax -L -Logfile ~/vax.log /dev/ttyS0 9600
**# Attach to it (multi-attach: others can be attached too):**
screen -x vax
**# Attach exclusively, detaching anyone else:**
screen -r vax
**# Detach and leave it running:**
Ctrl-A d
**# Kill it for good, without attaching:**
screen -S vax -X quit
**# Send a command into the session without attaching:**
screen -S vax -X stuff "SHOW TIME^M"
**# List sessions:**
screen -ls
**# Remove "(Dead ???)" entries left by crashed sessions:**
screen -wipe
==== The two gotchas that will waste your afternoon ====
**# 1. The log file is buffered — 10 seconds by default.**
Reading ''~/vax.log'' right after sending a command shows nothing, and it looks
like the command never ran. Turn buffering off:
screen -S vax -X logfile flush 0
Add it right after starting the session. Without it, anything scripted against
the log will read stale data.
**# 2. ''stuff'' expands shell-style variables.**
This does **not** send what you think:
screen -S vax -X stuff "LYNX :== $DKA0:[LYNX293]LYNX.EXE^M"
''$DKA0'' is eaten and the VAX receives ''LYNX :== :[LYNX293]LYNX.EXE''.
Escape every dollar sign:
screen -S vax -X stuff "LYNX :== \$DKA0:[LYNX293]LYNX.EXE^M"
This bites constantly on VMS, where ''$'' is everywhere — ''SYS$LOGIN'',
''f$search'', ''VMI$ROOT''.
==== screen keys ====
All prefixed by **Ctrl-A**.
^ Keys ^ Action ^
| ''Ctrl-A d'' | Detach, leave session running |
| ''Ctrl-A ?'' | Help / key list |
| ''Ctrl-A ['' | Scrollback mode (arrows/PgUp, ''q'' to leave) |
| ''Ctrl-A H'' | Toggle logging on/off |
| ''Ctrl-A a'' | Send a literal Ctrl-A to the far end |
| ''Ctrl-A k'' | Kill this window (confirm with ''y'') |
===== Only One Program Can Own the Port =====
picocom is built with ''USE_FLOCK'', so it takes an **exclusive** lock. While it
is running, nothing else can open the port — screen will simply fail.
**# Find out what is holding it:**
fuser -v /dev/ttyS0
lsof /dev/ttyS0
Output like this means picocom (PID 1996744) owns it:
USER PID ACCESS COMMAND
/dev/ttyS0: josephk 1996744 F.... picocom
Quit that program before starting another. If it is a screen session you have
forgotten about, ''screen -ls'' will show it.
===== Checking and Setting Line Parameters =====
**# Show current settings for the port:**
stty -F /dev/ttyS0 -a
Look for ''speed 9600 baud'', ''cs8'', ''-parenb'' (no parity), ''-cstopb''
(1 stop bit), ''-crtscts'' (no hardware flow control).
**# Set them by hand:**
stty -F /dev/ttyS0 9600 cs8 -parenb -cstopb -crtscts clocal
Normally unnecessary — picocom and screen set the line themselves.
===== Sending Files Over the Serial Line =====
Slow. At 9600 baud you get roughly **1 KB per second**, so about 17 minutes per
megabyte. Use the network if the machine has one.
**# Paste a small text file into a VMS session (works with no extra tools):**
On the VMS side:
CREATE MYFILE.COM
Then paste the text, and finish with ''Ctrl-Z''.
**# ZMODEM (needs lrzsz installed on Linux):**
sudo pacman -S lrzsz
Then in picocom, ''Ctrl-A Ctrl-S'' to send and ''Ctrl-A Ctrl-R'' to receive.
The far end needs matching ZMODEM software, which classic VMS does not have
by default.
**# For binary files on VMS, use FTP over the network instead.** Always set
binary mode first, and repair the record attributes on arrival:
SET FILE/ATTRIBUTES=(RFM:FIX,MRS:512,LRL:512,RAT:NONE) FILE.EXE
===== Troubleshooting =====
^ Symptom ^ Cause ^ Fix ^
| Permission denied on the device | not in the ''uucp'' / ''dialout'' group | ''usermod -aG uucp $USER'', then re-login |
| "Device or resource busy" | another program holds the port | ''fuser -v /dev/ttyS0'', quit it |
| Connects, but nothing appears | far end has no output yet | press ''Enter'' to draw a prompt |
| Garbage characters | wrong baud rate | ''Ctrl-A Ctrl-U'' / ''Ctrl-A Ctrl-D'' to hunt for it |
| Everything doubled | local echo on **and** remote echo | ''Ctrl-A Ctrl-C'' to toggle local echo off |
| Enter does nothing on VMS | CR/LF mapping | try ''picocom --omap crlf'' |
| Screen log is empty or stale | 10-second flush buffer | ''screen -S vax -X logfile flush 0'' |
| ''$'' vanishes from a ''stuff'' command | variable expansion | escape it as ''\$'' |
| Session gone after closing terminal | used picocom, not screen | use screen for long jobs |
===== Which One Should I Use? =====
^ ^ picocom ^ screen ^
| Quick interactive session | **yes** | works |
| Survives closing the terminal | no | **yes** |
| Two people on one session | no | **yes** |
| Automatic logging | with ''--logfile'' | **yes** |
| Scriptable from outside | no | **yes** (''-X stuff'') |
| Change baud mid-session | **yes** | no |
| Send BREAK | **yes** | ''Ctrl-A Ctrl-B'' |
Rule of thumb: **picocom to poke at something, screen for anything that must
not die** — a long build, an install, or a session you want a transcript of.