Автоматизация связи через последовательный порт в Linux

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

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

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

Ответ 1

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

Если мне нужно выполнить двоичную передачу с использованием стандартного протокола, я обычно использую инструменты командной строки в неинтерактивном режиме и создаю их из своего python script.

Вот часть инструментов, которые я построил: ожидая ввода, отправки данных через 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

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

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

expect {
   "Condition 1"  goto lable1
}

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

Ответ 3

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

Ответ 4

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

I script используя bash просто:

echo "your-command" > /dev/ttyUSB0

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

stty -F /dev/ttyUSB0 300

перед началом работы.