PDA

Просмотр полной версии : struct alignment в макросах



andemeno
28.10.2021, 10:53
Поддерживает ли компилятор макросов Конфигуратора СП3хх возможность задавать выравнивание для структур?
Если да, то как? Может быть есть информация какой компилятор используется в Конфигураторе?

Вариант
#pragma pack(arg) не даёт эффекта.

kondor3000
28.10.2021, 11:02
Поддерживает ли компилятор макросов Конфигуратора СП3хх возможность задавать выравнивание для структур?
Если да, то как? Может быть есть информация какой компилятор используется в Конфигураторе?

Вариант
#pragma pack(arg) не даёт эффекта.

Просто интересно, а как вы структуру передаёте в панель?
Вообще то структуры используются в ПЛК , а в панель вам надо передать только готовые цифры для отображения, в нужные регистры с учётом выравнивания.
Максимум, что можно сделать, это передать в панель массив переменных одного типа, упакованные в String, опять же с учётом выравнивания.

andemeno
28.10.2021, 11:10
Я считываю телеметрию из ПЛК в панель и хочу записать её в структуру.
Поскольку готовые цифры для отображения нужно правильно интерпретировать.

kondor3000
28.10.2021, 11:26
Я считываю телеметрию из ПЛК в панель и хочу записать её в структуру.
Поскольку готовые цифры для отображения нужно правильно интерпретировать.

Читайте выше, ещё раз. Вы не сможете передать в панель структуру.

Евгений Кислов
28.10.2021, 11:31
Поддерживает ли компилятор макросов Конфигуратора СП3хх возможность задавать выравнивание для структур?
Если да, то как? Может быть есть информация какой компилятор используется в Конфигураторе?

Вариант
#pragma pack(arg) не даёт эффекта.



typedef struct

{
__packed char member_1;
__packed DWORD member_2;
} str_name;



Так будет работать (экземпляр структуры займет 5 байт).

Но это не сработает, например, для поля типа float.

andemeno
28.10.2021, 11:40
Я не передаю в панель структуру. Я в панель читаю массив регистров из ПЛК и хочу интерпретировать этот кусок памяти как структуру

andemeno
28.10.2021, 13:57
typedef struct

{
__packed char member_1;
__packed DWORD member_2;
} str_name;



Так будет работать (экземпляр структуры займет 5 байт).

Но это не сработает, например, для поля типа float.

Очень жаль.... Но спасибо за ответ.

В силе остаётся вопрос про компилятор, используемый конфигуратором.

kondor3000
29.10.2021, 08:15
Ну так и отобрази этот кусок памяти как структуру эквивалентную размещению этого массива регистров.
Огорчить может только отсутствие ссылок в функциях (c89)

Вообще то, изначальный вопрос был про компилятор в панели и про возможность Задавать Компилятором, выравнивание структуры в панели.
В общем случае, структура может быть набита разными типами переменных в произвольном порядке. Отсюда и вопросы к ТС.

ЗЫ: Так и есть, на 2 стр. автор привёл в пример структуру из двух типов, WORD и REAL. И как ожидалось с выравниванием несвязуха.

andemeno
29.10.2021, 11:06
Ну так и отобрази этот кусок памяти как структуру эквивалентную размещению этого массива регистров.

Представьте, что телеметрия от ПЛК состоит из 3 регистров.
Я читаю эти регистры в массив:


const int plctm_regs_count = 3;
const WORD plctm_addr = 0;
static WORD plctm_regs[plctm_regs_count];
Reads(PLC, slave_id, MODBUS_RTU_REGS_3X, plctm_addr, plctm_regs_count, &plctm_regs);


Дальше я хочу скопировать этот массив в следующую структуру:


typedef struct plctm_telemetry_ {
WORD reg;
float real;
} plctm_telemetry_t;
plc_telemetry_t plctm;

memcpy(&plctm, plctm_regs, sizeof(plctm_regs));



Но этот код не работает так, как ожидается, потому что для компилятора структура выглядит так:


typedef struct plctm_telemetry_ {
WORD reg;
WORD reg_stub; // компилятор добавил это для 4-ехбайтного выравнивания
float real;
} plctm_telemetry_t;

и при копировании второй регистр телеметрии попадёт в reg_sub

А задать выравнивание для структуры, как выяснилось, возможности нет

petera
29.10.2021, 12:26
Контроллер не ОВЕН?
Потому, что кодесис выравнял бы автоматом и сделал бы для real четный адрес
https://owen.ru/forum/attachment.php?attachmentid=12345&d=1395648726

И читать в панели пришлось бы не 3, а 4 регистра и все попало бы куда нужно.

kondor3000
29.10.2021, 12:54
Представьте, что телеметрия от ПЛК состоит из 3 регистров.
и при копировании второй регистр телеметрии попадёт в reg_sub

Вот как раз про это я и намекал. Что вам мешает переставить местами WORD reg; float real;
Будет float real; WORD reg; ваши 3 регистра, а добавленный WORD reg_stub просто отбрасывать, или тупо добавить ещё один WORD и сделать структуру из 4 регистров.

andemeno
29.10.2021, 14:51
Контроллер не ОВЕН?
Потому, что кодесис выравнял бы автоматом и сделал бы для real четный адрес
https://owen.ru/forum/attachment.php?attachmentid=12345&d=1395648726

И читать в панели пришлось бы не 3, а 4 регистра и все попало бы куда нужно.

Нет, не ОВЕН

andemeno
29.10.2021, 14:53
Что вам мешает переставить местами WORD reg; float real;


Мешает другой соисполнитель, который не захочет это делать, потому что все протоколы уже согласованы на верхнем уровне...

andemeno
30.10.2021, 17:23
Сразу. У автора исходных данных (в том "не Овен" ПЛК) лажовая архитектура данных.
Архитектура такая какая есть. И есть задача написать ПО для панели. И альтернатив у меня нет.

Если уж на то пошло, то с точки зрения разработчика ПО с графическим интерфейсом, вместо такого рода панели лучше выбрать решение в таком же форм-факторе, но на базе например Astra Linux. Писать ПО для этой платформы в разы быстрее и вносить изменения проще. А когда я пытаюсь реализовать пожелания заказчика в Конфигураторе, то кажется что он не помогает мне, а сопротивляется....

Мой изначальный вопрос был не про то как мне читать телеметрию, и не то как изменить её структуру, а про возможность указать компилятору, что поля структуры надо выравнивать не по 4-ем, а по 2-ум или 1-му байту.
И ответ был получен - в большинстве случаев никак.

kondor3000
30.10.2021, 17:36
Валенок, я ещё вчера предложил два варианта, в том числе сделать структуру из 4 регистров и один откинуть, на что был ответ: НИЗЯЯЯЯ!
Ну на нельзя и спроса нет....

kondor3000
31.10.2021, 15:54
Валенок, сообщение #12.
Не надо ничего удалять, тут не борьба за авторство. Может у ТС изменятся обстоятельства и ваш код пригодится или ещё кому то).

andemeno
31.10.2021, 16:28
Так я и сказал - есть лажовая аритектура данных.
А критерий лажовости - это отсутствие в телеметрии ПЛК неиспользуемых регистров, которые воткнуты туда только для выравнивания по 4-ех байтовому адресу?


Лажовость архитектур данных не является чем-то необычным.
Именно. Почему тогда панель считает себя центром мира и готова работать только с данными, выровненными по 4-ем байтам?


Ну это ж Ваша проблема что не убедили до принятия ключевых решений
Моим мнением не интересовались. А даже если бы интересовались - узнать заранее из документации на Конфигуратор о том, что выравнивание для полей структур не поддерживается, нельзя. Там об этом ни слова.


Дык ничего и не поняли. Ширше смотрите, ширше - если б возможность и была то ничем бы не помогло ибо Вариант 1, но с Вариантом 2 (см.выше) и любое действие с полем флоата (за исключением, возможно, просто копирования) привело бы к вышеуказанным "воплям в ночи". Т.е. все равно придете к "как мне читать телеметрию, и ... изменить её структуру". Или думаете Вы 1-ый с такого рода проблемой ? ))) Приведён был простейший (имхо) способ решения, причем таки без изменения структуры - или тоже не поняли ?
Мне кажется это вы меня не поняли - о том что можно переставлять поля структур и читать с другим смещением мне известно. Я ищу нормальное решение, а не костыли. Но как выяснилось (#5) его нет.


Все прогерство это борьба с чем-то.
Но не с инструментом разработки!

andemeno
01.11.2021, 13:59
Вы хоть думаете что говорите ? Ну поддерживалось бы - и что ? Получили бы {ваш_ворд, неявный_ворд, флоат}.

Да ну нет же! Получилось бы {мой ворд; мой флоат;}! И все, и больше ничего неявного и ненужного. Но сделать так нельзя, можно только с неявным вордом

keysansa
01.11.2021, 16:45
Как 2 пальца. Не надо тока левыми структурами трясти как указано выше.

Для этого протокол надо указать.

keysansa
01.11.2021, 16:52
Ну так и отобрази этот кусок памяти как структуру эквивалентную размещению этого массива регистров.
Огорчить может только отсутствие ссылок в функциях (c89)

Отображение - это не передача структуры. Это обображение - передача-консолидация. Да, сейчас почти вся передаваемая информация идет по последовательному порту. Тут говорить, что "нельзя передать что-то сложнее бита" - кощунство )

andemeno
02.11.2021, 07:17
Штатно вашу структуру с адреса кратному 2 не разместите. А с адресом кратным разрядности камня "ваш_флоат" заляжет по нечетному слову
Мне не нужно размещать её по адресу кратному 2. Мне нужно чтобы каждое поле структуры занимало размер в памяти, кратный 2-ум.

keysansa
02.11.2021, 23:18
Тут про выравнивание

Прошу прощения, тему почистили, у меня нет доказательств.