Прерывания

Простейшие вопросы в области инженерной разработки
danya
junior
junior
Сообщения: 52
Зарегистрирован: 23 мар 2015, 18:29
Версия LabVIEW: 2010
Контактная информация:

Прерывания

Сообщение danya »

Здравствуйте! Вопрос у меня возник следующего характера. У меня есть плата стороннего производителя, не NI, есть библиотека на labview для работы с ней. Как мне отлавливать прерывания с этой платы? Имеется ВПП, который возвращает массив данных очередного прерывания.
Аватара пользователя
dadreamer

Activity Professionalism Автор
professor
professor
Сообщения: 3926
Зарегистрирован: 17 фев 2013, 16:33
Награды: 4
Версия LabVIEW: 2.5 — 2022
Благодарил (а): 11 раз
Поблагодарили: 126 раз
Контактная информация:

Re: Прерывания

Сообщение dadreamer »

Не зная производителя и марку платы, можно только сказать в общих чертах. Очевидно, что "ловить" прерывания нужно в цикле и с помощью API этой платы. Вот похожая тема: http://www.labviewportal.org/viewtopic.php?f=81&t=3119
danya
junior
junior
Сообщения: 52
Зарегистрирован: 23 мар 2015, 18:29
Версия LabVIEW: 2010
Контактная информация:

Re: Прерывания

Сообщение danya »

Плата фирмы Элкус, tc1/pci4. Благодарю, почитаю эту тему.
Аватара пользователя
dadreamer

Activity Professionalism Автор
professor
professor
Сообщения: 3926
Зарегистрирован: 17 фев 2013, 16:33
Награды: 4
Версия LabVIEW: 2.5 — 2022
Благодарил (а): 11 раз
Поблагодарили: 126 раз
Контактная информация:

Re: Прерывания

Сообщение dadreamer »

Что-то не могу найти такую плату в каталоге: http://www.elcus.ru/index.php?ID=price
danya
junior
junior
Сообщения: 52
Зарегистрирован: 23 мар 2015, 18:29
Версия LabVIEW: 2010
Контактная информация:

Re: Прерывания

Сообщение danya »

Извините, я ошиблась, опечаталась - TA1-PCI4. http://www.elcus.ru/boards.php?ID=ta1-pci4
В API есть ВПП, как я уже писала, возвращающая массив прерывания, полученного от устройства. Я немного не могу понять как именно со стороны labview, поймать его. Использовать событие или цикл, каким образом.
Аватара пользователя
dadreamer

Activity Professionalism Автор
professor
professor
Сообщения: 3926
Зарегистрирован: 17 фев 2013, 16:33
Награды: 4
Версия LabVIEW: 2.5 — 2022
Благодарил (а): 11 раз
Поблагодарили: 126 раз
Контактная информация:

Re: Прерывания

Сообщение dadreamer »

У вас в примере представлен вариант получения прерываний в цикле While:
2015-10-27_13-24-16.jpg
Описание выходных данных есть в контекстной справке :vi: и в DOC'овских файлах, идущих в комплекте с примерами.
danya
junior
junior
Сообщения: 52
Зарегистрирован: 23 мар 2015, 18:29
Версия LabVIEW: 2010
Контактная информация:

Re: Прерывания

Сообщение danya »

Да, и правда. То есть существует только вариант проверять tmkgtevd каждую 1 мс как на этой блок-диаграмме. Я думала, что возможно есть еще какой-то более удобный вариант, чтобы программа реагировала на появление очередного прерывания. Вам спасибо! :thank:
Аватара пользователя
dadreamer

Activity Professionalism Автор
professor
professor
Сообщения: 3926
Зарегистрирован: 17 фев 2013, 16:33
Награды: 4
Версия LabVIEW: 2.5 — 2022
Благодарил (а): 11 раз
Поблагодарили: 126 раз
Контактная информация:

Re: Прерывания

Сообщение dadreamer »

Ну, видимо, разработчик не удосужился реализовать эвенты или это оказалось сложновыполнимо. Но вы должны руководствоваться своим ТЗ. Если допускается более низкая частота опроса прибора, то можно задержку увеличить.
danya
junior
junior
Сообщения: 52
Зарегистрирован: 23 мар 2015, 18:29
Версия LabVIEW: 2010
Контактная информация:

Re: Прерывания

Сообщение danya »

А в случае, если нужна более высокая частота опроса, 2 кГц например, возможно ли такое реализовать?
Аватара пользователя
dadreamer

Activity Professionalism Автор
professor
professor
Сообщения: 3926
Зарегистрирован: 17 фев 2013, 16:33
Награды: 4
Версия LabVIEW: 2.5 — 2022
Благодарил (а): 11 раз
Поблагодарили: 126 раз
Контактная информация:

Re: Прерывания

Сообщение dadreamer »

Боюсь, что на обычной винде никак, потому что максимум, на который способен таймер - это 1 кГц. Для бóльших частот придётся использовать RT контроллер с RT OS. Однако придётся тогда и плату другую использовать.
AndreyDmitriev

Activity Professionalism Tutorials Gold Black
VIP
VIP
Сообщения: 1327
Зарегистрирован: 03 фев 2010, 00:42
Награды: 6
Версия LabVIEW: 6.1 - 2024
Откуда: Германия
Благодарил (а): 1 раз
Поблагодарили: 38 раз
Контактная информация:

Re: Прерывания

Сообщение AndreyDmitriev »

dadreamer писал(а):Боюсь, что на обычной винде никак, потому что максимум, на который способен таймер - это 1 кГц. Для бóльших частот придётся использовать RT контроллер с RT OS. Однако придётся тогда и плату другую использовать.
Ну не всё так уж плохо - процессор-то у нас не на 1 кГц тактируется, так что получить в LabVIEW более-менее детерминированную задержку меньше миллисекунды вполне себе можно. Единственное - с чем придётся смириться - в цикле ожидания нам придётся крутить "холостой" цикл, который будет требовать ресурсов процессора, но нынче процессоры многоядерные, так что на общей производительности это не очень скажется.
В последних версиях у нас есть таймер высокого разрешения, можно реализовать задержку на его основе. В старых версиях можно воспользоваться библиотекой:
http://www.ni.com/example/28582/en/
Только там таймер надо чуть доработать напильником - вызов DLL осуществлять не в UI потоке (пометить это дело как "потокобезопасный" вызов, ну и отключить отладку и поднять приоритет до time critical. Ну и вычесть накладные расходы на вызов таймера - у меня это примерно 40 микросекунд. Так что цикл с задержкой 0,46 мс крутится примерно на два килогерца.
Но надо понимать, что задержка там организована примерно вот так:
while ((current-start)< delay) Time_Get(&current);
так что одноядреный процессор чуть более чем полностью будет занят ожиданием.

Более правильно работать с прерываниями через библиотеку-обёртку. Грубо говоря в библиотеке, поставляемой с драйвером должна быть функция, в которую надо передать адрес своей функции-обработчика прерывания из обёртки. Соответственно при наступлении прерывания будет вызвана наша функция, а там уже можно передать данные в LabVIEW, скажем уведомив LabVIEW через occurence. Плюс такого подхода в том, что "вхолостую" крутящихся циклов у нас вообще не будет и загрузка процессора в режиме ожидания будет стремиться к нулю. Кроме того, прерывания должны быть буферизованы (если наступило следующее прерывание, а мы ещё не освободили обработчик, то данные складываются в буфер, содержимое которого будет нам передано при следующем вызове обработчика). Буфер в плате вроде есть - на 256 слов, а как организовать обработчик - это уже документацию надо смотреть.
В принципе надо понимать, что Windows - не есть система жёсткого реального времени, так что всегда есть опасность потери сообщений в том случае, когда буфер уже заполнен, но не прочитан и при этом наступило следующее прерывание. Чем больше буфер и ниже частота прерываний, тем меньше вероятность потери данных.
Аватара пользователя
dadreamer

Activity Professionalism Автор
professor
professor
Сообщения: 3926
Зарегистрирован: 17 фев 2013, 16:33
Награды: 4
Версия LabVIEW: 2.5 — 2022
Благодарил (а): 11 раз
Поблагодарили: 126 раз
Контактная информация:

Re: Прерывания

Сообщение dadreamer »

AndreyDmitriev писал(а):В последних версиях у нас есть таймер высокого разрешения, можно реализовать задержку на его основе.
А ведь верно, что-то у меня из головы вылетел вообще этот таймер. :D Видимо, торопился, когда писал. В 2010-м :labview: уже есть High Resolution Relative Seconds.vi, так что проблем с этим быть не должно.
AndreyDmitriev писал(а):как организовать обработчик - это уже документацию надо смотреть.
Вот что нашёл в документации на драйвер:
В драйверах Windows работа с прерываниями осуществляется через механизм событий Win32. Прежде всего, процесс должен сообщить драйверу идентификатор (handle) используемого события для текущего выбранного ТМК через вызов функции tmkdefevent, которой передается в качестве первого параметра идентификатор события Win32, полученный из Win32 вызова CreateEvent:

void tmkdefevent(HANDLE hEvent, BOOL fEventSet);

Нулевое значение hEvent отменяет использование события. Значение параметра fEventSet равное TRUE указывает на необходимость установки события драйвером через вызовы SetEvent, а значение FALSE - через вызовы PulseEvent. Внимание! В текущей версии драйвера значение переменной fEventSet игнорируется (принимается равным TRUE). Кроме того, рекомендуется вызывать функцию ResetEvent непосредственно перед вызовом tmkdefevent.
Во враппере для :labview: (lvtmk.dll) функция tmkdefevent есть. Только вот в примере почему-то никакой event не создаётся:
2015-11-12_0-14-20.jpg
2015-11-12_0-14-20.jpg (21.93 КБ) 10375 просмотров
Видимо, нужно создать эвент и передать его хэндл в функцию, а потом ожидать события через WaitForSingleObject, например. Сам это проверить не могу, ибо железки такой нет. :dntknw:
danya
junior
junior
Сообщения: 52
Зарегистрирован: 23 мар 2015, 18:29
Версия LabVIEW: 2010
Контактная информация:

Re: Прерывания

Сообщение danya »

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

Activity Professionalism Автор
professor
professor
Сообщения: 3926
Зарегистрирован: 17 фев 2013, 16:33
Награды: 4
Версия LabVIEW: 2.5 — 2022
Благодарил (а): 11 раз
Поблагодарили: 126 раз
Контактная информация:

Re: Прерывания

Сообщение dadreamer »

User Events здесь вообще никаким местом не подходят. Вам нужно использовать узлы Call Library Function Node для работы с прерываниями по событиям. Этот метод лучше постоянного опроса устройства тем, что снижается нагрузка на процессор. При инициализации платы делаете так:
1. hEvent CreateEvent (NULL, TRUE, FALSE, NULL);
2. bReset ResetEvent (hEvent);
3. void tmkdefevent (hEvent, TRUE);

В процессе работы в отдельном цикле выполняете:
4. dWait WaitForSingleObject (hEvent, INFINITE=0xFFFFFFF);
Как только функция вернула WAIT_OBJECT_0=0, получаете массив прерываний стандартным образом.

При закрытии платы вызываете
5. bResult CloseHandle (hEvent);

Вроде бы это всё. Не забудьте сделать вызовы CLFN реентерантными (Run In Any Thread), а то ожидание эвента подвесит UI поток :labview: .

Сделал вам вот такой пример. Не знаю, как будет работать в реальности, но надеюсь, что всё будет ок. Заодно улучшил некоторые :vi: от производителя для более удачного построения dataflow на БД (включены в исходную llb с пометкой _new). Если есть желание, можете переделать и другие :vi: по такому же принципу.
Вложения
LVTMK_Win32_Events.vi
lv2010
(17.78 КБ) 151 скачивание
Lvtmk.llb
(1.41 МБ) 148 скачиваний
m1ndst0rm
interested
interested
Сообщения: 7
Зарегистрирован: 10 окт 2011, 08:18
Версия LabVIEW: 9.0
Контактная информация:

Re: Прерывания TA1-104-2

Сообщение m1ndst0rm »

Подскажите, пожалуйста.
Плата тоже Элкус TA1-104-2 (два терминала независимых на одной плате формата pc/104).

Устройство генератор сигналов по МКПД отправляет посылки по 32 слова с максимальной скоростью, на которое способно.

Штатная программа-монитор от Элкус "ловит" около 1700 посылок в секунду.

Самая быстрая версия ОУ на LabVIEW (2009) нескомпилированная (возможно, это важно!) способна поймать порядка 400 посылок в секунду.

То есть монитор от Элкус (на С++, скорее всего)работает сильно быстрее LabVIEW.
В чем может быть проблема?


И второй вопрос, более важный:

Когда источник выдаёт посылки в режиме максимальной скорости (порядка 1700 в секунду по 32 слова) - прерывания с помощью tmkgetevd (TMK get event data) отлавливаются, с горем пополам (в 15-20 раз медленнее, чем приходят посылки).

Но если тот же источник отправляет посылки редко ( 1-10 а секунду) по тому же протоколу, той же линии итд - прерывания не приходят вообще.

Причём посылки достоверно отправляются - их видно монитором, в адрес того же ОУ1.

Как так может быть?
По какой причине ТМК в режиме ОУ может не генерировать прерывание в случае получения (??) посылки?

Я так понимаю, если посылка приходит, с любой скоростью (плотностью) передачи - по каждому сообщению генерируется прерывание, которое в цикле while можно ждать как 0 элемент массива данных функции tmkgetevd (если не 0 - значит пришли данные - оно же код результата обмена).
Почему tmkgetevd может никогда не выдавать "прерывания" при получении сообщений?
Ответить

Вернуться в «Для чайников»