Поддельная последовательная связь под Linux - PullRequest
15 голосов
/ 23 марта 2010

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

В целях тестирования я хочу использовать фиктивное программное устройство для проверки отправки и получения данных.

Пример кода Python

device = Device()
modem  = Modem()
device.connect(modem)

device.write("Hello")
modem_reply = device.read()

Теперь в моем последнем приложении я просто передам / dev / ttyS1 или COM1 или что-либо еще для использования приложением. Но как я могу сделать это в программном обеспечении? Я использую Linux и приложение написано на Python .

Я пытался создать FIFO (mkfifo ~/my_fifo), и это работает, но тогда мне понадобится один FIFO для записи и один для чтения. Я хочу открыть ~/my_fake_serial_port, прочитать и написать в него.

Я также оплатил модуль pty, но не могу заставить его работать. Я могу получить дескриптор файла master и slave из pty.openpty(), но попытка чтения или записи в них приводит только к IOError Bad File Descriptor сообщению об ошибке.

Обновление

Комментарии указали мне на вопрос SO Есть ли какая-нибудь программа, подобная COM0COM, в linux? , которая использует socat для настройки виртуального последовательного соединения. Я использовал это так:

socat PTY,link=$HOME/COM1 PTY,link=$HOME/COM2

Остальным, спасибо, что предоставили мне ценную информацию. Я решил принять ответ Vinay Sajips , поскольку именно к этому решению я стремился до появления предложения socat. Кажется, это работает достаточно хорошо.

Ответы [ 3 ]

9 голосов
/ 23 марта 2010

Вероятно, лучше использовать pyserial для связи с последовательным портом, и вы можете просто создать фиктивную версию класса serial.Serial, которая реализует read, readline, write и любые другие методы, которые вам нужны.

5 голосов
/ 24 марта 2010

Вы на правильном пути с псевдо-терминалами. Для этого вашему программному устройству необходимо сначала открыть мастер псевдотерминала - это дескриптор файла, с которого он будет считывать и записывать, когда общается с программным обеспечением, которое вы тестируете. Затем необходимо предоставить доступ и разблокировать псевдотерминальное ведомое устройство и получить имя подчиненного устройства. Затем он должен распечатать имя ведомого устройства где-нибудь, чтобы вы могли указать другому программному обеспечению открыть его как последовательный порт (т. Е. Это программное обеспечение будет открывать имя типа /dev/pts/0 вместо /dev/ttyS1).

Программное обеспечение симулятора просто читает и пишет с главной стороны псевдотерминала. В Си это будет выглядеть так:

#define _XOPEN_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>

int main(int argc, char *argv[])
{
    int pt;

    pt = open("/dev/ptmx", O_RDWR | O_NOCTTY);
    if (pt < 0)
    {
        perror("open /dev/ptmx");
        return 1;
    }

    grantpt(pt);
    unlockpt(pt);

    fprintf(stderr, "Slave device: %s\n", ptsname(pt));

    /* Now start pretending to be a modem, reading and writing "pt" */
    /* ... */
    return 0;
}

Надеюсь, это достаточно просто конвертировать в Python.

1 голос
/ 10 февраля 2012

Вот питонная версия последовательной связи pts-эмулированного (caf's):

from serial import Serial

driver = MyDriver()  # what I want to test
peer = serial.Serial()
driver.port.fd, peer.fd = posix.openpty()
driver.port._reconfigurePort()
peer.setTimeout(timeout=0.1)
peer._reconfigurePort()
driver.start()

# peer.write("something")
# driver.get_data_from_serial()

Он имеет некоторые преимущества по сравнению с пародированием Serial, а именно то, что используется последовательный код и выполняются некоторые артефакты последовательного порта.

Если вы хотите проверить открытие последовательных портов, вы можете поменять местами главный и подчиненный и использовать os.ttyname(salve_fd) в качестве имени последовательного порта. Я не могу ручаться за побочные эффекты обмена хозяина и раба, хотя. Наиболее примечательным является то, что вы можете закрыть и снова открыть раба, но если вы закроете его, мастер-раб тоже умрет.

Это работает как талисман, если ваш тестовый код выполняется в том же процессе. Я еще не сгладил изломы с несколькими / отдельными процессами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...