tonyk_av 45 14 апреля, 2023 Опубликовано 14 апреля, 2023 · Жалоба 1 hour ago, Arlleex said: не получится (в общем случае) Последние 20 лет получалось всегда. 1 hour ago, Arlleex said: Кодозависимый протокол с фреймером на таймингах не состыковать практически с любым ПК Стыкуется без проблем. Правда, китайские RS485-USB не использую. 21 minutes ago, jcxz said: Или всё-таки - на приоритете пользовательского приложения? Именно так. Модбас достаточно продуманный протокол, поэтому распознать в сплошном потоке его фреймы не сложно. Делали и на Линукск, и на MiniOS7, и даже на Винде. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 190 14 апреля, 2023 Опубликовано 14 апреля, 2023 · Жалоба 3 часа назад, artemkad сказал: Думаю, вот это тут будет самое оно: https://ru.wikipedia.org/wiki/SLIP https://en.wikipedia.org/wiki/Serial_Line_Internet_Protocol https://github.com/marcinbor85/slip/blob/master/slip.c Выглядит все там как-то громоздко... На мой взгляд. У меня так. В любом периодическом процессе вызывается декодер входящего потока Спойлер #define MAX_RX_MSG_SIZE 128 static union uRxMsg { struct { } UserExchangeStruct1; struct { } UserExchangeStruct2; ... u8 byte[MAX_RX_MSG_SIZE]; } RxMsg; static void decodeRxFlow() { #define READ_BUF_SIZE 16 static u8 buf[READ_BUF_SIZE]; u32 const charQnt = nsUART::readRxFIFO(buf, arrdpth(buf)); for(u32 i = 0; i < charQnt; ++i) { static bool isFlowSync = false; static u32 msgLen; static u8 oldChar; u8 const curChar = buf[i]; if(msgLen == MAX_RX_MSG_SIZE && curChar != 0xC0) isFlowSync = false; if(curChar != oldChar && oldChar == 0xC0) msgLen = 0, isFlowSync = true; if(isFlowSync) { if(oldChar == 0xDB) { if(curChar == 0xDC) RxMsg.byte[msgLen++] = 0xC0; else if(curChar == 0xDD) RxMsg.byte[msgLen++] = 0xDB; else isFlowSync = false; } else if(curChar != 0xC0) { if(curChar != 0xDB) RxMsg.byte[msgLen++] = curChar; } else parseRxMsg(&RxMsg, msgLen), isFlowSync = false; } oldChar = curChar; } } Захваченные декодированные данные кладутся в RxMsg и вызывается пользовательская parseRxMsg(), в которой происходит обработка входящих сообщений. А передача еще проще Спойлер static void sendMsg(u8 const *msg, u32 len) { #define WRITE_BUF_SIZE 16 static u8 buf[WRITE_BUF_SIZE]; u32 i = 1; buf[0] = 0xC0; for(u32 j = 0; j < len; ++j) { u8 const curChar = msg[j]; u8 escChar = 0; if(curChar == 0xC0) buf[i] = 0xDB, escChar = 0xDC; else if(curChar == 0xDB) buf[i] = 0xDB, escChar = 0xDD; else buf[i] = curChar; if(++i == arrdpth(buf)) nsUART::writeTxFIFO(buf, i), i = 0; if(escChar != 0) { buf[i] = escChar; if(++i == arrdpth(buf)) nsUART::writeTxFIFO(buf, i), i = 0; } } buf[i] = 0xC0; nsUART::writeTxFIFO(buf, i + 1); } Функции кодера/декодера SLIP написаны так, чтобы сократить кол-во обращений к (возможно) тяжелым функциям чтения/записи FIFO UART (чтобы побайтно не теребонить, когда можно разом). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
artemkad 92 14 апреля, 2023 Опубликовано 14 апреля, 2023 · Жалоба 41 минуту назад, Arlleex сказал: Выглядит все там как-то громоздко... Есть такое. Но там все есть и даже чуть больше (CRC), достаточно прозрачно, а потому начинающему есть от чего оттолкнуться. ЗЫ. Кстати, пересмотрел еще раз - не так уж и громоздко. Всего лишь использовали switch вместо if и байт-состояния(что как по мне перспективнее) вместо oldChar. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 190 14 апреля, 2023 Опубликовано 14 апреля, 2023 · Жалоба 7 часов назад, artemkad сказал: Есть такое. Но там все есть и даже чуть больше (CRC), достаточно прозрачно, а потому начинающему есть от чего оттолкнуться. CRC к SLIP отношения никакого не имеет, добавлять контрольные суммы и сверять их это задача вышестоящего протокола. 7 часов назад, artemkad сказал: ЗЫ. Кстати, пересмотрел еще раз - не так уж и громоздко. Всего лишь использовали switch вместо if и байт-состояния(что как по мне перспективнее) вместо oldChar. С точки зрения скорости побайтовой обработки не очень перспективно... P.S. Я ради интереса загнал этот код в онлайн компилятор и сразу же нашел 2 серьезных бага парсера входящих сообщений. Мой же отработал корректно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
artemkad 92 14 апреля, 2023 Опубликовано 14 апреля, 2023 · Жалоба 59 минут назад, Arlleex сказал: CRC к SLIP отношения никакого не имеет Дык потому и "и даже чуть больше". Ему ведь не SLIP надо, а данные передавать 1 час назад, Arlleex сказал: С точки зрения скорости побайтовой обработки не очень перспективно... Если не рассматривать DMA - по скорости без особой разницы. Самая медленная там скорость это скорость прихода символов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться