реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Структуры данных
inventor
сообщение Jan 18 2018, 10:02
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 524
Регистрация: 25-12-08
Из: Москва
Пользователь №: 42 748



Подскажите мне вот такую вещь
я хочу реализовать какой то хранитель или тип для данных разного размера
пример: по COM порту приходит пачка данных размером от
10 до 1000 байт.
я хочу положить их в свою структуру данных
данные разного размера
в какой то другом потоке я их забираю по указателю
если это что то типа связного списка или очередеи
то я вижу что там данные одного размера
чета я не понимаю, как мне сделать
чтобы хранить разный размер.
Go to the top of the page
 
+Quote Post
ArtemKAD
сообщение Jan 18 2018, 10:25
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 508
Регистрация: 26-06-06
Из: Киев
Пользователь №: 18 364



Примерно так:
Код
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;
Go to the top of the page
 
+Quote Post
Unfog
сообщение Jan 18 2018, 17:28
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 40
Регистрация: 20-05-12
Из: Санкт-Петербург
Пользователь №: 71 932



Не очень понял вопрос.
Нужно как то хранить посылки разной длины?
Список списков подойдет?
Go to the top of the page
 
+Quote Post
Baser
сообщение Jan 18 2018, 17:51
Сообщение #4


Просто Che
*****

Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881



Цитата(inventor @ Jan 18 2018, 12:02) *
я хочу реализовать какой то хранитель или тип для данных разного размера
пример: по COM порту приходит пачка данных размером от
10 до 1000 байт.
я хочу положить их в свою структуру данных
данные разного размера

Если вы хотите статический буфер, то придется выделять память под максимальный размер данных.
Далее применять union, как расписал ArtemKAD

Если же вы хотите каждый раз иметь буфер различной длины по размеру пришедшего пакета,
то применяйте динамическое выделение памяти из heap, при помоши malloc/free.
В первом слове буфера храните длину данных,
указатель на буфер передавайте в другой поток для чтения. Семафоры не забудьте.
Go to the top of the page
 
+Quote Post
inventor
сообщение Jan 19 2018, 07:42
Сообщение #5


Знающий
****

Группа: Свой
Сообщений: 524
Регистрация: 25-12-08
Из: Москва
Пользователь №: 42 748



Цитата(Baser @ Jan 18 2018, 20:51) *
Если вы хотите статический буфер, то придется выделять память под максимальный размер данных.
Далее применять union, как расписал ArtemKAD

Если же вы хотите каждый раз иметь буфер различной длины по размеру пришедшего пакета,
то применяйте динамическое выделение памяти из heap, при помоши malloc/free.
В первом слове буфера храните длину данных,
указатель на буфер передавайте в другой поток для чтения. Семафоры не забудьте.


похоже придется сделать кольцевой буфер на максимальное число
с malloc/free мне не нравится-так как засегментируется все за час
при интенсивном использовании
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jan 19 2018, 10:14
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(inventor @ Jan 19 2018, 10:42) *
кольцевой буфер на максимальное число

Зачем кольцевой? Почему не линейный?
Приняли посылку разной длины - разобрали, начиная с начала (сохраняя поля в структуру), поставили указатель на начало, начали опять принимать.
Если нужно принимать во время разбора - можно принимать в другой буфер, все равно в обоих случаях размер памяти не меняется.
Протокол обмена стандартный или самопал?



--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
ArtemKAD
сообщение Jan 19 2018, 10:57
Сообщение #7


Профессионал
*****

Группа: Свой
Сообщений: 1 508
Регистрация: 26-06-06
Из: Киев
Пользователь №: 18 364



Цитата
Зачем кольцевой? Почему не линейный?
Приняли посылку разной длины - разобрали,

Пока разбираешь, пару-тройку байт из потока теряешь. Что-бы не терять за время разбора кольцевой буфер и нужен.
Цитата
можно принимать в другой буфер, все равно в обоих случаях размер памяти не меняется.

Меняется. Кольцевой буфер обычно гораздо меньше основного.
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Jan 20 2018, 09:34
Сообщение #8


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Тут уже упоминали, что для передачи данных правильно применять сериализацию данных вместо простого копирования принятых байтов в union?


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
ArtemKAD
сообщение Jan 20 2018, 13:04
Сообщение #9


Профессионал
*****

Группа: Свой
Сообщений: 1 508
Регистрация: 26-06-06
Из: Киев
Пользователь №: 18 364



Цитата
Тут уже упоминали, что для передачи данных правильно применять сериализацию данных вместо простого копирования принятых байтов в union?

Например? Особенно по части приема...
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Jan 20 2018, 17:57
Сообщение #10


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Ну имеется ввиду, что существуют разные архитектуры процессоров. С разными требованиями по выравниванию данных. И даже с разным расположением байт в многобайтовых интах.
Таким образом описанная абсолютно одинаково на языке Си структура будет представлена в памяти совершенно по-разному!
Если обе системы и для приёма и для передачи будут применять простое копирование этого региона памяти в линию передачи данных то при неудачном стечении обстоятельств вы прините совсем не то что вам отправляли.

Например 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/


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
ArtemKAD
сообщение Jan 20 2018, 21:12
Сообщение #11


Профессионал
*****

Группа: Свой
Сообщений: 1 508
Регистрация: 26-06-06
Из: Киев
Пользователь №: 18 364



Цитата(sigmaN @ Jan 20 2018, 19:57) *
Ну имеется ввиду, что существуют разные архитектуры процессоров. С разными требованиями по выравниванию данных. И даже с разным расположением байт в многобайтовых интах.
Таким образом описанная абсолютно одинаково на языке Си структура будет представлена в памяти совершенно по-разному!
Если обе системы и для приёма и для передачи будут применять простое копирование этого региона памяти в линию передачи данных то при неудачном стечении обстоятельств вы прините совсем не то что вам отправляли.

Например STM8 big endian - вообще редкость, скажем так.
На AVR требований по выравниванию нет и все поля структуры лягут в память по порядку без дыр.
На STM32 же между uint8 и uint32 в структуре будет padding т.е. дыра.

#pragma pack(1)

или __packed для описания структуры
вполне спасет от возможных дырок и будет гораздо проще чем заниматься сериализацией.

Цитата(sigmaN @ Jan 20 2018, 19:57) *
И вот что-то нашел
https://habrahabr.ru/company/xakep/blog/258959/

По-моему в этом "что-то" как раз написано почему сериализацию лучше не делать.

По-моему весьма однозначно:
Цитата
WARNING

Если дорожишь эффективностью при передаче данных, то отдавай предпочтение бинарным протоколам (если, конечно, у тебя есть выбор).
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Jan 21 2018, 11:58
Сообщение #12


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



#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.


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Jan 21 2018, 14:04
Сообщение #13


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Цитата(sigmaN @ Jan 21 2018, 14:58) *
#pragma pack(1) вроде как моветон, на сколько я знаю.


Передавать набор упакованных структур (и принимать такой же набор) - вполне себе рабочий метод организации обмена. Просто, быстро и читается довольно легко.
Вот дальше работать с этими структурами - моветон, да (хотя, если дороже перекладывать туда-сюда - почему бы и нет?).


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
ArtemKAD
сообщение Jan 22 2018, 00:01
Сообщение #14


Профессионал
*****

Группа: Свой
Сообщений: 1 508
Регистрация: 26-06-06
Из: Киев
Пользователь №: 18 364



Цитата(sigmaN @ Jan 21 2018, 13:58) *
#pragma pack(1) вроде как моветон, на сколько я знаю.

Плохо знаешь. Моветон использовать его для рабочих переменных из-за оверхеда в коде при работе на 32 разрядных платформах. А там где надо что-бы было как написано, а не как оптимизатор посчитал нужным, там ему самое место.


Цитата(sigmaN @ Jan 21 2018, 13:58) *
Я приведенные ссылки полностью не читал, но в моем понимании бинарность протокола не исключает нормальной сериализации структур и приведения протокола к стандартному порядку байт... Передавать всё в JSON я не предлагал на маленьком контроллере )

Ну если не JSON, то ваять придется нечто свое. А значит вставлять дополнительные поля в передаваемые данные с метаинформацией и разбирать метаинформацию на приемном конце и все это писать своими руками. И что это поменяет кроме оверхеда в передаваемых данных, оверхеда в коде и оверхеда во времени обработки? Теперь надо особо обрабатывать не только на отдельных платформах, а обрабатывать метаинформацию в рантайме на всех платформах.



Цитата(sigmaN @ Jan 21 2018, 13:58) *
По идее вы должны вместо memcpy() реализовать некий метод serialize() который структуру преобразует в поток байтов в соответствии с принятым стандартом(serialization format). На приёмнике обратное преобразование. И никто не запрещает сделать этот протокол бинарным. Передача чего-то вроде JSON или строк - всего лишь частный случай serialization format.


По-моему, у топикстартера как раз работа и состоит в том, что приходит некий поток данных который надо разобрать. Т.е. вашим языком - у него вопрос по реализации самой "deserialize()"
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 06:29
Рейтинг@Mail.ru


Страница сгенерированна за 0.01484 секунд с 7
ELECTRONIX ©2004-2016