Версия для печати

Восстанавливаем исходный SCL текст из STL

Дата: 2008-11-03

Добавлено: komatic

Тема: SCL




Цель статьи
Теоретическая часть
Последовательность действий
Преобразуем STL код в SCL
Проверка результата
Видео приложение



Цель статьи:

Изложение оптимальной методики восстановления.



Теоретическая часть:

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

В любом случае, изначально мы имеем скомпилированную функцию или функциональный блок, при открытии которых в менеджере проектов Simatic S7, открывается STL редактор и мы видим STL код полученный в результате компиляции исходного SCL текста, которого у нас нет.

Наша задача получить этот исходный текст, который будет компилироваться в блок идентичный блоку, имеющемуся у нас. При сравнении эти блоки не должны давать отличий в MC7 коде и иметь одинаковый checksum, который можно посмотреть в свойствах этих блоков. Добиться этого можно используя SCL редактор одинаковой версии, и установив одинаковые параметры компиляции. Версию под которой был собран исследуемый блок мы можем посмотреть в комментариях STL кода. Обычно различия от версии к версии не очень заметны, поэтому можно попытаться компилировать версией, которая у вас имеется.



Последовательность действий.

Настройки компилятора. Вызываются Options -> Customize -> вкладка Compiler. Настроек компилятора не настолько много, чтобы это вызвало проблему в подборе. По сути их - несколько:

SCL

Вид настроек



Краткая расшифровка


Create object code

C этой опцией, вы определяете необходимость создания выполняемого кода. Компиляция без этой опции выполняет только синтаксическую проверку. (Обычно установлена).

Optimize object code

Когда вы выбираете эту опцию, блоки оптимизируются по использованию памяти и скорости выполнения кода в PLC. (Обычно установлена).

Monitor array limits

Если опция выбрана, в момент выполнения кода проверяется индекс массива и если он выходит за пределы заданного OK флаг сбрасывается в FALSE. (Обычно сброшена)

Create debug info

Создает отладочную информацию в коде, которая позволяет производить мониторинг SCL программы. Увеличивает размер кода. (Обычно сброшена).

Set OK flag

Позволяет обращаться к OK флагу из S7-SCL кода. (Обычно сброшена)

Permit nested comments

Разрешает использование вложенных комментариев. (Обычно установлена)

Maximum string length

Определяет максимальную длину строки, по умолчанию 254.

Значения настроек



Итак начнем - открываем блок в STL редакторе, выполнив двойной щелчок на блоке в Simatic Manager.


STL_1_2

Вид открытого блока с информацией о версии компилятора



Выполняем команду File -> Save (необходимо для того чтобы изменился признак Created in language = STL)

Далее File -> Generate source..., выбираем из списка только необходимый блок.



STL

Окно выбора.



Открываем полученный блок командой File -> Open


STL

Вид в STL редакторе.



Теперь создаем новый SCL файл в папке проекта Sources (команда Insert -> S7 software -> SCL source), открываем созданный файл и копируем в него все, что получили на предыдущем шаге.

Далее изменяем заголовок блока, чтобы была возможна безошибочная компиляция:
- Изменяем номер блока, чтобы при компиляции не перезаписать исходный блок,
- Ставим одинарные кавычки на признаках TITLE и VERSION.


Имена входных/выходных переменных не нуждаются в корректировке.




Преобразуем STL код в SCL.

Например:

L #in1 L #in2 +R T #result

Преобразуется в следующую строчку

result:=in1+in2;



Конструкцию IF..THEN..ELSE можно узнать по следующим строчкам.

A #START_ON // условие IF JCN M001 ..... // операторы для THEN JU M002M001: NOP 0 ..... // операторы для ELSE M002: CLR



Соответственно получаем

IF START_ON THEN ....; ELSE ....; END_IF;




Как выглядят другие языковые конструкции можно узнать, создав в SCL тестовый блок, с именно этой конструкцией и скомпилировав его.

Таблица некоторых общераспространенных конструкций (загрузить.pdf 36кБ.):

SCL_STL



Cкомпилируем полученный текст командой File -> Compile.



Проверка результата

Сравниваем полученные блоки командой Compare Blocks.
Если преобразование было выполнено успешно, результат должен выглядеть приблизительно так:



STL

Сравнение блоков.



Основной параметр здесь - Block checksum, если он одинаковый у двух блоков значит код тоже одинаковый и исходный SCL текст программы восстановлен.



Видео приложение

В ролике показан пример востановления исходного текста функции CRP_IN (библиотека ModPID)
Все в реальном времени, ничего не пропущено.
При просмотре лучше развернуть на весь экран.








Просмотров: 22768

Комментарии к материалу

Добавлен: alex    Дата: 2009-04-27

завис на фразе "Преобразуем STL код в SCL " подскажите это как?

Добавлен: 123    Дата: 2009-04-28

хорошая шутка )

Добавлен: komatic    Дата: 2009-04-28

Ну например:
L #in1
L #in2
+R
T #result
преобразуется в
result:=in1+in2;
ну и т.д.
:)

Добавлен: komatic    Дата: 2009-04-28

текст поправил, пойдет?

Добавлен: ART    Дата: 2010-05-09

нифига это не работает.
скомпилированный STL преобразуется в STL Source.

Добавлен: komatic    Дата: 2010-05-12

Посмотрите видео - все работает, декомпиляция делается ручками

Добавлен: Sid835    Дата: 2011-02-19

Пытаюсь декомпилировать один FB из библиотеки PCS7 и завис на логической конструкции:
O(
A #AUT_ON_OP
A #sbI_OD2
O
AN #AUT_ON_OP
AN #sbI_OD2
)
видно что это XOR, но как он получ

Добавлен: komatic    Дата: 2011-02-19

вообщето это - NOT XOR, а получается в результате свойств логических операций.
подробнее - http://ru.wikipedia.org/wiki/Двоичная_логика

Добавлен: Sid835    Дата: 2011-02-19

Согласен, но при компиляции взамен AN #AUT_ON имеем A #AUT_ON NOT. Непонятно какое выражение SCL скомпилировалось таким образом

Добавлен: komatic    Дата: 2011-02-19

какая версия SCL компилятора записана в комментарии к нетворку?

Добавлен: Sid835    Дата: 2011-02-19

в блоке - SCL V5.3 + HF1 (C5.3.0.5),
пробовал на SCL V5.3 и SCL V5.3 SP5 - результат тот же

Добавлен: Sid835    Дата: 2011-02-19

вот блок если что, http://dl.dropbox.com/u/1208469/FB66.AWL

Добавлен: Sid835    Дата: 2011-02-20

Разобрался, это выражение получается из, например, if AUT_ON_OP = bI_OD2 then ... в принципе что и эквивалентно XOR

Добавлен: Sid835    Дата: 2011-02-20

NOT XOR

Добавлен: komatic    Дата: 2011-02-21

Понятно, инетерсно, спасибо, буду тоже знать.

Добавлен: Poll    Дата: 2013-04-04

а вот такую конструкцию, ктонибудь распишет?
A #FillChar;
JCN A7d0;
L 1;
T #i;
A7d1: L #i;
L 9;
<=I ;
JCN A7d0;
L #i;
ITD ;
L L#1;
-D ;
L L#8;
*D ;
L #CharSet;
T LD 4;
TAK ;
T LD 8;
TAK ;
L P##CharFeld;
LAR1 ;
L W [AR1,P#0.0];
T LW 12;
OPN DB [LW 12];
L D [AR1,P#2.0];
L LD 8;
+D ;
LAR1 ;
L LD 4;
T B [AR1,P#0.0];
L #i;
ITD ;
L L#1;
-D ;
L L#8;
*D ;
L L#16;
+D ;
L #CharSet;
T LD 4;
TAK ;
T LD 8;
TAK ;
L P##Str_Ein;
LAR1 ;
L W [AR1,P#0.0];
T LW 12;
OPN DB [LW 12];
L D [AR1,P#2.0];
L LD 8;
+D ;
LAR1 ;
L LD 4;
T B [AR1,P#0.0];
L #i;
L 1;
+I ;
T #i;
JU A7d1;
A7d0: CLR ;
A #StrToChar;
JCN A7d3;
L 1;
T #i;
A7d4: L #i;
L 9;
<=I ;
JCN A7d3;
L #i;
ITD ;
L L#1;
-D ;
L L#8;
*D ;
L #i;
ITD ;
TAK ;
T LD 4;
TAK ;
L L#1;
-D ;
L L#8;
*D ;
L L#16;
+D ;
L P##Str_Ein;
LAR1 ;
TAK ;
T LD 8;
TAK ;
L W [AR1,P#0.0];
T LW 12;
OPN DB [LW 12];
L D [AR1,P#2.0];
L LD 8;
+D ;
LAR1 ;
L B [AR1,P#0.0];
T LD 8;
L P##CharFeld;
LAR1 ;
L W [AR1,P#0.0];
T LW 12;
OPN DB [LW 12];
L D [AR1,P#2.0];
L LD 4;
+D ;
LAR1 ;
L LD 8;
T B [AR1,P#0.0];
L #i;
L 1;
+I ;
T #i;
JU A7d4;
A7d3: CLR ;
A #CharToStr;
JCN A7d6;
L 1;
T #i;
A7d7: L #i;
L 9;
<=I ;
JCN A7d8;
L #i;
ITD ;
L L#1;
-D ;
L L#8;
*D ;
L L#16;
+D ;
L #i;
ITD ;
TAK ;
T LD 4;
TAK ;
L L#1;
-D ;
L L#8;
*D ;
L P##CharFeld;
LAR1 ;
TAK ;
T LD 8;
TAK ;
L W [AR1,P#0.0];
T LW 12;
OPN DB [LW 12];
L D [AR1,P#2.0];
L LD 8;
+D ;
LAR1 ;
L B [AR1,P#0.0];
T LD 8;
L P##Str_Aus;
LAR1 ;
L W [AR1,P#0.0];
T LW 12;
OPN DB [LW 12];
L D [AR1,P#2.0];
L LD 4;
+D ;
LAR1 ;
L LD 8;
T B [AR1,P#0.0];
L #i;
L 1;
+I ;
T #i;
JU A7d7;
A7d8: L B#16#9;
L P##Str_Aus;
LAR1 ;
TAK ;
L W [AR1,P#0.0];
T LW 4;
TAK ;
OPN DB [LW 4];
L D [AR1,P#2.0];
LAR1 ;
TAK ;
T B [AR1,P#1.0];
A7d6: CLR ;
A #CharToEin;
JCN A7d9;
L 1;
T #i;
A7da: L #i;
L 9;
<=I ;
JCN A7db;
L #i;
ITD ;
L

Добавлен: komatic    Дата: 2013-04-04

2Poll - Добавьте еще определение интерфейса, всех переменных тоесть.

Добавлен: poll    Дата: 2013-04-08

VAR_INPUT
StrToChar : BOOL ;
CharToStr : BOOL ;
CharToEin : BOOL ;
FillChar : BOOL ;
CharSet : CHAR ;
END_VAR
VAR_IN_OUT
CharFeld : ARRAY [1 .. 9] OF CHAR ;
Str_Ein : STRING [254];
Str_Aus : STRING [254];
END_VAR
VAR_TEMP
i : INT ;
END_VAR

ПАРАМЕТРИРУЕМАЯ ФУНКЦИЯ
CHAR_TO_STRIG
AND
STRING_TO_CHAR

Добавлен: komatic    Дата: 2013-04-08

ok, сделаем, вроде ничего сложного

Добавлен: poll    Дата: 2013-04-09

я не сомневаюсь что сделаете :) хотелось бы с коментариями.

Добавлен: komatic    Дата: 2013-04-10

Будет и с комментариями, скиньте еще и версию компилятора, она должна быть в комментарии первому нетворку (чтото типа: compiled by SCL compiler version: SCLCOMP K05.03.07.00_01.02.00.01 release)
а то что-то моя версия совсем не хочет такой код выдавать :)

Добавлен: komatic    Дата: 2013-04-12

Похоже это правленый в STL SCL, например вот это:
L #i; ITD ; L L#1;
-D ;
L L#8;
*D ;
T LD 8;
L P##CharFeld;
LAR1 ;
L W [AR1,P#0.0];
T LW 12;
OPN DB [LW 12];
L D [AR1,P#2.0];
L LD 8;
+D ;
LAR1 ;
L LD 4;
T B [AR1,P#0.0];

ну никак не хочет переводится в что-то подобное:
WORD_TO_BLOCK_DB(_CharFeld.DBNr.DBB[_CharFeld.Adr+[i-1]]:=CHAR_TO_BYTE(CharSet);

Добавлен: Oleg    Дата: 2013-10-22

Здравствуйте. Подскажите пожалуйста.. восстановил небольшой фрагмент... потом появился исходник блока. Результат преобразования с исходником сходится, но вот контрольная сумма отличается..... Как узнать в чем различия???
Код в STL:
SET ;
SAVE ;
= L 22.1;
L W#16#4;
T MW 20;
L MW 20;
L W#16#4;
<>I ;
JCN A7d0;
L 0;
T "DB_FILTR_CNT".state[4];
A7d0: LAR2 P#DBX 0.0;
OPN "DB_AIN";
CDB ;
UC "FB_AIN";
CDB ;
LAR2 P#DBX 0.0;
OPN DI 212;
UC "FB_DIO_CNT";
LAR2 P#DBX 0.0;
OPN DI 213;
UC "FB_FILTR_CNT";
LAR2 P#DBX 0.0;
OPN DI 103;
UC "FB_AOUT";
LAR2 P#DBX 0.0;
OPN DI 211;
UC "FB_RSRV_CNT";
LAR2 P#DBX 0.0;
OPN DI 216;
UC "FB_ALARM";
UC "FC_DO";
A L 22.1;
SAVE ;
BE ;
Код в SCL:
MW20 :=4;
IF MW20<>4 THEN DB_FILTR_CNT.state[4]:=0;END_IF;
FB_AIN.DB_AIN();
FB_DIO_CNT.DB_DIO_CNT();
FB_FILTR_CNT.DB_FILTR_CNT();
FB_AOUT.DB_AOUT();
FB_RSRV_CNT.DB_RSRV_CNT();
FB_ALARM.DB_ALARM();
FC_DO();
В проекте код полностью совпадает(Все отступы индентичны).

Добавлен: komatic    Дата: 2013-10-22

Почти уверен, что причина в том, что вы сравниваете с одной стороны блок сохраненный как STL, а с другой скомпилированный в SCL. Даже если они идентичны по STL коду, чексумма будет разная.
Попробуйте сгенерированный в SCL открыть без исходника в STL редакторе, сохранить и потом сравнить.

Добавлен: Mikhail    Дата: 2014-07-24

Помогите, пожалуйста в конвертацией с таким кодом:
FUNCTION_BLOCK FB 40
TITLE =Positioning and ramp generator for slitting
AUTHOR : Tuomo
FAMILY : Slitting
NAME : Slitting
VERSION : 1.0


VAR_INPUT
Encoder : DINT ;
SetPoint : REAL ;
Enable : BOOL ;
JogFWD : BOOL ;
JogBWD : BOOL ;
Cycle : INT ;
END_VAR
VAR_OUTPUT
ActValue : REAL ;
Speed : INT ;
OnPos : BOOL ;
Release : BOOL ;
END_VAR
VAR
Line : ARRAY [0 .. 2 ] OF STRUCT
MaxSpeed : REAL := 1.000000e+002;
ManSpeed : REAL := 3.000000e+001;
MinSpeed : REAL := 1.000000e+001;
Accuracy : REAL := 5.000000e-001;
Accelerate : REAL := 6.000000e-001;
SlowCurve : REAL := 3.000000e+002;
SlowLine : REAL := 3.000000e+001;
END_STRUCT ;
Wheel : REAL := 3.141590e+002; //Wheel perimeter
Pulses : REAL := 1.250000e+003; //Amount pulses of encoder
Difference : REAL ; //Length to go
AbsValue : REAL ; //Length to go (absolut value)
Memory : REAL ;
END_VAR
VAR_TEMP
Maksimi : REAL ;
Kiihdytys1 : REAL ;
Kiihdytys2 : REAL ;
Kerroin : REAL ;
Nopeus : REAL ;
OhjeArvo : REAL ;
END_VAR
BEGIN
NETWORK
TITLE =SCL network
//compiled by SCL compiler version: SCLCOMP K05.03.01.00_01.08.00.01 release
SET ;
SAVE ;
= L 24.1;
L "Order".Line;
ITD ;
L L#224;
*D ;
TAR2 ;
+D ;
LAR1 ;
L DID [AR1,P#20.0];
T #Line[0].MaxSpeed;
TAK ;
T LD 30;
TAK ;
L DID [AR1,P#24.0];
T #Line[0].ManSpeed;
L DID [AR1,P#28.0];
T #Line[0].MinSpeed;
L DID [AR1,P#32.0];
T #Line[0].Accuracy;
L DID [AR1,P#36.0];
T #Line[0].Accelerate;
L DID [AR1,P#40.0];
T #Line[0].SlowCurve;
L DID [AR1,P#44.0];
T #Line[0].SlowLine;
L DBW 0;
L 2;
==I ;
L "Main".Control.LinePot;
L 1;
= L 24.2;
==I ;
A L 24.2;
JCN A7d0;
L DBD 52;
T #Line[0].MaxSpeed;
A7d0: L "Order".Line;
L 1;
==I ;
JCN A7d1;
L #Wheel;
L #Pulses;
/R ;
L #Encoder;
DTR ;
*R ;
L 4.000000e+000;
/R ;
T #ActValue;
JU A7d2;
A7d1: L #Wheel;
L #Pulses;
/R ;
L #Encoder;
DTR ;
*R ;
L 4.000000e+003;
/R ;
T #ActValue;
A7d2: L #SetPoint;
L #ActValue;
-R ;
T #Difference;
ABS ;
T #AbsValue;
L #Line[0].Accuracy;
L #AbsValue;
>=R ;
JCN A7d3;
SET ;
= #OnPos;
JU A7d4;
A7d3: CLR ;
= #OnPos;
A7d4: L 2.764800e+001;
L #Line[0].Accelerate;
/R ;
L #Cycle;
ITD ;
DTR ;
*R ;
T #Kiihdytys1;
L 2.764800e+001;
L #Line[1].Accelerate;
/R ;
L #Cycle;
ITD ;
DTR ;
*R ;
T #Kiihdytys2;
CLR ;
A #JogFWD;
NOT ;
A #Enable;
= L 24.2;
A #JogBWD;
NOT ;
A L 24.2;
JCN A7d5;
L #Line[0].SlowCurve;
SQRT ;
L 2.764800e+004;
TAK ;
/R ;
T #Kerroin;
L #AbsValue;
L #Line[0].SlowLine;
>R ;
JCN A7d6;
L #AbsValue;
SQRT ;
L #Kerroin;

Добавлен: Mikhail    Дата: 2014-07-24

*R ;
T #Nopeus;
JU A7d7;
A7d6: L #Line[0].SlowLine;
SQRT ;
L #Kerroin;
*R ;
L #Line[0].SlowLine;
/R ;
L #AbsValue;
*R ;
T #Nopeus;
A7d7: L #Difference;
L

Добавлен: komatic    Дата: 2014-07-24

скиньте полностью на dda_dda@mail.ru

Добавлен: Atrin    Дата: 2014-10-12

A802: CLR
O(
A DIX [AR2,P#125.1]//_set_com_oldBit[9]
AN DIX [AR2,P#121.1]//_statusBit[25]
O
AN DIX [AR2,P#125.1]
A DIX [AR2,P#121.1]
)
= L 28.2
CLR
O(
A DIX [AR2,P#125.3]
AN DIX [AR2,P#121.3]
O
AN DIX [AR2,P#125.3]
A DIX [AR2,P#121.3]
)
O L 28.2
= L 28.2
CLR
O(
A DIX [AR2,P#125.2]
AN DIX [AR2,P#121.2]
O
AN DIX [AR2,P#125.2]
A DIX [AR2,P#121.2]
)
O L 28.2
= L 28.2
CLR
O(
A DIX [AR2,P#125.4]
AN DIX [AR2,P#121.4]
O
AN DIX [AR2,P#125.4]
A DIX [AR2,P#121.4]
)
O L 28.2
JCN A804

what expression SCL be compiled in such a way

Добавлен: komatic    Дата: 2014-10-12

Thats easy, this part looks like:

IF ((x125.1 AND NOT x121.1) OR (NOT x125.1 AND x121.1)) OR
((x125.3 AND NOT x121.3) OR (NOT x125.3 AND x121.3)) OR
((x125.2 AND NOT x121.2) OR (NOT x125.2 AND x121.2)) OR
((x125.4 AND NOT x121.4) OR (NOT x125.4 AND x121.4))
THEN...

but best way - send complete source to mail dda_dda@mail.ru

Добавлен: duran kartal    Дата: 2015-01-07

could you plase translate fc 105 block into scl language?
ıf you can,please send e-mail kartal.20@mynet.com.

Добавлен: duran kartal    Дата: 2015-01-07

could you plase translate fc 81 block into scl language?
ıf you can,please send e-mail kartal.20@mynet.com.

Добавлен: komatic    Дата: 2015-01-07

>duran kartal
pls write NAME of this functions, not only number :)

Добавлен: duran kartal    Дата: 2015-01-08

fc 105 SCALE fonctions and
fc 81 IBLKMOV fonctions

Добавлен: duran kartal    Дата: 2015-01-08

translate scl language

Добавлен: komatic    Дата: 2015-01-08

>duran kartal
SCALE is here
http://plc4good.org.ua/view_post.php?id=34

Добавлен: komatic    Дата: 2015-01-08

>duran kartal
if you mean blocks from Standart library -> TI-S7 Converting Blocks
Unfortunately
this blocks originaly created in STL, so identical revers not possible

Добавлен: duran kartal    Дата: 2015-01-09

no tıa
only s7 300 manager fc 105 and fc 81 translet

Добавлен: komatic    Дата: 2015-01-09

>duran kartal
OK, just send me this blocks to dda_dda@mail.ru

Добавлен: duran kartal    Дата: 2015-01-09

FUNCTION "IBLKMOV" : VOID
TITLE = INDIRECT BLOCK MOVE
AUTHOR : SEA
FAMILY : MOVE
NAME : IBLKMOV
VERSION : 2.0


VAR_INPUT
S_DATA : POINTER ; // Points to a pointer to start location of source data
LEN : POINTER ; // Points to number of elements to be moved
D_DATA : POINTER ; // Points to a pointer to start location of destination data
E_TYPE : BYTE ; // Indicates byte, word, or doubleword
END_VAR
VAR_TEMP
BLOCK_NO : WORD ; // Block number
TEMP_LEN : WORD ; // Working copy of LEN
TEMP_AR2 : DWORD ; // Storage for AR2 contents, which is restored before return
END_VAR
BEGIN
NETWORK
TITLE =

TAR2 #TEMP_AR2;
//
// AR1 := Starting address of source data
//
L P##S_DATA;
LAR1 ;
L 0;
L W [AR1,P#0.0];
==I ;
JZ IF01;
T #BLOCK_NO;
OPN DB [#BLOCK_NO];
IF01: NOP 0;
L D [AR1,P#2.0];
LAR1 ;
L W [AR1,P#0.0];
T #BLOCK_NO;
L D [AR1,P#2.0];
LAR1 ;
L 0;
L #BLOCK_NO;
==I ;
JZ IF02;
OPN DB [#BLOCK_NO];
IF02: NOP 0;


L P##LEN;
LAR2 ;
L 0;
L W [AR2,P#0.0];
==I ;
JZ IF03;
T #BLOCK_NO;
OPN DI [#BLOCK_NO];
L DW#16#5000000;
L D [AR2,P#2.0];
OD ;
JU IF04;
IF03: L D [AR2,P#2.0];
IF04: LAR2 ;
L W [AR2,P#0.0];
T #TEMP_LEN;
T #TEMP_LEN;
L 0;
==I ;
JZ EXIT;

L P##D_DATA;
LAR2 ;
L 0;
L W [AR2,P#0.0];
==I ; )
JZ IF05;
T #BLOCK_NO;
OPN DI [#BLOCK_NO];
L DW#16#5000000;
L D [AR2,P#2.0];
OD ;
JU IF06;
IF05: L D [AR2,P#2.0];
IF06: LAR2 ;
L 0;
L W [AR2,P#0.0];
==I ;
JZ IF07;
T #BLOCK_NO;
L DW#16#5000000;
L D [AR2,P#2.0];
OD ;
OPN DI [#BLOCK_NO];
JU IF08;
IF07: L D [AR2,P#2.0];
IF08: LAR2 ;

L W#16#2;
L #E_TYPE;
==I ;
JC C00B;
L W#16#8;
==I ;
JC C00D;
POP ;
AW W#16#FFFE;
L W#16#4;
==I ;
JC C00W;
POP ;
L W#16#6;
==I ;
JCN FAIL;

//
//
C00D: L #TEMP_LEN;
L00D: T #TEMP_LEN;
L D [AR1,P#0.0];
T D [AR2,P#0.0];
+AR1 P#4.0;
+AR2 P#4.0;
L #TEMP_LEN;
LOOP L00D;
JU EXIT;



C00B: L #TEMP_LEN;
L00B: T #TEMP_LEN;
L B [AR1,P#0.0];
T B [AR2,P#0.0];
+AR1 P#1.0;
+AR2 P#1.0;
L #TEMP_LEN;
LOOP L00B;
JU EXIT;



C00W: L #TEMP_LEN;
L00W: T #TEMP_LEN;
L W [AR1,P#0.0];
T W [AR2,P#0.0];
+AR1 P#2.0;
+AR2 P#2.0;
L #TEMP_LEN;
LOOP L00W;
EXIT: SET ;
JU SBR;
FAIL: CLR ;
SBR: SAVE ;
LAR2 #TEMP_AR2;
END_FUNCTION

Добавлен: duran kartal    Дата: 2015-01-09

FUNCTION "SCALE" : WORD
TITLE =SCALING VALUES
//
AUTHOR : SEA
FAMILY : CONVERT
NAME : SCALE
VERSION : 2.1


VAR_INPUT
IN : INT ; // input value to be scaled
HI_LIM : REAL ; // upper limit in engineering units
LO_LIM : REAL ; // lower limit in engineering units
BIPOLAR : BOOL ; // 1=bipolar; 0=unipolar
END_VAR
VAR_OUTPUT
OUT : REAL ; // result of the scale conversion
END_VAR
VAR_TEMP
IN_REAL : REAL ; // input value as a REAL number
K1 : REAL ; // low limit for input value
K2 : REAL ; // high limit for input value
SPAN : REAL ; // HI_LIM - LO_LIM
TEMP1 : REAL ; // temporary result
END_VAR
BEGIN
NETWORK
TITLE =
//
// set K1 and K2 constants based upon BIPOLAR
//
SET ; // if(BIPOLAR=0)
A #BIPOLAR; // .
JC EL01; // {
L 0.000000e+000; // K1=0
T #K1; // .
JU EI01; // } else {
EL01: L -2.764800e+004; // K1=-27648.0
T #K1; // .
EI01: NOP 0; // }
L 2.764800e+004; // K2=+27648.0
T #K2; // .
//
// convert input (IN) to real
//
L #IN; // ACC1=IN
ITD ; // convert to double integer
DTR ; // convert to real
T #IN_REAL; // IN_REAL-IN as a real
//
// determine SPAN = HI_LIM - LO_LIM
//
L #HI_LIM; // SPAN=HI_LIM-LO_LIM
L #LO_LIM; // .
-R ; // .
T #SPAN; // .
//
// If the input value is outside the K1 and K2 range, the output
// is clamped to the nearer of either the LO_LIM or the HI_LIM
// and an error is logged. If the input value is exactly at a limit the
// output will be set to the computed limit with no error returned.
// changed 2/14/00 by ERI per RQ210693
L #IN_REAL; // if(IN_REAL L #K1; // .
>=R ; // .
JC EL02; // {
L 8; // error
T #RET_VAL; // .
L #LO_LIM; // ACC1=LO_LIM
T #OUT; // OUT=ACC1
JU FAIL; // error
EL02: POP ; // } else {
L #K2; // if(IN_REAL>K2)
<=R ; // .
JC EI04; // {
L 8; // error
T #RET_VAL; // .
L #HI_LIM; // ACC1=HI_LIM
T #OUT; // OUT=ACC1
JU FAIL; // error
EI04: NOP 0; // }
NOP 0; // }
//
// scale the input
//
L #K2; // TEMP1=K2-K1
L #K1; // .
-R ; // .
T #TEMP1; // .
L #IN_REAL; // IN_REAL-K1
L #K1; // .
-R ; // .
L #TEMP1; // divide by TEMP1
/R ; // .
L #SPAN; // multiply by SPAN
*R ; // .
L #LO_LIM; // add LO_LIM
+R ; // .
T #OUT; // OUT=scale(IN_REAL)
//
// set BR bit : no error-set BR bit to 1; with error-set BR bit to 0.
//
L 0; // return error code 0
T #RET_VAL;
SET ; // RLO = 1 (NO ERROR)
JU SVBR; //
FAIL: CLR ; // RLO = 0 (ERROR)
SVBR: SAVE ; // BR = RLO
END_FUNCTION

Добавлен: komatic    Дата: 2015-01-11

Sad but his two blocks created in STL, no sense to revers it.
Block created in SCL have like this string in source text:
TITLE =SCL Netzwerk
//generiert vom SCL Ьbersetzer Version: SCL K5.1.3 (C5.1.8.5)

Добавлен: duran kartal    Дата: 2015-01-12

Im sorry
thanks for doing everything

Добавлен: duran kartal    Дата: 2015-01-12

ıf there is problem
I cant't answer
could I ask again

Добавлен: Сергей    Дата: 2015-02-01

Всем привет!
Есть библиотечный блок FB93 "MOD_D1" (ну, допустим), но я хочу немного расширить объем выдаваемой наружу информации. Хотел сделать "инъекцию" в блок, прям в виде STL-кода. Но если с остальными блоками всё срабатывало без "Export source", то с этим блоком не получается: ругается на слишком большое количество строк, мол, редактор столько не терпит. А если экспортировать, то потом при компиляции ругается на слишком большие сдвиги при обращении к регистрам. (+7500)
Собственно какие варианты:
1) Может у кого-то есть уже сконвертированные исходники библиотечных блоков, был бы благодарен их принять;
2) Может кто-то подскажет, как пихнуть в код свой кусок, не конвертируя его в SCL. Я так-то догадываюсь, что в файле SUBBLK.DBT код хранится, но в чём соль этого хранения, пока не понял=) Может есть возможность отредактировать код без этой ошибки на количество строк?
3) Может просто подскажете, как скомпилировать STLный код после экспорта, а то ругается на
+AR2 P#7578.0;
грит сдвиг слишком большой;

Заранее спасибо!

Добавлен: komatic    Дата: 2015-02-01

> Сергей
Что касается блока FB93 "MOD_D1" и похожих, по пунктам
1) самый легкий и универсальный путь - все таки через конвертацию в SCL,
2) о том чтобы SUBBLK.DBT кто-то правил , никогда не слышал
3) чтобы скомпилировать без ошибок после экспорта, сначала можно закомментировать проблемные участки (в основном это места где вызываются внешние функции), а потом в скомпилированном варианте можно вставить эти вызовы штатными средствами, например из:
+AR2 P#298.0;
UC SFB 35;
+AR2 P#7894.0;

потом преобразовать в

CALL #ALARM_8P_1
EN_R :=
SIG_1 :=
SIG_2 :=
SIG_3 :=
SIG_4 :=
SIG_5 :=
SIG_6 :=
SIG_7 :=
SIG_8 :=
ID :=
EV_ID :=
SEVERITY :=
DONE :=
ERROR :=
STATUS :=
ACK_STATE:=
SD_1 :=
SD_2 :=
SD_3 :=
SD_4 :=
SD_5 :=
SD_6 :=
SD_7 :=
SD_8 :=
SD_9 :=
SD_10 :=

конечно с адекватным назначением параметров.


Добавлен: Сергей    Дата: 2015-02-01

> komatic
Спасибо, значит буду так)
При ручной конвертации в SCL пока ещё не все моменты понятны)
Пользуясь случаем, задам вопрос: как в SCL получить номер инстансного DB блока, выход которого привязан к моему блоку? Можно ли это или я придумал?)

Добавлен: komatic    Дата: 2015-02-01

> Сергей
номер блока это легко
FUNCTION_BLOCK FB99
VAR_INPUT
X :INT;
END_VAR
VAR_OUTPUT
DBNR :INT;
END_VAR
VAR_TEMP
//---------------------------------------------------
// Definition artificial variables and an own
// data type view on the data type ANY
//---------------------------------------------------
TempPointer :ANY; // Artificial variable
AnyPointer AT TempPointer: STRUCT
BYTE0 :BYTE; // Byte 0
TYP :BYTE; // Byte 1 Data/Type of parameter
ANZ :WORD; // Byte 2+3 Length of the variables
DBNR :WORD; // Byte 4+5 DB-Number
BZ :DWORD; // Byte 6 to 10 Area pointers
END_STRUCT;
END_VAR
BEGIN
TempPointer := X; // Load artificial variable with pointer to
// input X
DBNR := WORD_TO_INT(AnyPointer.DBNR); // Access to byte 4 and 5
END_FUNCTION_BLOCK

взято из http://support.automation.siemens.com/WW/view/en/28044549

Добавлен: komatic    Дата: 2015-02-01

если, все таки нужен SCL исходник, подождите, скоро планирую заняться __PCS 7 BasisLibrary V80 и выложить здесь.
Если надо срочно пишите на dda_dda@mail.ru
функция легкая

Добавлен: Сергей    Дата: 2015-02-01

Ну, уже и на этом большое спасибо) Я не то, чтобы ленивый, искал долго, просто поисковый запрос сформировать иногда просто невозможно. Искать, очевидно, надо на форумах, а хрен его знает, чё у людей в голове, чтобы угадать с запросом)
PS Торопить не буду, та работа и так большого будет стоить;)

Добавлен: maks    Дата: 2016-07-02

// SIGNATURE a2031ac9
FUNCTION_BLOCK "PROFIBUS1"
VERSION : '0.1'


VAR_INPUT
IN0 : INT ;
IN1 : INT ;
IN2 : INT ;
IN3 : INT ;
IN4 : INT ;
IN5 : INT ;
IN6 : INT ;
IN7 : INT ;
IN8 : INT ;
IN9 : WORD := W#16#FFFF;
END_VAR
VAR
STAT10 : "S_SEND_SI";
STAT46 : "S_RECV_SI";
STAT84 : BOOL ;
STAT85 : BOOL ;
STAT86 : BOOL ;
STAT87 : BOOL ;
STAT88 : WORD ;
STAT89 : BOOL ;
STAT90 : BOOL ;
STAT91 : BOOL ;
STAT92 : BOOL ;
STAT93 : BOOL ;
STAT94 : INT ;
STAT95 : WORD ;
STAT96 : BOOL ;
STAT97 : INT ;
STAT98 : INT ;
STAT99 : BOOL ;
STAT100 : BOOL ;
STAT101 : BOOL ;
STAT102 : BOOL ;
STAT103 : BOOL ;
STAT104 : BOOL ;
STAT105 : INT ;
STAT106 : INT ;
STAT107 : INT ;
STAT108 : INT ;
STAT109 : INT ;
END_VAR
VAR_TEMP
TEMP110 : DWORD ;
TEMP111 : INT ;
TEMP112 : INT ;
TEMP113 : INT ;
END_VAR
BEGIN
NETWORK
TITLE =''

MW 220:=IN9;
IF #STAT97=0 THEN
STAT97:=1 ELSE
#TEMP111:=#IN1;
#TEMP112:=IN4;
END_IF;
IF #IN8=1 THEN
#in3:=W#16#6;
#IN2:=#STAT97-1*6;
#STAT107:=IN2+4;
#STAT109:=#STAT107-3;
END_IF;
IF STAT97=1 THEN
#in5:=0;


L #STAT97;
L 1;
==I ;
JCN M001;
L 0;
T #IN5;
L #STAT109;
SLW 3;
T #TEMP110;
OPN DB [#TEMP111];
O( ;
L DBB [#TEMP110];
L 5;
) ;
O( ;
L DBB [#TEMP110];
L 6;
) ;
==I ;
JC M005;
L #STAT107;
SLW 3;
T #TEMP110;
OPN DB [#TEMP111];
L DBW [#TEMP110];
SLW 1;
JU M006;
M005: L 6;
M006: L #IN5;
+I ;
T #STAT108;
M001: L #IN8;
L 2;
==I ;
JCN M00a;
L 1;
L #STAT97;
==I ;
JCN M00b;
L W#16#6;
T #IN3;
L 0;
T #IN2;
T #IN5;
M00b: L 2;
L #STAT97;
==I ;
JCN M00c;
L W#16#A;
T #IN3;
L 6;
T #IN2;
L 32;
T #IN5;
M00c: L 3;
L #STAT97;
==I ;
JCN M002;
L W#16#A;
T #IN3;
L 16;
T #IN2;
L 42;
T #IN5;
JU M002;
M00a: A( ;
L #STAT97;
L 1;
>I ;
) ;
A( ;
L #STAT97;
L #STAT105;
<>I ;
) ;
JCN M002;
L #STAT108;
T #IN5;
L #STAT109;
SLW 3;
T #TEMP110;
OPN DB [#TEMP111];
O( ;
L DBB [#TEMP110];
L 5;
) ;
O( ;
L DBB [#TEMP110];
L 6;
) ;
==I ;
JC M007;
L #STAT107;
SLW 3;
T #TEMP110;
OPN DB [#TEMP111];
L DBW [#TEMP110];
SLW 1;
JU M008;
M007: L 6;
M008: L #IN5;
+I ;
T #STAT108;
M002: A( ;
L #STAT97;
L #STAT105;
<>I ;
) ;
AN #STAT84;
AN #STAT86;
AN #STAT87;
S #STAT84;
L #STAT97;
T #STAT105;
A( ;
O #STAT86;
O #STAT87;
) ;
A #STAT84;
R #STAT84;
L #STAT97;
L 1;
-I ;
T #TEMP113;
L 220;
SLW 3;
L #TEMP113;

Добавлен: maks    Дата: 2016-07-02

+I ;
LAR1 ;
AN M [AR1,P#0.0];
R #STAT84;
CALL #STAT10 (
REQ := #STAT84,
R := #STAT85,
LADDR := #IN0,
DB_NO := #IN1,
DBB_NO := #IN2,
LEN := #IN3,
DONE := #STAT86,
ERROR := #STAT87,
STATUS := #STAT88,
COM_RST := #STAT89);
A #STAT87;
FP #STAT104;
R #STAT84;
JC M004;
NETWORK
TITLE =

A #STAT86;
AN #STAT87;
R #STAT84;
AN #STAT90;
S #STAT90;
L #STAT97;
L 1;
-I ;
T #TEMP113;
L 220;
SLW 3;
L #TEMP113;
+I ;
LAR1 ;
AN M [AR1,P#0.0];
R #STAT90;
CALL #STAT46 (
EN_R := #STAT90,
R := #STAT91,
LADDR := #IN0,
DB_NO := #IN4,
DBB_NO := #IN5,
NDR := #STAT92,
ERROR := #STAT93,
LEN := #STAT94,
STATUS := #STAT95,
COM_RST := #STAT96);
A( ;
A #STAT92;
AN #STAT93;
) ;
FP #STAT101;
R #STAT90;
R #STAT84;
JC M004;
FP #STAT102;
R #STAT90;
R #STAT84;
JC M004;
A( ;
A M 0.3;
FP #STAT103;
) ;
JCN M003;
L #STAT98;
+ 1;
T #STAT98;
L 6;
>=I ;
JCN M003;
R #STAT84;
M004: L 0;
T #STAT98;
L #STAT97;
+ 1;
T #STAT97;
L #IN7;
>I ;
JCN M003;
L 1;
T #STAT97;
M003: NOP 0;
END_FUNCTION_BLOCK

Помогите с переводом, буду очень благодарен!

Добавлен: ED    Дата: 2017-04-14

Помогите с переводм в SCL.
Подобных блоко много.
Нужно хотябы с чегото начать.

FUNCTION_BLOCK FB 3
TITLE =
VERSION : 0.0


VAR_INPUT
IN0 : TIMER ;
IN1 : BOOL ;
IN2 : BOOL ;
IN3 : BOOL ;
END_VAR
VAR_OUTPUT
OUT4 : BOOL ;
OUT5 : BOOL ;
OUT6 : BOOL ;
OUT7 : BOOL ;
END_VAR
VAR_IN_OUT
IO8 : BOOL ;
END_VAR
VAR_TEMP
TEMP9 : S5TIME ;
END_VAR
BEGIN
NETWORK
TITLE =

SET ;
SAVE ;
= L 2.1;
A #IO8;
L S5T#1S500MS;
L DIW [AR2,P#0.0];
T LW 4;
TAK ;
SE T [LW 4];
CLR ;
L DIW [AR2,P#0.0];
T LW 4;
TAK ;
R T [LW 4];
L DIW [AR2,P#0.0];
T LW 4;
TAK ;
LC T [LW 4];
T #TEMP9;
L DIW [AR2,P#0.0];
T LW 4;
TAK ;
A T [LW 4];
= #OUT4;
A #IO8;
JCN M001;
CLR ;
= #IO8;
M001: CLR ;
A #IN1;
= #OUT5;
A #IN2;
= #OUT6;
A #IN3;
= #OUT7;
A L 2.1;
SAVE ;
BE ;
END_FUNCTION_BLOCK

Добавлен: Andrey007x    Дата: 2017-05-09

Добрый день! Подскажите пожалуйста в чем проблема.
У меня тоже не сходится чексумма восстановленного блока. Код идентичен, а чексумма разная. Оригинальный блок скомпилирован на немецком языке. Восстановленный блок тоже компилировался на немецком языке. Сравнивались блоки созданные в scl. Код сравнивался путем сохранения блоков в stl и последующей генерации исходников, откуда в дальнейшем я брал текст и сравнивал текст обоих исходников. Текст исходников идентичен.

Добавлен: Константин    Дата: 2017-05-11

Добрый день!
После декомпиляции STL блока чексуммы оригинального и скомпилированного блоков совпадают. Но если открыть скомпилированный из SCL блок в STL-редакторе, нумерация меток немного другая по сравнению с оригиналом (+-2). В остальном код идентичен. Исходник создавался в версии K05.03.08.02_01.02.00.01, я компилирую в версии K05.03.08.03_04.01.00.01.
Может ли быть такое из-за другой версии компилятора?

Добавлен: Константин    Дата: 2017-05-14

Нашел разницу - вместо конструкции ELSIF .. END_IF; в некоторых местах надо было писать ELSE IF .. END_IF; END_IF; и наоборот.

Добавлен: komatic    Дата: 2017-06-03

так точно, при elsif в нумерации происходит пропуск одной метки

Добавить комментарий

Ваше имя:

Текст комментария (4000 max):

Введите сумму с картинки: