Перейти к содержанию
    

Arlleex

Свой
  • Постов

    5 796
  • Зарегистрирован

  • Посещение

  • Победитель дней

    14

Arlleex стал победителем дня 6 апреля

Arlleex имел наиболее популярный контент!

Репутация

130 Очень хороший

2 Подписчика

Информация о Arlleex

  • Звание
    Гуру
    Гуру

Контакты

  • ICQ
    Array

Посетители профиля

17 667 просмотров профиля
  1. Это будет подтягивать динамическое выделение памяти, такое меня уже не устроит. Ух тут сколько всего написали (это хорошо, дискуссия жива🙂) - однако я внесу немножко понятностей. Не важно, что за протокол, важно то, что он пакетный: длина пакета выкорчевывается внеполосной сигнализацией на уровне проводов или (для примитивных байтовых интерфейсов) промежуточный канальный фреймер разбирает поток байтов на кадры/пакеты. Короче говоря, я всегда знаю, сколько данных мне прилетело в пакете. Пакет, как обычно, уже содержит заголовок со всякими типами содержимого для идентификации этого пакета и т.д. Шмалять в сеть пакеты фиксированной длины здесь очень избыточно - это точно красный флаг. Так вот. У меня девайс состоит из множества плат, каскадно соединенных друг с другом порой сильно разными интерфейсами. Пакет данных со входа до самой дальней платы может пройти пару-тройку интерфейсных мостов со своими протокольно-зависимыми особенностями. Каждая "промежуточная" плата имеет механизм проброса "не своих" пакетов данных туда дальше в "паровозик". Чтобы облегчить ПО каждой платы, она детально даже не разбирает "не свои" пакеты, а как есть его пересылает дальше. Где-то закладывать CRC не имело бы смысла, а где-то, из-за этого "прозрачного режима", CRC пакету нужен. Например: девайс состоит из двух плат (1) и (2), между ними прокинут UART. С платы (1) наружу девайса торчит Ethernet, воткнутый в комп. С компа шлю данные плате (2) - и, казалось бы, езернет уже гарантирует целостность своего фрейма, т.е. можно не вносить контрольную сумму для данных, но данные ведь предназначены плате (2), а чтобы туда попасть, данные должны преобразоваться в UART платой (1) и транслироваться на плату (2). Этот UART - байтовый, поэтому поверх него работает SLIP. Но для контроля целостности данных на приеме платой (2) пакет нужно долполнить контрольной суммой. Что и делает сразу отправляющая сторона перед засовыванием в езернет. Насчет положения CRC в структуре: да, можно в хедер ее пихнуть. Однако это маааленький такой костыль с тасованием расположения, который конкретно в данном случае вполне поможет (за счет наличия в Си и (с позволения компиляторов) C++ FAM в структурах). Да, удобно, если КС в конце - сверил - и результат будет 0. Оданко по затратам на вычисление это будет почти один-в-один с пробегом по хедеру и по данным и последующим сравнением полученной КС с той, что в хедере лежит (в случае размещения КС в хедере). Исторически у меня так завелось, что хедеры могут быть разных размеров, и поэтому КС размещалась строго в конце, несмотря на то, что размер кадра плавающий. Меня полностью устраивает этот вариант и поныне. И я хотел, чтобы несколько "костыльно" выглядящее определение структуры с гибким массивом в конце наконец обрело лаконичный вид в C++. Мне не нужна динамическая память - мне нужно как-то сказать компайлеру, чтобы на статически выделенном куске создавал структуру, в которой после гибкого массива расположен еще какой-то элемент. Условно, чтобы это выглядело примерно так (как я это вижу): struct FlexFrame { Header hdr; u8 data[]; // <- гибкий массив, а значит дальше можно ставить только элементы с атрибутом "гибкого положения" u32 crc __attribute__((flexible)); // положение этого члена "гибкое", в зависимости от объема поля data при создании структуры }; ... static u8 RxPacketMemory[1024]; // статически выделенная память для создания "гибких" структур // вызвали с len == 10 void sendPacket(u32 len) { // тут нужен был бы синтаксис объявления структуры, например FlexFrame frame __attribute__((RxPacketMemory, len)); // компилятор думает, что frame имеет data[10], размещая frame в памяти RxPacketMemory frame.crc = ...; // компилятор для доступа к полю crc использует соответствующее смещение, полученное на основе аргумента функции }
  2. Работает все прекрасно и у меня. И 15 лет назад тоже все работало. Меня интересовало, додумалось ли C++ сообщество до чего-то более удобоваримого в этом плане. P.S. Какие указатели в протоколе передачи данных??? Вы о чем? Вроде понятно, что данные снабжаются КС и уже улетают в провод. В дизасм смотреть или даже не пытаться?🙂 P.S. Я с МК тоже отправляю, так что способ ищу легковесный. Если нет - мне проще (как всегда, собственно) написать свой небольшой класс.
  3. Я от того и спрашиваю, что задача тривиальная, а решалась всегда "криво"🙂 Но, видимо, нужно создать класс-оболочку над неким массивом известной длины (достаточной, чтобы вместить нужное количество данных) и с ним уже работать. Длину не нужно передавать, т.к. сам протокол умеет детектировать ее по механизму кадрирования нижних уровней. ИМХО, ужасное решение🙂 Потому что у меня десятки разных управляющих структур бегают, с разным содержимым и длиной. Контрольную сумму логично располагать где-то в одном конкретном месте для всех структур: и это либо начало кадра, либо самый его хвост. Иначе, чтобы определить положение КС, нам надо "узнать", что это за структура, а лезть в ее поля, не проверив КС - нельзя. У меня "узаконен" формат с CRC в хвосте. Алгоритм приема и отбраковки битых кадров становится универсальным.
  4. Можно ли в C++ как-то красиво описать структуру с гибким положением последнего элемента? Допустим, есть структура struct TxRS485 { Header hdr; u8 byte[N]; u32 crc; } N должно будет стать известно в рантайме, поэтому шаблоны тут вряд ли помогут. Задача простая (и применяемая ну совсем повсюду): из поля ввода юзер-данных считать строчку, запихнуть ее в структуру с определенным паттерном (снабдив заголовками и т.д.), последним элементом должен "приклеиться" CRC-чек. Вроде все просто, однако как будто нет решения, кроме как по старинке "клеить" вручную хедер с данными, а потом к этому всему дописывать контрольную сумму.
  5. У китайцев чуть более прогнозируемая ситуация: если купить становится затруднительно у основного поставщика, то по инерции можно еще полгода точно ехать с помощью других продаванов, в это время подготавливая почву для внедрения новой аппаратной платформы. Другое дело - например, евреи - i.MX6 (по крайней мере, нужные нам SoM) пропали за месяц от слова "навсегда".
  6. У манагеров всегда все просто. Это вечно недовольным инженерам вечно то конденсаторов не хватает, то дорожки не лезут.
  7. К этому и сводится большая часть программирования, несмотря на рядом стоящую помойку под названием стандартная библиотека.
  8. А, понял. Ок. На листы разбивать хорошо - даже поощрительно: название листа отражает то, что на нем находится. У меня тоже есть проекты с десятками листов - очень удобно.
  9. А почему нельзя просто графически схему нормально рисовать, чтобы сразу понятно было, какая россыпь конденсаторов к какой микросхеме относится?
  10. Насколько я помню - itoa ограничивает длину строки 33 и 65 символами для int и long long, соответственно. Буквально вчера отказался от монструозных sprintf(), чтобы ужать first-bootloader под МК на нужный размер.
  11. itoa не возвращает длину строки, или хотя бы указателя на последний записанный элемент в предоставленном буфере. А то получилась полная фигня - передаем буфер - функция возвращает указатель на него же Из-за этого приходится вызывать strlen() каждый раз после itoa() при самостоятельном формировании строк.
  12. Понял, спасибо. Мы же можем написать множество шаблонов функции с одним именем, и в случае, если в параметрах функции можно было бы не указывать какие-то параметры шаблона, компилятор не смог бы разобраться, какую из шаблонных функций инстанцировать.
  13. Почему при введении шаблона функции нужно обязательно присутствие всех параметров шаблона в качестве формальных параметров функции? Т.е. допустимо template<class A, class B> void func(A a, B b) { ... } и недопустимо template<class A, class B> void func(A a) { B b; ... } несмотря на то, что тип B используется в теле функции. Учебники пишут только декларативно, зачастую (как в моем случае) не объясняя причин.
  14. 20 лет назад выпадали, и щас зашел посмотреть - ничего не изменилось...😆
×
×
  • Создать...