Создание пары между реальным и виртуальным последовательным портом

Я работаю над утилитой, которая автоматизирует тестирование устаревшего приложения. Устаревшее приложение работает в Windows 2000 и использует 3 устройства, подключенных через последовательные (COM) порты.

У меня есть доступ к исходному коду приложения, но нет разрешения вносить какие-либо изменения. Однако исходный код позволил мне проверить, что имена COM-портов устройства жестко запрограммированы в приложении как COM1 (принтер), COM2 (считыватель банкнот) и COM3 (считыватель штрих-кода / OMR). Я также могу видеть байты, отправленные на каждое устройство, и то, как приложение обрабатывает возврат.

А пока я хотел бы написать тесты, касающиеся считывателя банкнот. Я прочитал здесь различные вопросы (например, Подделка последовательного порта RS232), которые я могу использовать com0com, чтобы подделать последовательный порт. Я надеялся, что существует способ отправлять байты от имени реального устройства с COM-портом, которое будет подхвачено приложением.

После установки утилиты я настроил пару как «COM2» - «COM6». Метка COM2 отображается красным цветом, и когда я нажимаю ОК, я получаю следующее сообщение:

Имя порта COM2 уже используется для другого устройства \ Device \ Serial1

Затем я могу нажать «Отмена», «Повторить попытку» или «Продолжить».

Нажав «Продолжить», я получаю:

Имя порта COM2 уже зарегистрировано как "используемый" в базе данных COM-портов.

Снова нажимаю «Продолжить».

Я написал небольшое приложение на C # для проверки спаривания портов COM2 и COM6. Когда я отправляю допустимые байты в COM2, я получаю ожидаемые 11 байтов обратно (что точно отражает сценарий в устаревшем приложении). По COM6 ничего не получено. Когда я отправляю одни и те же байты на COM6, я не получаю ответа ни от COM2, ни от COM6.

Я попытался перезагрузить компьютер, снова настроить сопряжение, попробовать разные COM-порты (от COM1 до COM6, от COM3 до COM6), но так и не получил ответа на эти виртуальные порты (COM1 и COM3 также отображаются красным цветом и выдают те же ошибки. через com0com).

Тестовое приложение C # выглядит следующим образом:

using System;
using System.IO.Ports;

public class Com
{
    private static byte[] s_pDataSent = new byte[32];
    private static byte[] s_pDataRead = new byte[32];

    private static void port_OnReceivedDatazz(
        object sender,
        SerialDataReceivedEventArgs e)
    {
        var sp = (SerialPort)sender;
        var buffer = new byte[sp.BytesToRead];
        Console.WriteLine("DATA RECEIVED ON " + sp.PortName);
        sp.Read(buffer, 0, buffer.Length);
        foreach(var b in buffer)
        {
            Console.Write(b.ToString() + " ");
        }
        Console.WriteLine();
    }

    public void Do(string portName, string virtualPort)
    {
        var port = new SerialPort(
            portName,
            9600,
            Parity.Even,
            7,
            StopBits.One);
        port.RtsEnable = false;
        port.DtrEnable = false;
        port.DataReceived += port_OnReceivedDatazz;
        port.Open();

        if (!port.IsOpen)
        {
            Console.WriteLine("Port is closed");
        }

        var vport = new SerialPort(
            virtualPort,
            9600,
            Parity.Even,
            7,
            StopBits.One);
                vport.RtsEnable = false;
                vport.DtrEnable = false;
                vport.DataReceived += port_OnReceivedDatazz;
                vport.Open();

        if (!vport.IsOpen)
        {
            Console.WriteLine("VPort is closed");
        }

        for (var i = 0; i < s_pDataSent.Length; ++i)
        {
            s_pDataSent[i] = 0;
        }

        // populate s_pDataSent ...
        // I have left these steps out of this example
        // ...but they do exist in my test app

        port.Write(
            s_pDataSent,
            0,
            8);

        Console.ReadLine();
        Console.WriteLine("Closing");
        port.Close();
    }
}

Когда я использую HyperTerminal, я вижу, что сообщения отправляются между двумя виртуальными портами, но между реальным и виртуальным портом ничего не отправляется.

Можно ли соединить реальный и виртуальный COM-порт через com0com или иным способом?

Если да, как я могу решить свою проблему?

Есть ли альтернатива подделке выходных данных реального последовательного порта?


person Class Skeleton    schedule 02.12.2016    source источник
comment
Почему вы хотите соединить реальный и виртуальный порт? Что именно ты пытаешься сделать? вы хотите прослушать все сообщения, отправленные на какой-либо последовательный порт на ПК?   -  person idanp    schedule 02.12.2016
comment
@Idank - Нет, я хочу отправлять сообщения подключенному приложению от имени реального порта. Я предположил, что могу подключиться к виртуальному порту и писать в этот порт (чтобы он стал выводом на реальный порт). Это неправильно?   -  person Class Skeleton    schedule 02.12.2016
comment
Мне кажется, что может быть не так с двумя парными виртуальными портами com0com? зачем тебе второй порт чтоб был реальным?   -  person idanp    schedule 02.12.2016
comment
@Idank - эти тесты выполняются на машине с подключенными устройствами. Приложение жестко запрограммировано для подключения к определенным COM-портам и в основном проверяет эти устройства каждые 200 мс.   -  person Class Skeleton    schedule 02.12.2016


Ответы (3)


Вы можете изменить физические порты на 7, 8 и 9 и оставить порты 1, 2, 3 жестко закодированными, после чего вы можете установить 3 виртуальные COM-пары, такие как COM1-COM4, ​​COM2-COM5, COM3-COM6, чтобы «старое» приложение могло open, и вы можете отслеживать, а затем направлять прочитанные байты на другой порт.

СТАРОЕ ПРИЛОЖЕНИЕ -> COM1 -> COM4 -> ВАШЕ ПРИЛОЖЕНИЕ -> COM7 (принтер)

person Miguel de Sousa    schedule 02.12.2016

Быстрое и грязное решение вместо использования com0com:

Просто подключите один из портов ПК (COM6) к другому порту (COMx), используя кроссоверный кабель (" нуль-модем ") (поменяйте местами Tx и Rx). Теперь вы можете использовать два порта, которые подключены друг к другу, с двумя разными приложениями, каждый байт, отправленный на один порт, принимается другим, и наоборот.

И оба порта настоящие.

Теперь вы можете эмулировать свое устройство с помощью другого приложения с помощью COMx.

person idanp    schedule 02.12.2016
comment
Значит, отправка байтов в COMx будет считана исходным устаревшим приложением, которое прослушивает COM2? - person Class Skeleton; 02.12.2016
comment
Похоже, OP хочет, чтобы COM-порт приложения был подключен к реальному устройству. - person barny; 02.12.2016
comment
@camelcase да. - person idanp; 02.12.2016

Мне удалось запустить и запустить полностью автоматизированную тестовую систему:

  • Используя com0com, установите 2 пары виртуальных портов (COM6-COMD и COMI-COMJ).
  • Написание простого приложения, которое имитирует устройство, записывая набор байтов в COMD, когда что-то читается в COMD. Записанные назад байты будут набором по умолчанию байтов «ничего не делать», если тестовые байты также не были прочитаны в COMJ.
  • Добавлена ​​функциональность в мои сценарии автоматического тестирования, которые могут отправлять определенные байты в COMI. Например, байты, представляющие прочитанную купюру в 5 фунтов стерлингов или недействительную купюру.
  • Изменил устаревший исполняемый файл с помощью шестнадцатеричного редактора, чтобы заменить строку ascii «COM2:» (т.е. жестко заданный порт) на «COM6:».

Теперь у меня есть тестовый терминал, настроенный для использования исходного устаревшего приложения для ручного тестирования. Все устройства работают исправно. На том же терминале сценарии автоматизированного тестирования связаны с измененным исполняемым файлом. Этот исполняемый файл будет использовать эмулируемые устройства.

Мне нужно поддерживать «модифицированный» исполняемый файл до тех пор, пока не будет завершена работа по настройке COM-портов в приложении.

Одно небольшое наблюдение заключалось в том, что мне нужно было использовать «настоящие» имена COM-портов в модифицированном exe. Я, например, не мог использовать "КОМА". Это должно быть от COM1 до COM9.

person Class Skeleton    schedule 08.12.2016