Автор Тема: Протокол Атола  (Прочитано 8655 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Andy

  • Администратор Форумa
  • Эксперт
  • *
  • Сообщений: 1803
  • Карма: 15
  • Пол: Мужской
  • Нельзя отремонтировать то, что не сломано...
    • minilabmaster
    • Просмотр профиля
    • Форум "Минилаб-Мастер"
Протокол Атола
« : 27 Мая 2012, 16:51:07 »
Цитировать
Внимание: Байты данных, равные DLE и ETX, передаются как последовательность
двух байт: 10h как <DLE DLE>, 03h как <DLE ETX>. Такая операция далее будет
называться маскировкой. Все остальные байты (даже равные остальным
управляющим символам) передаются просто – как один байт. DLE аналогичен
символу \'\\\' в языке С (сравните последовательности "\\n", "\\\\", "\\\\n", "\\\\\\n" и <DLE
ETX>, <DLE DLE>, <DLE DLE ETX>, <DLE DLE DLE ETX>).

Фу, как не красиво, И это протокол передачи данных по ком порту. И я сейчас с ним занимаюсь любовью. У меня есть два массива по 255 байт, приходится готовую команду проверять на DLE тасуя между массивами и принятую команду парсить на этот самый 10H гоняя байты между массивами.

На закуску там в одном протоколе используются 2 кодировки - dos и какая-то своя левая еще числа (не все) идут в формате BCD. Даже страшно. По сранвнению с этим штриховский протокол вершина изящества. Для начала про долбаный DLE костыль - может есть идеи как проще его парсить?
Заклинило деталь - надави на нее, если она сломалась - ничего, ее все равно надо было менять.

Andy

  • Администратор Форумa
  • Эксперт
  • *
  • Сообщений: 1803
  • Карма: 15
  • Пол: Мужской
  • Нельзя отремонтировать то, что не сломано...
    • minilabmaster
    • Просмотр профиля
    • Форум "Минилаб-Мастер"
Re: Протокол Атола
« Ответ #1 : 27 Мая 2012, 16:56:42 »
Вот как это примерно выглядит:

Цитировать
Поле <CRC> команды и ответа
Контрольная сумма подсчитывается по алгоритму: «выполнение
операции побайтное исключающее ИЛИ (XOR) по всем символам блока,
включая ETX, но исключая STX».
Пример: передать блок данных <1F 00 FF 10 02 03 1A>.
1. Маскируем байты, равные DLE и ETX (10h и 03h): <1F 00 FF 10 10 02 10 03 1A>.
2. Добавляем в конец ETX: <1F 00 FF 10 10 02 10 03 1A 03>.
3. Подсчитываем <CRC>: 1F XOR 00 XOR FF XOR 10 XOR 10 XOR 02 XOR 10
XOR 03 XOR 1A XOR 03 = E8.
4. Добавляем в начало STX: <02 1F 00 FF 10 10 02 10 03 1A 03>.

При передаче посылки используется 8 таймаутов.... :\'(
Заклинило деталь - надави на нее, если она сломалась - ничего, ее все равно надо было менять.

pumpkin

  • Модератор Раздела
  • Профи
  • *
  • Сообщений: 240
  • Карма: 2
  • Пол: Мужской
  • Это Я :-)
    • Просмотр профиля
Re: Протокол Атола
« Ответ #2 : 28 Мая 2012, 21:38:39 »
В один проход его:
Цитировать
$regfile = "m48def.dat"

$crystal = 4000000

$baud = 19200

Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0


Dim Aori(32) As Byte
Dim Aenc(32) As Byte
Dim Lori As Integer
Dim Lenc As Integer
Dim I As Integer
Dim Crc As Byte

Dim Dle As Byte
Dim Etx As Byte
Dim Stx As Byte
Dim Oops As Byte

Print "Hello, demo!"

Dle = &H10
Etx = &H03
Stx = &H02

\'Наш блок данных
Aori(1) = &H1F
Aori(2) = &H00
Aori(3) = &HFF
Aori(4) = &H10
Aori(5) = &H02
Aori(6) = &H03
Aori(7) = &H1A
Lori = 7

Print ">> Encoding:"
Gosub Atolaenc

For I = 1 To Lenc
  Print Hex(aenc(i))
Next I
Print "CRC = " ; Hex(crc)


For I = 1 To Lori
  Aori(i) = 0
Next I

Print ">> Decoding:"
Gosub Atoladec

If Oops > 0 Then
  Print "Error decoding"
Else
  For I = 1 To Lori
    Print Hex(aori(i))
  Next I
  Print "CRC = " ; Hex(crc)
End If

End

\' ================== Процедура кодирования ===================
Atolaenc:
\'пишем STX в начало
Lenc = 1
Aenc(lenc) = Stx
Crc = 0
\'пошли по входному массиву
For I = 1 To Lori
  If Aori(i) = Dle Or Aori(i) = Etx Then
    \'если символ надо экранировать (DLE или ETX) то
    \'суем в выходной массив внеочередной символ DLE
    \'и сразу обновляем контрольную сумму
    Crc = Crc Xor Dle
    Lenc = Lenc + 1
    Aenc(lenc) = Dle
  End If
  \'обрабатываем сам символ в обычном образом так как
  \'то что надо экранировать уже отэкранировано
  Crc = Crc Xor Aori(i)
  Lenc = Lenc + 1
  Aenc(lenc) = Aori(i)
Next I
\'прилепляем сзади ETX
Crc = Crc Xor Etx
Lenc = Lenc + 1
Aenc(lenc) = Etx
Return


\' ============== Процедура декодирования =====================
Atoladec:
Lori = 0
Crc = Etx
Oops = 0
\'если первый не STX или последний не ETX - ошибка
If Aenc(1) <> Stx Or Aenc(lenc) <> Etx Then
  Oops = 1
Else
  \'пошли по закодированному массиву
  Lenc = Lenc - 1
  For I = 2 To Lenc
    If Aenc(i) = Dle Then
      \'экран, пропускаем его, но к CRC "прибавляем"
      Crc = Crc Xor Dle
      I = I + 1
    End If
    \'а здесь уже нормальный байт
    Crc = Crc Xor Aenc(i)
    Lori = Lori + 1
    Aori(lori) = Aenc(i)
  Next I
End If
Return

Andy

  • Администратор Форумa
  • Эксперт
  • *
  • Сообщений: 1803
  • Карма: 15
  • Пол: Мужской
  • Нельзя отремонтировать то, что не сломано...
    • minilabmaster
    • Просмотр профиля
    • Форум "Минилаб-Мастер"
Re: Протокол Атола
« Ответ #3 : 29 Мая 2012, 04:44:34 »
Очень неплохо, мой код по другому сделан, но я написал но не тестировал его еще. Но седня ночью меня озарила мысль что можно в принципе обойтись одним массивом, и все операции делать над ним же командой memcopy. По сложности будет так же но экономится массив, который снова не надо загружать из i2c памяти в моем коде. Который может быть потенциально подвержен сбоям. Сейчас на работе, как будет время - попробую.

Заклинило деталь - надави на нее, если она сломалась - ничего, ее все равно надо было менять.

pumpkin

  • Модератор Раздела
  • Профи
  • *
  • Сообщений: 240
  • Карма: 2
  • Пол: Мужской
  • Это Я :-)
    • Просмотр профиля
Re: Протокол Атола
« Ответ #4 : 29 Мая 2012, 05:01:35 »
Можно и в одном массиве, с двумя индексами.

При кодировании (данне растут) массив должен быть в два раза больше исходных данных (для самого худшего случая), и помещать данные надо в конец массива и идти от головы, либо наоборот, помещать в начало и идти с хвоста.

С декодированием проще (данные уменьшаются).

Форум проекта "Минилаб-Мастер"

Re: Протокол Атола
« Ответ #4 : 29 Мая 2012, 05:01:35 »

Andy

  • Администратор Форумa
  • Эксперт
  • *
  • Сообщений: 1803
  • Карма: 15
  • Пол: Мужской
  • Нельзя отремонтировать то, что не сломано...
    • minilabmaster
    • Просмотр профиля
    • Форум "Минилаб-Мастер"
Re: Протокол Атола
« Ответ #5 : 29 Мая 2012, 05:37:48 »
А если идти по массиву циклом и если встретися dle сдвигать оставшийся необработаный кусок на один байт в влево командой мемкопи. Попутно правя длину команды (она известна) пропуская следующий символ. Надо изучить, можно ли командой мемкопи копировать в саму себя. В два раза увеличивать массив - жалко памяти.
« Последнее редактирование: 29 Мая 2012, 05:59:39 от admin »
Заклинило деталь - надави на нее, если она сломалась - ничего, ее все равно надо было менять.

Andy

  • Администратор Форумa
  • Эксперт
  • *
  • Сообщений: 1803
  • Карма: 15
  • Пол: Мужской
  • Нельзя отремонтировать то, что не сломано...
    • minilabmaster
    • Просмотр профиля
    • Форум "Минилаб-Мастер"
Re: Протокол Атола
« Ответ #6 : 29 Мая 2012, 05:47:10 »
Например массив mass 10 - массив из 10 символов на 3 месте - dle

Dim Dimmy As Byte
Dim Mass(10) As Byte

Dimmy = Memcopy(mass(4) , Mass(3) , 6)

Пример компилится.
« Последнее редактирование: 29 Мая 2012, 05:50:49 от admin »
Заклинило деталь - надави на нее, если она сломалась - ничего, ее все равно надо было менять.

pumpkin

  • Модератор Раздела
  • Профи
  • *
  • Сообщений: 240
  • Карма: 2
  • Пол: Мужской
  • Это Я :-)
    • Просмотр профиля
Re: Протокол Атола
« Ответ #7 : 29 Мая 2012, 05:59:47 »
надо попробовать. но это вечером.
и надо посмотреть цену этой операции.

Andy

  • Администратор Форумa
  • Эксперт
  • *
  • Сообщений: 1803
  • Карма: 15
  • Пол: Мужской
  • Нельзя отремонтировать то, что не сломано...
    • minilabmaster
    • Просмотр профиля
    • Форум "Минилаб-Мастер"
Re: Протокол Атола
« Ответ #8 : 29 Мая 2012, 06:21:58 »
И чудится мне обратную операцию - добавление dle надо будет делать с конца массива с обратным счетчиком. Надо эксперементировать, ага.
Заклинило деталь - надави на нее, если она сломалась - ничего, ее все равно надо было менять.

Andy

  • Администратор Форумa
  • Эксперт
  • *
  • Сообщений: 1803
  • Карма: 15
  • Пол: Мужской
  • Нельзя отремонтировать то, что не сломано...
    • minilabmaster
    • Просмотр профиля
    • Форум "Минилаб-Мастер"
Re: Протокол Атола
« Ответ #9 : 29 Мая 2012, 15:33:25 »
Вот такой красивый кодик раскодирования у меня получился:

Цитировать

Atoladec:
Crc = 0                                                           \' Обнуляем CRC
Decr Lenc                                                        \' Уменьшаем длину на еденицу
Dimmy = Memcopy(indata(2) , Indata(1) , Lenc)     \' Удаляем 02 в начале
  For I = 1 To Lenc                                            \' Все в одном проходе
     Crc = Crc Xor Indata(i)                                  \' Обнавляем CRC
     J = I + 1                                                     \' Еще одной переменоной инкримируем счетчик
     Dlinna = Lenc - I                                          \' Подготавливаем переменную для вычитания массива
      If Indata(i) = Dle Then                                  \' Если DLE
       Crc = Crc Xor Indata(j)                                 \' Подсчитываем зарание CRC следующего байта в массиве
       Dimmy = Memcopy(indata(j) , Indata(i) , Dlinna) \' И сдвигаем массив на один байт влево
       Decr Lenc                                                    \'
     End If

  Next
Return                                                                  \'Вроде работает!

Заклинило деталь - надави на нее, если она сломалась - ничего, ее все равно надо было менять.

Форум проекта "Минилаб-Мастер"

Re: Протокол Атола
« Ответ #9 : 29 Мая 2012, 15:33:25 »

Andy

  • Администратор Форумa
  • Эксперт
  • *
  • Сообщений: 1803
  • Карма: 15
  • Пол: Мужской
  • Нельзя отремонтировать то, что не сломано...
    • minilabmaster
    • Просмотр профиля
    • Форум "Минилаб-Мастер"
Re: Протокол Атола
« Ответ #10 : 29 Мая 2012, 16:29:56 »
А вот кодирование так красиво кажется не получится. Придеться, видимо писать свою функцию, которая умеет копировать байты вправо в массиве. Она должна уметь копировать байты не по возрастающей, а наоборот, с дальнего максимального адреса по минимальный. Иначе она будет как змея, кусающая себя за шею :-) Прямо как в игре Питон :-)
Заклинило деталь - надави на нее, если она сломалась - ничего, ее все равно надо было менять.

pumpkin

  • Модератор Раздела
  • Профи
  • *
  • Сообщений: 240
  • Карма: 2
  • Пол: Мужской
  • Это Я :-)
    • Просмотр профиля
Re: Протокол Атола
« Ответ #11 : 29 Мая 2012, 20:27:38 »
С кодированием - да. Там растет, а мемкопи при первом же вызове затрет весь массив первым байтом.
Можно написать свой мемкопи реверсный, а можно исходные данные кинуть один раз во вторую половину массива, а потом двумя индексами парсить, побайтово перкидывая в начало массива.

Andy

  • Администратор Форумa
  • Эксперт
  • *
  • Сообщений: 1803
  • Карма: 15
  • Пол: Мужской
  • Нельзя отремонтировать то, что не сломано...
    • minilabmaster
    • Просмотр профиля
    • Форум "Минилаб-Мастер"
Re: Протокол Атола
« Ответ #12 : 30 Мая 2012, 01:23:36 »
Ага, вчера почти закончил код. Написал реверсный мемкопи. Выложу попозже.
Заклинило деталь - надави на нее, если она сломалась - ничего, ее все равно надо было менять.

Форум проекта "Минилаб-Мастер"

Re: Протокол Атола
« Ответ #12 : 30 Мая 2012, 01:23:36 »