Cypress EZ-USB FX2 streaming problemer med CyAPI og CyUSB

E

Elephantus

Guest
Jeg er at designe et streaming dataindhentning ansøgning med Cypress EZ-USB FX2, bruger CyAPI.De data, der overføres fra eksterne logik via slave FIFO grænseflade til en quad-bufferet bulk endpoint i FX2.PC henter data fra FX2 bruger overførsel prescheduling ved kødannelse overlappede overførsler (det BeginXfer-WaitXfer-FinishXfer fremgangsmåde som vist i CyAPI serpentine eksempel).
Den angivne fremgangsmåde bør udbytte løbende hentning af data på USB-bus og omfattende stødpudeeffekt bruges på PC med henblik på at maksimere stream gennemstroemningsmaengden.

Men ved test og målinger, overvågning af FLAGB (FIFO fuld flag) har vist, at FX2 FIFO bliver tømt ikke-kontinuerligt afhængigt af den aktuelle CPU belastning.I en ansøgning, der bruger tre parallelle tråde (en til at hente og præ-forfaldsplan USB data,
dels til at modtage data og udløse forarbejdning og tredje som simulerer behandling for en given periode) at overvåge FLAGB havde vist, at FX2 FIFO var fuld (unserviced ved USB Host) for den nøjagtige varighed af den simuleret behandling (for en nærmere angivet periode med høj CPU-belastning).Lignende resultater blev opnået, når den samlede CPU-belastning blev rejst ved hjælp af en parallel CPU-tidkrævende proces.

Yderligere målinger og observation af FLAGB adfærd tydede på, at der er en mulighed for at hente og preschedule tråd der ikke gives tilstrækkelig CPU tid,
hvilket resulterede i unsufficient hastighed overførsel omlægning, som tømmes af prescheduled overførsel kø.Men øge buffer / overførsel størrelser og ændre tråd prioritet ikke fjerne problemet.For den givne design, nå de løbende data streaming er afgørende på grund af begrænsede stødpudeeffekt kapaciteter af den underliggende hardware.Den ikke-kontinuerlig hentning af data resulterer i et tab af data som følge af bufferoverløb, hvilket er uacceptabelt i den givne design.

De spørgsmål er: er den afhængighed af overføringshastighed på CPU belastning forårsaget af CyAPI / CyUSB føreren arkitektur, og er der en måde at øge ydeevnen med CyUSB driver?Kunne ydeevne forhøjes med direkte adgang til CyUSB føreren via CyIOCTL grænseflade?

Hvis nogen har et svar, eller andre idéer om det givne problem, jeg vil sætte pris på enhver hjælp.

 
til fuldt ud at bruge båndbredde af cypres FX2, der er en
USB 2.0-enhed,
pc'en har en enorm arbejdsbyrde.

Som vi har observeret på tidligere projekter under streaming processen, alle vinduer-trække vil medføre midlertidige pakkekoblende stall.

Det
er sorta system grænse.Ikke er forårsaget af føreren eller sth.

 
Nå båndbredden var vi håber på at bruge noget omkring 30-40 megabit per sekund, dog yderligere CPU belastning overhovedet synes at bryde båndbredde.
Eller anden måde ser det ud til, at den ansøgning, der udfører de givne opgaver, ikke kan opretholde den nødvendige gennemstroemningsmaengde hele tiden eller på alle, uanset den omstændighed, at FX2 båndbredde er ikke fuldt udnyttet.

 
Jeg ved, at dette er en gammel tråd, men hvis jeg kan finde det, andre vil også.

Jeg programmerede dataoverførsel fra CCD-sensor modul med Cypress USB og skifte fra CyAPI at CyUSB fordi jeg synes, at overlappede IO er ikke rigtig arbejder i CyAPI.

Med direkte adgang til CyUSB (via DeviceIOCtrl) Jeg kan starte overførsel i to separate buffere og chaufføren returnerer hver buffer, når det er fyldt.Så snart en buffer er fyldt,
vil jeg begynde på en ny buffer, så der altid er 2 buffere modtager.

I teorien kunne du gøre det samme med CyAPI, men hvis jeg gør det, får jeg den første tilbagekald, når både buffere er færdig.

Så den eneste måde for mig er at gøre direkte brug af CyUSB.

1) Inkluder "cyioctl.h"

2) optælle (sorry, tyske kommentarer)
Code:

/ / / GUID des Cypress USB Treibers

statisk GUID CYUSBDRV_GUID = (0xae18aa60, 0x7f6a, 0x11d4, 0x97, 0xdd, 0x0, 0x1, 0x2, 0x29, 0xb9, 0x59);/ / / Zeilenanfangskennung

statisk const usignerede int XXX_LINE_MAGICNUMBER = 0x555A;/ / / Adresse des USB endpoints

# define XXX_TX_ENDPOINT_ADDR 0x08/ / / Transferdatenblockgröße

# define DEFAULT_TX_TRANSFER_SIZE 64/ / Handle auf den Gerätetreiber holen

HDEVINFO hwDeviceInfo = SetupDiGetClassDevs ((LPGUID) & CYUSBDRV_GUID, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);

if (hwDeviceInfo! = INVALID_HANDLE_VALUE)

(

/ / DevInterfaceData Struktur vorbereiten

SP_DEVICE_INTERFACE_DATA devInterfaceData;

devInterfaceData.cbSize = sizeof (devInterfaceData);/ / Liste Aller vorhandenen Modul erstellen

mens ((modules.size () <XXX_MAX_MODULES) & & (SetupDiEnumDeviceInterfaces (hwDeviceInfo, 0, (LPGUID) & CYUSBDRV_GUID, (DWORD) modules.size (), & devInterfaceData)))

(

/ / DeviceInfoData Struktur vorbereiten

SP_DEVINFO_DATA deviceInfoData;

memset (& deviceInfoData, 0, sizeof (SP_DEVINFO_DATA));

deviceInfoData.cbSize = sizeof (SP_DEVINFO_DATA);/ / DeviceInterfaceDetailData Struktur vorbereiten

PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData;

ULONG requiredLength = 0, reservedLength = 0, realLength = 0;

if (! SetupDiGetDeviceInterfaceDetail (hwDeviceInfo, & devInterfaceData, NULL, 0, & requiredLength, NULL))

(

int errorCode = GetLastError ();

if (errorCode! = ERROR_INSUFFICIENT_BUFFER)

(

perror ( "FEJL: SetupDiGetDeviceInterfaceDetail () [1] ikke -");

printf ( "Fejlkode% d (0x% x) \ n", errorCode, errorCode);

FreeModuleList ();

tilbagevenden ERR_XXX_SETUPAPI;

)

)

reservedLength = requiredLength;

deviceInterfaceDetailData = (PSP_INTERFACE_DEVICE_DETAIL_DATA) nye CHAR [reservedLength];

memset (deviceInterfaceDetailData, 0, reservedLength);

deviceInterfaceDetailData-> cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA);/ / Detaljer abfragen

realLength = reservedLength;

if (SetupDiGetDeviceInterfaceDetail (hwDeviceInfo, & devInterfaceData, deviceInterfaceDetailData, reservedLength, & realLength, & deviceInfoData))

(

/ / Modul initialisieren

XXXModule * newModule = new XXXModule ((int) modules.size (), deviceInterfaceDetailData-> DevicePath);

modules.push_back (newModule);

) Else

(

int error =:: GetLastError ();

std:: cerr << "XXXEnumerator:: UpdateModuleList: SetupDiGetDeviceInterfaceDetail mislykkedes med kode" <<fejl << "\" "<<ErrorMessage (fejl) <<" \ "" <<std:: endl;

FreeModuleList ();

tilbagevenden ERR_XXX_SETUPAPI;

)/ / Für deviceInterfaceDetailData reservierten Speicher freigeben

Slet deviceInterfaceDetailData;

deviceInterfaceDetailData = NULL;

)/ / Auflistung beenden

SetupDiDestroyDeviceInfoList (hwDeviceInfo);/ / Fertig

tilbagevenden ERR_XXX_OK;/ / Gerätetreiber nicht vorhanden -> ergo keine Modul

) Else

(

tilbagevenden ERR_XXX_NODRIVER;

)
 
Overlappede lyder ikke er meget veldokumenteret, men de har arbejde.Du vil aldrig gøre det bedre end omkring 15 MB / sek i min erfaring med den standard blokerer læse opkald, og du får alvorlige udfald i hvert fald over ~ 6 MB / sek.

Jeg
har brugt denne kode til at modtage op til 32 MB / sek fra Cypress FX2.Det har kørt i flere dage ad gangen uden frafald på 10 MB / sek (med en 16KB hardware FIFO.)

Code:S32 ADC_acquire (void)

(

Overlappede inOv [QSIZE] / / 32 i mit tilfælde

statisk U8 * buff [QSIZE];

U8 * sammenhænge [QSIZE];BulkInPipe4-> SetXferSize (Nbytes); / / 65.536 i mit tilfældeADC_enable_acquisition (1) / / (application-specifikke)S32 max_size = BulkInPipe4-> MaxPktSize;

S32 xfer_size = BulkInPipe4-> GetXferSize ();printf ( "MaxPkt =% d, XferSize = 0x% x, bHighSpeed =% d \ n",

max_size, xfer_size, USBDevice-> bHighSpeed);hævde (NSAMPLES == (xfer_size / 4));for (S32 i = 0; i <QSIZE; i )

(

buff = (U8 *) malloc (xfer_size);

hævde (buff ! = NULL);memset (& inOv , 0, sizeof (inOv ));

inOv . hEvent = CreateEvent (NULL, falske, urigtige, NULL);sammenhænge = BulkInPipe4-> BeginDataXfer (buff , xfer_size, & inOv );

)printf ( "Modtagelse af data \ n \ n");S64 start = mono_time_uS ();

S64 forløbet = 0;

S64 byte = 0;S32 bufnum = 0;S32 resultat = 0;for (;;)

(

forløbet = mono_time_uS () - start;if (_kbhit ())

(

resultat = (_getch ()! = 27);

break;

)/ / Vent til denne xfer for at fuldføreif (! BulkInPipe4-> WaitForXfer (& inOv [bufnum], 1000))

(

ADC_enable_acquisition (0);

BulkInPipe4-> Abort ();

hævde (0);

WaitForSingleObject (inOv [bufnum]. HEvent, INFINITE);

)LONG rLen = xfer_size;if (! BulkInPipe4-> FinishDataXfer (buff [bufnum], rLen, & inOv [bufnum], sammenhænge [bufnum]))

(

ADC_enable_acquisition (0);

show_last_error ();

exit (1);

)/ / Process Nbytes af data fra buff [bufnum]U8 * src = buff [bufnum];

/ / .../ / Genindsendelseslinket overførselsammenhænge [bufnum] = BulkInPipe4-> BeginDataXfer (buff [bufnum], xfer_size, & inOv [bufnum]);bufnum = (bufnum 1)% QSIZE;

bytes = rLen;

)ADC_enable_acquisition (0);

flush (0);if (forløbet)

(

printf ( "\ n \ n% I64d bytes,% I64d USEC =% I64d byte / sec",

bytes,

udløbet,

bytes * 1000000 / forløbet);

)/ / CleanupBulkInPipe4-> Abort ();for (S32 i = 0; i <QSIZE; i )

(

if (! BulkInPipe4-> WaitForXfer (& inOv , 1000))

(

BulkInPipe4-> Abort ();

WaitForSingleObject (inOv . HEvent, INFINITE);

)LONG rLen = xfer_size;

BulkInPipe4-> FinishDataXfer (buff , rLen, & inOv , sammenhænge );CloseHandle (inOv . HEvent);gratis (buff );

buff = NULL;

)tilbagevenden resultat;

)

 

Welcome to EDABoard.com

Sponsor

Back
Top