SCL. Получение указателя на выход

Промышленные Логические Контроллеры SIMATIC S7-200/300/400
Post Reply
Rex2701
Posts: 336
Joined: Wed Oct 13, 2010 8:44 am
Location: Russian Federation

SCL. Получение указателя на выход

Post by Rex2701 » Tue Aug 24, 2021 11:33 am

Помогите разобраться со следующей проблемой:
Есть тестовый блок-прототип, написанный на SCL:

Code: Select all

FUNCTION Point : VOID

VAR_INPUT

    In      : BYTE;
    In_Len  : INT := 16;
    Out_Len : INT := 16;
    Val1_In : WORD := W#16#0000;
    Val2_In : WORD := W#16#0000;
    Val3_In : WORD := W#16#0000;
    Val4_In : WORD := W#16#0000;
    Val5_In : WORD := W#16#0000;
    Val6_In : WORD := W#16#0000;
    Val7_In : WORD := W#16#0000;
    Val8_In : WORD := W#16#0000;

END_VAR

VAR_OUTPUT

    Out         : BYTE;
    Val1_Out    : WORD := W#16#0000;
    Val2_Out    : WORD := W#16#0000;
    Val3_Out    : WORD := W#16#0000;
    Val4_Out    : WORD := W#16#0000;
    Val5_Out    : WORD := W#16#0000;
    Val6_Out    : WORD := W#16#0000;
    Val7_Out    : WORD := W#16#0000;
    Val8_Out    : WORD := W#16#0000;

END_VAR

VAR_TEMP

    tAny    : ANY;

    stAny AT tAny :
        STRUCT
            S7Code : BYTE;
            DataType : BYTE;
            Length : INT;
            DBNumber : INT;
            MemoryArea : BYTE;
            ByteAddressMSB : BYTE;
            ByteAddressLSB : WORD;
        END_STRUCT;

    tLenIn  : INT;
    tLenOut : INT;
    tAddr   : ARRAY[1..8] OF WORD;
    tRetVal : INT;
    tByte1  : BYTE;
    tByte2  : BYTE;
    tByte3  : BYTE;
    tByte4  : BYTE;
    tWord   : WORD;
    tInt1   : INT;
    tInt2   : INT;
    
END_VAR

BEGIN

    tLenIn := In_Len;
    IF tLenIn < 1 THEN
        tLenIn := 1;
    ELSIF tLenIn > 16 THEN
        tLenIn := 16;
    END_IF;

    tLenOut := Out_Len;
    IF tLenOut < 1 THEN
        tLenOut := 1;
    ELSIF tLenOut > 16 THEN
        tLenOut := 16;
    END_IF;


    tAny := In;
    stAny.DataType := B#16#02;
    stAny.Length := tLenIn;

    tRetVal := BLKMOV(SRCBLK :=  tAny, DSTBLK := tAddr);
  
    Val1_Out := tAddr[1];
    Val2_Out := tAddr[2];
    Val3_Out := tAddr[3];
    Val4_Out := tAddr[4];
    Val5_Out := tAddr[5];
    Val6_Out := tAddr[6];
    Val7_Out := tAddr[7];
    Val8_Out := tAddr[8];

    tAddr[1] := Val1_In;
    tAddr[2] := Val2_In;
    tAddr[3] := Val3_In;
    tAddr[4] := Val4_In;
    tAddr[5] := Val5_In;
    tAddr[6] := Val6_In;
    tAddr[7] := Val7_In;
    tAddr[8] := Val8_In;

    tAny := Out;

    tByte1 := stAny.S7Code;
    tByte2 := stAny.DataType;
    tInt1 := stAny.Length;
    tInt2 := stAny.DBNumber;
    tByte3 := stAny.MemoryArea;
    tByte4 := stAny.ByteAddressMSB;
    tWord := stAny.ByteAddressLSB;

    stAny.DataType := B#16#02;
    stAny.Length := tLenOut;
    
    tRetVal := BLKMOV(SRCBLK :=  tAddr, DSTBLK := tAny);

END_FUNCTION
Ко входу In привязан IB120, к выходу Out - QB160 (адреса ничего не значат, всё происходит в PLCSIM для теста)
Когда я в tAny беру указатель на вход In, то в структуре получаю корректные данные:
0x10 - тип ANY
0x02 - размерность BYTE
0x01 - длина
0x00 - № DB
0x81 - межзонный указатель на область I
0x0003С0 - адрес 120

Но когда очередь доходит до получения указателя на Out, то в структуре наблюдается следующее:
0x10
0x02
0x01
0x00
0x87 - межзонный указатель на область L (локальный стек блока)
0x000008 - адрес 1
Ожидалось, что последние две записи будут равны 0x82 (область Q) и 0x000500 соответственно.

В первой версии In и Out имели тип ANY и всё отлично работало, но рабочий блок будет иметь тип FB, в которых выходы не могут быть ANY.

sania
Site Admin
Posts: 1297
Joined: Sat Aug 13, 2005 6:15 am
Contact:

Re: SCL. Получение указателя на выход

Post by sania » Tue Aug 24, 2021 12:51 pm

перенеси в in/out, тогда сможешь прочитать

Rex2701
Posts: 336
Joined: Wed Oct 13, 2010 8:44 am
Location: Russian Federation

Re: SCL. Получение указателя на выход

Post by Rex2701 » Tue Aug 24, 2021 1:15 pm

Да, это рабочее решение "в лоб". Я уже пробовал.
Но оно некрасивое, выход цепляется слева на вход.
Непонятно, почему в FC выход ANY нормально считывается, а в FB возникает такой косяк.

MaxS
Posts: 39
Joined: Sat May 17, 2014 1:26 am

Re: SCL. Получение указателя на выход

Post by MaxS » Wed Aug 25, 2021 4:55 am

Rex2701 wrote:
Tue Aug 24, 2021 1:15 pm
Непонятно, почему в FC выход ANY нормально считывается, а в FB возникает такой косяк.
Ганс Бергер
Автоматизация посредством STEP 7 с использованием STL и SCL и программируемых контроллеров SIMATIC S7-300/400.
Глава 26 - Прямой доступ к переменным.

Image

Rex2701
Posts: 336
Joined: Wed Oct 13, 2010 8:44 am
Location: Russian Federation

Re: SCL. Получение указателя на выход

Post by Rex2701 » Wed Aug 25, 2021 7:08 am

MaxS wrote:
Wed Aug 25, 2021 4:55 am
Автоматизация посредством STEP 7 с использованием STL и SCL и программируемых контроллеров SIMATIC S7-300/400.
Глава 26 - Прямой доступ к переменным.
Там сказано ровно то же самое. Страница 26-11, таблица 26-4. Тип ANY нельзя использовать как OUTPUT внутри FB.
Если посмотреть для FC, на стр. 26-8 в таблице 26-3 - использование разрешено.
При этом, формально, использовать ANY как OUTPUT в FB допускается. Ни редактор LAD/FBD/STL, ни компилятор SCL ругаться не будут. Но ANY просто не будет работать.
Это больше смахивает на какой-то узаконенный баг. Разницы между FC и FB никакой, кроме экземплярной DB, но она ломает работоспособность указателя на выходе.

sania
Site Admin
Posts: 1297
Joined: Sat Aug 13, 2005 6:15 am
Contact:

Re: SCL. Получение указателя на выход

Post by sania » Thu Aug 26, 2021 5:05 am

а если перейти на STL и вытянуть через p#DIXx.x...?
адресация абсолютная или символьная?

Rex2701
Posts: 336
Joined: Wed Oct 13, 2010 8:44 am
Location: Russian Federation

Re: SCL. Получение указателя на выход

Post by Rex2701 » Thu Aug 26, 2021 5:20 pm

Я тут сам уже немного запутался из-за кучи всевозможных перебранных вариантов.
Короче ситуация получается такая:
Внутри FC:
Для IN:
Если используется один из простых типов (я использовал BYTE) или ANY - указатель возвращается правильный.
Для OUT:
Если используется один из простых типов, то указатель возвращается на область V (16#87)
Если используется ANY, то указатель возвращается правильно.

Внутри FB:
Для IN:
Если используется один из простых типов, то указатель возвращается на DIX экземплярной DB.
Если используется ANY, то указатель возвращается правильно.
Для OUT:
Если используется один из простых типов, то указатель возвращается на DIX экземплярной DB.
ANY использовать нельзя.

Писанина на STL проблематична, потому что это PCS...
Получить указатель на DIX? А смысл? Да и в самом DIXе будет лежать простой тип с выходным значением.

Короче FC со входами/выходами ANY прямо идеальный вариант, за исключением того, что мне нужна FB.
Пока в голову пришла только наркомания выдавать в OUTе массив значений. В нулевом индексе - число задействованных элементов, с 1го - значения на выходы. И всё это подать на вход отдельного блочка FC, который завернёт это все в свой OUT ANY, потому что у него с этим проблем нет.

sania
Site Admin
Posts: 1297
Joined: Sat Aug 13, 2005 6:15 am
Contact:

Re: SCL. Получение указателя на выход

Post by sania » Thu Aug 26, 2021 8:11 pm

да уж..

а зачем внутри блока,если не секрет, знать на какой аут пошло значение?

udt? struct?
block_move без проблем должен принять на входе udt и выдать на выходы и не надо ещё блок.
только pcs пользует P-area а не IO-area
не понятно как используешь поинтер для PQ или всё-таки обычный Q?
с Q проблематичнее они обновляют вых. только в ОВ1, значит и блок должен вызываться из ОВ1

оффтоп и лирика:
какая религия мешает использовать stl? pcs отлично понимает даже lad.во всяком случае с 5 по 8 версию, в 9 не знаю, до неё апгрейд ещё не делал...

Rex2701
Posts: 336
Joined: Wed Oct 13, 2010 8:44 am
Location: Russian Federation

Re: SCL. Получение указателя на выход

Post by Rex2701 » Sun Aug 29, 2021 8:00 am

sania wrote:
Thu Aug 26, 2021 8:11 pm
а зачем внутри блока,если не секрет, знать на какой аут пошло значение?
Блок будет являться драйвером обмена с устройством PROFIBUS.
Но, как это часто бывает, размеры областей входов и выходов могут варьироваться, в зависимости от "воткнутых" записей из GSD.
В моём случае, входы могут гулять от 1 до 40 байт, выходы от 1 до 20 байт.
Поэтому предполагалось, что программист будет привязываться только к первому байту входа и выхода (которые будут в любом варианте), а блок на основании заданного числа входов и выходов будет читать и писать их необходимое количество.
Для этого и нужен корректный указатель на указанный выход, чтобы BLKMOV потом мог отправить подготовленный массив по адресу.

winice
Posts: 26
Joined: Mon Jul 26, 2010 4:09 am

Re: SCL. Получение указателя на выход

Post by winice » Mon Dec 06, 2021 12:13 pm

На входи выход поставить UDT? (boom)

Post Reply