Одна из самых сложных задач решена: однопроводной протокол заработал. Эмулятор повязки на компьютере успешно общается с датчиком. Обращается к нему по адресу и получает из датчика данные, принятые по ИК, если такие имеются.
Теперь
набросок протокола, вернее его начало.
Название я пока оставил SSP - Smart Sensor Protocol, потому что в коде уже много где такая аббревиатура.
1. Физический уровень:
Полудуплексный UART. Но можно и другой интерфейс. Все устройства по-умолчанию слушают линию, если не передают в данный момент. Приемник читает входящий поток в буффер. Принятые данные постоянно анализируются, и если они выглядят, как валидный пакет, происходит его обработка. Приемник сбрасывается по таймауту. Это для защиты от наводок и для горячего подключения.
2. Канальный+сетевой уровень:
Пакет = заголовок пакета + аргумент команды (если есть).
Ответный пакет (если предполагается) может передаваться без задержки сразу же.
Определения типов данных и структуры заголовока (выдержка из кода):
Код:
typedef uint16_t SSP_Address;
typedef uint16_t SSP_Command;
typedef uint8_t SSP_Argument_Size;
#pragma pack(push, 1)
typedef struct {
SSP_Command command;
SSP_Address target;
SSP_Argument_Size size;
} SSP_Header;
#pragma pack(pop)
#define SSP_BROADCAST_ADDRESS ((SSP_Address) 0xFFFF)
#define SSP_MASTER_ADDRESS ((SSP_Address) 0xFFF0)
Тут, я думаю, все очевидно. Заголовок пакета содержит идентификатор команды, адрес получателя и размер аргумента команды (ноль, если аргумента нет).
Адресация: у каждого сенсора свой индивидуальный двухбайтовый адрес (зачем два байта, почему не хватит одного - напишу позднее). Есть широковещательный, SSP_BROADCAST_ADDRESS == 0xFFFF. Команды, посланные на SSP_BROADCAST_ADDRESS, принимают все датчики.
У повязки всегда конкретный адрес, SSP_MASTER_ADDRESS = 0xFFF0. Гарантируется, что ни у одного датчика такого никогда не будет.
Что конкретно должен сделать датчик, определяется кодом команды (SSP_Header.command) и её аргументом, который идет после заголовка. Гарантируется, что ни один датчик не передает данные по своей инициативе, а только в ответ на пакет-запрос, адресованный лично ему. Широковещательные пакеты не могут запрашивать данные, а могут лишь менять состояние датчиков (например: всем зажечь красный).
Товарищи, есть ли какие-то вопросы и возражения?
3. По прикладному уровню, а также подробнее об адресах и их генерации напишу пост позже. Тогда и обсудим конкретный пересень команд.