Разработка sdr-драйвера LabVIEW
- Mad_Ahab
- junior
- Сообщения: 66
- Зарегистрирован: 12 янв 2015, 16:33
- Версия LabVIEW: 2013
- Контактная информация:
Re: Разработка sdr-драйвера LabVIEW
В общем, на данный момент я переделал библиотечную С++ функцию чтения данных из прибора: теперь она принимает в качестве параметра фиксированный приемный буфер, а также указатель на переменную, в которой будет храниться количество принятых из прибора байт. Теперь, после вызова функции чтения, будет записано что-то в приемный буфер, и известно в явном виде какого размера это что-то в байтах.
Теперь нужно сделать быстрое создание массива в по заданному размеру с заданным содержанием, потом этот получившийся массив, который является сообщением, предстоит поместить в очередь.
Теперь нужно сделать быстрое создание массива в по заданному размеру с заданным содержанием, потом этот получившийся массив, который является сообщением, предстоит поместить в очередь.
-
Vitekkz88
- expert
- Сообщения: 1100
- Зарегистрирован: 21 янв 2014, 15:45
- Награды: 3
- Версия LabVIEW: 12,13,14
- Откуда: Томск
- Контактная информация:
Re: Разработка sdr-драйвера LabVIEW
Вы что передаёте? Текст что ли? Или у вас смесь из данных и текста? Коль функция чтения возвращает массив данных uint8 - то и на строне LabVIEW принимайте в uint8. Если Вы по TCP/IP принимать данные будете и всё-таки планируете со строками работать - то ведите счетчик принятых байт. Я не знаю, какая у Вас структура пакета и протокол передачи. Если в заголовке первым словом идет величина пакета - то заводите условие на приём данных:То есть, я хотел бы в очередь помещать не голый поток 8-разрядных слов, а именно сообщения, чтобы потом их парсить. Как можно сделать это в ?
На ум приходит только функция Concatenate Strings, выполненная очень быстро при получении данных для формирования сообщения перед размещением его в очереди - только это функция для какого-то фиксированного числа строк, поданных на вход, чего обеспечить я не смогу.Теперь нужно сделать быстрое создание массива в по заданному размеру с заданным содержанием, потом этот получившийся массив, который является сообщением, предстоит поместить в очередь.
если размер принятого сообщения менее значения первого слова, то читаем дальше. Считанные ранее байты объединяем.
Если данные отправляются в uint8, то и конвертируйте их сразу в uint8 и принимайте сразу весь массив(блоком).
Если одного блока мало для обработки и отображения - копите таких блоков N штук хоть в регистре, хоть в очереди.
Пример накопления данных в регистре приложил. Для очередей делается по аналогии, только контроль ведется по кол-ву элементов в очереди.
И еще, не мешайте всё в один канал. Гораздо удобней(на мой взгляд) использовать два канала: канал на передачу данных и канал на передачу текстовых сообщений или служебной информации.
- Вложения
-
- Untitled 1.vi
- (13.28 КБ) 180 скачиваний
Инженер - это открыто светящийся интеллект, свободный и не обидный юмор, это легкость и широта мысли...Это воспитанность, тонкость вкусов, хорошая речь, плавно согласованная и без сорных словечек...
-А. И. Солженицын
-А. И. Солженицын
- Mad_Ahab
- junior
- Сообщения: 66
- Зарегистрирован: 12 янв 2015, 16:33
- Версия LabVIEW: 2013
- Контактная информация:
Re: Разработка sdr-драйвера LabVIEW
Большое спасибо за ответ, офигенно , сразу много начал понимать.
- Да, я принимаю смесь данных и текста.
Я разбираю Ваш прибор, пытаюсь понять как он работает и вижу следующее:
создаются очереди, одна для данных, другая - для буферизации. Также задается массив, пусто, он передается отдельно в цикл накопления данных, и в цикл обработки (буферизации) и в цикл визуализации. Меня интересует большой цикл буферизации: Вы передаете туда массив, а также данные, полученные в параллельном независимом цикле в виде очереди, затем пополняете массив данными из очереди данных, проверяете размер получившегося массива, если он оказывается больше предельного заданного размера буфера, то Вы отрезаете от массива часть буферного размера и помещаете снова в очередь, а остаток - куда Вы его отправляете? Обратно в массив? А как он обновляется?
Я спрашиваю, потому что у меня возникла проблема с чтением данных Error 1097 в библиотечной функции read, эта функция пытается записать данные по недоступному для нее адресу - это я выяснил указанным Вами (замечательным!) способом отладки. Очевидно, я неправильно передаю массив в эту функцию, потому что она вылетает только при повторном и далее вызовах... То ли я удаляю указатель на массив где-то в .
Поэтому я и спрашиваю - каким образом после такого цикла можно корректно обновить массив чтобы снова его туда же в цикл передать? Сдвиговые регистры, если протянуть массив через весь цикл тоже дадут такую ошибку (в точку 1 - первый регистр, в точку 3 - второй, а в точку 2 - ответвление, проведенное до точки 3) И еще тут встал вопрос: как взаимодействуют и поток, запущенный DLL? То есть, например, если у меня DLL запускает прием и складирование данных в очереди, сама их там где-то формирует и прочее, и делает это - в отдельном потоке (адресное пространство DLL), то как потом можно из получить доступ к этому автономному, отдельному потоку DLL, который где-то-то там крутится?
Vitekkz88 писал(а): Вы что передаёте? Текст что ли? Или у вас смесь из данных и текста?
- Да, я принимаю смесь данных и текста.
- Пожалуйста, расскажите чуть подробнее. Как я их разделю? Все равно данные идут сплошным потоком. Мне придется при парсинге делать данные - какие-то на консоль/экран, какие-то - дальше на обработку, Вы имели в виду это?И еще, не мешайте всё в один канал. Гораздо удобней(на мой взгляд) использовать два канала: канал на передачу данных и канал на передачу текстовых сообщений или служебной информации.
Я разбираю Ваш прибор, пытаюсь понять как он работает и вижу следующее:
создаются очереди, одна для данных, другая - для буферизации. Также задается массив, пусто, он передается отдельно в цикл накопления данных, и в цикл обработки (буферизации) и в цикл визуализации. Меня интересует большой цикл буферизации: Вы передаете туда массив, а также данные, полученные в параллельном независимом цикле в виде очереди, затем пополняете массив данными из очереди данных, проверяете размер получившегося массива, если он оказывается больше предельного заданного размера буфера, то Вы отрезаете от массива часть буферного размера и помещаете снова в очередь, а остаток - куда Вы его отправляете? Обратно в массив? А как он обновляется?
Я спрашиваю, потому что у меня возникла проблема с чтением данных Error 1097 в библиотечной функции read, эта функция пытается записать данные по недоступному для нее адресу - это я выяснил указанным Вами (замечательным!) способом отладки. Очевидно, я неправильно передаю массив в эту функцию, потому что она вылетает только при повторном и далее вызовах... То ли я удаляю указатель на массив где-то в .
Поэтому я и спрашиваю - каким образом после такого цикла можно корректно обновить массив чтобы снова его туда же в цикл передать? Сдвиговые регистры, если протянуть массив через весь цикл тоже дадут такую ошибку (в точку 1 - первый регистр, в точку 3 - второй, а в точку 2 - ответвление, проведенное до точки 3) И еще тут встал вопрос: как взаимодействуют и поток, запущенный DLL? То есть, например, если у меня DLL запускает прием и складирование данных в очереди, сама их там где-то формирует и прочее, и делает это - в отдельном потоке (адресное пространство DLL), то как потом можно из получить доступ к этому автономному, отдельному потоку DLL, который где-то-то там крутится?
- Mad_Ahab
- junior
- Сообщения: 66
- Зарегистрирован: 12 янв 2015, 16:33
- Версия LabVIEW: 2013
- Контактная информация:
Re: Разработка sdr-драйвера LabVIEW
В общем, я справился с функцией чтения данных, она отрабатывает корректно. Теперь вопрос: как можно заставить ее работать параллельно с выполнением программы в ?
Я могу просто на диаграмме расположить цикл в самом начале, точнее, в первом, отдельном кадре открытой последовательности в виде которой у меня сейчас существует программа, который будет крутиться и вычитывать данные из очереди (вопрос с очередью все еще открыт) до тех пор, пока работает программа? Если да, то как? Или есть более простой путь, например, сделать управлением событиями?
Вообще, в идеале управление должно выглядеть следующим образом: на панели управления есть тумблер, по щелчку которого начинают отображаться данные - те, что текстовые - в дисплей, иные - на диаграмме, или просто выгружаться в файл, к примеру. Потом перебрасываем тумблер или отжимаем кнопку, и данные перестают отображаться. При этом - и до отображения, и после окончания, они продолжают поступать. Интерфейс просто иногда, по желанию пользователя, "подсоединяется" к потоку данных и их отображает.
Я в принципе представляю как это сделать - я могу сделать callback из DLL: библиотека, при вызове, запустит функцию чтения, создаст для нее поток, и передаст наверх - в , ссылку на этот поток, в нем будет крутиться цикл, который в одну и ту же область памяти будет перезаписывать вновь поступающие данные, и программа в будет по своему усмотрению (требованию пользователя) читать и отображать данные из этой области памяти.
Но я не хочу это делать в DLL, я хочу запустить отдельный поток в для чтения данных, который будет вне зависимости от событий программы все время крутиться, перезаписывая область памяти, как я уже описывал раньше, и прекращая это делать только с прекращением сеанса работы с прибором. Вот как это реализовать?
Я могу просто на диаграмме расположить цикл в самом начале, точнее, в первом, отдельном кадре открытой последовательности в виде которой у меня сейчас существует программа, который будет крутиться и вычитывать данные из очереди (вопрос с очередью все еще открыт) до тех пор, пока работает программа? Если да, то как? Или есть более простой путь, например, сделать управлением событиями?
Вообще, в идеале управление должно выглядеть следующим образом: на панели управления есть тумблер, по щелчку которого начинают отображаться данные - те, что текстовые - в дисплей, иные - на диаграмме, или просто выгружаться в файл, к примеру. Потом перебрасываем тумблер или отжимаем кнопку, и данные перестают отображаться. При этом - и до отображения, и после окончания, они продолжают поступать. Интерфейс просто иногда, по желанию пользователя, "подсоединяется" к потоку данных и их отображает.
Я в принципе представляю как это сделать - я могу сделать callback из DLL: библиотека, при вызове, запустит функцию чтения, создаст для нее поток, и передаст наверх - в , ссылку на этот поток, в нем будет крутиться цикл, который в одну и ту же область памяти будет перезаписывать вновь поступающие данные, и программа в будет по своему усмотрению (требованию пользователя) читать и отображать данные из этой области памяти.
Но я не хочу это делать в DLL, я хочу запустить отдельный поток в для чтения данных, который будет вне зависимости от событий программы все время крутиться, перезаписывая область памяти, как я уже описывал раньше, и прекращая это делать только с прекращением сеанса работы с прибором. Вот как это реализовать?
-
dadreamer
- professor
- Сообщения: 3926
- Зарегистрирован: 17 фев 2013, 16:33
- Награды: 4
- Версия LabVIEW: 2.5 — 2022
- Благодарил (а): 11 раз
- Поблагодарили: 127 раз
- Контактная информация:
Re: Разработка sdr-драйвера LabVIEW
А нельзя завести отдельную функцию получения буфера с данными (GetBuffer), как это обычно во множестве продуктов сделано? А в этой функции вы делаете обычное копирование из ваших внутренних потоков/буферов в этот буфер:Mad_Ahab писал(а):Но я не хочу это делать в DLL, я хочу запустить отдельный поток в для чтения данных, который будет вне зависимости от событий программы все время крутиться, перезаписывая область памяти, как я уже описывал раньше, и прекращая это делать только с прекращением сеанса работы с прибором. Вот как это реализовать?
Код: Выделить всё
memcpy(LV_Buffer, Your_Buffer, Buffer_Length)
Мне кажется, управлять этим потоком из не получится, т.к. он находится в другом контексте, хотя вы можете это проверить Запустите поток в DLL, передайте в хэндл, потом попробуйте завершить его из через TerminateThread. Проделайте это несколько раз, потом закройте все . Если не упадёт и в логе ошибок ничего не отобразится, то можно сказать, что такие манипуляции имеют право на жизнь. Но по идее нужно искать более элегантное решение, а то мало ли, может ваша библиотека завершит поток раньше, чем ... Посмотрите вот эту тему, может, что-то полезное там найдёте.Mad_Ahab писал(а):И еще тут встал вопрос: как взаимодействуют и поток, запущенный DLL? То есть, например, если у меня DLL запускает прием и складирование данных в очереди, сама их там где-то формирует и прочее, и делает это - в отдельном потоке (адресное пространство DLL), то как потом можно из получить доступ к этому автономному, отдельному потоку DLL, который где-то-то там крутится?
Последний раз редактировалось dadreamer 27 фев 2015, 19:15, всего редактировалось 1 раз.
- Mad_Ahab
- junior
- Сообщения: 66
- Зарегистрирован: 12 янв 2015, 16:33
- Версия LabVIEW: 2013
- Контактная информация:
Re: Разработка sdr-драйвера LabVIEW
Я скачал - драйвер для осциллографов PICO: https://www.picotech.com/downloads (содержится в Development Kit), и, хоть у меня и не было DLL для этих осциллографов, мне удалось посмотреть для работы с ними. В нем есть функция stream, которая является subVI, состоящим из вызовов функций библиотеки - и среди них есть функция ps2000_run_streaming_ns, которая, по всей видимости (мне так показалось), запускает поток и в нем уже собирает и складирует информацию, в соответствии с переданными в нее параметрами настройки буфера.
Значит, и мне стоит организовать у себя нечто такое же, и я попробую вариант с использованием функции _beginthreadex из process.h для WinAPI. Хотел не использовать нативный код, но, видимо, уже не объехать.
О результатах отчитаюсь.
Значит, и мне стоит организовать у себя нечто такое же, и я попробую вариант с использованием функции _beginthreadex из process.h для WinAPI. Хотел не использовать нативный код, но, видимо, уже не объехать.
О результатах отчитаюсь.
- Mad_Ahab
- junior
- Сообщения: 66
- Зарегистрирован: 12 янв 2015, 16:33
- Версия LabVIEW: 2013
- Контактная информация:
Re: Разработка sdr-драйвера LabVIEW
С удовольствием бы, вот только буфер постоянно перезаписывается, скорость передачи данных потом будет до 80 Мбайт/с, и данные в буфер DLL сыпятся постоянно, и остается главный вопрос: как мне сделать постоянный просмотр этого буфера, чтобы из него копировать в буфер данные? Я с великим удовольствием так сделал бы, но проблема все та же: мне нужно не в каком-то месте программы копировать его один раз себе, а постоянно обновлять буфер данными из буфера DLL. Как это сделать параллельно с выполнением программы в ?dadreamer писал(а): В просто вызываете GetBuffer, передавая туда массив U8 (указатель) и размер (длину) в байтах.
-
dadreamer
- professor
- Сообщения: 3926
- Зарегистрирован: 17 фев 2013, 16:33
- Награды: 4
- Версия LabVIEW: 2.5 — 2022
- Благодарил (а): 11 раз
- Поблагодарили: 127 раз
- Контактная информация:
Re: Разработка sdr-драйвера LabVIEW
Я не хотел бы опять привязываться к "extcode.h", но там есть такая полезная функция, как PostLVUserEvent. Если в зарегистрировать стандартными пользовательский эвент, передать его хэндл в DLL, и оттуда вызвать PostLVUserEvent, то сработает Event-структура в (её нужно будет разместить предварительно на диаграмме). Таким образом можно ловить данные из различных callback функций, например из libvlc библиотеки и т.п. Пример: http://labviewportal.org/viewtopic.php?p=48149#p48149Mad_Ahab писал(а):Как это сделать параллельно с выполнением программы в ?
- Mad_Ahab
- junior
- Сообщения: 66
- Зарегистрирован: 12 янв 2015, 16:33
- Версия LabVIEW: 2013
- Контактная информация:
Re: Разработка sdr-драйвера LabVIEW
Вы стреляете только крупным калибром, и как всегда, попадаете) Спасибо за отличный пример
И мне тоже придется подключать и использовать kernel32.dll для GetProcAddress?
То есть, я в event-структуру упаковываю всю свою программу, выходит? Чтобы осуществить изначальную подписку на событие появления данных в буфере, т.к. они начнут возникать там еще при настройке прибора, я правильно Вас понял?dadreamer писал(а):... то сработает Event-структура в (её нужно будет разместить предварительно на диаграмме).
И мне тоже придется подключать и использовать kernel32.dll для GetProcAddress?
-
dadreamer
- professor
- Сообщения: 3926
- Зарегистрирован: 17 фев 2013, 16:33
- Награды: 4
- Версия LabVIEW: 2.5 — 2022
- Благодарил (а): 11 раз
- Поблагодарили: 127 раз
- Контактная информация:
Re: Разработка sdr-драйвера LabVIEW
Mad_Ahab, можно оставить инициализацию и конфигурирование за бортом эвента. Ну и, соответственно, закрытие устройства и прочую очистку. У вас же новые данные начнут поступать после аналога функции Start/Play/...? Или же сразу после инициализации? Vitekkz88 предложил хорошую организацию программы с помощью очередей. Я бы разместил эвент в отдельном потоке , а всю остальную обработку с конечным буфером в вынес бы в другой поток (чтобы не тормозить получение данных, т.к. эвент будет выполняться с большой частотой и там не должно быть ничего лишнего: ни задержек, ни работы с массивами - только копирование по указателю в массив и опционально помещение в очередь). Похожим образом я работал с видеокамерами, пользовательский эвент всегда выполнялся параллельно с остальным кодом. Остановка программы реализована через нотифаер, т.к. это удобно при работе с множеством потоков LabVIEW.
Попробуйте для начала создать простенькую DLL, генерирующую случайный массив, и передать этот массив через PostLVUserEvent, а в получить его. Поэкспериментируйте, может быть, вам этот способ вовсе не подойдет.
Это было сделано для установки Callback'а для API видеокамеры. Если у вас нет подобных функций, то можно это и не делать.И мне тоже придется подключать и использовать kernel32.dll для GetProcAddress?
Попробуйте для начала создать простенькую DLL, генерирующую случайный массив, и передать этот массив через PostLVUserEvent, а в получить его. Поэкспериментируйте, может быть, вам этот способ вовсе не подойдет.
- Mad_Ahab
- junior
- Сообщения: 66
- Зарегистрирован: 12 янв 2015, 16:33
- Версия LabVIEW: 2013
- Контактная информация:
Re: Разработка sdr-драйвера LabVIEW
dadreamer, да у меня после автодетекта появляются первые данные в буфере, затем при установке конфигурации прибора в буфере появляются отклики от DSP, которые уже имеют текстовый вид, появляются там они вместе с потоком всяких статусных данных от ПЛИС и DSP. И вот потом, собственно, по усмотрению пользователя "Start/Play" так сказать. И тоже пойдут данные, после указания параметров приема.
Большое спасибо.
Вопрос дня: а как мне организовать эту самую многопоточность? Это просто циклы? Я с радостью применю, только никак понять не могу эту "многопоточность" - мне нужен не Data Flow, а именно поток как единица планирования ОС. Извините, я просто не знаю как это выполняется в , и гуглю видимо неправильно.dadreamer писал(а):Я бы разместил эвент в отдельном потоке , а всю остальную обработку с конечным буфером в вынес бы в другой поток (чтобы не тормозить получение данных, т.к. эвент будет выполняться с большой частотой и там не должно быть ничего лишнего: ни задержек, ни работы с массивами - только копирование по указателю в массив и опционально помещение в очередь).
Если у меня нет каких именно функций?dadreamer писал(а):dadreamer, Это было сделано для установки Callback'а для API видеокамеры. Если у вас нет подобных функций, то можно это и не делать.
Большое спасибо.
-
dadreamer
- professor
- Сообщения: 3926
- Зарегистрирован: 17 фев 2013, 16:33
- Награды: 4
- Версия LabVIEW: 2.5 — 2022
- Благодарил (а): 11 раз
- Поблагодарили: 127 раз
- Контактная информация:
Re: Разработка sdr-драйвера LabVIEW
Mad_Ahab, тогда вам придётся зарегистрировать эвент и отослать в DLL его хэндл до автодетекта. Чтобы был готов к приёму данных и ничего не потерялось.
В качестве примера сделал вот такую библиотеку:
Диаграмма в LV:
Для того, чтобы разобраться с PostLVUserEvent, этого хватит в самый раз. Заодно и продемонстрирована работа нотифаера.
Два не связанных проводами цикла While - это два потока . Поток данных в идёт по проводам, это базовый принцип data flow. Если у вас в программе имеется две или более веток проводов - то столько же и будет потоков при запуске программы. Если взять опять же диаграмму Vitekkz88 с очередями, то там образуется три потока: генератор данных, обработчик и приёмник (или два приёмника, без разницы). На самом деле такое представление грубовато, но для начала сойдёт. Подробнее можете почитать здесь.Вопрос дня: а как мне организовать эту самую многопоточность? Это просто циклы?
Функций для установки пользовательского callback'а (SetCallback и т.п.). API видеокамеры не знает, какую функцию ему вызывать при поступлении новых данных. Вот я ему и указываю на неё с помощью получения её адреса в памяти и передачи этого адреса в API через SetCallback. Дальше уже API будет обращаться каждый раз к моей функции. Но вы можете пропустить этот этап и просто постить новые события при поступлении очередных данных внутри вашей библиотеки.Если у меня нет каких именно функций?
В качестве примера сделал вот такую библиотеку:
Код: Выделить всё
#include "stdafx.h"
#include "extcode.h"
LVUserEventRef *LVEvent;
uInt8 Array[100]; //тестовый массив
uInt8 *pArray = Array; //указатель на массив
extern "C"{
__declspec(dllexport) void SendEvent(LVUserEventRef *EventRef);
__declspec(dllexport) void GenerateArray();
}
//запоминаем ссылку на event
__declspec(dllexport) void SendEvent(LVUserEventRef *EventRef)
{
LVEvent = EventRef;
}
__declspec(dllexport) void GenerateArray()
{
float64 xp = 0;
int32 i = 0;
//заполняем массив случаными числами
for (i=0; i<100; i++)
{
RandomGen(&xp);
Array[i] = (uInt8)(xp * 255);
}
//передаём указатель на него в LabVIEW
//(LabVIEW автоматически разыменовывает указатель (void *),
//так что берём не сам указатель на массив, а его адрес)
PostLVUserEvent(*LVEvent, (void *)&pArray);
}
- Вложения
-
[Расширение dll было запрещено, вложение больше недоступно.]
-
- PostArray.vi
- lv2011
- (19.51 КБ) 164 скачивания
-
Vitekkz88
- expert
- Сообщения: 1100
- Зарегистрирован: 21 янв 2014, 15:45
- Награды: 3
- Версия LabVIEW: 12,13,14
- Откуда: Томск
- Контактная информация:
Re: Разработка sdr-драйвера LabVIEW
Mad_Ahab, я не понимаю Вашу озабоченность на счет приёма данных. В примере, который выше приводил, добавляйте отдельный цикл с вложенной event-cтруктурой. В event-cтруктуре обрабатывайте события с GUI.
Сделайте отдельную функцию чтения данных с прибора и вызывайте эту .dll-функцию в потоке захвата данных в LabVIEW.
У Вас должна получится следующая последовательность в приложении: Открытие сессии работы с прибором, пуск, захват данных,завершение работы. Я Вам картинку приложил, взята с http://www.ni.com/tutorial/3382/en/ . Только там единичный захват данных, пример для осциллографа. А у Вас непрерывный захват, значит нужно в цикл взять функцию захвата(чтения) данных. Всё остальное - это предварительные настройки. Обработку ошибок пока оставим на потом.
Мне не ясно, удалось ли Вам выполнить чтение данных?
Если да, то в цикле вызывайте эту функцию и проверяйте ( в примере в цикле "Поток захвата данных" вместо цикла for вставляйте функцию чтения данных).
Если у Вас сложность с парсингом, то опишите структуру пакета и мы разберемся как реализовать парсинг. Или у Вас пакеты имеют разную структуру?
Повторюсь, я бы не стал смешивать всё в один поток: и данные и текстовые сообщения. Это маразм какой-то...извините за грубость.
Передавайте данные функцией "Чтение данных" и текстовые сообщения функцией "Чтение сообщений". Данные могут поливать непрерывным потоком.А выполнять чтение текстовых сообщений можете хоть каждую секунду в отдельном потоке.
Сделайте отдельную функцию чтения данных с прибора и вызывайте эту .dll-функцию в потоке захвата данных в LabVIEW.
У Вас должна получится следующая последовательность в приложении: Открытие сессии работы с прибором, пуск, захват данных,завершение работы. Я Вам картинку приложил, взята с http://www.ni.com/tutorial/3382/en/ . Только там единичный захват данных, пример для осциллографа. А у Вас непрерывный захват, значит нужно в цикл взять функцию захвата(чтения) данных. Всё остальное - это предварительные настройки. Обработку ошибок пока оставим на потом.
Мне не ясно, удалось ли Вам выполнить чтение данных?
Если да, то в цикле вызывайте эту функцию и проверяйте ( в примере в цикле "Поток захвата данных" вместо цикла for вставляйте функцию чтения данных).
Если у Вас сложность с парсингом, то опишите структуру пакета и мы разберемся как реализовать парсинг. Или у Вас пакеты имеют разную структуру?
Повторюсь, я бы не стал смешивать всё в один поток: и данные и текстовые сообщения. Это маразм какой-то...извините за грубость.
Передавайте данные функцией "Чтение данных" и текстовые сообщения функцией "Чтение сообщений". Данные могут поливать непрерывным потоком.А выполнять чтение текстовых сообщений можете хоть каждую секунду в отдельном потоке.
- Вложения
-
- Untitled 1.vi
- (17.83 КБ) 167 скачиваний
Инженер - это открыто светящийся интеллект, свободный и не обидный юмор, это легкость и широта мысли...Это воспитанность, тонкость вкусов, хорошая речь, плавно согласованная и без сорных словечек...
-А. И. Солженицын
-А. И. Солженицын
- Mad_Ahab
- junior
- Сообщения: 66
- Зарегистрирован: 12 янв 2015, 16:33
- Версия LabVIEW: 2013
- Контактная информация:
Re: Разработка sdr-драйвера LabVIEW
Огроменное спасибо, Vitekkz88 и dadreamer.
Все резко стало понятнее. Да, мне удалось прочесть данные из устройства, и теперь я медленно но верно реализую чтение данных в отдельных потоках. Пришлось ради этого сделать несколько правок в коде DLL, а также добавить в нее несколько функций.
В процессе добавления я использовал фрагмент кода, предоставленного dadreamer:
При попытке компиляции выскакивает ошибка линковщика №2019: driver_tcp_labview.obj : error LNK2019: unresolved external symbol _PostLVUserEvent . То есть, линковщику нужна DLL, в которой реализована функция PostLVUserEvent.
Где взять эту DLL?
Все резко стало понятнее. Да, мне удалось прочесть данные из устройства, и теперь я медленно но верно реализую чтение данных в отдельных потоках. Пришлось ради этого сделать несколько правок в коде DLL, а также добавить в нее несколько функций.
В процессе добавления я использовал фрагмент кода, предоставленного dadreamer:
Код: Выделить всё
PostLVUserEvent(*LVEvent, (void *)&pArray);
Где взять эту DLL?
- Mad_Ahab
- junior
- Сообщения: 66
- Зарегистрирован: 12 янв 2015, 16:33
- Версия LabVIEW: 2013
- Контактная информация:
Re: Разработка sdr-драйвера LabVIEW
Отвечу сам себе, а также для тех, кто пойдет за мной:
библиотека labviewv.lib лежит в папке C:\Program Files (x86)\National Instruments\LabVIEW [ваша версия LV]\cintools, подключить ее в MS VC++ можно кликнув правой клавишей на проекте в Solution Explorer -> Properties и прописав в Additional Dependencies после точки с запятой в конце указанный путь до статической библиотеки.
Это неправильный способ, но приемлемый, вообще рекомендуется все это собирать с помощью CMake, и там указывать соответствующие цели для линковки.
библиотека labviewv.lib лежит в папке C:\Program Files (x86)\National Instruments\LabVIEW [ваша версия LV]\cintools, подключить ее в MS VC++ можно кликнув правой клавишей на проекте в Solution Explorer -> Properties и прописав в Additional Dependencies после точки с запятой в конце указанный путь до статической библиотеки.
Это неправильный способ, но приемлемый, вообще рекомендуется все это собирать с помощью CMake, и там указывать соответствующие цели для линковки.
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
- 5 Ответы
- 433 Просмотры
-
Последнее сообщение Artem.spb
-
- 3 Ответы
- 2075 Просмотры
-
Последнее сообщение PozhiloyGoblin
-
- 0 Ответы
- 344 Просмотры
-
Последнее сообщение maxim_MA
-
- 23 Ответы
- 2435 Просмотры
-
Последнее сообщение dadreamer
-
- 2 Ответы
- 391 Просмотры
-
Последнее сообщение ujin1