PDA

Просмотр полной версии : мистическая комбинация в ПЛК150



Ian
14.04.2021, 16:14
Добрый день,

В программе на ST написанной для ПЛК 150, булевская переменная принимает странное значение и показывает ошибку для переменной xInit. Саму программу в которой это было обнаружено я упростил, убрал все лишнее, чтобы продемонстрировать ошибку. Если написать программу четко, как на скрине, то будет ошибка.

Ошибка возникает только если iCount:=6 и массив aBuffer: ARRAY [1..5] OF WORD из пяти элементов.

Можно подумать, что массив из 5 элементов, а iCount равен 6 и поэтому запись в массив некорректная, но во-первых причем тут булевская переменная xInit, которую вообще не трогают, а во-вторых при любых других значения iCount больших 6, такой ситуации не возникает.
И в принципе никогда больше такой ситуации не возникает, в которой булевская переменная принимает не свойственное ее типу ошибочное значение, какие бы комбинации размеров массива и iCount я не делал. То есть только комбинация когда массив из 5 элементов и iCount:=6 дает ошибочное значение xInit ни каким боком не относящейся к этому массиву и переменной iCount. Если массив и переменную wX сделать типа INT то ошибки также не возникает даже при комбинации iCount=6 и массива aBuffer: ARRAY [1..5] OF INT.

Прошу пояснить эту мистику на ПЛК150.


В приложении скрины.

С уважением, Михаил

Ian
14.04.2021, 22:19
Зачем было так тратиться на лишние слова и эмоции, после которых ничего не стало яснее.


А причем тут ПЛК150 ? У вас массив 1..5 а пишете хрен знает куда, и хрень будет в любом языке на любом плк, пк, и прочем утюге.
Вопрос был почему так выходит только при такой комбинации когда массив из пяти, пишется значение в шестой и возникает неправильное значение в булевской переменной, которая не относится к этому массиву. Если писать в седьмой или любой другой, которого тоже нет, то ошибки не возникает. Ошибка если только в шестой.


Уверены ? Залейте поллитру в стакан и подумайте - причем тут пол который вообще не трогают.

Если бы я в чем то был уверен, то вопросы бы не задавал, а искал бы по форумам на кого бы вызвериться. Если хотите помочь понять, то лучше как то пояснее, без поллитра, а побольше конкретики.


Да что вы, а не досуг было hex в dec перевести, сравнить с чем нить и немного подумать ?
То что значение переменной wX попадает в xInit это сразу было понятно. Непонятно почему оно туда попадает только когда массив из 5 элементов и значение пишется в шестой. Если сделать массив из 4 элементов, и писать в пятый или в любой другой, то ошибка не появляется. В этом и мистика для меня лично.

Евгений Кислов
15.04.2021, 06:31
Вопрос был почему так выходит только при такой комбинации когда массив из пяти, пишется значение в шестой и возникает неправильное значение в булевской переменной, которая не относится к этому массиву. Если писать в седьмой или любой другой, которого тоже нет, то ошибки не возникает. Ошибка если только в шестой.

Потому что компилятор размещает переменную xInit по адресу памяти, расположенному следом за адресом последнего элемента массива.
Cедьмой, восьмой и другие несущестующие элементы соответствуют другим адресам памяти, которые не имеют отношения к переменной xInit.


То что значение переменной wX попадает в xInit это сразу было понятно. Непонятно почему оно туда попадает только когда массив из 5 элементов и значение пишется в шестой. Если сделать массив из 4 элементов, и писать в пятый или в любой другой, то ошибка не появляется. В этом и мистика для меня лично.

Вы, видимо, просто не выполняете команду Проект - Очистить все при внесении изменений - в этом случае компилятор, вероятно, не перераспределяет адреса.

54554

Естественно, никакой "мистической комбинации" нет, и такое поведение будет воспроизводиться при любой размерности массива:

54555 54556 54558

Sergey666
15.04.2021, 08:31
А причем тут ПЛК150 ? У вас массив 1..5 а пишете хрен знает куда, и хрень будет в любом языке на любом плк, пк, и прочем утюге.


Вообще-то любой нормальный ПЛК при таких инцестах в стоп вываливается...даже ПЛК на КДС 2.3 от другого Российского производителя, а то что позволяет наливать поллитру в стакан и на пол это может быть хорошо где-то на уровне учебных стендов, а ПЛК для промышленности (любой) должен давать подзатыльник за попытки переливов.
Тут разница в подходе производителя, один взял "как есть" и тру-ля-ля, а другой допилил ту-же КДС под свое понимание жизни.

Sulfur
15.04.2021, 08:57
Ради интереса повторил программу. Результат другой:
54568

Sergey666
15.04.2021, 08:58
Ради интереса повторил программу. Результат другой:
54568

Так это в симуляции...

Sulfur
15.04.2021, 09:09
Нет под рукой ПЛК150. И не предвидится.
А не проще ли программно ограничить переменную индекса массива, и при выходе её за пределы вывешивать флаг ошибки, как пример.

IF iCount<=5 AND iCount=>1 THEN bIndexOk:=TRUE;
ELSE bIndexOk:=FALSE;
END_IF;



IF bIndexOk THEN
aBuffer[iCount]:=xW;
ELSE (*свистать всех наверх, приготовиться к торпедной атаке!*)
END_IF;





---
-Доктор, когда я вот так делаю, мне больно.
-Дык не делайте так.

Sergey666
15.04.2021, 09:17
Тогда уж проще iCount ограничивать принудительно
if iCount<1 then
iCount:=1;
elsif iCount>5 then
iCount:=5;
end_if;

Просто не все так законтролировать можно, напр. тот же фокус с делением на 0, все используют какие-то бибки, где гарантия, что там внутри никогда в знаменателе "0" не появится.

Sulfur
15.04.2021, 09:22
Принудительно ограничение тоже имеет место быть. Но зависит от задачи. Если в проекте индекс получается по результатам вычислений или состоянию входов\переменных, то мой метод предпочтительнее.

Sergey666
15.04.2021, 09:46
Принудительно ограничение тоже имеет место быть. Но зависит от задачи. Если в проекте индекс получается по результатам вычислений или состоянию входов\переменных, то мой метод предпочтительнее.
Ага, каждому его метод предпочтительнее, см. притчу о лисе и журавле.

У вас предусмотрено (млин вот все как у Овена, вы часом не у них на курсах учились) какое-то не понятное поведение системы - если bIndexOk=False что тогда? Что в массиве?

saii
15.04.2021, 10:18
Ага, каждому его метод предпочтительнее, см. притчу о лисе и журавле.

У вас предусмотрено (млин вот все как у Овена, вы часом не у них на курсах учились) какое-то не понятное поведение системы - если bIndexOk=False что тогда? Что в массиве?

А почему Вы считаете, что всегда, когда индекс массива выходит за допустимый диапазон, должны изменяться крайние элементы?

Ian
15.04.2021, 10:28
Естественно, никакой "мистической комбинации" нет, и такое поведение будет воспроизводиться при любой размерности массива:

Да у вас нет мистики, а на моем плк она к сожалению есть. Вероятно потому что плк-150 2007 года выпуска с прошивкой того же года(обновить не получается ни у меня ни у тех.отдела OWEN). Прилагаю мистические скрины, на них видно что ошибки нет при других комбинациях.

Sergey666
15.04.2021, 10:45
А почему Вы считаете, что всегда, когда индекс массива выходит за допустимый диапазон, должны изменяться крайние элементы?

Потому что считаю, что индекс массива не стоит выводить за допустимый диапазон.

Ian
15.04.2021, 10:48
Вы, видимо, просто не выполняете команду Проект - Очистить все при внесении изменений - в этом случае компилятор, вероятно, не перераспределяет адреса.

Делал сто раз вчера очистить все, потому что прежде чем написать в чат перепроверил все что можно. Но решил еще раз сегодня очистить все и ошибка пропала теперь даже при комбинации 6 и 5 нет ошибки. Опять все очистил, пересохранил, перекомпилировал, выключил включил и прочие танцы исполнил. Ошибки нет. Бред какой то. Должен же он записывать в соседнюю ячейку или нет если элемент вываливается, если должен то почему сейчас все не записывает.

Подскажите где-то описано в какой нибудь литературе как работает компилятор в Codesys?

Sergey666
15.04.2021, 10:51
Да у вас нет мистики, а на моем плк она к сожалению есть. Вероятно потому что плк-150 2007 года выпуска с прошивкой того же года(обновить не получается ни у меня ни у тех.отдела OWEN). Прилагаю мистические скрины, на них видно что ошибки нет при других комбинациях.

А вы, Батенька, жулик... xInit на первую строчку поставил и ... все данные в массив переливаются хрен знает куда, теперь, ради хохмы попробуйте прочитать значение в массиве с индексом [7].
Это не ПЛК и не среда разработки, это называется культура программирования и очень часто вижу такие опусы, что их аффтаров хочется бить по голове палкой из виноградной лозы(она не ломается).

IVM
15.04.2021, 10:59
Делал сто раз вчера очистить все, потому что прежде чем написать в чат перепроверил все что можно. Но решил еще раз сегодня очистить все и ошибка пропала теперь даже при комбинации 6 и 5 нет ошибки. Опять все очистил, пересохранил, перекомпилировал, выключил включил и прочие танцы исполнил. Ошибки нет. Бред какой то. Должен же он записывать в соседнюю ячейку или нет если элемент вываливается, если должен то почему сейчас все не записывает.

Подскажите где-то описано в какой нибудь литературе как работает компилятор в Codesys?

Кончай ерундой заниматься.

Ian
15.04.2021, 11:57
А вы, Батенька, жулик... xInit на первую строчку поставил и ... все данные в массив переливаются хрен знает куда, теперь, ради хохмы попробуйте прочитать значение в массиве с индексом [7].
Это не ПЛК и не среда разработки, это называется культура программирования и очень часто вижу такие опусы, что их аффтаров хочется бить по голове палкой из виноградной лозы(она не ломается).
Нервные все тут на форуме) Жулик, палкой бить... Эти выпады в мою сторону удивляют и забавляют. Я в этой теме две недели, а отвечающие с 2008 года судя по регистрации на форуме. Вопросы задаю потому что мне реально непонятно. Поменял порядок потому что пробовал разные варианты и забыл. Поставил на место, опять ошибка, но уже без мистики на всех комбинациях. В итоге получается два момента: 1) От мистики избавился за счет очистить все. 2) Если xInit на первой строке ошибки нет, а если на последней то есть. Только непонятно почему все так.

A.Simonov
15.04.2021, 12:11
Нервные все тут на форуме) Жулик, палкой бить... Эти выпады в мою сторону удивляют и забавляют. Я в этой теме две недели, а отвечающие с 2008 года судя по регистрации на форуме. Вопросы задаю потому что мне реально непонятно. Поменял порядок потому что пробовал разные варианты и забыл. Поставил на место, опять ошибка, но уже без мистики на всех комбинациях. В итоге получается два момента: 1) От мистики избавился за счет очистить все. 2) Если xInit на первой строке ошибки нет, а если на последней то есть. Только непонятно почему все так.

Что не понятного то?
Вы создали массив из пяти элементов (они в памяти занимают 5 ячеек памяти).
Когда вы обращаетесь к 6-му элементу массива, которого нет, то попадаете в соседнюю ячейку памяти, а в ней находится ваша булевская переменная.
А находится она там по тому, что память выделяется в момент объявления переменной, причем это, очевидно, происходит в той последовательности в которой переменные объявлены.
Если вы следом объявите еще одну переменную. то обращаясь к 7-му элементу массива сможете перезаписать и её.

Вообще, если уже на то пошло. То обращаться к несуществующим элементам массива не стоит, это некорректно и приводит к тому, что вы наблюдаете.

Ian
15.04.2021, 12:39
Вообще, если уже на то пошло. То обращаться к несуществующим элементам массива не стоит, это некорректно и приводит к тому, что вы наблюдаете.
Я купил книгу для изучения Сергея Романова "Изучаем Structured Text стандарта МЭК 61131-3", набирал пример фильтрования аналогового сигнала, при отладке увидел что возникает ошибка, начал искать почему, удалил все что не вызывает ошибку и потом упростил то что получилось специально для того чтобы задать вопрос и чтобы тот кто будет отвечать смог быстро вникнуть и по сути пояснить. Естественно я не хотел изначально записывать данные в несуществующий элемент массива. Но меня тут стали бить палкой и обвинять в глупости. Короче вот такая история)

Sergey666
15.04.2021, 13:10
Я купил книгу для изучения Сергея Романова "Изучаем Structured Text стандарта МЭК 61131-3", набирал пример фильтрования аналогового сигнала, при отладке увидел что возникает ошибка, начал искать почему, удалил все что не вызывает ошибку и потом упростил то что получилось специально для того чтобы задать вопрос и чтобы тот кто будет отвечать смог быстро вникнуть и по сути пояснить. Естественно я не хотел изначально записывать данные в несуществующий элемент массива. Но меня тут стали бить палкой и обвинять в глупости. Короче вот такая история)

Конкретно вас ни кто по голове бить не собирался, вы еще пока не представляете опасности в роли программиста устройств АСУ-ТП, так что можете расслабиться, ну и слог более-менее, на программерских форумах вообще трэш+жаргон специфический, так что обижаться не продуктивно.
И книжки это хорошо, но изучение конкретной среды разработки и изучение руководств по программированию конкретных устройств может быть более полезно, подобный фокус с наложением на сименсе, шнайдере и на чем угодно еще просто бы не прокатил.

Sergey666
15.04.2021, 13:19
1. Не "нормальный" ПЛК а ПЛК для домохозяек и начинающих.
2. На кой лично мне потеря времени на онлайн проверку индексов на уровне системы ? Я в себе уверен и сторонник отсутствия какого-либо контроля своих данных. Читаем что-нить про индексы, например, в сях. Тех кому нужно обязательно сообщить что "горячий кофе на себя лить нельзя" - не читать.
3. Для не ведающих что творят собственные руки этот Российского производитель оставил воможность сделать что хошь - см. хэлп про CheckBounds. Хошь перезагрузка, хошь стоп, хошь - звонок Путину с жалобой на Овен.


Такие "понимающие жизнь" у дочки в школе запретили ПАЛКИ для лыж. В натуре. Оне ведь понимают - дети сразу будут палками глаз тыкать. Думаю что обучение плаванию такие "понимающие жизнь" проводят на беговой дорожке.

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

В себе уверен я, не дрогну ни на миг...
Не все-ж такие россомахи программирования и нюансы разные бывают, а техногенные аварии не дремлют, только натянул указатель не туда, так и...