EnglishУкраїнськаmRussian
Login/New
Topic with no new replies

[BugWrong] Не выключается контроллер


Author Message
Written on: 16. 01. 2014 [08:19]
Godzilla
Арсен Закоян
Contributor
Topic creator
registered since: 12.02.2013
Posts: 123
Добрый день.Создаю пользовательский протокол и в библиотеке устройств шаблон.Создаю контроллер на логическом уровне и добавляю параметр для него.Параметры ожидания ответа транспорта 5000:1000.Если шаблоне делаю попытку запросов 10 раз то зачастую выдает ошибку "Задача sub_DAQ.mod_LogicLev.cntr_230SGH не остановлена!".А если добавить для контроллера еще несколько параметров то остановить контроллер почти невозможно,ошибка повторяется регулярно.Если попытка всего одна то проблем не возникает.Я так понимаю чем дольше время выполнения шаблона тем больше проблем.Менял и максимальное время вычисления в шаблоне,не помогает.Что я делаю не так?
Written on: 16. 01. 2014 [08:43]
roman
Roman Savochenko
Moderator
Contributor
Developer
registered since: 12.12.2007
Posts: 3750
"Godzilla" wrote:

Добрый день.
Создаю пользовательский протокол и в библиотеке устройств шаблон.Создаю контроллер на логическом уровне и добавляю параметр для него.Параметры ожидания ответа транспорта 5000:1000.Если шаблоне делаю попытку запросов 10 раз то зачастую выдает ошибку "Задача sub_DAQ.mod_LogicLev.cntr_230SGH не остановлена!".

Ну так, сам себе злобный Буратино. Он честно прерывает ожидание транспорта, а Вы его 10 раз туда-же возвращаете. А если 100 поставить то он процедуры прерывать по таймауту безопасности начнёт!

Не ошибка!

Learn, learn and learn better than work, work and work.
Written on: 16. 01. 2014 [09:04]
Godzilla
Арсен Закоян
Contributor
Topic creator
registered since: 12.02.2013
Posts: 123
Но сами запросы то работают, честно пытается запросить 10 раз(сниффером проверял).Или я так понимаю один шаблон - одно срабатывание транспорта,а если мне нужно реализовать несколько попыток, где это можно сделать?
код шаблона таков:
k=0;
while ( k<10)
{req = SYS.XMLNode().setAttr("ProtIt","mercury").setAttr("netaddr",netaddr).setAttr("data",SYS.strFromCharCode(0x01,0x01,Special.FLibSYS.str2int(password.slice(0,1)), Special.FLibSYS.str2int(password.slice(1,2)), Special.FLibSYS.str2int(password.slice(2,3)), Special.FLibSYS.str2int(password.slice(3,4)), Special.FLibSYS.str2int(password.slice(4,5)), Special.FLibSYS.str2int(password.slice(5,6))));
SYS.Transport["Serial"]["out_"+transport].messIO(req,"UserProtocol");
if(req.text().length >1) break;
k++;}
if(req.text().length <1) answer = EVAL_STR;
else answer =req.text();

[This article was edited 3 times, at last 16.01.2014 at 09:09.]
Written on: 16. 01. 2014 [10:24]
roman
Roman Savochenko
Moderator
Contributor
Developer
registered since: 12.12.2007
Posts: 3750
"Godzilla" wrote:

Но сами запросы то работают, честно пытается запросить 10 раз(сниффером проверял).Или я так понимаю один шаблон - одно срабатывание транспорта,а если мне нужно реализовать несколько попыток, где это можно сделать?
код шаблона таков:

Читаем про "Циклическое программирование" и осознаём, что незачем плодить 10 запросов в одном цикле и ставить такие большие таймауты у транспорта.

Learn, learn and learn better than work, work and work.
Written on: 21. 01. 2014 [14:45]
Godzilla
Арсен Закоян
Contributor
Topic creator
registered since: 12.02.2013
Posts: 123
А где можно посмотреть конкретные примеры?Без них трудновато вникнуть в циклическое программирование.
Written on: 21. 01. 2014 [19:19]
roman
Roman Savochenko
Moderator
Contributor
Developer
registered since: 12.12.2007
Posts: 3750
"Godzilla" wrote:

А где можно посмотреть конкретные примеры?Без них трудновато вникнуть в циклическое программирование.

В реализациях пользовательских протоколов, например.

Learn, learn and learn better than work, work and work.
Written on: 23. 01. 2014 [14:38]
Godzilla
Арсен Закоян
Contributor
Topic creator
registered since: 12.02.2013
Posts: 123
Более-менее разобрался, f_frq отсчитывает время с начала цикла.А если мне надо например выполнить несколько попыток запроса в определенное время а не спустя какое-то количество секунд,можно ли это сделать в формате cron?
Written on: 23. 01. 2014 [19:37]
roman
Roman Savochenko
Moderator
Contributor
Developer
registered since: 12.12.2007
Posts: 3750
"Godzilla" wrote:

Более-менее разобрался, f_frq отсчитывает время с начала цикла.А если мне надо например выполнить несколько попыток запроса в определенное время а не спустя какое-то количество секунд,можно ли это сделать в формате cron?

Не разобрались совсем!
f_frq ничего не отсчитывает, а содержит значение частоты вычисления задачи с этой процедурой.
Причём тут количества секунд? Задача может выполняться и чаще 1Гц и соотвентственно следующая попытка это просто запрос в следующем цикле. А cron это вообще период 1 минута, но если попытки с такой периодичностью устраивают то можно и его.

Learn, learn and learn better than work, work and work.
Written on: 31. 01. 2014 [13:54]
Godzilla
Арсен Закоян
Contributor
Topic creator
registered since: 12.02.2013
Posts: 123
Ну вот например создал я контроллер,создал два параметра,каждый из которых будут иметь по 2 атрибута.Каждый атрибут опрашивается в 1 цикл .Поставил в настройках контроллера опрос раз в 1 мин cron * * * * *.Опрос идет в следующем порядке:
1 первый атрибут первого параметра
2 первый атрибут второго параметра
3 второй атрибут первого параметра
4 второй атрибут второго параметра
минута проходит и опять по кругу.
А хотелось бы чтобы каждый параметр опрашивался по порядку.Если я раньше последовательно писал в шаблоне все опросы по порядку,проблем не было кроме как с выключением контроллера,что как оказалось было неверно.А как писать шаблон и циклическим опросом и чтоб все было по порядку я еще не до конца понял.
Вот код шаблона,что я делаю не так?
JAVASCRIPT
if(f_start)n=0;
if(((cnt++)%max(1,perGet*f_frq))&&(n==0))return;
if(n==0)
{req = SYS.XMLNode().setAttr("ProtIt","test").setAttr("netaddr",netaddr);
SYS.Transport["Serial"]["out_"+transport].messIO(req,"UserProtocol");
n=1;}
else if (n==1)
{req = SYS.XMLNode().setAttr("ProtIt","test").setAttr("netaddr",netaddr2);
SYS.Transport["Serial"]["out_"+transport].messIO(req,"UserProtocol");
n=0;}


[This article was edited 2 times, at last 31.01.2014 at 13:57.]
Written on: 31. 01. 2014 [16:11]
roman
Roman Savochenko
Moderator
Contributor
Developer
registered since: 12.12.2007
Posts: 3750
"Godzilla" wrote:

А хотелось бы чтобы каждый параметр опрашивался по порядку.Если я раньше последовательно писал в шаблоне все опросы по порядку,проблем не было кроме как с выключением контроллера,что как оказалось было неверно.А как писать шаблон и циклическим опросом и чтоб все было по порядку я еще не до конца понял.
Вот код шаблона,что я делаю не так?

Что тут вообще так?
Я Вам говорил, что cron для этого использовать не нужно, причём в связке со счётчиком циклов!
JAVASCRIPT
if(f_start) cnt = n = 0;
if(((cnt++)%max(1,perGet*f_frq)) == 0) n = 0;
if(n = 0); //Request parameter 1
else if(n = 1); //Request parameter 1
n++;


И вообще проблема не в запросе нескольких параметров в одном цикле, а в попытке их запроса при получении ошибки на первом-же. А также сильно завышенных таймаутах.

Чтобы была понятна суть проблемы и почему так нельзя делать повторю:
Вы в одном цикле вызывали 10 попыток запроса. Если связь нормальная то это не проблема, поскольку запрос быстро проходит и задача завершается. Однако если связи нет, то он ожидает ответа 5 секунд (ваши таймауты), затем ещё 10 раз по пять.
Функция останова контроллера в течении 5 секунд шлёт сигналы SIG_ALARM прерывающих эти таймауты ожидания, а Вы его 10 раз возвращаете назад, ещё и не факт, что и на протокольной стороне нет ещё десятка попыток. В результате он просто не дожидается завершения бесплодных и бессмысленных попыток повтора.

Вывод:
1) Не нужно попытками компенсировать низкое качество связи. Т.е. больше двух вообще смысла уже не имеет и только создаёт проблемы.
2) Нужно ставить таймауты под реальные свойства устройства. Т.е. если устройство отвечает за 10 мс, то не нужно ставить таймаут подключения в 1 секунду и 20 мс достаточно, а про время символа написано тут: http://wiki.oscada.org/Doc/Serial#h835-6
3) Не выполнять следующих по порядку запросов если предыдущей с ошибкой.

Learn, learn and learn better than work, work and work.



3406