Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: SLP - последовательный протокол
Форум разработчиков электроники ELECTRONIX.ru > Интерфейсы > Форумы по интерфейсам
Огурцов
Цель - разработка, испытания, некая стандартизация.
Как думаете, будет ли интересен сабж ?
Огурцов
В качестве прототипов - 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
umup
как-то все сложно и запутанно, какие-то stuff-коды и т.п...
я сделал проще - полудуплексный протокол с пакетами переменной длины и станд. заголовком :

заколовок пакета:

u16 packet_size - размер (включая CRC),
u8 node_from - адрес узла-отправителя,
u8 node_to - адрес узла-получателя,
u16 cmd - команда/тип пакета,
......... - данные пакета, индивидуальные для каждой команды,
u16 crc - к.с. пакета (так как нет никакого стаффинга, считается на лету при приеме/передаче каждого байта).

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

есть библ. на С на контроллеров (прием/передача встраиваются в преорывания RX,TX, плюс прерывание таймера для контроля тайм-аута приема и паузы перед передачей отв. пакета, вся обработка - в осн.цикле по флагам готовности пакета), библ. на Питоне для приема/передачи/расшифровки пакетов.
Огурцов
Цитата(umup @ Oct 5 2008, 14:53) *
u16 crc - к.с. пакета (так как нет никакого стаффинга, считается на лету при приеме/передаче каждого байта).


Да, CRC считается только от данных, без учета стаффинга, поэтому тоже "на лету".

packet_size - зло. Я долго бился над его оптимизацией, а теперь, отказавшись, понимаю, что без него все гораздо прямее.

node_from - вот с этим вопрос открыт. Пока нет необходимости, поэтому не могу привести случаи, когда оно могло бы пригодиться. В большей степени кажется необходимым иметь не адрес мастера, а адрес шины, с которой получили пакет, для возможности маршрутизации. Маршрутизация уже сейчас напрашивается, хоть по-идее не является необходимой для сабжевого типа шин.
umup
Цитата(Огурцов @ Oct 5 2008, 18:51) *
packet_size - зло. Я долго бился над его оптимизацией, а теперь, отказавшись, понимаю, что без него все гораздо прямее.
а как контролировать завершение приема пакета ? сравнивать к.с. для каждого байта ?
Цитата
node_from - вот с этим вопрос открыт. Пока нет необходимости, поэтому не могу привести случаи, когда оно могло бы пригодиться. В большей степени кажется необходимым иметь не адрес мастера, а адрес шины, с которой получили пакет, для возможности маршрутизации. Маршрутизация уже сейчас напрашивается, хоть по-идее не является необходимой для сабжевого типа шин.
модет пригодится, например для мульти-мастерной сети
Огурцов
Цитата(umup @ Oct 5 2008, 16:45) *
а как контролировать завершение приема пакета ? сравнивать к.с. для каждого байта ?

Дыкть, специально для этого символ предусмотрен - Slp_packet_end.
А вот Вы как обнаруживаете начало пакета, тот байт, в котором packet_size ?
Что будете делать, если пакет придет наполовину, как начало следующего ловить ?

Цитата(umup @ Oct 5 2008, 16:45) *
модет пригодится, например для мульти-мастерной сети

Так наверно мастрера сами разберутся, кто какие запросы отправлял и будут ловить предназначенные им ответы. Шина общая и запросы по-любому должны идти друг за другом, а не одновременно, и ответы не перепутаются, даже если запросы будут одинаковые но от разных мастеров.
umup
Цитата
А вот Вы как обнаруживаете начало пакета, тот байт, в котором packet_size ?
Что будете делать, если пакет придет наполовину, как начало следующего ловить ?

просто - по тайм-ауту приема. если пакет/к.с./данные/адреса неверные, последующие данные просто игнорируются до наступления тайм-аута, указатель приема данных сбрасывается на начало буфера. Так можно работать с устройствами, которые имеют разные настройки скорости/четности/стопов на одной шине.
если мастер не получает ответа на свой запрос, после паузы шлет повторные запросы, если превышено макс. количество запросов, возвращает в основную программу ошибку.
Цитата
Дыкть, специально для этого символ предусмотрен - Slp_packet_end.
а если он будет искажен помехой ? контролироваться должны все данные.

в приложении - текст библиотеки.
Огурцов
Цитата(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

Про перечисление устройств я уже писал где-то рядом, а остальное вроде бы должно быть понятно.
Огурцов
В процессе кое-что поменялось.

Нажмите для просмотра прикрепленного файла

Добавил флаг ошибки в код ответа, в принципе красиво получилось. Для этого (пока) пришлось изменить порядок областей в диапазоне кодов 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
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.