TOG 0 10 ноября, 2023 Опубликовано 10 ноября, 2023 · Жалоба Товарищи, есть в программе структура типа такой: typedef struct { uint8_t Cnt; float Len; float Depth; uint8_t Roll; float Pitch; uint8_t Hours; uint8_t Minutes; uint8_t Day; uint8_t Month; uint8_t Year; } LOG_Type; Если посчитать, то получается размер 19 байт. Но если использовать sizeof(LOG_Type), то получается 28 байт. Посмотрел в памяти и увидел, что компилятор все float'ы выровнял по границе 4 байт. А мне эту структуру надо отправлять по SPI побайтно и все эти лишние нули мне совсем не нужны. Как быть ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 10 ноября, 2023 Опубликовано 10 ноября, 2023 · Жалоба 4 minutes ago, TOG said: Как быть ? Почитайте про "__attribute__((packed))", пример: struct __attribute__((packed)) T_UINT32 { uint32_t v; }; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 183 10 ноября, 2023 Опубликовано 10 ноября, 2023 · Жалоба Ну, поехали🙂 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 10 ноября, 2023 Опубликовано 10 ноября, 2023 · Жалоба 2 minutes ago, Arlleex said: Ну, поехали🙂 да пускай чуток по-страдает, все через это проходят )) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 10 ноября, 2023 Опубликовано 10 ноября, 2023 · Жалоба 32 минуты назад, TOG сказал: А мне эту структуру надо отправлять по SPI побайтно и все эти лишние нули мне совсем не нужны. Как быть ? Т.е. - за 17 лет пребывания на этом форуме вы не видели здесь не одной темы про выравнивание и упаковку? Коих только за последнее время было несколько. И учебник по си не открывали ни разу? И не читали в нём ничего про выравнивание и про структуры вообще? ЗЫ: В таком случае уже ничего не сделаешь.... 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
TOG 0 10 ноября, 2023 Опубликовано 10 ноября, 2023 · Жалоба On 11/10/2023 at 12:53 PM, Forger said: Почитайте про "__attribute__((packed))", пример: Сделал. Спасибо, Forger ! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
unix 2 28 декабря, 2023 Опубликовано 28 декабря, 2023 · Жалоба Также, если указатель на такую структуру объявлять, тоже надо указывать packed Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
johnshadow 1 29 декабря, 2023 Опубликовано 29 декабря, 2023 · Жалоба 12 часов назад, unix сказал: Также, если указатель на такую структуру объявлять, тоже надо указывать packed Это как и зачем? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 29 декабря, 2023 Опубликовано 29 декабря, 2023 · Жалоба 13 hours ago, unix said: Также, если указатель на такую структуру объявлять, тоже надо указывать packed нет, это бессмысленно, т.к. компилятор и так прекрасно знает с какой структурой работает, а если не знает, то просто будет ошибка компиляции 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
firstvald 24 29 декабря, 2023 Опубликовано 29 декабря, 2023 · Жалоба On 11/10/2023 at 11:17 AM, Arlleex said: Ну, поехали🙂 On 11/10/2023 at 10:48 AM, TOG said: Товарищи, есть в программе структура типа такой: typedef struct { uint8_t Cnt; float Len; float Depth; uint8_t Roll; float Pitch; uint8_t Hours; uint8_t Minutes; uint8_t Day; uint8_t Month; uint8_t Year; } LOG_Type; Если посчитать, то получается размер 19 байт. Но если использовать sizeof(LOG_Type), то получается 28 байт. Посмотрел в памяти и увидел, что компилятор все float'ы выровнял по границе 4 байт. А мне эту структуру надо отправлять по SPI побайтно и все эти лишние нули мне совсем не нужны. Как быть ? уже сломано копий немеряно. будут советы по атрибуту packed. я делаю так. разбираем структуру руками поэлементно. если есть что- то длиннее char, затаскиваю в специально созданный union в котором будет 2 short int 1 float и 4 char и оттуда каждый элемент побайтно вытаскиваем. громоздко, но вы никогда не будете размышлять: что и куда у вас попадет. как разновидность, можно указателю на char присваивать указатель на очередной длинный объект и по элементу вытаскивать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 29 декабря, 2023 Опубликовано 29 декабря, 2023 · Жалоба 37 minutes ago, firstvald said: я делаю так. разбираем структуру руками поэлементно порой это невозможно и порядок полей определен извне кем-то и приходится работать с тем что есть Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
firstvald 24 29 декабря, 2023 Опубликовано 29 декабря, 2023 · Жалоба а вот и наоборот. как раз это снимает элемент случайности. а метод выравнивания полей и объединение с массивом как раз ужас ужас который дает прикурить всем. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 29 декабря, 2023 Опубликовано 29 декабря, 2023 · Жалоба 1 час назад, firstvald сказал: разбираем структуру руками поэлементно. если есть что- то длиннее char, затаскиваю в специально созданный union в котором будет 2 short int 1 float и 4 char и оттуда каждый элемент побайтно вытаскиваем. громоздко, но вы никогда не будете размышлять: что и куда у вас попадет. Ну да - в таком буреломе на пустом месте, больше размышлять придётся ища баги. Не до попаданий будет. И ещё не забывая всё это безобразие перепахивать по новой при малейшем изменении структуры. Зачем ваять лисапед с треугольными колёсами, вместо того чтобы воспользоваться штатными возможностями компилятора?? Вы и 32-разрядные числа тоже поразрядно складываете? Снимая элемент случайности. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 10 29 декабря, 2023 Опубликовано 29 декабря, 2023 · Жалоба 6 минут назад, jcxz сказал: ... это безобразие перепахивать по новой при малейшем изменении структуры. Этого не избежать когда определён "сетевой порядок следования" байт, не совпадающий с порядком в МК. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 29 декабря, 2023 Опубликовано 29 декабря, 2023 · Жалоба 3 минуты назад, Палыч сказал: Этого не избежать когда определён "сетевой порядок следования" байт, не совпадающий с порядком в МК. А при чём тут...? Вроде разговор был про "выравнивание членов структуры", а не про "порядок байт". Да и со сменой порядка байт тоже можно сделать нормально, а не через одно место: Во первых - можно такие типы данных определить как объекты классов. И перегрузить их операторы присвоения или операторы приведения типа к стандартным типам. В которых и сделать смену порядка байт. Во-вторых - например в ARM имеются специальные команды изменения порядка байт в слове. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться