Linux 上的自动化串行端口通信

发布于 2024-09-26 12:35:52 字数 461 浏览 2 评论 0原文

我有一台 Linux 服务器(Red Hat 4),其中一个串行端口连接到嵌入式 Linux 设备,另一个串行端口连接到该设备的电源控制器。我当前控制它们的方法是打开两个 minicom 会话,每个会话都在自己的窗口中。我想通过脚本自动化这种通信。起初,我开始思考如何使用 minicom 实现自动化,然后意识到当脚本应该能够直接与端口通信时,我不需要尝试使用控制台应用程序实现自动化。

我了解一些 Perl 和一些 Python。我以前没有调制解调器通信(使用 AT 命令)的经验。 Perl 有 Device::Modem,尽管它只是测试版,Perl 似乎是一个不错的选择,因为我更喜欢它的文本提取和整理功能。但是,如果我需要学习如何控制调制解调器和编写/调试脚本,这会增加我的任务时间。

是否可以/常见地使用脚本交互式控制像 minicom 这样的控制台应用程序?如果没有,有哪些好的资源可以帮助我学习如何使用调制解调器 AT 命令?或者还有其他资源可以为我简化事情吗?

I have a linux server (Red Hat 4) with one serial port connection to an embedded linux device, and another serial port connection to a power controller for that device. My current way to control them is to open two minicom sessions, each in its own window. I would like to automate this communication through scripts. At first, I began to think how I could automate using minicom, then realized I shouldn't need to try to automate using a console application when a script should be able to speak to the port directly.

I know some Perl and some python. I do not have previous experience with modem communication (using AT commands). Perl has Device::Modem, though it's only beta, and Perl seems like a good choice because I prefer its text extraction and wrangling abilities. But, if I need to learn how to control a modem and write/debug a script, that adds more time to my task.

Is it possible/common to interactively control a console app like minicom with a script? If not, what are some good resources for me to learn how to use modem AT commands? Or is there another resource out there that could simplify things for me?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

极度宠爱 2024-10-03 12:35:52

Kermit是一个类似于minicom的串行通信应用程序,它有自己的脚本语言,我用它在嵌入式设备上进行一些自动上传。然而,它非常有限和/或有错误,所以我最终转而使用 python 和 pyserial。
每当您处理文本模式时,例如 AT 命令集或通过串行线路与 shell 对话,它都非常强大。

如果我需要使用某些标准协议进行二进制传输,我通常在非交互模式下使用命令行工具,并从我的 python 脚本中生成它们。

以下是我构建的工具的一部分:等待一些输入、通过 xmodem 发送数据、向 u-boot 发送命令并使用 kermit 协议开始传输。我用它来自动刷新和测试嵌入式设备。

class Parser :
    def __init__(self, sport_name):
        self.currentMsg = ''
        if sport_name :
            self.ser = serial.Serial(sport_name, 115200)
    def WaitFor(self, s, timeOut=None):
        self.ser.timeout = timeOut
        self.currentMsg = ''
        while self.currentMsg.endswith(s) != True :
            # should add a try catch here
            c=self.ser.read()
            if c != '' :
                self.currentMsg += c
                sys.stdout.write(c)
            else :
                print 'timeout waiting for ' + s
                return False
        return True

    def XmodemSend(self,fname):
        if not self.WaitFor('C', 1) :
            print 'RomBOOT did not launch xmodem transfer'
            return
        self.ser.flushInput()
        self.ser.close()
        call(["xmodem","-d",self.ser.port,"-T",fname])
        self.ser.open() 

def UbootLoad(self, fname):
    self.ser.write('loadb 0x20000000\n')
    if not self.WaitFor('bps...',1) :
        print 'loadb command failed'
        sys.exit()
    self.ser.flushInput()
    self.ser.close()
    retcode=call(['kermit','-y','kermit_init','-s',fname])
    if retcode != 0 :
        print 'error sending' + fname
        sys.exit()
    self.ser.open()
    self.UbootCmd('echo\n')

Kermit is a serial communication app like minicom and it has its own script language, and I used it for some automatic upload on embedded devices. However, it is quite limited and/or buggy, so I finally switched to using python and pyserial.
Whenever you deal with texte mode, like AT command set or speaking to a shell over a serial line, it is really powerful.

If I need to do binary transfer using some standard protocol, I usually use command line tools in non interactive mode, and spawn them from my python script.

Here is some part of the tools I built : waiting for some input, sending data through xmodem, sending a command to u-boot and starting a transfer using the kermit protocol. I use it for automatic flashing and testing of embedded devices.

class Parser :
    def __init__(self, sport_name):
        self.currentMsg = ''
        if sport_name :
            self.ser = serial.Serial(sport_name, 115200)
    def WaitFor(self, s, timeOut=None):
        self.ser.timeout = timeOut
        self.currentMsg = ''
        while self.currentMsg.endswith(s) != True :
            # should add a try catch here
            c=self.ser.read()
            if c != '' :
                self.currentMsg += c
                sys.stdout.write(c)
            else :
                print 'timeout waiting for ' + s
                return False
        return True

    def XmodemSend(self,fname):
        if not self.WaitFor('C', 1) :
            print 'RomBOOT did not launch xmodem transfer'
            return
        self.ser.flushInput()
        self.ser.close()
        call(["xmodem","-d",self.ser.port,"-T",fname])
        self.ser.open() 

def UbootLoad(self, fname):
    self.ser.write('loadb 0x20000000\n')
    if not self.WaitFor('bps...',1) :
        print 'loadb command failed'
        sys.exit()
    self.ser.flushInput()
    self.ser.close()
    retcode=call(['kermit','-y','kermit_init','-s',fname])
    if retcode != 0 :
        print 'error sending' + fname
        sys.exit()
    self.ser.open()
    self.UbootCmd('echo\n')
寄风 2024-10-03 12:35:52

我发现了 runscript(“$ man runscript”),这是一个为 minicom 添加类似期望的脚本编写功能的实用程序。预期行为对我很有用,因为该设备使用专有的交互式启动顺序。这是基本的但足够了。当使用“-S scriptname”标志启动 minicom 时,可以调用脚本,并且脚本中的特定文本可以发送到日志文件,这在从脚本运行 minicom 时非常有用。我还没有找到将控制台内容发送到日志的方法,因此让外部脚本知道 minicom 内部发生的情况涉及写入日志并让脚本监视日志。我计划仅使用 runscript 来重新启动并进入 shell,然后通过 ssh 到设备以在更高级别的语言脚本(例如 Python 或 Perl)中进行真正的交互。如果 minicom 还没有到位,我会采用 shodanex 的方法。

Runscript 不能有嵌套的期望。我通过使用 goto 和标签解决了这个问题,无论如何,这可以说比嵌套预期更具可读性:

expect {
   "Condition 1"  goto lable1
}

lable1:
    send "something"
    expect {
       "Condition 2"  goto label2
    }
lable2:
    # etcetera

I discovered runscript ("$ man runscript"), a utility that adds an expect-like scripting ability to minicom. The expect behavior is useful to me since this device uses a proprietary interactive boot sequence. It's rudimentary but sufficient. A script can be invoked when starting minicom with the "-S scriptname" flag, and specific text from within the script can be sent to a log file, which is useful when running minicom from a script. I haven't found a way to send console content to a log, so having an external script know what's going on inside minicom involves writing to a log and having the script monitor the log. I plan to use runscript only to restart and get to a shell, then ssh to the device for real interaction, within a higher level language script such as Python or Perl. If minicom weren't already in place, I would take shodanex's approach.

Runscript cannot have nested expects. I got around this by using goto's and labels, which is arguably more readable than nested expects anyway:

expect {
   "Condition 1"  goto lable1
}

lable1:
    send "something"
    expect {
       "Condition 2"  goto label2
    }
lable2:
    # etcetera
雨夜星沙 2024-10-03 12:35:52

我正在使用这样一个电源控制器,我使用RS232来控制。

我使用 bash 编写脚本,只需发出:

echo "your-command" > /dev/ttyUSB0

我正在使用的特定设备也使用 300 波特率,所以我发出:

stty -F /dev/ttyUSB0 300

事先。

I'm using such a power controller which I use RS232 to control.

I script it using bash simply by issuing:

echo "your-command" > /dev/ttyUSB0

the specific device I'm using also uses 300 baud rate so I issue:

stty -F /dev/ttyUSB0 300

before hand.

凉世弥音 2024-10-03 12:35:52

如果只是控制设备而不做其他事情(例如处理消息、与其他操作系统服务交互等),您可以使用 聊天程序。正是为此而写的。
您可以在任何 Linux 发行版的 ppp 软件包中找到它。

If it's just about controlling the devices and nothing else (like processing messages, interacting with other operating system services, etc) you can use the chat program. It's written exactly for this.
You may find it in the ppp package on any Linux distro.

甜柠檬 2024-10-03 12:35:52

Python 现在拥有 PySerial 库:http://pyserial.sourceforge.net/

Ruby 拥有 SerialPort gem:< a href="http://rubygems.org/gems/serialport" rel="nofollow">http://rubygems.org/gems/serialport

Perl可能有类似的库,但我找不到它。

我从非常有用的 Arduino Playground 中发现了这两个内容:
http://playground.arduino.cc//Main/Interface

CJ

Python now has the PySerial library: http://pyserial.sourceforge.net/

Ruby has the SerialPort gem: http://rubygems.org/gems/serialport

Perl probably has a similar library, but I was unable to find it.

I discovered both of these from the very useful Arduino Playground:
http://playground.arduino.cc//Main/Interfacing

CJ

草莓味的萝莉 2024-10-03 12:35:52

使用 picocom 进行回答

#!/bin/bash

# barf on error
set -e
# configure port, exit immediately, don't reset
picocom -qrX -b 115200 ... other settings ... /dev/ttyS0
# send contents of cmd.txt, line by line, 
# waiting 1 sec in-between, after host sends reply
while read ln; do
     echo "$ln" | picocom -qrix 1000 /dev/ttyS0
done < cmd.txt

取自 链接

或者在一行中:

echo "command" |  picocom -qrx 1000 /dev/ttyS0 

Answer using picocom

#!/bin/bash

# barf on error
set -e
# configure port, exit immediately, don't reset
picocom -qrX -b 115200 ... other settings ... /dev/ttyS0
# send contents of cmd.txt, line by line, 
# waiting 1 sec in-between, after host sends reply
while read ln; do
     echo "$ln" | picocom -qrix 1000 /dev/ttyS0
done < cmd.txt

Taken from link

Or in one line:

echo "command" |  picocom -qrx 1000 /dev/ttyS0 
叶落知秋 2024-10-03 12:35:52

使用 socat 进行回答

echo "command" | socat - /dev/ttyUSB0,crnl

Answer using socat

echo "command" | socat - /dev/ttyUSB0,crnl
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文