Автоматизация связи через последовательный порт в Linux - PullRequest
10 голосов
/ 06 октября 2010

У меня есть сервер Linux (Red Hat 4) с одним последовательным портом для подключения к встроенному устройству Linux и другим последовательным портом для контроллера питания для этого устройства. Мой текущий способ управления ими - открыть две сессии Minicom, каждая в своем собственном окне. Я хотел бы автоматизировать это общение с помощью сценариев. Сначала я начал думать о том, как я могу автоматизировать использование minicom, затем понял, что мне не нужно пытаться автоматизировать использование консольного приложения, когда скрипт должен иметь возможность напрямую взаимодействовать с портом.

Я знаю немного Perl и немного Python. У меня нет предыдущего опыта общения с модемом (с использованием AT-команд). В Perl есть Device :: Modem, хотя это всего лишь бета-версия, и Perl кажется хорошим выбором, потому что я предпочитаю его возможности извлечения текста и споры. Но, если мне нужно научиться управлять модемом и писать / отлаживать скрипт, это добавляет больше времени к моей задаче.

Возможно ли / является обычным интерактивное управление консольным приложением, таким как minicom, с помощью скрипта? Если нет, то какие у меня есть хорошие ресурсы, чтобы научиться использовать AT-команды модема? Или есть другой ресурс, который мог бы упростить для меня вещи?

Ответы [ 5 ]

5 голосов
/ 08 октября 2010

Я обнаружил runScript ("$ man runcript"), утилиту, которая добавляет в minicom возможность сценариев, похожих на ожидаемые.Ожидаемое поведение полезно для меня, так как это устройство использует запатентованную интерактивную последовательность загрузки.Это элементарно, но достаточно.Сценарий может быть вызван при запуске minicom с флагом «-S scriptname», а конкретный текст из сценария может быть отправлен в файл журнала, что полезно при запуске minicom из сценария.Я не нашел способа отправить консольное содержимое в журнал, поэтому наличие внешнего сценария, позволяющего узнать, что происходит внутри minicom, предполагает запись в журнал и отслеживание журнала сценарием.Я планирую использовать сценарий выполнения только для перезапуска и доступа к оболочке, а затем для реального взаимодействия с ssh на устройстве в рамках языкового сценария более высокого уровня, такого как Python или Perl.Если бы Minicom еще не был на месте, я бы использовал подход Shodanex.

Runscript не может иметь вложенных ожиданий.Я справился с этим, используя goto's и метки, которые в любом случае, возможно, более читабельны, чем вложенные:

expect {
   "Condition 1"  goto lable1
}

lable1:
    send "something"
    expect {
       "Condition 2"  goto label2
    }
lable2:
    # etcetera
4 голосов
/ 07 октября 2010

Kermit - это приложение для последовательной связи, такое как minicom, и оно имеет собственный язык сценариев, и я использовал его для автоматической загрузки на встроенные устройства.Тем не менее, он довольно ограничен и / или содержит ошибки, поэтому я наконец-то переключился на использование python и pyserial.
Всякий раз, когда вы имеете дело с текстовым режимом, таким как набор команд AT или разговор с оболочкой по последовательной линии, он действительно мощный.

Если мне нужно выполнить двоичную передачу с использованием какого-либо стандартного протокола, я обычно использую инструменты командной строки в неинтерактивном режиме и порождаю их из своего скрипта 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')
2 голосов
/ 07 октября 2010

Я использую такой контроллер питания, для управления которым я использую RS232.

Я пишу его с помощью bash, просто выдав:

echo "your-command" > /dev/ttyUSB0

конкретное устройство, которое я использую такжеиспользует скорость 300 бод, поэтому я выдаю:

stty -F /dev/ttyUSB0 300

перед раздачей.

2 голосов
/ 06 октября 2010

Если речь идет только об управлении устройствами и ничем иным (как обработка сообщений, взаимодействие с другими службами операционной системы и т. Д.), Вы можете использовать программу chat .Это написано именно для этого.Вы можете найти его в пакете ppp в любом дистрибутиве Linux.

1 голос
/ 10 июня 2013

Python теперь имеет библиотеку PySerial: http://pyserial.sourceforge.net/

В Ruby есть гем SerialPort: http://rubygems.org/gems/serialport

Возможно, в Perl есть похожая библиотека, но я не смог ее найти.

Я обнаружил их на очень полезной игровой площадке Arduino: http://playground.arduino.cc//Main/Interfacing

CJ

...