Просмотр полной версии : Чтение буфера из системной памяти
Дано:
1. АЦП/ЦАП на USB.
2. Управление устройством осуществляется через библиотеку функций его драйвера.
3. Драйвер для Windows, не для LabView. Библиотека цепляется корректно, ее функции также работают корректно.
4. Драйвер устройства сваливает получаемые данные в буфер, расположенный в системной памяти.
5. Известны: адрес буфера, его размер, указатель на расположенные в нем данные.
6. Устройство исправно, поскольку ПО поставляемое разработчиком работает корректно.
Задача: Как прочитать полученные данные из буфера?
ЗЫ: Пробовал использовать функцию ReadFromPhysicalMemory из библиотеки cviVXDWrapper.dll и функцию RTLMoveMemory из библиотеки kernel32.dll. Первая читает некие данные, явно не корректные, а вторая так и не заработала. Наверное, неправильно их подключал.
Как я понимаю речь идет о внутреннем буфере драйвера?
По идее, как обычно делают в таких системах, в драйвере должна быть функция которая производит чтение данных из своего внутреннего буфера, в качестве входных параметров у нее должен быть указатель на область памяти, куда надо скопировать данные.
Есть список функций, которые можно использовать?
Речь идет о буфере в области системной памяти, который доступен любой программе. Драйвер дает только адрес этого буфера, его размер и положение каждой новой порции поступающих в него данных.
Попробовал вот это http://sine.ni.com/devzone/cda/epd/p/id/1132
вроде работает
Да, это работает (правда тоже есть отдельные неясности), но оно читает максимум только 2 слова. Данных же по объему гораздо больше, например: 1 канал*2 слова*4096 отсчетов = 65 кб. Если включить не один канал и, например, реализовывать осциллограф с разверткой 5мс/дел, то данная функция не сможет вовремя выбирать все данные.
PS: Можно ли вообще использовать в LabView функции типа RtlMoveMemory из kernel32? Если да, то как правильно импортировать библиотеку и настроить данную функцию?
Да действительно только по 2 слова
Конечно можно пользоваться любой функцией из длл-ки, только надо оболочку правильно сделать, тут надо идти к msdn: http://msdn2.microsoft.com/en-us/library/ms803004.aspx
Вот что-то получилось с длл-кой, проверь, за правильность работы не отвечаю...
Смотри сюда (http://labview.ilc.edu.ru/forum/showthread.php?t=1283&highlight=%F3%EA%E0%E7%E0%F2%E5%EB%E8). Смотри библиотеку \resource\cviVXDWrapper.dll на предмет функции ReadFromPhysicalMemory, описание здесь (http://zone.ni.com/reference/en-XX/help/370051H-01/cvi/cvireadfromphysicalmemory/).:)
ЗЫ:
Зная как устроен массив LV в памяти можно попробовать "набросить" его на область памяти dll'ки. Но это уже на грани фантастики.:cool:
Вот что-то получилось с длл-кой, проверь, за правильность работы не отвечаю...
Ааа, эта штука хитрая оказалась. Пока меня не послали из техподдержки вот сюда (http://zone.ni.com/devzone/cda/tut/p/id/2719), я не мог ее корректно запустить. В итоге получилось то же, что и у тебя, только на выходе прицепляется не новый массив, а LocalVariable входного (см. рис. внизу)
Смотри сюда (http://labview.ilc.edu.ru/forum/showthread.php?t=1283&highlight=%F3%EA%E0%E7%E0%F2%E5%EB%E8). Смотри библиотеку \resource\cviVXDWrapper.dll на предмет функции ReadFromPhysicalMemory, описание здесь (http://zone.ni.com/reference/en-XX/help/370051H-01/cvi/cvireadfromphysicalmemory/).:)
С этой штукой я в итоге тоже разобрался. Однако оказалось, что она, в полном соответствии со свом названием :) , читает именно физическую память. А в мое распоряжение, оказывается, попадает некий "виртуальный" указатель на буфер. Не силен в "С", но в прототипе функции, которая возвращает этот указатель, он объявлен как void**buffer. В общем, штатная виндовая RtlMoveMemory прекрасно его понимает.
Что касается PointerTools, то они, насколько я понял, не позволяют читать данные со знаком.
Зная как устроен массив LV в памяти можно попробовать "набросить" его на область памяти dll'ки. Но это уже на грани фантастики.:cool:Чего? :eek:
В общем, штатная виндовая RtlMoveMemory прекрасно его понимает.
Можно использовать не только стандартную виндовую функцию но и стандартную лабвьюшную - MoveBlock из библиотеки lvrt.dll (или labview.exe).
Что касается PointerTools, то они, насколько я понял, не позволяют читать данные со знаком.
Проверить сейчас не смогу. Но по идее должно читаться все. В конце концов, можно преобразовать полученный массив к знаковому типу.
Чего? :eek:
Если у тебя библиотека возвращает только указатель на область памяти. И эта область памяти постоянно занимает одно и то же адресное пространство. Так почему бы LV не сказать, что эта область памяти есть ничто иное, как ее массив.:)
Проверить сейчас не смогу. Но по идее должно читаться все. В конце концов, можно преобразовать полученный массив к знаковому типу.Проверил, действительно читает значения со знаком и отлично работает в моем приложении :o
Можно использовать не только стандартную виндовую функцию но и стандартную лабвьюшную - MoveBlock из библиотеки lvrt.dll (или labview.exe).О, про такую штуку не слышал. Посмотрю.
Если у тебя библиотека возвращает только указатель на область памяти. И эта область памяти постоянно занимает одно и то же адресное пространство. Так почему бы LV не сказать, что эта область памяти есть ничто иное, как ее массив.:)Насколько я понял, для этого нужно как минимум научиться говорить LV, в какой области памяти создавать свои переменные ...
А MoveBlock, похоже, пошустрее работает :)
Насколько я понял, для этого нужно как минимум научиться говорить LV, в какой области памяти создавать свои переменные ...
необязательно, можно все свести к манипуляции c указателями на области памяти. но всего скорей это очень сильно не понравиться Labview.
А MoveBlock, похоже, пошустрее работает :)
А почему у тебя функция возвращает Err?
в хедере ничего про это не написано:
VOID
RtlMoveMemory(
IN VOID UNALIGNED *Destination,
IN CONST VOID UNALIGNED *Source,
IN SIZE_T Length
);
З.Ы. В msdn советуют использовать RtlCopyMemory говорят она быстрее
А почему у тебя функция возвращает Err?
в хедере ничего про это не написано: ...
Это артефакт от применения ReadFromPhysicalMemory - следствие кривого глаза, не совсем прямых рук и спешки. :D
З.Ы. В msdn советуют использовать RtlCopyMemory говорят она быстрееПро эту эту штуку много где говорят на просторах Сети. Есть даже мнение, что RTLCopyMemory - та же RTLMoveMemory, только хитро объявленная. Не знаю, как оно на самом деле, а у меня в kernel32.dll этой функции нет.
он объявлен как void**buffer.
Любят они местами так делать, это указатель на массив, причем, неопределенного типа. тоесть то, что ты получаеш это не адрес того места где данные лежат, а адрес того места, в котором записан адрес того места, где данные лежат.
адрес того места, в котором записан адрес того места, где данные лежат.Вот что-то типа этого мне рассказывал разработчик железки. Однако вот в чем штука - и RTLCopyMemory и MoveBlock и функция из PointerTools читают нужные мне данные только в том случае, если я получаю указатель как ArrayDataPointer, а использую как Value. В общем, в пору учить Си :)
все довольно просто виглядит на си. например так
int val;
val=((int*)(*buffer))[0];
таким макаром можно достать значение типа i32 и без всяких дополнительнизх функций.
все довольно просто виглядит на си. например так
int val;
val=((int*)(*buffer))[0];
таким макаром можно достать значение типа i32 и без всяких дополнительнизх функций.
Еще немного - и свою dll с функцией копирования можно написать:D
легко. я сделал CIN для доставания значений из результатов работи запроса mysql. там примерно та же ситуация, тип ROW не что иноє как char**.
Вот код CIN'а
/* CIN source file */
#include "extcode.h"
#include <windows.h>
MgErr CINRun(LStrHandle String, int32 *row, int32 *Index);
MgErr CINRun(LStrHandle String, int32 *row, int32 *Index)
{
char **mrow;
int32 len;
// MessageBox(NULL,s,"Row prt",MB_OK);
/*
if(row[0])
{*/
mrow=(char**)row[0];
if(mrow[Index[0]])
{
len=StrLen(mrow[Index[0]]);
NumericArrayResize(uB, 1L,(UHandle *)&String, len);
LStrLen(*String)=len;
MoveBlock(mrow[Index[0]], LStrBuf(*String), len);
}
else
{
NumericArrayResize(uB, 1L,(UHandle *)&String, 4);
LStrLen(*String)=4;
MoveBlock("NULL", LStrBuf(*String), 4);
}
return noErr;
}
а вот и обертка для того кина
а это будет работать для Линукс вызова mmap(.......) функции?
vBulletin v3.6.1, Copyright ©2000-2012, Jelsoft Enterprises Ltd. Русский перевод: zCarot, Vovan & Co