Поделиться переменной между C и Labview? - PullRequest
5 голосов
/ 04 января 2011

Каков наилучший способ разрешить коду C регулярно получать мгновенное значение целого числа, сгенерированного из отдельной программы Labview?

У меня есть критичный по времени код C, который контролирует научный эксперимент и записывает данные один разкаждые 20 мс.У меня также есть некоторый код labview, который управляет другим прибором и выдает целочисленное значение каждые 100 мс.Я хочу, чтобы мой код на C мог записывать значение из labview.Каков наилучший способ сделать это?

Одна идея состоит в том, чтобы Labview записал целое число в файл в цикле, а код C считал значение файла в цикле.(Я мог бы добавить второй поток в мой C-код, если это необходимо.) Labview также может ссылаться на C dll's.Так что я мог бы написать DLL на C, что каким-то образом облегчает совместное использование между двумя программами.Это желательно?Как бы я это сделал?

Ответы [ 3 ]

4 голосов
/ 04 января 2011

У меня есть похожее приложение, и я использую сокеты TCP с установленным параметром TCP_NO_DELAY (отключает алгоритм Nagle, который выполняет какую-то буферизацию пакетов).Сокеты должны обеспечивать частоту обновления 100 мсек без проблем, хотя фактическая сетевая задержка всегда будет оставаться неизвестной переменной.Для моего приложения это не имеет значения, пока оно находится под определенным лимитом (это также проверяется отправкой метки времени с каждым пакетом и большими красными диалоговыми окнами, если дельта метки времени становится слишком большой:]).Имеет ли это значение для вашего приложения?Т.е. важно ли, чтобы всякий раз, когда инструмент LV получал новый семпл, его значение приходилось делать в приложении C в пределах x mSec?

Вы можете получить подход dll, но он не так прост, как сокеты иэто сделает два приложения более зависимыми друг от друга.Переменный доступ будет в значительной степени мгновенным, хотя.Я вижу по крайней мере две возможности:

  • поместить ваше целое C приложение в dll (поначалу может показаться странным подходом, но он работает), и LV загрузить его и вызватьметоды на это.Например, чтобы запустить приложение, LV вызывает метод dll Start (), а затем в цикле LV получает свои образцы, вызывает метод dll NewSampleValue (0 или около того. Также означает, что ваше приложение не может работать автономно, если вы не напишите для него отдельный процесс хоста.
  • просмотр общей памяти процесса и совместное использование памяти приложением C и другой dll. LV загрузит эту dll и вызовет для нее метод для записи значения в общую память, а затем приложение C сможет прочитать еепосле опроса флага (который нуждается в блокировке!).
  • может также быть возможным заставить приложение C вызывать программу LV с использованием вызовов dll / activeX /?, но я не знаю, как работает эта система..

Я бы определенно держался подальше от файлового подхода: дисковый ввод-вывод может быть реальным узким местом, а также имеет проблему с блокировкой, которую сложно решить с файлами. Приложение C не может прочитать файлв то время как LV пишет это, и наоборот, что может привести к дополнительным задержкам.

В отношении sidenote вы можете видеть, что каждый из описанных выше подходов использует либомодель push или pull (TCP может быть реализована обоими способами), это может повлиять на ваше окончательное решение о том, какой путь выбрать. Push = LV сигнализирует напрямую приложению C, pull = C приложение должно опрашивать флаг или запрашивать LVдля значения.

3 голосов
/ 10 февраля 2011

Я проверил один из идеалов @ stijn:

имеет приложение C, а другой dll разделяет общую память.LV загрузит эту dll и вызовет метод для ее записи в общую память, а затем приложение C сможет прочитать его после опроса флага (который требует блокировки!).

Я написалбиблиотека InterProcess, доступная здесь: http://github.com/samuellab/InterProcess

InterProcess - это компактная общая библиотека, которая устанавливает общую память Windows с использованием CreateFileMapping() и MapViewOfFile().Это позволяет пользователю беспрепятственно хранить значения любого типа (int, char, ваша структура ... что угодно) в произвольном количестве именованных полей.Он также реализует объекты Mutex, чтобы избежать столкновений и условий гонки, и абстрагирует все это в чистом и простом интерфейсе.Проверено на Windows XP.Должно работать с любой современной Windows.

Для взаимодействия между моим существующим кодом C и labview я написал небольшую DLL-оболочку, которая находится поверх InterProcess и предоставляет только те специфические функции, к которым мой код C или labview должен иметь доступ.,Таким образом, вся разделяемая память полностью удалена.

Надеюсь, кто-то найдет этот код полезным.

3 голосов
/ 04 января 2011

Я сотрудник National Instruments, и я хотел убедиться, что вы не пропустили API сетевых переменных, предоставляемый в LabWindows / CVI, среде разработки National Instruments C. API-интерфейс сетевых переменных позволит вам легко взаимодействовать с программой LabVIEW через общие переменные (http://zone.ni.com/devzone/cda/tut/p/id/4679). При чтении этих ссылок обратите внимание, что сетевая переменная и общая переменная - это одно и то же - разные именаК сожалению, ...

Хорошая особенность API сетевых переменных заключается в том, что он обеспечивает простую совместимость с LabVIEW, предоставляет строго типизированный механизм связи и предоставляет модель обратного вызова для уведомления, когда переменная Network / Sharedизменение свойств (например, значения).

Этот API можно получить, установив LabWindows / CVI, но при этом нет необходимости использовать среду LabWindows / CVI. Файл заголовка доступен по адресу C: \Программные файлы \ National Instruments \ CVI2010 \ include \ cvinetv.h , и файл .lib, расположенный по адресу C: \ Program Files \ National Instruments \ CVI2010 \ extlib \ msvc \ cvinetv.lib , может бытьсвязаны с любыми инструментами разработки на C, которые вы используете.

...