feat(protocan-transport): транспортный уровень ProtoCAN и каталог GUI
Перенесён из репозитория protocan-transport, который подключался сабмодулем в CAN_to_RS485. Кадрирование AA 55 с CRC16 поверх любого байтового потока (RS485, RS232, USB CDC), разбор 29-битного идентификатора, общее адресное пространство регистров и каталог с подпиской на поток значений для SETGUI. Состояние живёт в структурах вызывающего, поэтому в одной прошивке поднимается сколько угодно независимых каналов. Порт STM32F4 (USART + DMA) в комплекте. Хостовые тесты test_transport и test_gui проходят.
This commit is contained in:
78
c/protocan-transport/docs/FRAME.md
Normal file
78
c/protocan-transport/docs/FRAME.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# Транспортный кадр
|
||||
|
||||
## Формат
|
||||
|
||||
```
|
||||
+------+------+-----+-----+-------+----------------+-------------+-------+-------+
|
||||
| 0xAA | 0x55 | LEN | SEQ | FLAGS | ID0 ID1 ID2 ID3| DATA[0..8] | CRC_L | CRC_H |
|
||||
+------+------+-----+-----+-------+----------------+-------------+-------+-------+
|
||||
```
|
||||
|
||||
| Поле | Байт | Описание |
|
||||
|---|---:|---|
|
||||
| SOF | 2 | сигнатура `0xAA 0x55` |
|
||||
| `LEN` | 1 | длина участка `SEQ..DATA` = `6 + DLC`, диапазон 6..14 |
|
||||
| `SEQ` | 1 | счётчик кадров 0..255, инкремент на каждый успешно отданный кадр |
|
||||
| `FLAGS` | 1 | см. ниже |
|
||||
| `ID` | 4 | 29-битный CAN-идентификатор, little-endian (старшие 3 бита = 0) |
|
||||
| `DATA` | 0..8 | `DLC = LEN - 6` байт данных CAN |
|
||||
| `CRC` | 2 | CRC-16/CCITT-FALSE, little-endian |
|
||||
|
||||
CRC считается по байтам от `LEN` до последнего байта `DATA` включительно;
|
||||
сигнатура SOF в расчёт не входит. Полином `0x1021`, начальное значение
|
||||
`0xFFFF`, без рефлексии и без финального XOR — контрольное значение для
|
||||
строки `123456789` равно `0x29B1`.
|
||||
|
||||
Максимальный размер кадра — 19 байт (`PCAN_FRAME_MAX`).
|
||||
|
||||
## FLAGS
|
||||
|
||||
| Бит | Имя | Значение |
|
||||
|---:|---|---|
|
||||
| 0 | `IDE` | 1 = расширенный ID (29 бит), 0 = стандартный (11 бит) |
|
||||
| 1 | `RTR` | 1 = remote frame |
|
||||
| 2 | `DIR` | 0 = кадр пришёл из CAN, 1 = кадр надо передать в CAN |
|
||||
| 3 | `ERR` | 1 = служебный кадр моста (диагностика), не трафик шины |
|
||||
| 7..4 | — | резерв, передавать нулями |
|
||||
|
||||
## Синхронизация
|
||||
|
||||
Приёмник ищет `0xAA 0x55`, читает `LEN`, проверяет диапазон `6..14`,
|
||||
набирает `LEN + 2` байт и сверяет CRC. При неверном `LEN` или несовпадении
|
||||
CRC разборщик возвращается к поиску сигнатуры, причём байт, оборвавший
|
||||
разбор, сам проверяется на `0xAA` — последовательность `AA AA 55` тоже
|
||||
распознаётся. Потеря синхронизации стоит не больше одного кадра.
|
||||
|
||||
Счётчики разбора (`pcan_parse_stats_t`) отдельно считают кадры, ошибки CRC,
|
||||
неверные `LEN` и байты вне кадров — по ним видно, шумит линия или сбоит
|
||||
источник.
|
||||
|
||||
## SEQ
|
||||
|
||||
`SEQ` инкрементируется только на успешно отданном кадре: если кадр не влез
|
||||
в очередь передачи, счётчик не двигается, и приёмник не засчитает потерю
|
||||
там, где кадра просто не было. Разрыв в `SEQ` на приёме означает реальную
|
||||
потерю в линии.
|
||||
|
||||
## Почему так
|
||||
|
||||
- **Длина плюс CRC, без байт-стаффинга.** Стаффинг раздувает кадр
|
||||
непредсказуемо и усложняет расчёт таймингов на полудуплексной линии.
|
||||
Фиксированный заголовок даёт заранее известный максимум 19 байт.
|
||||
- **Сигнатура из двух байт.** Один байт слишком часто встречается в
|
||||
случайных данных; два дают приемлемую вероятность ложного старта,
|
||||
который всё равно отсеет CRC.
|
||||
- **`LEN` в начале.** Приёмник сразу знает, сколько байт набирать, и не
|
||||
зависит от содержимого данных.
|
||||
- **Little-endian везде.** Совпадает с порядком регистров в
|
||||
`PROTOCAN_SEND_GENERAL_ADDRESS_SPACE()` и с обоими целевыми МК.
|
||||
|
||||
## Пример
|
||||
|
||||
CAN-кадр: ID `0x1234567`, DLC 2, данные `AA BB`, `SEQ = 1`, флаг `IDE`.
|
||||
|
||||
```
|
||||
AA 55 08 01 01 67 45 23 01 AA BB FE 14
|
||||
```
|
||||
|
||||
`LEN = 6 + 2 = 8`, `FLAGS = 0x01`, CRC = `0x14FE`.
|
||||
Reference in New Issue
Block a user