Shell 腳本實現串口操做

前言

命令行下經常使用的串口鏈接工具備 screenminicom等。python

實際生產測試需求中,經常有串口連通性測試,其對應的最簡單的測試方法即:「調用非交互式串口工具登陸串口併發送(命令)接收數據(命令返回)」web

這種狀況下,screenminicom需交互模式下使用的工具已不適用(不易使用expect實現,並且須要額外安裝工具)。shell

根據測試方法能夠知道,實際測試工具所需具有功能並不複雜,因此一般咱們使用 c語言python 調用相關庫完成該工具的編寫。vim

但秉承能偷懶就偷懶,能用shell自己實現絕對很少**的宗旨,此文探索下 shell 的實現方法。bash

Shell實現

主要的實現思路:stty實現串口波特率等的設置,cat實現內容的讀取,echo實現串口輸入。微信

實現效果

  • 普通非交互式命令與普通終端操做無區別,如 lscd
  • 在使用交互式命令時,不太友好,但能夠實現一些簡單操做,如 vim中的上下翻頁等
  • 可拓展性好,可將串口登陸退出等操做嵌入腳本中,調用該腳本工具時只用關注命令發送和返回內容解析便可

stty修改串口終端設置

初始狀態時,使用cat /dev/ttyUSB0可能會出現刷屏或者亂碼,需使用stty進行相關參數設置。一般使用的命令爲stty -F /dev/$serial_port raw $port_speed。在該命令以後就能夠使用echo/cat進行輸入輸出操做了。session

可是在有些時候依舊有亂碼出現,這時候須要一些額外的參數設置。因爲相關參數設置較多,不能保證設置完後達到預期效果,因此須要一個比較取巧的辦法:「使用screen或者minicom等初始化設置串口以後的設置」。具體操做以下:多線程

  1. 首先使用 stty獲取當前串口默認值,從第一行開始分別是
    1. 串口波特率
    2. Special characters
    3. Special settings
    4. Control settings
    5. Input settings
    6. Output settings
    7. Local settings
[root@localhost ~]# stty -a -F /dev/ttyUSB0
speed 9600 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W;
lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel -iutf8
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
  1. 使用screen /dev/ttyUSB0 115200(或者使用minicom)登入串口,確承認以正常讀寫後退出併發

  2. 再使用stty獲取當前設置,主要查看第一步中 4-7 行app

[root@localhost ~]# stty -a -F /dev/ttyUSB0
speed 115200 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^H; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W;
lnext = ^V; flush = ^O; min = 100; time = 2;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread clocal -crtscts
-ignbrk brkint ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl ixon -ixoff -iuclc -ixany -imaxbel -iutf8
-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
  1. 比較二者可發現有些設置的不一樣,直接將4-7行帶入stty命令,便可完成對串口終端的正確設置,前面的1-3行內容也可視狀況導入,需根據幫助文檔作參數格式改動。

  2. 另,若只爲設置串口,不須要human-readable,可以使用stty-readable模式進行設置的導出和導入:

[root@localhost ~]# stty -g -F /dev/ttyUSB0
500:5:cbd:8a3b:3:1c:7f:15:4:0:1:0:11:13:1a:0:12:f:17:16:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0
[root@localhost ~]# stty  -F /dev/ttyUSB0 "406:0:18b2:8a30:3:1c:7f:8:4:2:64:0:11:13:1a:0:12:f:17:16:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0"
stty: /dev/ttyUSB0: unable to perform all requested operations
[root@localhost ~]# stty -a -F /dev/ttyUSB0
speed 115200 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^H; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W;
lnext = ^V; flush = ^O; min = 100; time = 2;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread clocal -crtscts
-ignbrk brkint ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl ixon -ixoff -iuclc -ixany -imaxbel -iutf8
-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

腳本實現

[root@localhost ~]# cat /opt/connect_serial.sh
#!/bin/bash

function usage()
{
    cat <<!
    Usage:
    $0 <device> <port speed>
    Example: $0 /dev/ttyS0 115200
!
    exit 255
}

function clean()
{
    # Terminate background read process
    kill $bgPid
    echo
    exit 0
}

# "Ctrl c" to exit
trap clean SIGINT
$# -ne 2 ] && usage

device_name=$1
port_speed=$2
# Set up device
stty -F $device_name $port_speed min 100 time 2 brkint ignpar \
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread clocal -crtscts \
-ignbrk brkint ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl ixon -ixoff \
-iuclc -ixany -imaxbel -iutf8 \
-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

# Let cat read the device $device_name in the background
cat $device_name &

# Capture PID of background process so it is possible to terminate it when done
bgPid=$!

# Read commands from user, send them to device $device_name
echo > $device_name
while read cmd
do
    echo "$cmd" > $device_name
    [ "$cmd" == "exit" -o "$cmd" == "quit" ] && clean
done

實際使用

此處只作交互式演示,若須要作非交互式測試等其餘需求,可自行修改輸入輸出邏輯,或使用expect實現

[root@localhost ~]# /opt/connect_serial.sh /dev/ttyUSB0 115200
000 login: 
UUT000000000000 login: admin
admin
Password: 123456

(audit 139) Sat Jan-01 2000-16:45:08 : [SERIAL] Login from IP:127.0.0.1 user:admin (strlen:70)
[2866 : 2866 INFO]SERIAL Login from IP:127.0.0.1 user:admin

old_active_active_session:0
current_active_sessions:1

# ls
ls
# pwd
pwd
/root
# exit

[root@localhost ~]#


往期精選

shell 多線程及線程數控制實現

tput應用:簡易時鐘實現

shell腳本一步完成多層ssh跳轉時的文件傳輸


長按關注
                       


以爲好看就點一哈!

本文分享自微信公衆號 - WriteSimpleDemo(this_is_a_wechat)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索