УкраїнськаEnglishmRussian
Вход/Новый
В теме нет новых постов

[BugWrong] Проблема анализа старших битов.


Автор Сообщение
Сообщение создано: 25. 03. 2016 [08:45]
Petr2off
Владимир Петров
Создатель темы
Зарегистрирован(а) с: 08.07.2015
Сообщения: 38
Добрый день. Потребовалось мне передавать 32-х разрядное статусное слово через 16- разрядные Modbus регистры.
Соответственно в PLC разбил на 2 16 разрядных целых, передал в SCADA, все хорошо.
В шаблоне сформировал код:

WS_32 = (YN03<<16)|YN02;
S_DSB = ((WS_32 & 0x80000000)!=0);


Значение WS_32 - 0x20000;

S_DSB в шаблоне 1 ! Когда я передал WS_32 в виджет там попробовал выполнить анализ бита S_DSB - равно 0.

Строка S_DSB = ((YN03 & 0x8000)!=0); в шаблоне работает нормально.
В чем может быть проблема ? Косячок в SCADA или у меня в голове ?
Сообщение создано: 25. 03. 2016 [13:53]
IrmIngeneer
Константин \m/
Contributor
Sponsor
Зарегистрирован(а) с: 16.09.2010
Сообщения: 185
Нарисуйте и выложите здесь махонький проект для демонстрации косяка. Думаю, в процессе его создания вопрос отпадет сам собой, если же нет - можно будет предметно анализировать, где что не так.
Сообщение создано: 25. 03. 2016 [14:13]
roman
Roman Savochenko
Moderator
Contributor
Developer
Зарегистрирован(а) с: 12.12.2007
Сообщения: 3750
"Petr2off" wrote:

В чем может быть проблема ? Косячок в SCADA или у меня в голове ?

Не понял из всего описанного в чём проблема!
Также не понятно зачем брать отдельно регистры если оба их можна взять целиком как 32-разрядное целое.

Такое у меня работает правильно:
JAVASCRIPT
YN02 = 0x1111;
YN03 = 0x8888;
WS_32 = (YN03<<16)|YN02;
rez = WS_32 & 0x80000000;


Подозреваю, что речь об 0.8 LTS, где такое возможно ввиду использования целого int32, в отличии от 0.9 Work, где int64.

Learn, learn and learn better than work, work and work.
Сообщение создано: 26. 03. 2016 [06:24]
Petr2off
Владимир Петров
Создатель темы
Зарегистрирован(а) с: 08.07.2015
Сообщения: 38
К сожалению брать как целое число не получается. По условиям договора, я пользуюсь Isagraf 3.22 с весьма архаичным драйвером Modbus. И принимать 2 регистра как одно целое не прокатывает. Пробовал. Выдает ошибку. А версия которую юзаю - да - 0.8 LTS.
Как я понял - такое поведение это фича 0.8 LTS ? Единственно мне не понятно, почему такая же обработка прокатывает, если я ее делаю в виджете ? Получается JS в шаблоне и JS в виджете это не одно и тоже ?
Сообщение создано: 26. 03. 2016 [07:15]
Petr2off
Владимир Петров
Создатель темы
Зарегистрирован(а) с: 08.07.2015
Сообщения: 38
Кстати, в догонку. Роман, твой код у меня тоже даст единицу. Если уж совсем корректно проверять, то проверять нужно последовательность:

ws = ox20000;
flg = ((ws & 0x80000000) !=0);

Получается, что при любом ws, flg = 1.
Сообщение создано: 26. 03. 2016 [08:28]
IrmIngeneer
Константин \m/
Contributor
Sponsor
Зарегистрирован(а) с: 16.09.2010
Сообщения: 185
"Petr2off" wrote:

Кстати, в догонку. Роман, твой код у меня тоже даст единицу. Если уж совсем корректно проверять, то проверять нужно последовательность:

ws = ox20000;
flg = ((ws & 0x80000000) !=0);

Получается, что при любом ws, flg = 1.



Очевидно, что ws должен быть равен 0x20000. У меня корректный код дает 0.
Действительно, похоже на косячок...
Сообщение создано: 26. 03. 2016 [10:16]
roman
Roman Savochenko
Moderator
Contributor
Developer
Зарегистрирован(а) с: 12.12.2007
Сообщения: 3750
"IrmIngeneer" wrote:

Действительно, похоже на косячок...

В голове!

Разбираемся со знаковым целочисленным представлением, что в случае int32 и 0x80000000 означает по сути знак и может стать 0xFFFFFFFF

Кроме того, такой код у меня работает везде, а именно всегда 0 или false::
JAVASCRIPT
ws = 0x20000;
flg = ws&0x80000000;
flg = ((ws & 0x80000000) !=0);


Не ошибка!

Learn, learn and learn better than work, work and work.
Сообщение создано: 26. 03. 2016 [10:27]
roman
Roman Savochenko
Moderator
Contributor
Developer
Зарегистрирован(а) с: 12.12.2007
Сообщения: 3750
"Petr2off" wrote:

К сожалению брать как целое число не получается. По условиям договора, я пользуюсь Isagraf 3.22 с весьма архаичным драйвером Modbus. И принимать 2 регистра как одно целое не прокатывает.

Глупость, документацию читайте внимательно!
Читает он всегда регистрами, вопрос в том как затем объединяет эти регистры в расширенные типы данных.

Learn, learn and learn better than work, work and work.
Сообщение создано: 26. 03. 2016 [10:32]
IrmIngeneer
Константин \m/
Contributor
Sponsor
Зарегистрирован(а) с: 16.09.2010
Сообщения: 185
"roman" wrote:

"IrmIngeneer" wrote:

Действительно, похоже на косячок...

В голове!

Разбираемся со знаковым целочисленным представлением, что в случае int32 и 0x80000000 означает по сути знак и может стать 0xFFFFFFFF

Кроме того, такой код у меня работает везде, а именно всегда 0 или false::
JAVASCRIPT
ws = 0x20000;
flg = ws&0x80000000;
flg = ((ws & 0x80000000) !=0);


Не ошибка!


Имел ввиду косяк НЕ OpenSCADA. У меня тоже куча кода написана подобным образом, все работает.
Сообщение создано: 27. 03. 2016 [07:35]
Petr2off
Владимир Петров
Создатель темы
Зарегистрирован(а) с: 08.07.2015
Сообщения: 38
Рад конечно, что у Вас работает. У меня в шаблоне не работает. Буду использовать разбиение на 2 регистра, тем более что оно у меня в разбитом состоянии и приходит. Насчет буковки o в ox20000 - это опечатка, извиняюсь. Конечно же в modbus регистре находится 0x20000.
Просто я хотел их в 1 32-х разрядный регистр свести, что бы битовые маски в обработке совпадали с битовыми масками документации торнадо, но видать не судьба. Механизм понятен, 0xffffffff & 0x20000 естественно дадут 1.



4192