Одна функция в разных потоках

Обсуждение SCADA-систем: Citect SCADA, Vijeo Citect, CitectSCADA, CitectFacilities, PowerLogic SCADA, PowerSCADA, MX4SCADA, Desigo Insight.
romasimeiz
Сообщений в теме: 4
Сообщения: 32
Зарегистрирован: 14 май 2015, 09:48

Одна функция в разных потоках

#1

Сообщение romasimeiz » 07 окт 2015, 14:01

Добрый день! Помогите пожалуйста, разобраться.
Написал универсальную функцию реализующую один алгоритм только с разными массивами переменных.
Сначала создал события, по которым одна и та же функция вызывается с разными параметрами. Если срабатывает только одно событие, то алгоритм отрабатывает нормальное. Если срабатывает сразу несколько событий с одной и той же функцией (параметры передаваемые в функцию разные) начинается неразбериха. алгоритм начинает работать правильно, но дальнейшая работа некорректная..
Решил выйти из ситуации - запускать функцию в TaskNew, тоже с разными параметрами.. Но стало ещё хуже...
Нельзя как то сконфигурировать сайтек, чтобы потоки работали как то независимо друг от друга ?
По идее , в отдельном потоке должна быть копия оригинальной функции, только с разными параметрами ?
Из отладчика видно, что потоки мешают друг другу.
Подскажите, или поделитесь, пожалуйста опытом : как использовать одну и ту же функцию одновременно для разных переменных!
Спасибо!



Ryzhij
Сообщений в теме: 1
Сообщения: 11
Зарегистрирован: 23 фев 2015, 20:22
Благодарил (а): 1 раз

Re: Одна функция в разных потоках

#2

Сообщение Ryzhij » 07 окт 2015, 15:11

По определению структурный блок типа "Функция" имеет в памяти ПЛК только один экземпляр кода.
Вызываться на исполнение этот участок кода одновременно из разных мест не может.
Вам надо создавать "Функциональный блок", код которого при компиляции копируется в тело программы нужное количество раз.



romasimeiz
Сообщений в теме: 4
Сообщения: 32
Зарегистрирован: 14 май 2015, 09:48

Re: Одна функция в разных потоках

#3

Сообщение romasimeiz » 07 окт 2015, 15:17

спасибо!
а как его объявить ? функциональный блок ?



Аватара пользователя
alex
Администратор
Сообщений в теме: 2
Сообщения: 1781
Зарегистрирован: 05 апр 2010, 21:58
Откуда: Москва
Благодарил (а): 52 раза
Поблагодарили: 111 раз
Контактная информация:

Re: Одна функция в разных потоках

#4

Сообщение alex » 07 окт 2015, 16:30

Можете показать Вашу функцию, как организованы данные и как передаются в функцию?



romasimeiz
Сообщений в теме: 4
Сообщения: 32
Зарегистрирован: 14 май 2015, 09:48

Re: Одна функция в разных потоках

#5

Сообщение romasimeiz » 07 окт 2015, 16:45

Код: Выделить всё

  INT cO;
 
FUNCTION Open_Discr(INT ShkafID, INT Valve_ID)
STRING KO = iGetKOString(ShkafID, Valve_ID); // текст этой функции приведен ниже
STRING SO = iGetSOString(ShkafID, Valve_ID); // аналогичны
STRING SC = iGetSCString(ShkafID, Valve_ID); // текст не привожу во избежание мусорки
STRING RO = iGetROString(ShkafID, Valve_ID);
IF donesenie[ShkafID] = 1 THEN TagWrite(RO,1); ELSE TagWrite(RO,0) END
INT c;
TagWrite(SO,1); 
TagWrite(SC,1);
FOR c = 0 TO T2[(ShkafID * 10 + Valve_ID) - 10] DO
Sleep(1);
cO = cO+1;
iTimerV[(ShkafID * 10 + Valve_ID) - 10] = iTimerV[(ShkafID * 10 + Valve_ID) - 10] + 1;      
   IF TagRead(KO) = "1" AND cO = T2[(ShkafID * 10 + Valve_ID) - 10] THEN
         IF iERR4[(ShkafID * 10 + Valve_ID) - 10] = 0 THEN
         IF iERR1[(ShkafID * 10 + Valve_ID) - 10] = 0 THEN
            IF iERR2[(ShkafID * 10 + Valve_ID) - 10] = 1 THEN
               TagWrite(SC,1);
               TagWrite(SO,1);
               iT_ERR[(ShkafID * 10 + Valve_ID) - 10] = 1;
            ELSE
               IF iERR3[(ShkafID * 10 + Valve_ID) - 10] = 1 THEN
                  TagWrite(SC,1);
                  iT_ERR[(ShkafID * 10 + Valve_ID) - 10] = 1;
               ELSE
                  TagWrite(SO,1);
                  TagWrite(SC,0);
               END             
            END
         END
      END
   ELSE IF TagRead(KO) = "0" THEN
              TagWrite(RO,0);
              cO = 0;
              iTimerV[(ShkafID * 10 + Valve_ID) - 10] = 0
              RETURN;
      END   
   END
END
TagWrite(RO,0);
cO = 0;
iTimerV[(ShkafID * 10 + Valve_ID) - 10] = 0
END


Код: Выделить всё

//привожу текст функции, которая формирует имя тега в зависимости от входных параметров
STRING FUNCTION iGetKOString(INT shkaf, INT valve)
STRING ans;
IF shkaf <=10 THEN
ans = "iDigValveCmd_" + IntToStr(shkaf) + "[" + IntToStr(KO_MF[valve]) + "]";
RETURN ans
ELSE IF shkaf <=20 THEN
     ans = "iDigValveCmd_" + IntToStr(shkaf) + "[" + IntToStr(KO_NaF[valve]) + "]";
     RETURN ans
     ELSE IF shkaf = 21 THEN
          ans = "iDigValveCmd_" + IntToStr(shkaf) + "[" + IntToStr(KO_VF[valve]) + "]";
          RETURN ans
          ELSE IF shkaf = 22 THEN
               ans = "iDigValveCmd_" + IntToStr(shkaf) + "[" + IntToStr(KO_DF[valve]) + "]";
               RETURN ans
               ELSE IF shkaf = 23 THEN
                    ans = "iDigValveCmd_" + IntToStr(shkaf) + "[" + IntToStr(KO_SP[valve]) + "]";
                    RETURN ans;
                    ELSE IF shkaf = 24 THEN
                         ans = "iDigValveCmd_" + IntToStr(shkaf) + "[" + IntToStr(KO_NO[valve]) + "]";
                         RETURN ans;
                         END
                    END
               END
          END
     END
 END
END


пример моего события1:
NAME TIME PERIOD TRIG EVENT
GLOBAL iDigValveCmd_1[0] = 1 Open_Discr(1, 0)

события 2:
NAME TIME PERIOD TRIG EVENT
GLOBAL iDigValveCmd_1[2] = 1 Open_Discr(1, 1)



Аватара пользователя
alex
Администратор
Сообщений в теме: 2
Сообщения: 1781
Зарегистрирован: 05 апр 2010, 21:58
Откуда: Москва
Благодарил (а): 52 раза
Поблагодарили: 111 раз
Контактная информация:

Re: Одна функция в разных потоках

#6

Сообщение alex » 08 окт 2015, 09:31

В данных исходниках меня смущает модульная переменная:
[syntax=cicode] INT cO;[/syntax]
которая используется функцией Open_Discr, которая, как я понимаю, вызывается из событий или запускается в отдельных задачах. Как выполняются несколько задач одновременно никто не знает, это внутренние дела Vijeo Citect, но однозначно что тело функции выполняется не "в один присест", и прерывается на выполнение других функций (это подразумевает многозадачность), поэтому в эту переменную могут писать свои значения как функция из одного события со своими параметрами по ходу выполнения, так и из другого со своими в свою очередь, когда ей будет выделено процессорное время, а первая функция будет в какой-то момент прервана. Я подозреваю что дело в этом.



romasimeiz
Сообщений в теме: 4
Сообщения: 32
Зарегистрирован: 14 май 2015, 09:48

Re: Одна функция в разных потоках

#7

Сообщение romasimeiz » 08 окт 2015, 11:44

убрал использование модульных переменных вообще. только локальные и переменные теги (массивы), обращение к которым строго по уникальному индексу. заработало!!! спасибо! )




Если эта тема может быть полезна другим, поделитесь ссылкой:

Вернуться в «Citect SCADA, Vijeo Citect, CitectSCADA, CitectFacilities, PowerLogic SCADA, PowerSCADA, MX4SCADA, Desigo Insight»