2009-10-09 2 views
1

У меня есть небольшое приложение, написанное на C#, которое прослушивает SerialPort для ввода информации. Информация поступает как: STX + data + ETX + BCC. Затем мы вычисляем BCC пакета передачи и сравниваем. Функция:Почему вычисленная контрольная сумма не соответствует BCC, отправленной через последовательный порт?

private bool ConsistencyCheck(byte[] buffer) 
{ 
    byte expected = buffer[buffer.Length - 1]; 
    byte actual = 0x00; 

    for (int i = 1; i < buffer.Length - 1; i++) 
    { 
     actual ^= buffer[i]; 
    } 

    if ((expected & 0xFF) != (actual & 0xFF)) 
    { 
     if (AppTools.Logger.IsDebugEnabled) 
     { 
      AppTools.Logger.Warn(String.Format("ConsistencyCheck failed: Expected: #{0} Got: #{1}", expected, actual)); 
     } 
    } 

    return (expected & 0xFF) == (actual & 0xFF); 
} 

И это работает более или менее. Он точно не включает STX или BCC и точно включает ETX в его вычисления. Кажется, он работает очень большой процент времени, однако у нас есть по крайней мере две машины, на которых мы запускаем это, оба из которых - это 64-разрядная версия Windows 2008, в которой НИКОГДА не добавляется счет BCC. Вытягивание из недавнего журнала, которое было у меня в одном байте 20, было отправлено, и я вычислил 16 и один, где было отправлено 11, и я вычислил 27.

Я абсолютно зациклен на том, что происходит здесь. Возможно ли, что 64-битный или Windows 2008 «gotcha» мне здесь не хватает? Любая помощь или даже дикие идеи будут оценены.

EDIT:

Вот код, который считывает данные в:

private void port_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) 
{ 
    // Retrieve number of bytes in the buffer 
    int bytes = serialPort.BytesToRead; 

    // Create a byte array to hold the awaiting data 
    byte[] received = new byte[bytes]; 

    //read the data and store it 
    serialPort.Read(received, 0, bytes); 

    DataReceived(received); 
} 

И функция DataReceived() принимает эту строку и присоединяет его к глобальному StringBuilder объекта. Затем он остается строковым построителем, пока он не будет передан этим различным функциям, после чего на него вызывается .ToString().

EDIT2: Изменен код, который отражает мои измененные процедуры, которые работают с байтами/байтовыми массивами, а не с строками.

EDIT3: Я до сих пор не понял этого, и у меня появилось больше тестовых данных, которые имеют совершенно непоследовательные результаты (количество, которое я выхожу из контрольной суммы отправки, меняется каждый раз без шаблона). Похоже, я просто неправильно подсчитываю контрольную сумму, но я не знаю, как это сделать.

+0

Похоже, вы все еще не уверены в том, связана ли проблема с последовательным портом, принимающим весь пакет или вычислением BCC. Можете ли вы написать небольшую автономную программу, которая считывает данные из файла журнала с известного хорошего компьютера, а затем вызывает «DataReceived» и выполняет всю последующую обработку? Если вы можете запустить это на одном из 64-битных «плохих» компьютеров Win2008, вы можете знать, где искать дальше. – mtrw

ответ

2

Буфер определяется как строка. Хотя я подозреваю, что данные, которые вы передаете, являются байтами. Я бы рекомендовал использовать байтовые массивы (даже если вы отправляете ascii/utf/любую кодировку). Затем после того, как контрольная сумма верна, преобразуйте данные в строку

+0

Хотя я согласен, что это, вероятно, хорошая идея, как именно это выиграет у меня? Мне не очень нравится рефакторинг всего приложения, чтобы использовать байтовый массив без причины. – Morinar

+1

Я бы не стал knwo, если вы кормили байты 0 - 255 в строку, если строковые символы также читали 0-255 ... так как некоторое преобразование происходит во внутреннем формате, вполне возможно, что они будут переведены и, следовательно, ваша контрольная сумма будет неправильной – Toad

+0

+1 для ответа Моринара. строки не подходят для представления массивов байтов. Это должно быть тривиально для рефакторинга из строки в байт []. Я бы поставил деньги на вашу проблему, чтобы использовать строку вместо байта []. – Bryan

0

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

port.DiscardNull = false; 

Кроме того, проверьте тип байта, поступающего в он последовательный порт, и принимать только данные:

private void port_DataReceived(object sender, SerialDataReceivedEventArgs e) 
{ 
    if (e.EventType == SerialData.Chars) 
    { 
     // Your existing code 
    } 
} 
1

вычисления ВСС нестандартный, но «определенный клиентом». мы программируем интерфейсы для наших клиентов и много раз находили разные алгоритмы, в том числе sum, xor, маскирование, размещение stx, etx или обоих, или разделение всех известных байтов. например, структура пакета - «stx, машинный код, код команды, данные, ..., данные, etx, bcc», а исчисление bcc (клиент указан!) как «двоичная сумма всех байтов от кода команды до последние данные, включительно, и все маскируются с помощью 0xCD ". То есть мы должны сначала добавить все неизвестные байты (нет смысла добавлять stx, etx или машинный код, если эти байты не совпадают, кадр все равно отбрасывается!их ценность проверяется, когда они получены, чтобы убедиться, что кадр начинается, заканчивается правильно, и он адресован принимающей машине, и в этом случае нам нужно оцепить только байты, которые могут меняться в кадре, это уменьшится время, как во многих случаях мы работаем с 4 или 8-битными медленными микроконтроллерами, и осторожно, это суммирование байтов, а не их xoring, это был всего лишь пример, другой клиент хочет что-то еще), а во-вторых, после того, как мы сумма (которая может быть 16 бит, если не усечена во время добавления), мы маскируем ее (побитовое И) с помощью ключа (в этом примере 0xCD). Этот тип материала часто используется для всех типов близких систем, например ATM (подключение последовательной клавиатуры к ATM) по причинам защиты и т. Д., В верхней части шифрования и других вещей. Итак, вам действительно нужно проверить (прочитайте «crack»), как ваши две машины вычисляют свои (нестандартные) BCC.

Смежные вопросы