|
SLP - последовательный протокол, Еще один велосипед |
|
|
|
 |
Ответов
(1 - 8)
|
Oct 5 2008, 13:06
|
Гуру
     
Группа: Участник
Сообщений: 3 928
Регистрация: 28-03-07
Из: РФ
Пользователь №: 26 588

|
В качестве прототипов - SLIP и WAKE. Недостаток первого - неудобные stuff-коды, усложняющие работу в полудуплексном режиме, у второго - наличие байта адреса, который вполне мог бы отсутствовать для всех безадресных команд. Не долго думая: Код #define Slp_packet_end 0xFF /* indicates end of packet */ #define Slp_stuffing_esc 0xFE /* indicates byte stuffing */ #define Slp_byte_esc_end 0xFD /* ESC ESC_END means END data byte */ #define Slp_byte_esc_esc 0xFC /* ESC ESC_ESC means ESC data byte */ Протокол пакетный, пакет заканчивается символом Slp_packet_end. А в полудуплексном режиме так же имеет префикс из 2х символов Slp_packet_end. Остальное, в общем, аналогично SLIP. Пакет начинается с кода команды. Далее, в случае адресных команд, идет адрес. В отличие от WAKE. Диапазон команд поделен пополам: 0x00..0x7F - запросы мастера, 0x80..0xFF - ответы слейвов. Код #define Slp_commands 0x00 #define Slp_pipe_commands 0x00 // потоковые, безадресные команды #define Slp_system_commands 0x10 // системные, безадресные команды #define Slp_sysdev_commands 0x20 // системные, MAC-адресные (16 байт) команды #define Slp_device_commands 0x30 // адресные (байт) команды #define Slp_user_commands 0x40 // определяется пользователем #define Slp_responses 0x80 // ответы Код ответа формируется из кода команды запроса + 0x80. Далее идет адрес слейва, если адрес был в запросе. В случае если команда устройством не поддерживается, либо при ее выполнении возникла ошибка, формирование ответа на этом заканчивается. Т.е. размер пакета может быть переменный. Но максимальный размер пакета, наверно нужно ограничить где-то 64 байтами - вопрос открыт. Все пакеты завершаются CRC16, полином 0x1021, дающий такие результаты на контрольных последовательностях Код // Пустой пакет 0x1D0F // A 0x9479 // 1234567890 xE5CC // 256*A chars 0xE938
Сообщение отредактировал Огурцов - Oct 5 2008, 13:20
|
|
|
|
|
Oct 5 2008, 14:53
|

Местный
  
Группа: Свой
Сообщений: 226
Регистрация: 2-06-06
Пользователь №: 17 720

|
как-то все сложно и запутанно, какие-то stuff-коды и т.п... я сделал проще - полудуплексный протокол с пакетами переменной длины и станд. заголовком :
заколовок пакета:
u16 packet_size - размер (включая CRC), u8 node_from - адрес узла-отправителя, u8 node_to - адрес узла-получателя, u16 cmd - команда/тип пакета, ......... - данные пакета, индивидуальные для каждой команды, u16 crc - к.с. пакета (так как нет никакого стаффинга, считается на лету при приеме/передаче каждого байта).
10 старших бит команды отведены для типа устройства, если равны 0 - команда универсальная, должна поддерживаться всеми устройствами (напр. получение текущего статуса устройства, проверка прохождения данных, получение информации о устройстве - тип, версия п.о., серийный номер, размер приемного буфера и т.д.), младшие 6 бит - собственно код команды.
есть библ. на С на контроллеров (прием/передача встраиваются в преорывания RX,TX, плюс прерывание таймера для контроля тайм-аута приема и паузы перед передачей отв. пакета, вся обработка - в осн.цикле по флагам готовности пакета), библ. на Питоне для приема/передачи/расшифровки пакетов.
|
|
|
|
|
Oct 5 2008, 15:51
|
Гуру
     
Группа: Участник
Сообщений: 3 928
Регистрация: 28-03-07
Из: РФ
Пользователь №: 26 588

|
Цитата(umup @ Oct 5 2008, 14:53)  u16 crc - к.с. пакета (так как нет никакого стаффинга, считается на лету при приеме/передаче каждого байта). Да, CRC считается только от данных, без учета стаффинга, поэтому тоже "на лету". packet_size - зло. Я долго бился над его оптимизацией, а теперь, отказавшись, понимаю, что без него все гораздо прямее. node_from - вот с этим вопрос открыт. Пока нет необходимости, поэтому не могу привести случаи, когда оно могло бы пригодиться. В большей степени кажется необходимым иметь не адрес мастера, а адрес шины, с которой получили пакет, для возможности маршрутизации. Маршрутизация уже сейчас напрашивается, хоть по-идее не является необходимой для сабжевого типа шин.
|
|
|
|
|
Oct 5 2008, 16:45
|

Местный
  
Группа: Свой
Сообщений: 226
Регистрация: 2-06-06
Пользователь №: 17 720

|
Цитата(Огурцов @ Oct 5 2008, 18:51)  packet_size - зло. Я долго бился над его оптимизацией, а теперь, отказавшись, понимаю, что без него все гораздо прямее. а как контролировать завершение приема пакета ? сравнивать к.с. для каждого байта ? Цитата node_from - вот с этим вопрос открыт. Пока нет необходимости, поэтому не могу привести случаи, когда оно могло бы пригодиться. В большей степени кажется необходимым иметь не адрес мастера, а адрес шины, с которой получили пакет, для возможности маршрутизации. Маршрутизация уже сейчас напрашивается, хоть по-идее не является необходимой для сабжевого типа шин. модет пригодится, например для мульти-мастерной сети
|
|
|
|
|
Oct 5 2008, 17:19
|
Гуру
     
Группа: Участник
Сообщений: 3 928
Регистрация: 28-03-07
Из: РФ
Пользователь №: 26 588

|
Цитата(umup @ Oct 5 2008, 16:45)  а как контролировать завершение приема пакета ? сравнивать к.с. для каждого байта ? Дыкть, специально для этого символ предусмотрен - Slp_packet_end. А вот Вы как обнаруживаете начало пакета, тот байт, в котором packet_size ? Что будете делать, если пакет придет наполовину, как начало следующего ловить ? Цитата(umup @ Oct 5 2008, 16:45)  модет пригодится, например для мульти-мастерной сети Так наверно мастрера сами разберутся, кто какие запросы отправлял и будут ловить предназначенные им ответы. Шина общая и запросы по-любому должны идти друг за другом, а не одновременно, и ответы не перепутаются, даже если запросы будут одинаковые но от разных мастеров.
|
|
|
|
|
Oct 5 2008, 17:26
|

Местный
  
Группа: Свой
Сообщений: 226
Регистрация: 2-06-06
Пользователь №: 17 720

|
Цитата А вот Вы как обнаруживаете начало пакета, тот байт, в котором packet_size ? Что будете делать, если пакет придет наполовину, как начало следующего ловить ? просто - по тайм-ауту приема. если пакет/к.с./данные/адреса неверные, последующие данные просто игнорируются до наступления тайм-аута, указатель приема данных сбрасывается на начало буфера. Так можно работать с устройствами, которые имеют разные настройки скорости/четности/стопов на одной шине. если мастер не получает ответа на свой запрос, после паузы шлет повторные запросы, если превышено макс. количество запросов, возвращает в основную программу ошибку. Цитата Дыкть, специально для этого символ предусмотрен - Slp_packet_end. а если он будет искажен помехой ? контролироваться должны все данные. в приложении - текст библиотеки.
|
|
|
|
|
Oct 5 2008, 19:40
|
Гуру
     
Группа: Участник
Сообщений: 3 928
Регистрация: 28-03-07
Из: РФ
Пользователь №: 26 588

|
Цитата(umup @ Oct 5 2008, 17:26)  просто - по тайм-ауту приема А если между пакетами пройдет помеха ? Тогда у Вас следующий пакет будет отброшен, хотя и мог бы быть принят без ошибок. В общем, не сюр. Кстати, в полудуплексе, на rs485 без растяжек Ваш протокол работает ? Без ошибок ? Цитата(umup @ Oct 5 2008, 17:26)  работать с устройствами, которые имеют разные настройки скорости/четности/стопов Жуть. Цитата(umup @ Oct 5 2008, 17:26)  а если он будет искажен помехой ? Значит слейв продолжит дожидать завершение пакета, а мастер, после таймаута, повторит запрос. Цитата(umup @ Oct 5 2008, 17:26)  контролироваться должны все данные. Считать CRC ? От управляющих символов ? Смысл ? При искажении итак перезапрос произойдет, хоть контролируй, хоть не контролируй. Часть команд: Код // Slp_pipe_commands =========================================================== // #define Slp_pipe_commands 0x00
#define Slp_pipe_a 0x0A // 0x0A D..D C-C #define Slp_pipe_b 0x0B // 0x0B D..D C-C #define Slp_pipe_c 0x0C // 0x0C D..D C-C #define Slp_pipe_d 0x0D // 0x0D D..D C-C Код // Slp_system_commands ========================================================= // #define Slp_system_commands 0x10
#define Slp_system_reset 0x10 // 0x10 C-C #define Slp_system_start 0x11 // 0x11 C-C #define Slp_system_wakeup 0x12 // 0x12 C-C #define Slp_system_sleep 0x13 // 0x13 C-C #define Slp_system_standby 0x14 // 0x14 C-C #define Slp_system_set_datetime 0x15 // 0x15 S-M-H-D-D-M-Y C-C #define Slp_system_set_bitrate 0x16 // 0x16 B-B-B C-C #define Slp_system_enumerate 0x17 // 0x17 A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A S C-C Про перечисление устройств я уже писал где-то рядом, а остальное вроде бы должно быть понятно.
|
|
|
|
|
Feb 17 2009, 09:46
|
Гуру
     
Группа: Участник
Сообщений: 3 928
Регистрация: 28-03-07
Из: РФ
Пользователь №: 26 588

|
В процессе кое-что поменялось.
slp_lib.rar ( 1.58 килобайт )
Кол-во скачиваний: 161Добавил флаг ошибки в код ответа, в принципе красиво получилось. Для этого (пока) пришлось изменить порядок областей в диапазоне кодов 0..255. Теперь распределение такое: // 0000xxxx Slp_device_commands // 0001xxxx Slp_sysdev_commands // 0010xxxx Slp_system_commands // 0011xxxx Slp_pipe_commands // // 0101xxxx Slp_user_commands as Slp_device_commands // 0100xxxx Slp_user_commands as Slp_sysdev_commands // 0111xxxx Slp_user_commands as Slp_system_commands // 0110xxxx Slp_user_commands as Slp_pipe_commands // 1000xxxx Response Slp_device_commands // 1001xxxx Response Slp_sysdev_commands // 1010xxxx Response Slp_device_commands Error // 1011xxxx Response Slp_sysdev_commands Error // // 1101xxxx Response Slp_user_commands as Slp_device_commands // 1100xxxx Response Slp_user_commands as Slp_sysdev_commands // 1111xxxx Response Slp_user_commands as Slp_device_commands Error // 1110xxxx Response Slp_user_commands as Slp_sysdev_commands Error
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|