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

Я работаю над утилитой, которая автоматизирует тестирование устаревшего приложения. Устаревшее приложение работает в 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 или иным образом?

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

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

3 ответа

Решение

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

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

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

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

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

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

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

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

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

И оба порта реальны.

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

Другие вопросы по тегам