Просмотр полной версии : Вопрос про 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;
//какой-то код....
Вопрос. Первый вариант лучше второго в плане экономии памяти, быстродействии или чего-то ещё? Или все едино?
В общем случае едино.
И лучше делать Start наобррот: FALSE, а потом писать что-то типа
IF (NOT(Start)) THEN
Start := TRUE;
.....
END_IF
Емельянов Кирилл
03.02.2023, 00:36
Тогда переменная должна называться notStart
Емельянов Кирилл Почему? Она ж при старте ставится в TRUE - вот, раз TRUE - значит старт успешен.
А вообще это прям в CodeSys FAQ есть (вот тут: https://www.owen.ru/forum/showthread.php?t=28167&p=304642&viewfull=1#post304642), так что троллинг очень толстый.
В общем случае едино.
И лучше делать Start наобррот: FALSE, а потом писать что-то типа
IF (NOT(Start)) THEN
Start := TRUE;
.....
END_IF
Как раз лучше начинать с TRUE, зачем Вам на каждом цикле делать операцию NOT?
И назвать ее можно что-то вида FirstCycle.
Как раз лучше начинать с TRUE, зачем Вам на каждом цикле делать операцию NOT?
Ну так это не микроконтроллер, где лишняя операция сожрёт несколько тактов.
И чего-то, если это не Z80, то мне помнится что в большинстве ассемблеров есть JZ и JNZ.
А ещё можно записать IF (Start = FALSE). Сколько тогда операций будет? =))
Проверил на 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 требует дополнительных команд.
Вот и повеселились!
А что? Кто-то на 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?
Если гарантировано, то насколько связыванием через структуры считается хорошим/дурным тоном?
Привязка нужна для соединения с панелью оператора.
disconnect555 Так, ага. Это плохой изврат, но так делать можно. Я такое виде в одном проекте, скопированном с какого-то другого: там брался первый адрес Modbus-регистров из Slave, и привязывался к адресу структуры. И поля совпадали. Но при малейших изменениях всё съезжало по адресам.
А вот что за адрес MWxxx? Это откуда взято? Я с такими не работал ни фига.
Формально верно следующее: в пределах одного объекта (структура, массив), все данные в памяти всегда располагаются последовательно. Так что адреса будут идти подряд.
Но надо обратить внимание:
а) На упаковку некоторых переменных (если специально не указано, то CodeSys может байт расширить до Word и так далее)
б) Про хранение строк. В каких-то из форматов строка занимает, условно 9 символов + конечный нулевой = 10.
У ОВЕНа это было в руководстве по программированию на CodeSys 2.3
disconnect555
20.02.2023, 13:01
disconnect555
А вот что за адрес MWxxx? Это откуда взято? Я с такими не работал ни фига.
Насколько я понимаю - это значит, что во внутренней памяти (не связанной со входами и выходами) по такому-то адресу находится WORD.
В моем случае ПЛК - Beckhoff.
Да, про то что переменные могут быть однобайтовыми, а строки - нуль-терминированными, я понял, спасибо.
..
Гарантировано ли, что адрес:
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
Валенок, спасибо большое.
Прошу прощения, что вклинился. Так переменные 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 стал срабатывать.
если есть такие "тяжёлые" блоки то сначала с ними разбирайтесь, с чего они такие "тяжёлые"
А вызывать что либо нужно только тогда, когда оно - нужно.
С конца.
Для чего нужна - это Ваше. Какой это тон - а вам не...? Вам же с этим работать. Размещение по абсолютным адресам иногда удобно, но сдуру можно... сломать.
Ключевое слово "выравнивание". Безотносительно ПЛК. Сами гуглим.
Локальная особенность при авторазмещении :
-байтовое пофиг //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 ...
{attribute 'pack_mode':='0'}
TYPE ...
В КДС2 на Овен - не катит.
В КДС3 ?
Да КДС3. Проверено
На железе ?
Конечно. SP17 СПК110М01, 107М01
Ну и замечательно. Обязательно всегда используйте возможность НЕ выравнивать. Очень поможет. При портированиях
Powered by vBulletin® Version 4.2.3 Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot