Помогите разобраться с кодом на STL

Промышленные Логические Контроллеры SIMATIC S7-200/300/400
franzferdinand
Posts: 12
Joined: Wed Mar 14, 2018 10:46 am

Помогите разобраться с кодом на STL

Post by franzferdinand »

Здравствуйте.
На заводе есть линия - ПЛК S7-300, панель Siemens и частотник ABB 880. Сеть - PROFIBUS.
Стали возникать проблемы, начал искать их корень в проекте. Исходника нет, слил из контроллера. Без комментариев соответственно. Шел-шел и дошел до FC на STL. В остальных местах язык инструкций тоже встречался, но там было как-то легче, разбирался. а тут уперся и все, не могу пройти дальше. Поэтому прошу помощи. Функция довольно большая, поэтому выкладывать весь код не буду. Напишу несколько мест, которые меня больше всего интересуют, если надо больше информации - предоставлю.
Итак

Code: Select all

A     L     52.3
      L     B [AR1,P#8.0]
      L     B#16#46
      =     L     52.3
      ==I   
      A     L     52.3
      O     L     52.2
      JCN   M001
меня интересует то, что происходит в позиции M001. Если я правильно понял, чтобы в нее попасть, нужно, чтобы L52.3 оказалось ложью. А для этого надо, чтобы B [AR1,P#8.0] стало НЕравно 16#46.
Так вот не понимаю, как формируется и откуда берется B [AR1,P#8.0]

Есть в этой функции еще строки

Code: Select all

L     P##IN0
      LAR1  
      L     W [AR1,P#0.0]
      T     LW    54
      OPN   DB [LW 54]
      L     D [AR1,P#2.0]
      LAR1  
мне кажется из них потом формируется B [AR1,P#8.0], но я вообще не понимаю эти инструкции во втором куске кода.
Очень жду советов!
Usver
Posts: 193
Joined: Fri Feb 24, 2012 8:28 am

Re: Помогите разобраться с кодом на STL

Post by Usver »

Похоже, что это было написано на SCL.
Ну, если я не ошибаюсь, первый кусок работает примерно так: if (not(B [AR1,P#8.0] <> B#16#46)and(L52.3)or(L52.2)), то прыжок.
Второй кусок:

Code: Select all

L     P##IN0          //Загружается адрес входа #IN0
      LAR1                      //Помещается в AR1
      L     W [AR1,P#0.0]  //Считывается значение типа ВОРД из #IN0
      T     LW    54           //Помещается в LW    54
      OPN   DB [LW 54]      //Открывается DB номер [LW    54] (#IN0)
      L     D [AR1,P#2.0]    //Считывается значение типа DВОРД по адресу AR1 + 2 байта
      LAR1                       //Помещается в AR1
 
franzferdinand
Posts: 12
Joined: Wed Mar 14, 2018 10:46 am

Re: Помогите разобраться с кодом на STL

Post by franzferdinand »

Usver, хорошо, спасибо. Неясно как работает указатель p#
Перепишу код с комментариями и еще добавлю своих

Code: Select all

L     P##IN0          //Загружается адрес входа #IN0. При вызове IN0 = DB10.DBX0.0
         LAR1                      //Помещается в AR1. Т.е. в AR1 лежит DB10.DBX0.0?
         L     W [AR1,P#0.0]  //Считывается значение типа ВОРД из #IN0
         T     LW    54           //Помещается в LW    54. я не знаю почему, но если мониторить значения онлайн, то в LW лежит "10"
         OPN   DB [LW 54]      //Открывается DB номер [LW    54] (#IN0). Открываем DB10?...
         L     D [AR1,P#2.0]    //Считывается значение типа DВОРД по адресу AR1 + 2 байта. это получается DB10.DBD2?
         LAR1                       //Помещается в AR1
 
Вопросы собственно в комментариях к коду. интуитивно понял, что это дело вращается вокруг DB10. этот блок данных, во-первых, не формируется в программе. не считая DB10.DBX55.0
Во-вторых, его содержимое - массив из 9 переменных CHAR, потом массив 14 переменных CHAR, потом строка из элементов первого массива, потом строка из эл-ов 2-ого массива, потом один логический бит. зачем там какие-то Char-ы...
Usver
Posts: 193
Joined: Fri Feb 24, 2012 8:28 am

Re: Помогите разобраться с кодом на STL

Post by Usver »

При вызове IN0 = DB10.DBX0.0
Хотите сказать, что IN0 типа BOOL? Напишите интерфейс функции.
я не знаю почему, но если мониторить значения онлайн, то в LW лежит "10"
в онлайне смотрели в представлении НЕХ или десятичный?
Неясно как работает указатель p#
в каком месте неясно?
franzferdinand
Posts: 12
Joined: Wed Mar 14, 2018 10:46 am

Re: Помогите разобраться с кодом на STL

Post by franzferdinand »

в каком месте неясно?
стало ясно после прочтения документа по STL.
в онлайне смотрели в представлении НЕХ или десятичный?
пойду еще смотреть. но вроде десятичный скорее.
Хотите сказать, что IN0 типа BOOL? Напишите интерфейс функции
нет. IN0 есть array [0..8] of char.

DB10 имеет такой вид:
0.0 array [0..8] of char
10.0 array [0..14] of char
26.0 string[9]
38.0 string [15]
55.0 bool

откуда после массивов берутся по лишнему байту? как я считаю, второй массив должен занимать адрес начиная с 9.0...
Rex2701
Posts: 374
Joined: Wed Oct 13, 2010 8:44 am
Location: Russian Federation

Re: Помогите разобраться с кодом на STL

Post by Rex2701 »

IN0 у тебя является указателем, на что намекает инструкция L P##IN0.
Чтобы работать с указателем, надо его закинуть в AR1.
Дальше читаем хелп, что есть указатель и из чего состоит.
Команда L W [AR1,P#0.0] берет слово из указателя по смещению 0, где (внезапно!) лежит № DB.
А команда L D [AR1,P#2.0] берет двойное слово по смещению 2, которое само является внутризонным указателем. Поэтому его снова кидаем в AR1.

Поэтому, в итоге, при вызове с IN0 = DB10.DBX0.0 ты получаешь LW54 = 10, а двойное слово будет D#16#8400 0000. Если же DB10 является инстансной для FB, то D#16#8500 0000.
Открыв полученный номер DB в OPN DB [LW 54] и загнав внутризонный указатель в AR1, они получили возможность обращаться к элементам внутри DB по индексу: L x [AR1, P#y.z].

Раз у вас первым в DB лежит массив CHAR'ов от 0 до 8, то как раз последний символ (L B [AR1,P#8.0] они проверяют на код 46, т.е. "F". Почему и зачем - вам виднее....
Last edited by Rex2701 on Mon Sep 17, 2018 12:37 pm, edited 1 time in total.
franzferdinand
Posts: 12
Joined: Wed Mar 14, 2018 10:46 am

Re: Помогите разобраться с кодом на STL

Post by franzferdinand »

ну в целом понял. после второй команды LAR мы начинаем работать с DB10, но не с начала, а с байта 2.0 кмк.
В любом случае это печально, потому что я не вижу, чтобы DB10 (он блок с данными, НЕ экземпляр) где-то явно формировался. поэтому дальнейшие изыскания малоперспективны.
спасибо.
Rex2701
Posts: 374
Joined: Wed Oct 13, 2010 8:44 am
Location: Russian Federation

Re: Помогите разобраться с кодом на STL

Post by Rex2701 »

franzferdinand wrote:откуда после массивов берутся по лишнему байту? как я считаю, второй массив должен занимать адрес начиная с 9.0...
STEP7 все разнородные данные выравнивает на границу слова, т.е. четные адреса.
Usver
Posts: 193
Joined: Fri Feb 24, 2012 8:28 am

Re: Помогите разобраться с кодом на STL

Post by Usver »

ну так-то IN0 не может быть DB10.DBX0.0. Вызов функции д.б.

Code: Select all

call fc number
IN0 = P#DB10.DBX0.0 BYTE 9
...
Поэтому номер ДБ для открытия лежит по адресу DB10.DBW0.
Вопросы собственно в комментариях к коду. интуитивно понял, что это дело вращается вокруг DB10. этот блок данных, во-первых, не формируется в программе. не считая DB10.DBX55.0
Об этом Вы не можете знать наверняка, т.к. работа с DB10 может быть организована также, как и в этой ф-ции.
Usver
Posts: 193
Joined: Fri Feb 24, 2012 8:28 am

Re: Помогите разобраться с кодом на STL

Post by Usver »

franzferdinand wrote:ну в целом понял. после второй команды LAR мы начинаем работать с DB10, но не с начала, а с байта 2.0 кмк.
В любом случае это печально, потому что я не вижу, чтобы DB10 (он блок с данными, НЕ экземпляр) где-то явно формировался. поэтому дальнейшие изыскания малоперспективны.
спасибо.
разумеется малоперспективны, если программа большая.
franzferdinand
Posts: 12
Joined: Wed Mar 14, 2018 10:46 am

Re: Помогите разобраться с кодом на STL

Post by franzferdinand »

Usver wrote:ну так-то IN0 не может быть DB10.DBX0.0. Вызов функции д.б..

Code: Select all

call fc number
IN0 = P#DB10.DBX0.0 BYTE 9
...
и тем не менее вызов именно такой: IN0 := P#DB10.DBX0.0
без BYTE 9
Usver
Posts: 193
Joined: Fri Feb 24, 2012 8:28 am

Re: Помогите разобраться с кодом на STL

Post by Usver »

и тем не менее вызов именно такой: IN0 := P#DB10.DBX0.0
без BYTE 9
ну верится с трудом, т.к.
franzferdinand wrote: IN0 есть array [0..8] of char.

DB10 имеет такой вид:
0.0 array [0..8] of char
10.0 array [0..14] of char
26.0 string[9]
38.0 string [15]
55.0 bool
, а P#DB10.DBX0.0 это адрес откуда брать (это не равносильно DB10.DBX0.0), а дальше должно указываться количество байт. Вы курсором в степе кликните по этому месту может появится продолжение.
Ну тем не менее адрес для открытия ДБ должен находится в DB10.DBW0. И если это 10, то Указатель на адрес для работы с этой ДБ должен находиться по адресу DB10.DBD2.
Rex2701
Posts: 374
Joined: Wed Oct 13, 2010 8:44 am
Location: Russian Federation

Re: Помогите разобраться с кодом на STL

Post by Rex2701 »

POINTER не может содержать количество данных, для этого есть ANY.
Usver
Posts: 193
Joined: Fri Feb 24, 2012 8:28 am

Re: Помогите разобраться с кодом на STL

Post by Usver »

Rex2701 wrote:POINTER не может содержать количество данных, для этого есть ANY.
Сегодня проверил на степе, да запись действительно такая, как POINTER. Но тем не менее на вход должен передаваться массив array [0..8] of char.
franzferdinand
Posts: 12
Joined: Wed Mar 14, 2018 10:46 am

Re: Помогите разобраться с кодом на STL

Post by franzferdinand »

Usver, вероятно указатель лишь указал функции точку, с которой начинать отсчет, а она, основываясь на своем интерфейсе, взяла нужное количество данных?
в любом случае я Вам предоставил 100% точную информацию по программе.
Rex2701
Posts: 374
Joined: Wed Oct 13, 2010 8:44 am
Location: Russian Federation

Re: Помогите разобраться с кодом на STL

Post by Rex2701 »

Usver wrote:
Rex2701 wrote:POINTER не может содержать количество данных, для этого есть ANY.
Сегодня проверил на степе, да запись действительно такая, как POINTER. Но тем не менее на вход должен передаваться массив array [0..8] of char.
Вы определённо не понимаете специфику Simatic - через входы-выходы нельзя передавать ничего кроме элементарных типов данных. И чтобы работать с массивами и структурами - придумали указатели POINTER и ANY, чтобы работать с ними косвенно "по удалёнке". Поэтому ваша функция получив указатель, работает с массивом поэлементно через AR1 + смещение.
Usver
Posts: 193
Joined: Fri Feb 24, 2012 8:28 am

Re: Помогите разобраться с кодом на STL

Post by Usver »

franzferdinand wrote:Usver, вероятно указатель лишь указал функции точку, с которой начинать отсчет, а она, основываясь на своем интерфейсе, взяла нужное количество данных?
Ну тут не совсем так. Если Вы создадите новый проект и в нем сделаете FC, у которого IN0 будет array [0..8] of char, сделаете такой же DB10 и в вызове функции напишите

Code: Select all

call fc number
IN0 = P#DB10.DBX0.0
, то увидите что P#DB10.DBX0.0 подсветится красным цветом. В информации об ошибке будет сказано, что тип POINTER не может использоваться для вызова этой FC, т.к. IN0 - это ARRAY. А если DB10 дать имя (допустим "QWE") и дать имя массиву в этой ДБ (допустим "rty") и в вызове написать IN0 = "QWE".rty, тогда все будет нормально. И в коментарии увидите P#DB10.DBX0.0. Я пару лет назад с таким сталкивался, тогда у меня на входе было UDT.
Usver
Posts: 193
Joined: Fri Feb 24, 2012 8:28 am

Re: Помогите разобраться с кодом на STL

Post by Usver »

Rex2701 wrote:Вы определённо не понимаете специфику Simatic
Ну на счет определенно или нет, наверно Вам виднее. Но все равно передается МАССИВ. Разумеется он передается через указатель, но передается именно он. (Если не верите, возьмите и сами попробуйте.) Другое дело, если Вы будете писать вызов этой функции с параметром IN0 = P#DB10.DBX0.0, то вряд ли получится (для степа на данном этапе P#DB10.DBX0.0 - ПОИНТЕР и информации о типе, т.е. что находится по этому адресу он не знает. Я тут не причем.) . А вот если бы можно было так :IN0 = P#DB10.DBX0.0 AS ARRAY [0..8] OF CHAR ... Да к сожалению такой записи не может быть.
Ну запамятовал как вызываются такие функции, ну с кем не бывает?
Rex2701 wrote:через входы-выходы нельзя передавать ничего кроме элементарных типов данных
Если я не ошибаюсь, это у Бергера написано. Читали когда-то. Давненько правда, но читали.
Rex2701 wrote:И чтобы работать с массивами и структурами - придумали указатели POINTER и ANY, чтобы работать с ними косвенно "по удалёнке"
Ну так этот принцип давно был придуман, и что-то я так подозреваю, что придуман он был не в Сименсе.
Dfcz
Posts: 878
Joined: Tue Dec 26, 2006 5:21 am
Location: Russia

Re: Помогите разобраться с кодом на STL

Post by Dfcz »

Пипец, кино и немцы.
Usver
Posts: 193
Joined: Fri Feb 24, 2012 8:28 am

Re: Помогите разобраться с кодом на STL

Post by Usver »

Dfcz wrote:Пипец, кино и немцы.
они самые)))))))))))))))
Dfcz
Posts: 878
Joined: Tue Dec 26, 2006 5:21 am
Location: Russia

Re: Помогите разобраться с кодом на STL

Post by Dfcz »

А как хорошо все начиналось:
franzferdinand wrote:...
Стали возникать проблемы, начал искать их корень в проекте....
И докатилось все до чего:
Rex2701 wrote:…. специфику Simatic - через входы-выходы нельзя передавать ничего кроме элементарных типов данных. И чтобы работать с массивами и структурами - придумали указатели POINTER и ANY, чтобы работать с ними косвенно "по удалёнке". Поэтому ваша функция получив указатель, работает с массивом поэлементно через AR1 + смещение.
А корень-то проблем в 99 случаев из 100 не в проекте.
franzferdinand
Posts: 12
Joined: Wed Mar 14, 2018 10:46 am

Re: Помогите разобраться с кодом на STL

Post by franzferdinand »

Ценю Ваше желание помочь (а оно ведь есть, раз отвечаете), но пост из серии "лишь бы написать", учитывая, что Вы не знаете всю историю.
Ответы на вопросы по теме я получил, спасибо.
Dfcz
Posts: 878
Joined: Tue Dec 26, 2006 5:21 am
Location: Russia

Re: Помогите разобраться с кодом на STL

Post by Dfcz »

Ну, в коде вы разобрались, теперь осталось найти проблему и ее решение.
:)
Удачи.
:)