?? txiso.cpp
字號:
/************************************************************************
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
* KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
* PURPOSE.
************************************************************************/
/************************************************************************
*
* Module: txiso.cpp
* Long name: VHPD1394 isochronous transmit example
* Description: This sample demonstrates how to use the VHPD1394
* device driver to transmit isochronous data to an
* isochronous channel.
* This sample is based on the VHPDLib C++ class library.
* It mainly demonstrates the usage of the class CVhpdIsoTalker.
*
* Runtime Env.: implemented as Win32 console application
* Used link libraries:
* vhpdlib.lib, setupapi.lib, user32.lib
* Author(s): Frank Senf
* Company: Thesycon GmbH, Ilmenau
************************************************************************/
// standard includes
#include <stdio.h>
#include <conio.h>
// definitions of used classes
#include "IsoTalker.h"
// print prefixes
#define PFX "TXISO: "
#define PFXERR "TXISO Error: "
// standard help message
static const char g_UseHelp[] = "For help, use TXISO -h.";
// GLOBAL VARIABLES
// isochronous talker instance
CIsoTalker g_IsoTalker;
// parameters of the isochronous data stream to transmit
// number of bytes to put to a single isochronous frame
// has to be DWORD-aligned
// (no default, always has to be specified)
unsigned long g_BytesPerIsoFrame;
// number of the channel used to transmit data (default is channel 0)
int g_Channel =0;
// speed of the isochronous data stream to transmit
// (default is 400 MBit/s)
VHPD_BUS_SPEED g_UsedSpeed =BusSpeed400;
// parameters of the buffer pool used for transmitting
// number of buffers in pool
unsigned long g_NumberOfBuffers =8;
// each buffer contains 160 isochronous frame, so it is transmitted in 20 ms
unsigned long g_FramesPerBuffer =160;
// name of the input file (optional)
const char* g_InFileName =NULL;
/*******************************************************************/
// support functions
/*******************************************************************/
//
// display usage information
//
void
PrintHelp(void)
{
fprintf(stdout,
"\n"
"usage: TXISO BytesPerIsoFrame <Options>\n"
"\n"
" BytesPerIsoFrame (required)\n"
" number of bytes to put to a single isochronous frame (has to be DWORD-aligned)\n"
"\n"
" Options:\n"
" -cChannel: isochronous channel to be used for transmission (optional, default %d)\n"
" -sSpeed: transfer speed of the selected channel (optional)\n"
" (1 -> 100MBit/s, 2 -> 200MBit/s, 4 -> 400MBit/s, default %d)\n"
" -nBufferCount: number of buffers in buffer queue\n"
" (optional, default %d)\n"
" -bFramesPerBuffer: number of isochronous frames contained in one buffer\n"
" (optional, default %d)\n"
" -fInputFile: file that contains the isochronous data to be transmitted (optional)\n"
" random data will be transmitted if this parameter is omitted\n"
,g_Channel,g_UsedSpeed,g_NumberOfBuffers,g_FramesPerBuffer);
fprintf(stdout,"\nPress any key to continue\n");
getch();
} // PrintHelp
/*******************************************************************/
// main function
/*******************************************************************/
int __cdecl main(int argc, char *argv[])
{
/*******************************************************************/
// fixed command line argument
// check for required arguments
if ( argc < 2 ) {
// at least BytesPerIsoFrame has to be specified
PrintHelp();
return 1;
}
// store values for required arguments
int val;
if ( 1==sscanf(argv[1]," %i ",&val) ) {
// check if BytesPerIsoFrame is DWORD-aligned
if ( val%sizeof(unsigned long) ) {
fprintf(stderr, PFXERR" BytesPerIsoFrame is not DWORD-aligned\n");
return 3;
} else {
// store value
g_BytesPerIsoFrame = val;
}
} else {
// invalid option format, ignore it
fprintf(stderr, PFXERR"Invalid BytesPerIsoFrame argument\n");
return 4;
}
/*******************************************************************/
// optional command line options
int i;
char* p;
for ( i=1; i<argc; i++ ) {
p = argv[i];
if ( (*p) == '-' ) {
p++;
switch ( *p ) {
case 'h':
case 'H':
case '?':
// help
PrintHelp();
return 0;
// isochronous channel
case 'c':
// read number
if ( 1==sscanf(p+1," %i ",&val) ) {
if ( val>=0 && val<=63 ) {
// valid channel number, store it
g_Channel = val;
} else {
// invalid channel number, ignore it
fprintf(stderr, PFXERR"Invalid channel number %d ignored\n",val);
}
} else {
// invalid option format, ignore it
fprintf(stderr, PFXERR"Invalid argument '%s' ignored\n",argv[i]);
}
break;
// transfer rate of isochronous data stream
case 's':
// read number
if ( 1==sscanf(p+1," %i ",&val) ) {
// check value
switch ( val ) {
case 1:
g_UsedSpeed = BusSpeed100; break;
case 2:
g_UsedSpeed = BusSpeed200; break;
case 4:
g_UsedSpeed = BusSpeed400; break;
default:
// invalid transfer rate, ignore it
fprintf(stderr, PFXERR"Invalid transfer rate %d ignored\n",val);
break;
} // switch
} else {
// invalid option format, ignore it
fprintf(stderr, PFXERR"Invalid argument '%s' ignored\n",argv[i]);
}
break;
// buffer count
case 'n':
// read number
if ( 1==sscanf(p+1," %i ",&val) ) {
// store value
g_NumberOfBuffers = val;
} else {
// invalid option format, ignore it
fprintf(stderr, PFXERR"Invalid argument '%s' ignored\n",argv[i]);
}
break;
// buffer size (in iso frames per buffer)
case 'b':
// read number
if ( 1==sscanf(p+1," %i ",&val) ) {
// store value
g_FramesPerBuffer = val;
} else {
// invalid option format, ignore it
fprintf(stderr, PFXERR"Invalid argument '%s' ignored\n",argv[i]);
}
break;
// input file name
case 'f':
if ( *(p+1) != 0 ) {
// save string pointer
g_InFileName = p+1;
} else {
// invalid filename
fprintf(stderr, PFXERR"Invalid argument '%s' ignored\n",argv[i]);
}
break;
// unknown options
default:
fprintf(stderr, PFXERR"Unrecognized option '%s' ignored. %s\n",argv[i],g_UseHelp);
break;
} // switch
}
} // for
/*******************************************************************/
// setup g_IsoTalker
unsigned long Status;
// open the input file if a file name was given
if ( g_InFileName != NULL ) {
Status = g_IsoTalker.OpenFile(g_InFileName);
if ( Status != 0 ) {
// ERROR !!!
fprintf(stderr, PFXERR"Open input file '%s' failed (0x%08X)\n",g_InFileName,Status);
return 10;
}
}
// prepare an OS-internal device list used for the open call
HDEVINFO DevList; DevList = NULL;
// device list will contain devices that provide the VHPD_IID interface
// please refer to to the documentation (chapter 7.4) for details on how
// to define your private interface (strongly recommended)
const GUID VhpdDefaultIID = VHPD_IID;
DevList = CVhpd::CreateDeviceList(&VhpdDefaultIID);
if ( DevList == NULL ) {
// ERROR !!!
fprintf(stderr, PFXERR"CreateDeviceList failed\n");
goto Exit;
}
// open a handle to a device, we use device zero for now
Status = g_IsoTalker.Open(0,DevList,&VhpdDefaultIID);
if ( Status != VHPD_STATUS_SUCCESS ) {
// ERROR !!!
// this may be caused by the fact that currently no device associated to the
// VHPD1394 driver is connected to the local node (this computer)
fprintf(stderr, PFXERR"Failed to open the device (0x%08X)\n",Status);
goto Exit;
}
// device opened, destroy the device list, we don't need it anymore
CVhpd::DestroyDeviceList(DevList);
DevList = NULL;
// setup the g_IsoTalker
// NOTE: we call CVhpdIsoChannel::SetupTalk()
Status = g_IsoTalker.SetupTalk(
(g_BytesPerIsoFrame*8000), // expected maximum bandwidth (bytes/s)
g_FramesPerBuffer, // isochronous frames hold by a single buffer
g_NumberOfBuffers, // number of buffers used for data transmission
g_Channel, // number of isochronous channel
g_UsedSpeed // transfer speed of isochronous channel
);
if ( Status != VHPD_STATUS_SUCCESS ) {
// ERROR !!!
fprintf(stderr, PFXERR"Failed to initialize talker (0x%08X)\n",Status);
goto Exit;
}
// start worker thread of g_IsoTalker
// this worker thread continuously fills and submits all buffers
// of the g_IsoTalker pool to the driver and finally starts data transmission
if ( !g_IsoTalker.StartThread() ) {
// ERROR !!!
fprintf(stderr, PFXERR"Failed to start worker thread\n");
goto Exit;
}
/*******************************************************************/
// now loop until we are told to exit
fprintf(stdout, PFX"Transmitting isochronous data ... press any key to exit\n");
for(;;) {
// query current data rate transported via this file handle
VHPD_QUERY_RATE_COUNTER RateCount;
__int64 r;
memset(&RateCount,0x0,sizeof(RateCount));
Status = g_IsoTalker.QueryRateCounter(&RateCount);
if (Status != VHPD_STATUS_SUCCESS) {
// ERROR !!!
fprintf(stderr, "\n"PFXERR"Failed to query data rate (0x%08X)",Status);
break;
}
// convert to bytes per second
r = RateCount.CurrentMeanValue/*bytes*/;
r = (1000*r) / RateCount.FilterDelay/*ms*/;
// display state of data reception
fprintf(stdout, PFX"Avg. rate is %I64d Bytes/s %d buffer errors (last 0x%08X) \r",
(__int64)r, g_IsoTalker.GetErrorCount(),g_IsoTalker.GetLastError());
// check if thread is still running
// worker thread may terminate itself, even if ShutdownThread was not called
// (e.g. because PreProcessBuffer returns false or an internal error was detected)
if ( g_IsoTalker.ThreadExited() ) {
fprintf(stdout,"\n"PFX"Worker thread has terminated ... aborting.\n");
break;
}
// check for user break
if ( kbhit() ) {
getch();
break;
}
// suspend some time
Sleep(500);
} // for()
fprintf(stdout, "\n"PFX"Exiting ...\n");
// stop data transmission
g_IsoTalker.StopChannel();
/*******************************************************************/
// ERROR!!! or normal exit
// release claimed resources
Exit:
if ( !g_IsoTalker.ShutdownThread() ) {
// ERROR !!!
fprintf(stderr, PFXERR"FATAL: Failed to stop worker thread\n");
}
g_IsoTalker.CloseFile();
g_IsoTalker.Shutdown();
g_IsoTalker.Close();
return 0;
} // main
/*************************** EOF **************************************/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -