Российский производитель и разработчик сертифицированного измерительного оборудования с 1987 года


Ошибка при работе с буфером

Вы не вошли.

 Поиск | Регистрация | Вход 

Александр
01.08.2011 09:44:00
#1

Гость

Ошибка при работе с буфером

Здравствуйте. Пытаюсь сделать подобие осцилографа для карточки l791, при работе с буфером возникли проблемы.
открываю устройство загружаю библиотеки при создании формы. ниже код заполения значений и процедура сбора данных

ap.t2.s_Type := L_ADC_PARAM;
   ap.t2.AutoInit := 1;
   ap.t2.dRate := 20.0;
   ap.t2.dKadr := 0.0;
   ap.t2.SynchroType := 0;
   ap.t2.SynchroSrc := 0;
   ap.t2.NCh := 6;
   ap.t2.Chn[0] := $0;
   ap.t2.Chn[1] := $1;
   ap.t2.Chn[2] := $2;
   ap.t2.Chn[3] := $3;


   ap.t2.FIFO := FIFO;
   ap.t2.IrqStep := IrqStep;
   ap.t2.Pages := pages;
   ap.t2.IrqEna := 1;
   ap.t2.AdcEna := 1;

   pLDev.FillDAQparameters(ap.t2);

  // tm := 1024*1024;  // мы захотели 100000 отсчетов
   tm:=100000;
   pLDev.RequestBufferStream(tm,L_STREAM_ADC);

   Memo1.Lines.Add(//'Allocated memory size(word) : //'+IntToStr(tm));

   pLDev.SetParametersStream(ap.t2, tm, data, sync,L_STREAM_ADC);

   Memo1.Lines.Add(//'Buffer size(points): //'+IntToStr(tm));
   Memo1.Lines.Add(//'Pages: //'+IntToStr(ap.t2.Pages));
   Memo1.Lines.Add(//'Rate: //'+FloatToStr(ap.t2.dRate));
   Timer1.Enabled:=True;
   pLDev.InitStartLDevice;
   pLDev.StartLDevice;

//процедура чтения из буфера
procedure TDataCollectThreat;
var
halfbuffer:integer;
fl1,k,j:integer;
s:string;
begin
k:=0; fl1:=0;j:=0;
halfbuffer := IrqStep * pages div 2; // Собираем половинками кольцевого буфера
while(Collect) do
  begin
    if(sync^ <= halfbuffer) then // Текушая половина буфера - первая
      begin
        while((sync^ <= halfbuffer) AND Collect) do Sleep(0);

        fl1 := 0; // Текушая половиной стала вторая, первая заполнена, в из нее будем считывать
        end
        else // Текушая половина буфера - первая
          begin
          while((sync^ > halfbuffer) AND Collect) do Sleep(0);
          fl1 := 1; // Текушей половиной стала первая, вторая заполнена, в из нее будем считывать
          end;

      k := halfbuffer * fl1; // начало половины буфера
if(Collect) then for j := 0 to ((halfbuffer div 4) - 1) do
begin
//считываем 4 числа, так как 4 канала
S := IntToStr(data[k]) + #9 + IntToStr(data[k + 1]) + #9 + IntToStr(data[k + 2]) + #9 + IntToStr(data[k + 3]);
form1.Memo1.lines.Add(S);
k := k + 4;
end;

Sleep(0);
end;
end;

когда пытаюсь запустить поток сбора данных
hThread:=CreateThread(0,$2000,@TDataCollectThreat,0,0,hThread);

вылазиет ошибка "Thread Start", и курсор ставится на строку
while((sync^ > halfbuffer) AND Collect) do Sleep(0);
Значение halfBuffer в этот момент 16384

Где я накосячил?

01.08.2011 10:31:10
#2

Сотрудник "Л Кард"
Откуда: Москва
Здесь с 23.04.2014
Сообщений: 3,727

Re: Ошибка при работе с буфером

Да везде. Почитайте про треды в Delphi и взаимодействие с компонентами форм. И пользуйтесь делфийскими функциями для этого.

Александр
01.08.2011 10:42:26
#3

Гость

Re: Ошибка при работе с буфером

Что значит везде?как бы можно было и указать на явные ошибки, не все же Гуру программеры. Я так понял ошибка именно в потоке?заменить WinAPI на стандартные функции создания потоков в делфи?

01.08.2011 11:21:07
#4

Сотрудник "Л Кард"
Откуда: Москва
Здесь с 23.04.2014
Сообщений: 3,727

Re: Ошибка при работе с буфером

Да. И там правильно обращаться к элементам форм через синхронайз или типа того. Код сишный посмотрите такого потока в примерах. Данные обрабатывать на лету можно только если есть уверенность что это быстро происходит.

Александр
01.08.2011 12:36:58
#5

Гость

Re: Ошибка при работе с буфером

Учел свои косяки переписал код, но ошибка все равно появляется там же когда начинаю собирать данные.

Гляньте пожалуйста отрывки кода

const
   FIFO = 1024;
   IrqStep = 1024;
   pages = 32;
   multi=4;

type
  WA = array [0..512000] of ULONG;
  SA = array [0..1023] of ULONG;
  PWA = ^WA;

var
  Form1: TForm1;

  pLDev: IDaqLDevice;
  pIUnknown:LUnknown;
  hr:Integer;
  sl:SLOT_PAR;
  dev: THandle;
  pd: PLATA_DESCR_L791;
  ap: ADC_PAR;
  ad:DAC_PAR;
  tm: ULONG;
  data:PWA;
  sync:PULONG;
  buffsize : ULONG;
  a:ASYNC_PAR;
  i:double;
  collect:boolean;
  hThread:THAndle;

procedure TForm1.FormCreate(Sender: TObject);
begin
   Timer1.Enabled:=False;

   Memo1.Lines.Clear;
   Memo1.Lines.Add(//'Testing library//');
   if(CallCreateInstance(//'lcomp.dll//')=1) then
   begin
      Memo1.Lines.Add(//'Loading library - success.//');
      Memo1.Lines.Add(//'//');
   end;

   pIUnknown:=CreateInstance(0);
   hr := pIUnknown.QueryInterface(IID_ILDEV,pLDev);
   if(not Succeeded(hr)) then MessageBox(0,//'Get interface failed//',//'Error//',MB_OK);
   pIUnknown.Release;
   dev:=pLDev.OpenLDevice;
end;

procedure TForm1.Button1Click(Sender: TObject);
var s:string;
begin
   s:=IntToStr(0{pLDev.LoadBios(//'l1450//')});
   Memo1.Lines.Add(//'LoadBios status //'+s);
   s:= IntToStr(pLDev.PlataTest);
   Memo1.Lines.Add(//'PlataTest status //'+s);

   s:=IntToStr(pLDev.ReadPlataDescr(pd));

   Memo1.Lines.Add(//'ReadPlataDescr status //'+s);

   Memo1.Lines.Add(//'//');
   Memo1.Lines.Add(//'Serial Num. //'+pd.SerNum);
   Memo1.Lines.Add(//'Board Name //'+pd.BrdName);
   Memo1.Lines.Add(//'Revision //'+pd.Rev);
   Memo1.Lines.Add(//'DSP Type //'+pd.DspType);
   Memo1.Lines.Add(//'Quartz //'+IntToStr(pd.Quartz));
//   Memo1.Lines.Add(//'IsDacPresent //'+IntToStr(pd.IsDacPresent));
   Memo1.Lines.Add(//'//');

   pLDev.GetSlotParam(sl);

   Memo1.Lines.Add(//'//');
   Memo1.Lines.Add(//'Slot parameters//');
   Memo1.Lines.Add(//'Base - //'+IntToHex(sl.Base,4));
   Memo1.Lines.Add(//'BaseL - //'+IntToHex(sl.BaseL,4));
   Memo1.Lines.Add(//'Mem - //'+IntToHex(sl.Mem,8));
   Memo1.Lines.Add(//'MemL - //'+IntToHex(sl.MemL,8));
   Memo1.Lines.Add(//'Type - //'+IntToStr(sl.BoardType));
   Memo1.Lines.Add(//'DSPType - //'+IntToStr(sl.DSPType));
   Memo1.Lines.Add(//'Irq - //'+IntToStr(sl.Irq));

end;

procedure TForm1.Button2Click(Sender: TObject);
var
i:integer;
begin
   ap.t2.s_Type := L_ADC_PARAM;
   ap.t2.AutoInit := 1;
   ap.t2.dRate := 20.0;
   ap.t2.dKadr := 0.0;
   ap.t2.SynchroType := 0;
   ap.t2.SynchroSrc := 0;
   ap.t2.NCh := 6;
   ap.t2.Chn[0] := $0;
   ap.t2.Chn[1] := $1;
   ap.t2.Chn[2] := $2;
   ap.t2.Chn[3] := $3;


   ap.t2.FIFO := FIFO;
   ap.t2.IrqStep := IrqStep;
   ap.t2.Pages := pages;
   ap.t2.IrqEna := 1;
   ap.t2.AdcEna := 1;

   pLDev.FillDAQparameters(ap.t2);

  // tm := 1024*1024;  // мы захотели 100000 отсчетов
   tm:=100000;
   pLDev.RequestBufferStream(tm,L_STREAM_ADC);

   Memo1.Lines.Add(//'Allocated memory size(word) : //'+IntToStr(tm));

   pLDev.SetParametersStream(ap.t2, tm, data, sync,L_STREAM_ADC);

   Memo1.Lines.Add(//'Buffer size(points): //'+IntToStr(tm));
   Memo1.Lines.Add(//'Pages: //'+IntToStr(ap.t2.Pages));
   Memo1.Lines.Add(//'Rate: //'+FloatToStr(ap.t2.dRate));
   Timer1.Enabled:=True;
   pLDev.InitStartLDevice;
   pLDev.StartLDevice;
end;

procedure WriteValue;
begin
  form1.Memo1.lines.Add(S);
end;

procedure CollectObj.Execute;
var
halfbuffer:integer;
fl1,k,j:integer;
s:string;
begin
//sync:=0;
halfbuffer := IrqStep * pages div 2; // Собираем половинками кольцевого буфера
while(unit1.collect) do
  begin
    if(sync^ <= halfbuffer) then // Текушая половина буфера - первая
      begin
        while((sync^ <= halfbuffer) AND unit1.Collect) do Sleep(0);

        fl1 := 0; // Текушая половиной стала вторая, первая заполнена, в из нее будем считывать
        end
        else // Текушая половина буфера - первая
          begin
          while((sync^ > halfbuffer) AND unit1.Collect) do Sleep(0);
          fl1 := 1; // Текушей половиной стала первая, вторая заполнена, в из нее будем считывать
          end;

      k := halfbuffer * fl1; // начало половины буфера
if(unit1.Collect) then for j := 0 to ((halfbuffer div 4) - 1) do
begin
//считываем 4 числа, так как 4 канала
S := IntToStr(data[k]) + #9 + IntToStr(data[k + 1]) + #9 + IntToStr(data[k + 2]) + #9 + IntToStr(data[k + 3]);
Synchronize(WriteValue);
k := k + 4;
end;

Sleep(0);
end;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
th:=CollectObj.Create(true);
th.Resume;
th.Priority:=tpLower;
end;

Ошибку выдает в строке
while((sync^ > halfbuffer) AND unit1.Collect) do Sleep(0);

Есть подозрения что я напутал с размерами буферов или переменными...

С Уважением,Александр

01.08.2011 13:42:23
#6

Сотрудник "Л Кард"
Откуда: Москва
Здесь с 23.04.2014
Сообщений: 3,727

Re: Ошибка при работе с буфером

У L791 вообще-то все немного не так в смысле чтения sync. там смещение есть см пример. и буфер там всегда 128к отсчетов. Примеры смотрите L791.DPR и L791.TST

Александр
03.08.2011 07:47:26
#7

Гость

Re: Ошибка при работе с буфером

Уважаемый Poul,не могли бы вы поконкретнее рассказать о Sync[I_ADC_PCI_COUNT_L791] т.к.при обращении к ней выскакивает Access Violation.

03.08.2011 11:47:34
#8

Сотрудник "Л Кард"
Откуда: Москва
Здесь с 23.04.2014
Сообщений: 3,727

Re: Ошибка при работе с буфером

А как примеры работают?

Александр
03.08.2011 12:20:43
#9

Гость

Re: Ошибка при работе с буфером

L791.tst выводит Sync[I_ADC_PCI_COUNT_L791] в арифметической пос-ти., ну и Sync[I_DAC_PCI_COUNT_L791] что мне не очень важно.

моя процедура чтения данных из потока
procedure CollectObj.Execute;
var
halfbuffer:integer;
fl1,k,j:integer;
s:string;
b:Ulong;
begin
k:=0;
fl1:=1;
halfbuffer := (IrqStep * pages) div 2; // Собираем половинками кольцевого буфера
while(unit1.collect) do        //сбор разрешен
  begin
    if(sync[I_ADC_PCI_COUNT_L791] <= halfbuffer)
    then // Текушая половина буфера - первая
      begin
        while((sync[I_ADC_PCI_COUNT_L791] <= halfbuffer) AND unit1.Collect) do Sleep(0);
        fl1 := 0; // Текушая половиной стала вторая, первая заполнена, в из нее будем считывать
      end
    else // Текушая половина буфера - первая
      begin
        while((sync[I_ADC_PCI_COUNT_L791] > halfbuffer) AND unit1.Collect) do Sleep(0);
        fl1 := 1; // Текушей половиной стала первая, вторая заполнена, в из нее будем считывать
      end;
      k := halfbuffer * fl1; // начало половины буфера
if(unit1.Collect) then
  for j := 0 to ((halfbuffer div 4) - 1) do
    begin
    //считываем 4 числа, так как 4 канала
    S := IntToStr(data[k] and $FFFF) + #9 + IntToStr(data[k + 1]and $FFFF) + #9 + IntToStr(data[k + 2]and $FFFF) + #9 + IntToStr(data[k + 3]and $FFFF);
    Synchronize(WriteValue);
    k := k + 4;
    end;

Sleep(0);
end;
end;

Прошу критики подправьте где ошибся, а то замучался уже.

03.08.2011 13:26:18
#10

Сотрудник "Л Кард"
Откуда: Москва
Здесь с 23.04.2014
Сообщений: 3,727

Re: Ошибка при работе с буфером

если последний цикл for убрать то как себя ведет программа?

Александр
03.08.2011 14:03:53
#11

Гость

Re: Ошибка при работе с буфером

тоже самое- ошибка в строке  while((sync[I_ADC_PCI_COUNT_L791] <= halfbuffer) AND unit1.Collect) do Sleep(0);

Периодически при запуске ошибка появляется либо в этой строке либо в
while((sync[I_ADC_PCI_COUNT_L791] > halfbuffer) AND unit1.Collect) do Sleep(0);

03.08.2011 15:59:20
#12

Сотрудник "Л Кард"
Откуда: Москва
Здесь с 23.04.2014
Сообщений: 3,727

Re: Ошибка при работе с буфером

тогда ждите...как поставлю дельфи и вспомню что да как там и пример состряпаю какой-нибудь...

Александр
04.08.2011 05:17:07
#13

Гость

Re: Ошибка при работе с буфером

Cпасибо,буду ждать. Отпишитесь пожалуйста в этой теме как сделаете.Хотелосб бы пример с потоковым сбором данных с карты и их выводом в каком либо формате на форму