Arlleex 172 16 апреля Опубликовано 16 апреля · Жалоба 9 часов назад, _pv сказал: для месье понимающих толк, С вроде как умеет вот так: int get_data_size(){ return 0xF + (rand() & 0xF);} int main(){ struct { uint8_t hdr[8]; uint8_t byte[get_data_size()]; uint32_t crc; } *pkt = (void*)data; pkt->crc = 42; ... Это будет подтягивать динамическое выделение памяти, такое меня уже не устроит. Ух тут сколько всего написали (это хорошо, дискуссия жива🙂) - однако я внесу немножко понятностей. Не важно, что за протокол, важно то, что он пакетный: длина пакета выкорчевывается внеполосной сигнализацией на уровне проводов или (для примитивных байтовых интерфейсов) промежуточный канальный фреймер разбирает поток байтов на кадры/пакеты. Короче говоря, я всегда знаю, сколько данных мне прилетело в пакете. Пакет, как обычно, уже содержит заголовок со всякими типами содержимого для идентификации этого пакета и т.д. Шмалять в сеть пакеты фиксированной длины здесь очень избыточно - это точно красный флаг. Так вот. У меня девайс состоит из множества плат, каскадно соединенных друг с другом порой сильно разными интерфейсами. Пакет данных со входа до самой дальней платы может пройти пару-тройку интерфейсных мостов со своими протокольно-зависимыми особенностями. Каждая "промежуточная" плата имеет механизм проброса "не своих" пакетов данных туда дальше в "паровозик". Чтобы облегчить ПО каждой платы, она детально даже не разбирает "не свои" пакеты, а как есть его пересылает дальше. Где-то закладывать 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 использует соответствующее смещение, полученное на основе аргумента функции } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 69 16 апреля Опубликовано 16 апреля · Жалоба 1 hour ago, Arlleex said: Это будет подтягивать динамическое выделение памяти, такое меня уже не устроит. какое ещё выделение памяти??? это просто объявление указателя, на структуру. и он даже эти несчастные 4 байта под указатель на стэке выделять не будет, а просто посчитает адрес crc. тоже самое что uint8_t *pkt = data; *(uint32_t*) &pkt[crc_offset] = 42; только crc_offset компилятор посчитает в рантайме, исходя из подсунутого в объявление типа структуры размера массива. правда кроме gcc остальные скорее всего на vla внутри структуры ругаться будут. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tonyk_av 41 17 апреля Опубликовано 17 апреля · Жалоба 7 hours ago, Arlleex said: И я хотел, чтобы несколько "костыльно" выглядящее определение структуры с гибким массивом в конце А как идёт приём пакета, неужели побайтно, с прерыванием по приходу очередного байта? Если всё-таки с использованием DMA, то вопрос не понятен, потому что как не крути, но нужно знать максимальный размер пакета, и тогда вопрос с гибким массивом в конце отпадает сам собой. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 17 17 апреля Опубликовано 17 апреля · Жалоба В 17.04.2024 в 07:55, tonyk_av сказал: потому что как не крути, но нужно знать максимальный размер пакета ну допустим, в основном, 90% пакетов - это 10...20 байт. Но есть пакеты до 128 байт. Т.е. максимальный размер 128. Как это поможет? В стандратном C++ нет прямой поддержки добавления переменных после fam в структуре. гибкий массив должен быть последним членом структуры. Но компиляторы могут поддерживать расширения, позволяющие размещать дополнительные члены после fam. Например, расширение GCC "Zero-Length Array" (ZLA) позволяет добавлять дополнительные члены после гибкого массива. struct FlexFrame { Header hdr; int length; u8 data[]; // <- гибкий массив, а значит дальше можно ставить только элементы с атрибутом "гибкого положения" u32 crc; // положение этого члена "гибкое", в зависимости от объема поля data при создании структуры }; использование таких расширений делает код нестандартным и не переносимым между различными компиляторами и платформами. Лучше избегать использования таких расширений и следовать стандарту C++. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 17 17 апреля Опубликовано 17 апреля · Жалоба В 16.04.2024 в 23:55, Arlleex сказал: несколько "костыльно" выглядящее определение структуры с гибким массивом в конце наконец обрело лаконичный вид в C++ структура в с++ это уже костыльно. Зачем в с++ в этом случае структура? В 15.04.2024 в 12:27, Arlleex сказал: мне проще (как всегда, собственно) написать свой небольшой класс. коль вы выехали из деревни, так и бросьте деревенские привычки переехали в с++, так и пишите на с++, пишите классы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 172 17 апреля Опубликовано 17 апреля · Жалоба 8 часов назад, _pv сказал: какое ещё выделение памяти??? это просто объявление указателя, на структуру. и он даже эти несчастные 4 байта под указатель на стэке выделять не будет, а просто посчитает адрес crc. Прошу прощения, не обратил внимания, что указатель. Вы правы. Однако да, мой компайлер обозвал меня представителем европейского модного движения за VLA внутри структуры А так - это почти то, что я хотел🙂 3 часа назад, tonyk_av сказал: А как идёт приём пакета, неужели побайтно, с прерыванием по приходу очередного байта? Если всё-таки с использованием DMA... А разница? В одном проекте - по прерываниям делал, в текущем - DMA принимает. Как это влияет на разбор байтового потока? Цитата ... потому что как не крути, но нужно знать максимальный размер пакета, и тогда вопрос с гибким массивом в конце отпадает сам собой. Зачем его знать? DMA настраивается в кольцевой режим. Задача, обслуживающая канал приема, читает эти байты и отдает его фреймеру SLIP-а, а тот уже на выходе выдает пакеты данных. 32 минуты назад, juvf сказал: структура в с++ это уже костыльно. Зачем в с++ в этом случае структура? Потому что структуру в ее самом девственном виде проще читать и давать ее другим разработчикам, дабы понимали ее формат при поддержке протоколов общения. Когда передается 100500 разных классов, начиненных еще каким-то функционалом - становится вообще-то затруднительно сходу въехать в порядок разложения этой порнографии на байтики в реальном проводе. Структура весьма самодокументируема - сразу понятно, что за чем идет. В классе, в котором помимо данных набито еще 100 строк всяких методов и перегрузок, разобраться тяжелее сходу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tonyk_av 41 17 апреля Опубликовано 17 апреля · Жалоба 2 hours ago, Arlleex said: Зачем его знать? DMA настраивается в кольцевой режим. Можно и так. 3 hours ago, juvf said: Но есть пакеты до 128 байт. Т.е. максимальный размер 128. Как это поможет? Выделяете место под пакет максимальной длины. 128 байт- это не много. Приняли пакет- получили одно прерывание по RTO или IDLE. Дпльше уже разбираетесь с тем, что получили. u8 data[ 128 ]; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 17 17 апреля Опубликовано 17 апреля · Жалоба В 17.04.2024 в 12:58, tonyk_av сказал: 128 байт- это не много. а с какой цифры начинается много? лично для меня и 128 бит много. Нужно массив в 10 байт - выделяем 128. 👍 А потом почему-то памяти для какого нибудь регистратора не хватает или канал передачи в 1 Gb не прокачивает. В 16.04.2024 в 23:55, Arlleex сказал: static u8 RxPacketMemory[1024]; // статически выделенная память для создания "гибких" структур 1024/128 = 8. +хидер, +кс, как итог максимально 7 пакетов в такой буфер влезет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tonyk_av 41 17 апреля Опубликовано 17 апреля · Жалоба 3 hours ago, juvf said: а с какой цифры начинается много? Смотрите процент, которые составляют эти 128 байт от всего ОЗУ. Конечно, можно с самого начала убиваться за каждый бит-байт. Вот когда не будет хватать памяти, тогда и будете думать, что делать: взять кристалл с бОльшим ОЗУ или заняться оптимизацией. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 22 17 апреля Опубликовано 17 апреля · Жалоба 19 minutes ago, tonyk_av said: Конечно, можно с самого начала убиваться за каждый бит-байт. ну вот и тут коснулись традиционной темы "религии", местные служители "Культа Экономии Драгоценного Бита" скоро прибудут ))) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tonyk_av 41 17 апреля Опубликовано 17 апреля · Жалоба 1 hour ago, Forger said: местные служители "Культа Экономии Драгоценного Бита" скоро прибудут ))) Не хотел, чтобы из-за меня срач начался. Вроде, почти процитировал известное изречение уважаемого человека. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 59 17 апреля Опубликовано 17 апреля · Жалоба On 4/17/2024 at 4:54 PM, tonyk_av said: уважаемого человека. Прочитал цитаты из приведенной вами ссылки. Как по мне, так бред полнейший. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tonyk_av 41 17 апреля Опубликовано 17 апреля · Жалоба 5 minutes ago, dimka76 said: Как по мне, так бред полнейший. Или мир сошёл с ума, или кто-то чего-то недопонимает, потому что Quote На январь 2013 года Кнут занимал 37-е место в списке самых цитируемых авторов в области информатики согласно проекту CiteSeer[9]. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 22 17 апреля Опубликовано 17 апреля · Жалоба 17 minutes ago, tonyk_av said: Не хотел, чтобы из-за меня срач начался ... но это уже началось ))) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 172 17 апреля Опубликовано 17 апреля · Жалоба 19 часов назад, dimka76 сказал: Прочитал цитаты из приведенной вами ссылки. Как по мне, так бред полнейший. Именно. Профессоры обычно только и печатали книжки, не имея ни малейшего представления о реальном коде. Туда же книжки Макконела и Мартина - т.е. в жопито😉 Посмотрел цитаты великого цитируемого (с моими скромными комментами): Цитата Цитаты[править] Лучший способ в чём-то разобраться до конца — это попробовать научить этому компьютер. - Вообще-то, ребенка. Опасайтесь багов в приведенном коде; я доказал его корректность, но не запускал. - Крыша поехала? О чем ты, дядь? Математические формулы не могут «принадлежать» кому-либо! Математика принадлежит Богу. - Беды с башкой, очевидно. Я не могу заказать блюдо в ресторане потому, что постоянно смотрю на шрифты в меню. - Проф.деформация. Самая важная вещь в языке программирования — его имя. Язык не будет иметь успеха без хорошего имени. Я недавно придумал очень хорошее имя, теперь осталось изобрести подходящий язык. - Без комментариев. Давайте сменим традиционный подход к построению программ: будем считать, что наша цель — не дать указания компьютеру о ходе его работы, а объяснить человеку, что именно мы хотим добиться от компьютера. - Давайте. 18 часов назад, tonyk_av сказал: Или мир сошёл с ума, или кто-то чего-то недопонимает, потому что За любым столом после 3-й рюмки уже обычно начинаются пространные рассуждения о смысле жизни и трехэтажная философия. Здесь из этого же разряда - просто потому, что "классики" больше никакой нет. За неимением цитируют вот таких вот деятелей. P.S. И кстати, а причем тут щас вообще оптимизация? Я вроде о ней даже не говорил. Нет, ну я конечно стараюсь сразу более менее вменяемо подходить к написанию кода - т.е. там, где можно сразу сделать хорошо - делаю. Другой подход мне уже не приживется, ибо это, как и любовь к говнокодингу - либо навсегда, либо никогда. Сегодня вот на моем смартфоне при открытии камеры вываливалось сообщение "Невозможно подключиться к камере". Б%ять! И никакая перезагрузка не помогает. Калькулятор весит 100 мегов - скоро, видимо, и считать правильно перестанет. И так со всем программным, что меня окружает в нынешнем мире. Вот такая философия с преждевременной оптимизацией и породила покрасчиков кнопок, которым похрен на юзеров, которым для моргания лымпочкой нужна ардуина на распбери пай, не меньше. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться