inventor 0 18 января, 2018 Опубликовано 18 января, 2018 · Жалоба Подскажите мне вот такую вещь я хочу реализовать какой то хранитель или тип для данных разного размера пример: по COM порту приходит пачка данных размером от 10 до 1000 байт. я хочу положить их в свою структуру данных данные разного размера в какой то другом потоке я их забираю по указателю если это что то типа связного списка или очередеи то я вижу что там данные одного размера чета я не понимаю, как мне сделать чтобы хранить разный размер. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
artemkad 53 18 января, 2018 Опубликовано 18 января, 2018 · Жалоба Примерно так: typedef union //rx_tx_packet_union { unsigned char buffer[SIZE_RX_TX_BUFFER]; /// принимаемые короткие short_rx_input sh_rx; // короткая посылка приема tag_packet_check_struct tag_check; tag_packet_prog_struct tag_prog; // tag_packet_password_struct tag_password; /// принимаемые длинные long_rx_input lg_rx; // длинная посылка приема /// передаваемые короткие short_tx_output sh_tx; // короткая посылка передачи master_packet_struct master_send; // /// передаваемые длинные // long_tx_output lg_tx; // длинная посылка передачи }rx_tx_packet_union; Ну и пример парочки структур: typedef struct // short_rx_input { unsigned char data[2][3]; // unsigned char parity[2][3]; // }short_rx_input; typedef struct //tag_packet_check_struct { unsigned long rnd :8; // unsigned long low_bat :1; // unsigned long button :1; // unsigned long cnt :22; // unsigned int signature; // }tag_packet_check_struct; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Unfog 0 18 января, 2018 Опубликовано 18 января, 2018 · Жалоба Не очень понял вопрос. Нужно как то хранить посылки разной длины? Список списков подойдет? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Baser 5 18 января, 2018 Опубликовано 18 января, 2018 · Жалоба я хочу реализовать какой то хранитель или тип для данных разного размера пример: по COM порту приходит пачка данных размером от 10 до 1000 байт. я хочу положить их в свою структуру данных данные разного размера Если вы хотите статический буфер, то придется выделять память под максимальный размер данных. Далее применять union, как расписал ArtemKAD Если же вы хотите каждый раз иметь буфер различной длины по размеру пришедшего пакета, то применяйте динамическое выделение памяти из heap, при помоши malloc/free. В первом слове буфера храните длину данных, указатель на буфер передавайте в другой поток для чтения. Семафоры не забудьте. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
inventor 0 19 января, 2018 Опубликовано 19 января, 2018 · Жалоба Если вы хотите статический буфер, то придется выделять память под максимальный размер данных. Далее применять union, как расписал ArtemKAD Если же вы хотите каждый раз иметь буфер различной длины по размеру пришедшего пакета, то применяйте динамическое выделение памяти из heap, при помоши malloc/free. В первом слове буфера храните длину данных, указатель на буфер передавайте в другой поток для чтения. Семафоры не забудьте. похоже придется сделать кольцевой буфер на максимальное число с malloc/free мне не нравится-так как засегментируется все за час при интенсивном использовании Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DogPawlowa 0 19 января, 2018 Опубликовано 19 января, 2018 · Жалоба кольцевой буфер на максимальное число Зачем кольцевой? Почему не линейный? Приняли посылку разной длины - разобрали, начиная с начала (сохраняя поля в структуру), поставили указатель на начало, начали опять принимать. Если нужно принимать во время разбора - можно принимать в другой буфер, все равно в обоих случаях размер памяти не меняется. Протокол обмена стандартный или самопал? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
artemkad 53 19 января, 2018 Опубликовано 19 января, 2018 · Жалоба Зачем кольцевой? Почему не линейный? Приняли посылку разной длины - разобрали, Пока разбираешь, пару-тройку байт из потока теряешь. Что-бы не терять за время разбора кольцевой буфер и нужен. можно принимать в другой буфер, все равно в обоих случаях размер памяти не меняется. Меняется. Кольцевой буфер обычно гораздо меньше основного. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sigmaN 0 20 января, 2018 Опубликовано 20 января, 2018 · Жалоба Тут уже упоминали, что для передачи данных правильно применять сериализацию данных вместо простого копирования принятых байтов в union? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
artemkad 53 20 января, 2018 Опубликовано 20 января, 2018 · Жалоба Тут уже упоминали, что для передачи данных правильно применять сериализацию данных вместо простого копирования принятых байтов в union? Например? Особенно по части приема... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sigmaN 0 20 января, 2018 Опубликовано 20 января, 2018 · Жалоба Ну имеется ввиду, что существуют разные архитектуры процессоров. С разными требованиями по выравниванию данных. И даже с разным расположением байт в многобайтовых интах. Таким образом описанная абсолютно одинаково на языке Си структура будет представлена в памяти совершенно по-разному! Если обе системы и для приёма и для передачи будут применять простое копирование этого региона памяти в линию передачи данных то при неудачном стечении обстоятельств вы прините совсем не то что вам отправляли. Например STM8 big endian - вообще редкость, скажем так. На AVR требований по выравниванию нет и все поля структуры лягут в память по порядку без дыр. На STM32 же между uint8 и uint32 в структуре будет padding т.е. дыра. Всё это не важно пока и приёмник и передатчик работают на одном процессоре(точнее с одинаковым порядком байт и требованиями по выравниванию). Кажется в этой статье можно найти что-то полезное на эту тему. https://thatskriptkid.wordpress.com/2015/01...80%D1%83%D0%BA/ И вот что-то нашел https://habrahabr.ru/company/xakep/blog/258959/ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
artemkad 53 20 января, 2018 Опубликовано 20 января, 2018 · Жалоба Ну имеется ввиду, что существуют разные архитектуры процессоров. С разными требованиями по выравниванию данных. И даже с разным расположением байт в многобайтовых интах. Таким образом описанная абсолютно одинаково на языке Си структура будет представлена в памяти совершенно по-разному! Если обе системы и для приёма и для передачи будут применять простое копирование этого региона памяти в линию передачи данных то при неудачном стечении обстоятельств вы прините совсем не то что вам отправляли. Например STM8 big endian - вообще редкость, скажем так. На AVR требований по выравниванию нет и все поля структуры лягут в память по порядку без дыр. На STM32 же между uint8 и uint32 в структуре будет padding т.е. дыра. #pragma pack(1) или __packed для описания структуры вполне спасет от возможных дырок и будет гораздо проще чем заниматься сериализацией. И вот что-то нашел https://habrahabr.ru/company/xakep/blog/258959/ По-моему в этом "что-то" как раз написано почему сериализацию лучше не делать. По-моему весьма однозначно: WARNING Если дорожишь эффективностью при передаче данных, то отдавай предпочтение бинарным протоколам (если, конечно, у тебя есть выбор). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sigmaN 0 21 января, 2018 Опубликовано 21 января, 2018 · Жалоба #pragma pack(1) вроде как моветон, на сколько я знаю. Я приведенные ссылки полностью не читал, но в моем понимании бинарность протокола не исключает нормальной сериализации структур и приведения протокола к стандартному порядку байт... Передавать всё в JSON я не предлагал на маленьком контроллере ) In computer science, in the context of data storage, serialization is the process of translating data structures or object state into a format that can be stored (for example, in a file or memory buffer) or transmitted (for example, across a network connection link) and reconstructed later (possibly in a different computer environment).[1] When the resulting series of bits is reread according to the serialization format, it can be used to create a semantically identical clone of the original object. В предложенном выше в топике подходе, для сериализации тупо используется memcpy из структуры в буфер->линия передачи данных->буфер->memcpy в union. Со всеми вытекающими последствиями о которых я говорил ранее. По идее вы должны вместо memcpy() реализовать некий метод serialize() который структуру преобразует в поток байтов в соответствии с принятым стандартом(serialization format). На приёмнике обратное преобразование. И никто не запрещает сделать этот протокол бинарным. Передача чего-то вроде JSON или строк - всего лишь частный случай serialization format. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 5 21 января, 2018 Опубликовано 21 января, 2018 · Жалоба #pragma pack(1) вроде как моветон, на сколько я знаю. Передавать набор упакованных структур (и принимать такой же набор) - вполне себе рабочий метод организации обмена. Просто, быстро и читается довольно легко. Вот дальше работать с этими структурами - моветон, да (хотя, если дороже перекладывать туда-сюда - почему бы и нет?). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
artemkad 53 22 января, 2018 Опубликовано 22 января, 2018 · Жалоба #pragma pack(1) вроде как моветон, на сколько я знаю. Плохо знаешь. Моветон использовать его для рабочих переменных из-за оверхеда в коде при работе на 32 разрядных платформах. А там где надо что-бы было как написано, а не как оптимизатор посчитал нужным, там ему самое место. Я приведенные ссылки полностью не читал, но в моем понимании бинарность протокола не исключает нормальной сериализации структур и приведения протокола к стандартному порядку байт... Передавать всё в JSON я не предлагал на маленьком контроллере ) Ну если не JSON, то ваять придется нечто свое. А значит вставлять дополнительные поля в передаваемые данные с метаинформацией и разбирать метаинформацию на приемном конце и все это писать своими руками. И что это поменяет кроме оверхеда в передаваемых данных, оверхеда в коде и оверхеда во времени обработки? Теперь надо особо обрабатывать не только на отдельных платформах, а обрабатывать метаинформацию в рантайме на всех платформах. По идее вы должны вместо memcpy() реализовать некий метод serialize() который структуру преобразует в поток байтов в соответствии с принятым стандартом(serialization format). На приёмнике обратное преобразование. И никто не запрещает сделать этот протокол бинарным. Передача чего-то вроде JSON или строк - всего лишь частный случай serialization format. По-моему, у топикстартера как раз работа и состоит в том, что приходит некий поток данных который надо разобрать. Т.е. вашим языком - у него вопрос по реализации самой "deserialize()" Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться