Добавляет ли класс .NET 3.5 SP1 SerialPort дополнительные 0 при передаче? - PullRequest
0 голосов
/ 22 июня 2010

Обновление

Оказывается, ошибка была в коде криптопроцессора, который исправлен.Но теперь мы сталкиваемся с тем, что кажется, что это проблема рукопожатия.

При первой передаче мы получаем один байт от устройства со значением 0xFF (не знаю почему, инженер, с которым я работаюне слишком опытен с RS-232).Затем все работает как обычно (просто отправляя устройство по одному байту за раз и ожидая соответствующего эха).Однако ни устройство, ни приложение .NET не могут отправлять более пары байтов за раз, прежде чем один из них заблокируется и откажется отправлять или получать.


На работе я пишуприложение, которое взаимодействует через RS232 с криптопроцессором внутри устройства для перепрограммирования флеш-модулей внутри устройства.

Чтобы сделать все медленно и убедиться, что все наши заголовки верны, мы пишем по одному байту за раз сSerialPort.Write ().Однако, когда мы запускаем код на криптопроцессоре, он читает дополнительный NULL между каждым байтом.Когда я тестирую код .NET на моей локальной машине с двумя последовательными портами и перекрестным кабелем, я записываю выходные данные в HyperTerminal или Putty, и при просмотре журнала в Notepad ++ никаких дополнительных NULL нет.

Однакочтобы еще больше усложнить ситуацию, когда мы вручную набираем сообщения побайтно через HyperTerminal для криптопроцессора, он считывает входные данные только как один байт, без дополнительных NULL (по сравнению с приложением .NET).У кого-нибудь есть опыт работы с .NET таинственными вещами, когда он пишет в SerialPort?

Мы инициализируем тестовый блок с этим:

byte[] testBytes = new byte[] { (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', (byte)'H' };
byte[] byteArray = new byte[256];
for (int i = 0; i < 32; i++)
{
    testBytes.CopyTo(byteArray, i * 8);
}

И отправляем его с этим:

public void StutterSend(byte[] data, long delayMs)
{
    bool interactive = false;
    if (delayMs < 0)
        interactive = true;

    for (int i = 0; i < data.Length; i++)
    {
        serialPort.Write(data, i, 1);
        if (interactive)
        {
            WriteLine("Sent byte " + (i + 1) + " of " + data.Length + ". Press any key to send moar.");
            Console.ReadKey();
        }
        else
        {
            double timer = DateTime.Now.TimeOfDay.TotalMilliseconds;
            do { } while ((DateTime.Now.TimeOfDay.TotalMilliseconds - timer) < delayMs);
        }
    }
    WriteLine("Done sending bytes.");
}

Наш SerialPort сконфигурирован со всеми соответствующими параметрами (стоп-биты, биты данных, четность, скорость передачи в бодах, имя порта), и наше рукопожатие установлено на Нет (именно так работает наш драйвер uart).

Ответы [ 3 ]

1 голос
/ 22 июня 2010

Какое свойство Encoding для serialPort установлено в? Документы для SerialPort.Write( byte[], int, int) говорят, что он пропускает свои данные через объект кодировщика (что на самом деле не имеет смысла для byte[]). Предполагается, что по умолчанию установлено значение ASCIIEncoding, но, похоже, может быть установлено что-то другое. попробуйте явно установить его на ASCIIEncoding и посмотрите, поможет ли это. Я не могу вспомнить, была ли это проблема для меня, когда я делал какие-то вещи с последовательным портом в .NET для общения со встроенной платой ...

Обратите внимание, что даже при использовании ASCIIEncoding вы получите некоторое (возможно, нежелательное) преобразование данных - если вы попытаетесь отправить что-то выше значения 127, кодировщик преобразует его в '?' так как это не допустимый символ ASCII. Я не могу вспомнить, как у меня получилось, что последовательный порт просто оставил мои данные в покое - мне придется покопаться в некотором исходном коде ...

1 голос
/ 25 июня 2010

Что касается вашего обновления, похоже, у вашего криптопроцессора есть еще проблемы. Возвращение 0xff может быть результатом неожиданного сбоя времени <= 1 бита на линии Tx порта RS232. Это интерпретируется как стартовый бит ПК. После сбоя линия Tx возвращается в состояние метки, и теперь, когда UART на ПК имеет стартовый бит, она интерпретирует биты «данных» как все единицы (значение для состояния метки). Состояние пометки также является правильным значением для стоп-бита, поэтому UART вашего компьютера получил действительный байт со значением 0xff. Обратите внимание, что сбой может быть очень быстрым относительно скорости передачи данных RS232 и по-прежнему интерпретироваться как стартовый бит, поэтому ваш инженер посмотрит на эту строку с помощью осциллографа в обычном режиме / триггерной последовательности для подтверждения этого. </p>

0 голосов
/ 22 июня 2010

SerialPort устанавливает для свойства Parity значение Parity.None, если вы его не указали.Это означает, что если ваш получатель ожидает бит Partity, он никогда не получит его, если вы не скажете SerialPort явным образом отправить бит четности с передаваемыми данными.

И тот факт, что он прошел хорошона HyperTerminal может быть то, что HyperTerminal по умолчанию использует бит четности (я плохо знаю HyperTerminal).

...