PDA

Просмотр полной версии : Вопрос про ST от новичка (Codesys 3.5)



disconnect555
02.02.2023, 13:10
Добрый день.

Допустим у меня есть две программы. Main и Prg1

Первый вариант:
PROGRAM MAIN
VAR
START:BOOL:=True;
END_VAR

IF START THEN
PRG1();
START := FALSE;
END_IF


Второй вариант:
PROGRAM MAIN
VAR
END_VAR
PRG1();


PROGRAM PRG1
VAR
START:BOOL:=True;
//какие-то переменные
END_VAR


IF NOT START THEN RETURN; END_IF
START := FALSE;
//какой-то код....



Вопрос. Первый вариант лучше второго в плане экономии памяти, быстродействии или чего-то ещё? Или все едино?

Cs-Cs
02.02.2023, 16:13
В общем случае едино.
И лучше делать Start наобррот: FALSE, а потом писать что-то типа
IF (NOT(Start)) THEN
Start := TRUE;
.....
END_IF

Емельянов Кирилл
03.02.2023, 00:36
Тогда переменная должна называться notStart

Cs-Cs
03.02.2023, 08:50
Емельянов Кирилл Почему? Она ж при старте ставится в TRUE - вот, раз TRUE - значит старт успешен.
А вообще это прям в CodeSys FAQ есть (вот тут: https://www.owen.ru/forum/showthread.php?t=28167&p=304642&viewfull=1#post304642), так что троллинг очень толстый.

saii
03.02.2023, 13:29
В общем случае едино.
И лучше делать Start наобррот: FALSE, а потом писать что-то типа
IF (NOT(Start)) THEN
Start := TRUE;
.....
END_IF

Как раз лучше начинать с TRUE, зачем Вам на каждом цикле делать операцию NOT?
И назвать ее можно что-то вида FirstCycle.

Cs-Cs
03.02.2023, 13:32
Как раз лучше начинать с TRUE, зачем Вам на каждом цикле делать операцию NOT?
Ну так это не микроконтроллер, где лишняя операция сожрёт несколько тактов.
И чего-то, если это не Z80, то мне помнится что в большинстве ассемблеров есть JZ и JNZ.
А ещё можно записать IF (Start = FALSE). Сколько тогда операций будет? =))

saii
03.02.2023, 14:30
Проверил на Codesys 2.3 трансляцию ST в IL :D

IF Start THEN...
преобразуется в


LDN Start
JMPC Else1



IF NOT Start THEN...
преобразуется в


LD Start
JMPC Else1



IF Start = FALSE THEN...
преобразуется в


LD Start
EQ FALSE
NOT
JMPC Else1


Т.е. если стоимость операций LD и LDN не отличается, то варианты
IF Start THEN и
IF NOT Start THEN равнозначны.

А вот сравнение с FALSE требует дополнительных команд.

Cs-Cs
03.02.2023, 14:37
Вот и повеселились!
А что? Кто-то на IL ещё пишет?
Косяки CDS 3.5 другие. Это, например, скорость работы встроенных драйверов Modbus, где между запросами идёт 70 мсек задержка.
А сколько байт займёт IF - пофиг.

disconnect555
20.02.2023, 11:20
Спасибо всем за ответы.

Если позволите, то ещё один вопрос.

У меня структура
TYPE Example :
STRUCT
First:INT;
Second:REAL;
Third:STRING[9];
Fourth:WORD;
END_STRUCT
END_TYPE

Затем объявляется экземпляр этой структурой с привязкой к адресу.
Expl: AT %MW2000:Example;

Гарантировано ли, что адрес:
Expl.First будет MW2000?
Expl.Second будет MW2001?
Expl.Third будет MW2003?
Expl.Fourth будет MW2013?

Если гарантировано, то насколько связыванием через структуры считается хорошим/дурным тоном?
Привязка нужна для соединения с панелью оператора.

Cs-Cs
20.02.2023, 11:26
disconnect555 Так, ага. Это плохой изврат, но так делать можно. Я такое виде в одном проекте, скопированном с какого-то другого: там брался первый адрес Modbus-регистров из Slave, и привязывался к адресу структуры. И поля совпадали. Но при малейших изменениях всё съезжало по адресам.
А вот что за адрес MWxxx? Это откуда взято? Я с такими не работал ни фига.


Формально верно следующее: в пределах одного объекта (структура, массив), все данные в памяти всегда располагаются последовательно. Так что адреса будут идти подряд.
Но надо обратить внимание:
а) На упаковку некоторых переменных (если специально не указано, то CodeSys может байт расширить до Word и так далее)
б) Про хранение строк. В каких-то из форматов строка занимает, условно 9 символов + конечный нулевой = 10.
У ОВЕНа это было в руководстве по программированию на CodeSys 2.3

disconnect555
20.02.2023, 13:01
disconnect555
А вот что за адрес MWxxx? Это откуда взято? Я с такими не работал ни фига.


Насколько я понимаю - это значит, что во внутренней памяти (не связанной со входами и выходами) по такому-то адресу находится WORD.
В моем случае ПЛК - Beckhoff.
Да, про то что переменные могут быть однобайтовыми, а строки - нуль-терминированными, я понял, спасибо.

Валенок
21.02.2023, 08:59
..
Гарантировано ли, что адрес:
Expl.First будет MW2000?
Expl.Second будет MW2001?
Expl.Third будет MW2003?
Expl.Fourth будет MW2013?

Если гарантировано, то насколько связыванием через структуры считается хорошим/дурным тоном?
Привязка нужна для...
С конца.
Для чего нужна - это Ваше. Какой это тон - а вам не...? Вам же с этим работать. Размещение по абсолютным адресам иногда удобно, но сдуру можно... сломать.

Ключевое слово "выравнивание". Безотносительно ПЛК. Сами гуглим.
Локальная особенность при авторазмещении :
-байтовое пофиг //byte, sint, using, string и их производные в виде array
-2х байтное адрес кратный 2 //word, int, uint и их производные из array
-4х байтное адрес кратный 4 //real, dword, dint и структуры и их производные из array/struct в любом сочетании.
+(местное) размер struct автодобивается под кратность 4.

Отсюда
1. Да т. к. 2000, struct и first
2. Нет. т. к. real с +2(т.к. MW) . Перед ним будет неявный word
3. Нет, но из за 2-ого, а так stringу пофиг. Итог +4(MW!)
4. Нет, но из за 2-ого. А так, в сочетании того что sizeof 3-ого четный пофиг
Ну и т.к. 2й +2(MW!), а sizeof(2й) + sizeof(3й) кратен 4, в конце struct НЕ будет ничего автодобавлено.

disconnect555
05.03.2023, 18:34
Валенок, спасибо большое.

Boyko
26.04.2023, 16:02
Прошу прощения, что вклинился. Так переменные START в Main и в Prg1 - это же разные переменные. Так и надо?

keysansa
26.04.2023, 21:40
Как раз лучше начинать с TRUE, зачем Вам на каждом цикле делать операцию NOT?
И назвать ее можно что-то вида FirstCycle.

Лучше начинать не с TRUE, ни с FALSE, а с условия начала работы.

PROGRAM MAIN
VAR
END_VAR

PRG1(Start:= ButtonStart AND PowerOk AND StartEnabled);

keysansa
26.04.2023, 21:47
Спасибо всем за ответы.

Если позволите, то ещё один вопрос.

У меня структура
TYPE Example :
STRUCT
First:INT;
Second:REAL;
Third:STRING[9];
Fourth:WORD;
END_STRUCT
END_TYPE

Затем объявляется экземпляр этой структурой с привязкой к адресу.
Expl: AT %MW2000:Example;

Гарантировано ли, что адрес:
Expl.First будет MW2000?
Expl.Second будет MW2001?
Expl.Third будет MW2003?
Expl.Fourth будет MW2013?

Если гарантировано, то насколько связыванием через структуры считается хорошим/дурным тоном?
Привязка нужна для соединения с панелью оператора.


Вам нужен указатель на элемент структуры? Так и используйте указатели.
ST - это высокоуровневый язык. Я не помню, как в Codesys они реализуются, но, например, в B&R - Вот Так:
VAR
MyInt: REFERENCE TO Int;
MyReal: REFERENCE TO Real;

MyInt:= ADDR(Example.First);
MyReal:- ADDR(Examlpe.Second);

keysansa
26.04.2023, 21:49
Прошу прощения, что вклинился. Так переменные START в Main и в Prg1 - это же разные переменные. Так и надо?

Разные, но понятно, что имелось ввиду, думаю )

keysansa
26.04.2023, 22:01
Вообще, мое мнение - вызовы FB - должны выполняться всегда.
В смысле, что вот такое:
IF START THEN
PRG1();
START := FALSE;
END_IF
это жуть!

Начинает прыгать среднее время выполнения цикла, возникают вопросы, а что произойдет с FB, когда его снова вызовут (с учетом того, как его вызывали последний раз). Для оптимизации времени выполнения - тоже не подходит. 3-4 "тяжелых" блока однажды начнут выполняться одновременно - замучаетесь ловить, почему Watchdog стал срабатывать.

Валенок
28.04.2023, 08:39
если есть такие "тяжёлые" блоки то сначала с ними разбирайтесь, с чего они такие "тяжёлые"
А вызывать что либо нужно только тогда, когда оно - нужно.

AlexZ
25.05.2023, 15:29
С конца.
Для чего нужна - это Ваше. Какой это тон - а вам не...? Вам же с этим работать. Размещение по абсолютным адресам иногда удобно, но сдуру можно... сломать.

Ключевое слово "выравнивание". Безотносительно ПЛК. Сами гуглим.
Локальная особенность при авторазмещении :
-байтовое пофиг //byte, sint, using, string и их производные в виде array
-2х байтное адрес кратный 2 //word, int, uint и их производные из array
-4х байтное адрес кратный 4 //real, dword, dint и структуры и их производные из array/struct в любом сочетании.
+(местное) размер struct автодобивается под кратность 4.

Отсюда
1. Да т. к. 2000, struct и first
2. Нет. т. к. real с +2(т.к. MW) . Перед ним будет неявный word
3. Нет, но из за 2-ого, а так stringу пофиг. Итог +4(MW!)
4. Нет, но из за 2-ого. А так, в сочетании того что sizeof 3-ого четный пофиг
Ну и т.к. 2й +2(MW!), а sizeof(2й) + sizeof(3й) кратен 4, в конце struct НЕ будет ничего автодобавлено.

{attribute 'pack_mode':='0'}
TYPE ...

Валенок
26.05.2023, 00:48
{attribute 'pack_mode':='0'}
TYPE ...
В КДС2 на Овен - не катит.
В КДС3 ?

AlexZ
26.05.2023, 15:46
Да КДС3. Проверено

Валенок
26.05.2023, 16:42
Да КДС3. Проверено
На железе ?

AlexZ
29.05.2023, 09:51
Конечно. SP17 СПК110М01, 107М01

Валенок
31.05.2023, 23:55
Ну и замечательно. Обязательно всегда используйте возможность НЕ выравнивать. Очень поможет. При портированиях