Witam.
libusb-win32 jest biloteką dll do obsługi urządzeń usb.
Muszę napisać program który z pewnego czytnika odczyta mi dane (75kb). Odczyt jest dokonywany za pomocą funkcji zawartej w ww. dll. Ze względu na jego działanie musze odczytywać po 64 bajty (1200 operacji odczytu).
Wszystko działa, poza drobnym szczegółem. Cała operacja zajmuje u mnie ponad 8 sekund, a mam demo programu korzystającego z tej biblioteki, który robi to poniżej sekundy. Bibliotekę dołączam statycznie na początku, odczyt mam w pętli "for". korzystam z DevC++. Może ktoś poradzi jak to przyśpieszyć..w razie czego wrzucę za chwil mój kod.
Pozdrawiam i z góry dziękuję za ewentualną pomoc.
moze wykonujesz to synchronicznie zamiast operacji asynchronicznych - bez oprozniania buforow zapisu ?
tak ale wszystkie funkcje w tej bibliotece są synchroniczne..
to jest moja funkcja odczytu:
int finescan_getimg(void)
{
char sbuff[64];
char *p_sbuff;
int res,i,j;
p_sbuff=sbuff;
res=usb_control_msg(udevhandle,64,0xc2,0x0208,0,0,0,1000);//02
i=0;
res=64;
res=usb_control_msg(udevhandle,192,0xc3,0x0008,0,0,0,1000);
for (i=0;i<1200;i++)
{
res = usb_bulk_read(udevhandle,0x81, p_sbuff, 64, 100);
for (j=0;j<64;j++)
{
imgBuffer[i*64+j]=p_sbuff[j];
}
}
res=usb_control_msg(udevhandle,64,0xc2,0x0008,0,0,0,1000);
return 1;
}
// kod źródłowy bierz w tag odpowiedni, a nie powiększaj mu czcionkę - m.Q
Czemu czytasz do jakiegoś bufora pomocniczego? W dodatku potem przepisujesz po bajcie dane...
Ten kod powinien działać szybciej.
int finescan_getimg(void)
{
int res,i;
res=usb_control_msg(udevhandle,64,0xc2,0x0208,0,0,0,1000);//02
i=0;
res=64;
res=usb_control_msg(udevhandle,192,0xc3,0x0008,0,0,0,1000);
for (i=0;i<1200;i++)
{
res = usb_bulk_read(udevhandle,0x81, (char*)&imgBuffer[i*64], 64, 100);
}
res=usb_control_msg(udevhandle,64,0xc2,0x0008,0,0,0,1000);
return 1;
}
Może nie komentujmy moich "kwiatków"...;)) szkoda na nie słów..no chyba że pośmiać sie:) ... douczę sie
A w tym wypadku raczej nie mają one większego znaczenia, ale mimo to dzięki za korektę!!
Chodzi oto ze sama funkcja usb_bulk_read wywołuje się bardzo wolno (te 8 sekund na całość, które na początku napisałem na normalnym komputerze są 2-3 ...ale to i tak za długo ). No i nie wiem czy chodzi o czas dostępu do niej (raczej nie) , czy po prostu ta biblioteka tak ma (wszystkie funkcje wykonywane są w niej synchronicznie) a jeśli tak to rzucić nią w kat i brać się za WinAPI?? ale z ort! strony to demko które mam korzysta z tej biblioteki (a przynajmniej udaje) i chodzi dobrze...
Pozdrawiam
Drobna modyfikacja:
for (i=0;i<1200;i++)
{
res = usb_bulk_read(udevhandle,0x81, (char*)&imgBuffer[i*64], 64, 100);
if(res<0)break;
}
Wiem.. jest jeszcze parę innych szczegółów, aby to było w pełni poprawne.... ale to nie zmienia faktu że 1200. krotne wywołanie tej funkcji trwa o wiele za długo. Potrzebuje pomysłu jak to realnie przyśpieszyć...albo innego rozwiązanie.
Jesteś pewien, że odczyt musi być w tak małych porcjach? Może obadaj debuggerem to demo?
No niestety tak, próbowałem czytać większe to mi ładnie duplikuje pierwsze 64 bajty. No chyba że producent jeszcze coś ukrywa.... (nie napisał np w nocie katalogowej Vendorcode'ów które trzeba wysłać żeby mu jaką kolwiek konfigurację zrobić)
a co do debugera ... to spróbuje zobaczyć
0x666 napisał(a)
Drobna modyfikacja:
I jeszcze 2 drobniejsze:
i=0;
do{
res = usb_bulk_read(udevhandle,0x81, imgBuffer+(i<<6), 64, 100);
}while(++i<1200 && res>=0) // (!(res<0)) popraw, ja tylko przepisalem, zeby pasowalo
albo wlasciwie:
i=0;
while((res=usb_bulk_read(udevhandle,0x81,imgBuffer+(i<<6),64,100))>=0 && ++i<1200);
Cofam to co wcześniej napisałem. Wbrew temu co jest napisane w dokumentacji dla tej biblioteki jednak są jakieś funkcje asynchroniczne.
Problem z użyciem ma taki że jednym z parametrów jest void ** context , lub void * context czyli referencje do jakeś zmiennej dowolnego typu. Podejrzewam że ma to być jakaś struktura ... ale nic na jej temat nie widze
Witam
Poradziłem się ze wszystkim... jakiś czas już temu;)) błąd okazał się w konfiguracji...a nie metodzie;))
dołączam źródła mojego cosia może komuś się przydadzą licencja moich wypocin oczywiście GPL v2 ;)
jest to uproszczony sterownik dla czytnika MBF200 dla windows; używa biblioteki libusb-win32 (usb.h) kompilowany w devC++
fragmenty( deklaracje struktur) mogą pochodzić ze sterownika fps200 dla linux lub przykładów użycia biblioteki libusb-win32
mbfdll.h
/*licencja gpl v2*/
#ifndef _DLL_H_
#define _DLL_H_
#if BUILDING_DLL
# define DLLIMPORT __declspec (dllexport)
#else /* Not BUILDING_DLL */
# define DLLIMPORT __declspec (dllimport)
#endif /* Not BUILDING_DLL */
//class DLLIMPORT DllClass
//{
// public:
// DllClass();
// virtual ~DllClass(void);
//
// private:
//
//};
extern "C" DLLIMPORT int initmbf200(void);
extern "C" DLLIMPORT int closembf200(void);
extern "C" DLLIMPORT int getimgmbf200(unsigned char* imgBuffer);
extern "C" DLLIMPORT int setimgareambf200(unsigned int r1,unsigned char c1,unsigned int r2,unsigned char c2);
extern "C" DLLIMPORT int getsubimgmbf200(unsigned char* imgBuffer);
extern "C" DLLIMPORT int settimeout(int t_out);
extern "C" DLLIMPORT int setDTR(unsigned char rdtr); //rdtr=0..127 default 64
extern "C" DLLIMPORT int setDCR(unsigned char rdcr); //rdcr=0..15 default 2
extern "C" DLLIMPORT int setPGC(unsigned char rpgc); //rpgc=0..15 default 13
extern "C" DLLIMPORT unsigned char intfnmbf200(int to); // przerwanie
//{
//int DLLIMPORT initmbf200(void);
//int DLLIMPORT closembf200(void);
//unsigned char* DLLIMPORT getimgmbf200(void);
//}
#endif /* _DLL_H_ */
mbfdll.cpp
/* Replace "dll.h" with the name of your header */
/*licencja gpl v2*/
#include "mbfdll.h"
#include <windows.h>
#include <time.h>
#include "usb.h"
#include <stdio.h> // do testu
//konewncja
// funkcje zwraaja 0 gdy brak powodzenia 1 gdy powodzenie wywo�ania
// chyba �e funkcja ma zwruci� okre�lon� warto��.. wtedy bl�d wykonania bedze usatlony indywidualnie
//!!!!!vendorcode!!!!!!!
// zapis rejestru: code=0xc2
//odczyt rejestru: code=0xc3
//#include <iostream>
//DllClass::DllClass()
//{
//
//}
//
//
//DllClass::~DllClass ()
//{
//
//}
BOOL APIENTRY DllMain (HINSTANCE hInst /* Library instance handle. */ ,
DWORD reason /* Reason this function is being called. */ ,
LPVOID reserved /* Not used. */ )
{
switch (reason)
{
case DLL_PROCESS_ATTACH:
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
/* Returns TRUE on success, FALSE on failure */
return TRUE;
}
// zmienne globalne
// global vars
int isDeviceOpen=0;
char last_error_code=0;
int time_out=300; // czas oczekiwania na odczyt
unsigned char dtr=64;
unsigned char dcr=2;
unsigned char pgc=13;
struct usb_dev_handle *udevhandle;
struct usb_iso_packet_desc
{
unsigned int length;
unsigned int actual_length;
unsigned int status;
};
struct usb_urb
{
unsigned char type; /* >CM */
unsigned char endpoint; /* >CM */
int status; /* <C */
unsigned int flags; /* TCO */
void *buffer; /* >CM */
int buffer_length; /* >CM */
int actual_length; /* <C */
int start_frame; /* T-XX */
int number_of_packets; /* >--X */
int error_count; /* <--X */
unsigned int signr; /* signal to be sent on error. */
/* -1 if none should be sent (sic, try 0!) */
void *usercontext; /* >CO */
struct usb_iso_packet_desc iso_frame_desc[0];
};
struct usb_urb *context0;
//deklaracje lokalne funkcji
int finescan_init(void);
int finescan_usb_init(void);
int finescan_getimg(char* imbuf);
int finscan_close (struct usb_dev_handle *udevhandle);
void sleep(unsigned int mseconds);
static int usb_bulk_read();
int finescan_getsubimg(char* imbuf);
int subimg_init(unsigned int r1,unsigned char c1,unsigned int r2,unsigned char c2);
//char context0[256*10];
void sleep(unsigned int mseconds)
{
clock_t goal = mseconds + clock();
while (goal > clock());
}
extern "C" DLLIMPORT unsigned char intfnmbf200(int to)
{
int res;
char ir;
char* pir;
pir=&ir;
res=usb_control_msg(udevhandle,64,0xc2,0x000E,0,0,0,1000);
res=usb_control_msg(udevhandle,64,0xc2,0x0509,0,0,0,1000);
res=usb_control_msg(udevhandle,64,0xc2,0x000F,0,0,0,1000);
res=usb_control_msg(udevhandle,64,0xc2,0x010D,0,0,0,1000);
res=usb_bulk_read(udevhandle,0x82,pir,1,to);// endpoint2
return (unsigned char) ir;
}
// definicje funkcji golkobalnycc
extern "C" DLLIMPORT int setDTR(unsigned char rdtr) //dtr=0..127 default 64
{
dtr=rdtr & 0x7F; // zabezpieczene bo msb=0
return 1;
}
extern "C" DLLIMPORT int setDCR(unsigned char rdcr) //dcr=0..15 default 2
{
dcr=rdcr & 0x1F;// zabezpieczenie bo b7..5 =0
return 1;
}
extern "C" DLLIMPORT int setPGC(unsigned char rpgc) //pgc=0..15 default 13
{
pgc=rpgc & 0x0F; // zabezpieczenie bo b7..4=0
return 1;
}
extern "C" DLLIMPORT int initmbf200(void)
// inicjalizacja czytnika
{
int ret=0;
if (finescan_usb_init())
{
ret=finescan_init();
}
return ret;
}
extern "C" DLLIMPORT int getimgmbf200(unsigned char* imgBuffer)
{
int ret;
char* ib1;
ib1=(char*)imgBuffer;
ret=finescan_getimg(ib1);
if (ret!=0)
return ret;
}
//int closembf200(void)
extern "C" DLLIMPORT int closembf200(void)
{
int ret=0;
ret=finscan_close (udevhandle);
return 1;
}
extern "C" DLLIMPORT int settimeout(int t_out)
{
time_out=t_out;
return 1;
}
extern "C" DLLIMPORT int setimgareambf200(unsigned int r1,unsigned char c1,unsigned int r2,unsigned char c2)
{
int res=0;
res=subimg_init(r1,c1,r2,c2);
return res;
}
extern "C" DLLIMPORT int getsubimgmbf200(unsigned char* imgBuffer)
{
int ret;
char* ib1;
ib1=(char*)imgBuffer;
ret=finescan_getsubimg(ib1);
return ret;
}
//definivje funkcji lokalnych
int finescan_usb_init(void)
{
int err=0;
int ret=0;
// inicjalizacja bibloteki
usb_init();
err=usb_find_busses();
if (err==-1) return 0;
err=usb_find_devices();
if (err==-1) return 0;
isDeviceOpen=0;
//------------------------------------------------------------------------------
// wykrywanie urzondzenia;
unsigned int idVendor=0x061A;
unsigned int idProduct=0x0200;
struct usb_bus *busses;
struct usb_bus *bus;
struct usb_device *dev;
struct usb_device *dev1;
int deviceFound1=0;
busses = usb_get_busses ();
/* Match MBF200 scanner to correct usb device. */
for (bus = busses; bus; bus = bus->next)
{
for (dev = bus->devices; dev; dev = dev->next)
{
//if MBF200 is detected
if ((dev->descriptor.idVendor == idVendor) && (dev->descriptor.idProduct == idProduct))
{
// Yes, it was detected
dev1 = dev;
deviceFound1=1;
}
}
}
if (!deviceFound1)
{
// something wrong bad
last_error_code=1;
ret=0;
}
else
{
//good!!-- conytinue init;
int s_open=0;
int stat1;
int stat2;
int stat3;
if (!isDeviceOpen)
{
udevhandle=usb_open(dev1);
s_open=0;
if ((udevhandle != NULL))
{
// Get configuration ready
stat1 = usb_set_configuration (udevhandle, 1);
stat2 = usb_claim_interface (udevhandle, 0);
stat3 = usb_set_altinterface (udevhandle, 0);
// If any of the configuration fails
if ((udevhandle == NULL) || (stat1 < 0) || (stat2 < 0) || (stat3 < 0))
{
// ERROR, DEVICE NOT OPEN
s_open=0;
isDeviceOpen=0;
ret=0;
}
else
{
isDeviceOpen=1;
s_open=1;
ret=1;
}
}
}
if (!s_open)
{
// cos nie tak
last_error_code=2;
ret=0;
}
}
return ret;
}
int finescan_init(void)
{
int res,rval;
res=usb_control_msg(udevhandle,64,0xc2,0x0509,0,0,0,1000); //ctrlb
if (res==-1) return 0;
rval=(dtr<<8)|0x06;
res=usb_control_msg(udevhandle,64,0xc2,rval,0,0,0,1000); //DTR czas martwy?? //40
if (res==-1) return 0;
rval=(dcr<<8)|0x07;
res=usb_control_msg(udevhandle,64,0xc2,rval,0,0,0,1000); //DCR opuznienie odzytu?? //02
if (res==-1) return 0;
rval=(pgc<<8)|0x0c;
res=usb_control_msg(udevhandle,64,0xc2,rval,0,0,0,1000); // wzmocnenie 5
if (res==-1) return 0;
return 1;
}
int finescan_getimg(char* imbuf)
{
int res;
res=usb_control_msg(udevhandle,64,0xc2,0x0208,0,0,0,1000);//CTRLA 02 - getimg (full)
if (res==-1) return 0;
// res=usb_control_msg(udevhandle,192,0xc3,0x0008,0,0,0,1000); // was is das??
// if (res==-1) return 0;
// res=usb_bulk_read(udevhandle,0x81,(char*)&imgBuffer,1200*64,time_out);
res=usb_bulk_read(udevhandle,0x81,imbuf,1200*64,time_out);
if (res==-1) return 0;
res=usb_control_msg(udevhandle,64,0xc2,0x0008,0,0,0,1000);
if (res==-1) return 0;
return 1;
}
int finscan_close (struct usb_dev_handle *udevhandle)
{
/* prevent compiler from complaining about unused parameters */
// handle = handle;
/* Close any open device */
int res;
if (isDeviceOpen)
{
res=usb_release_interface(udevhandle, 0);
usb_close(udevhandle);
isDeviceOpen = 0;
}
return 1;
}
int subimg_init(unsigned int r1,unsigned char c1,unsigned int r2,unsigned char c2)
{
int res;
unsigned char rh,rl;
unsigned int rw;
// pierwsza wspo�rz�dna
rl=char(r1);
rh=char(r1>>8)&0x7F; //bo b7 is reserved
rw=0x00 | int(rh<<8); //RAH
res=usb_control_msg(udevhandle,64,0xc2,rw,0,0,0,1000); //RAH
if (res==-1) return 0;
rw=0x01 | int(rl<<8); //RAL
res=usb_control_msg(udevhandle,64,0xc2,rw,0,0,0,1000); //RAL
if (res==-1) return 0;
rw=0x02 | int(c1<<8); //CAL
res=usb_control_msg(udevhandle,64,0xc2,rw,0,0,0,1000); //CAL
if (res==-1) return 0;
//druga wsp��rzaena
rl=char(r2);
rh=char(r2>>8)&0x7F; //bo b7 is reserved
rw=0x03 | int(rh<<8); //REH
res=usb_control_msg(udevhandle,64,0xc2,rw,0,0,0,1000); //REH
if (res==-1) return 0;
rw=0x04 | int(rl<<8); //REL
res=usb_control_msg(udevhandle,64,0xc2,rw,0,0,0,1000); //REL
if (res==-1) return 0;
rw=0x05 | int(r2<<8); // CEL
res=usb_control_msg(udevhandle,64,0xc2,rw,0,0,0,1000); //CEL
if (res==-1) return 0;
int rval;
rval=(dtr<<8)|0x06;
res=usb_control_msg(udevhandle,64,0xc2,rval,0,0,0,1000); //DTR czas martwy?? //40
if (res==-1) return 0;
rval=(dcr<<8)|0x07;
res=usb_control_msg(udevhandle,64,0xc2,rval,0,0,0,1000); //DCR opuznienie odzytu?? //02
if (res==-1) return 0;
rval=(pgc<<8)|0x0c;
res=usb_control_msg(udevhandle,64,0xc2,rval,0,0,0,1000); // wzmocnenie 5
if (res==-1) return 0;
return 1;
}
int finescan_getsubimg(char* imbuf)
{
int res;
res=usb_control_msg(udevhandle,64,0xc2,0x0408,0,0,0,1000);//CTRLA 04 - getsubimg ()
if (res==-1) return 0;
// res=usb_bulk_read(udevhandle,0x81,(char*)&imgBuffer,1200*64,time_out);
res=usb_bulk_read(udevhandle,0x81,imbuf,1200*64,time_out);
if (res==-1) return 0;
res=usb_control_msg(udevhandle,64,0xc2,0x0008,0,0,0,1000);
if (res==-1) return 0;
return 1;
}
Cześć
Widze że temat dawno został wyjaśniony, ale ja nie dawno zabrałem się za biblioteke libusb-win32 i mam problem. Mianowicie funkcja usb_find_devices() zawsze zwraca mi wartość 0 bez względu na to czy podepnę coś do usb czy nie, a powinna zwracać ilość zmienionych urządzeń na portach usb. Czy ktoś z was miał ten problem? Ja pracuję pod XP. Magistrale mi znajduje bez problemu funkcja usb_find_busses().
Hejka