|
VX/IP-2698
DEVICE SUPPORT PACKAGE SUMMARY AND SAMPLE APPLICATION PROGRAMS
copyright (c) 1996
Compware Corp.
2698B Octal Driver
tyOctSerDrv
tyOctSerDrv is a vxWorks
device driver supporting multiple asynchronous serial communications ports
provided by the IP-Octal 2698B UART Industry Pack (IP). Each IP-Octal
implements 8 serial ports when installed in Greenspring 310 or 610 VMEbus
carrier boards or the Motorola MVME162. Each IP is identified to the driver
by supplying a base VMEbus address, interrupt levels, and interrupt vector.
Once initialized, each port is then available for device creation where a
device name and buffer parameters are assigned for subsequent tyLib service
calls.
tyOctSerDrv takes full
advantage of the vxWorks tyLib functions. This provides the capability to
accept application program calls that are not device specific increasing
the portability of vxWorks serial communications applications.
Driver Startup and
Entry Points
The binary
tyOctSerDrv.o can either be linked to the vxWorks kernel or downloaded
(linked) dynamically. Addressing and configuration of Octal IP's is
performed through calls to driver entry points at runtime or through command
line calls. The following entry points are provided:
tyOctSerDrv() for
starting the driver
tyOctSerPack( address,
vector, level1, level2) to allocate driver memory and to initialize
hardware for an Industry Pack
tyOctSerDevCreate(
name, channel, readBufSize, writeBufSize) to make a port available for
tyLib access
Driver startup is
performed by calling tyOctSerDrv with no arguments. This call installs the
driver as part of the vxWorks I/O subsystem. This function returns OK if
succesful otherwise ERROR.
Device Initialization
Each IP installed as
part of the serial I/O system must be initialized. A call to tyOctSerPack
identifies those parameters necessary to uniquely identify the hardware to
the driver. Table memory that maintains configuration and status
information is allocated at this time. tyOctSerPack also resets the
hardware for each port on the pack and installs handlers for transmit and
receive interrupts. During initialization, the address passed is probed for
existence of the hardware registers and the ID PROM is checked for
compatibility. The function prototype of the initialization call is shown
below:
STATUS tyOctSerPack(
int baseVmeAddress, int interruptVector, int interruptLevel1, int
interruptLevel2 );
Where: baseVmeAddress,
is the physical address in short I/O of the IP interruptVector, is the
vector number assigned for this IP (0-255) interruptLevel1,2, are the 2
levels assigned (jumpered) to this IP (1-7)
NOTE: If using default
PALS with Greenspring's VIPC 310/610 for interrupt allocation, two
interrupt levels are necessary to fully support all 8 ports of the IP.
These are normally set by the location of jumpers on the carrier board and
must be identified to the driver for proper operation. Refer to the VME
carrier board documentation for more details on jumper configuration.
Returned status is OK
or ERROR.
Device Creation
A serial device is
created by calling tyOctSerDevCreate. This call will create a device
"file", add the device to tyLib, initialize the port to a default
state of 9600 baud, 8 bits/character, 1 stop bit, no parity, and create a
channel/port assignment in the driver. This call must be made prior to any
'open' calls by an application.
The function prototype
for the device creation call is shown below:
STATUS
tyOctSerDevCreate(char *name, int channel, int readBufSize, int
writeBufSize );
Where:
name, is the filename
associated with this device (ex. /tyCo/portA)
channel, is the
channel assignment for this device and is used internally by the driver and
for showing stats on devices
read &
writeBufSize, allocate ring buffer sizes in tyLib. It is recommended that
the read buffer be at least twice the write buffer size and that the write
buffer be at least large enough to hold 2 of the largest communications
packets.
Returned status is OK
or ERROR.
Application Interface
Applications access
the serial ports of the Octal IP indirectly via tyLib routines for open,
read, write, and ioctl. Each of these are documented in the vxWorks
Reference Guide and shown in the sample programs below.
The application
designer should be aware of the 2 ways to read from a serial port. There is
the normal 'read' call for non-blocking access to the contents of the ring
buffer. This call would be used as part of a known protocol perhaps where
block sizes vary. The other call is 'fioRead' which includes an argument
for the size of the buffer to read which causes vxWorks to perform multiple
'reads' to satisfy that size request.
Device and IP
information is displayed to stdio through the following calls:
tyOctSerShow()
to see configuration
parameters and registers for all channels that have been added to the I/O
system. This is primarily a dump of the device structure maintained for
each port and contains the following information: Industry Packs available
device tables allocated channels active (created) For each channel: channel
number created flag (indicates that a device has been created for this
channel) port A flag (TRUE if this is the "a" port of the pair)
interrupt vector interrupt level number of data bits number of stop bits
contents of all readable registers
tyOctSerShowChan( int
channel )
to see information
about a channel Address of channel struct created flag (indicates that a
device has been created for this channel) port A flag (TRUE if this is the
"a" port of the pair) interrupt vector interrupt level number of
data bits number of stop bits block hardware address interrupt mask
register contents pointer (since the IMR is a READONLY register, a copy is
saved in memory for each block of the device) IMR value used during
initialization IMR value to use when enabling the transmitter IMR value to
use when resetting the interrupts ACR reset value used during reset address
of Ip struct associated with this port index that indicates which block of
4 this port resides in
tyOctSerShowReg( int
channel )
to see the mode and
status registers associated with a particular channel address and contents
of both mode registers address and contents of status register address and contents
of IMR mask memory location address of receive hold register address and
contents of interrupt vector register
These calls were
developed for driver debug and evaluation. End-user adaptation is possible
to support application requirements. IOCTL's Several ioctl's are provided
with the driver for control of the 2698B Octal IP in addition to those
ioctl's supported by tyLib.
Ioctl's are invoked
using the following syntax: ioctl( fd, operation, argument );
TYCO_2698B_MODE
This allows the
application opportunity to set or clear mode register bits under program
control. Knowledge of the operation of both mode registers is required to
ensure proper operation of the 2698B, particularly interrupt servicing.
Care must be taken to avoid clearing bits that are already set in the mode
registers. Refer to the product specification for the SCC2698B for a
detailed description of the contents of mode registers 1 and 2. The include
file scc2698.h contains bit mask definitions for each function in the mode
registers and are OR'ed together to form the argument to the ioctl call.
Mode register 1 uses the lower 8 bits of argument while mode register 2
uses the upper 8 bits of argument.
For example, to setup
the port for local loopback, 1 stop bit, no parity, and 8-bit characters,
the following code fragment could be used:
int modepair;
/* setup port for
local loopback */
modepair = (
CHAN_MODE_LL | STOP_BITS_1 ) << 8; modepair |= ( PAR_MODE_NO |
BITS_CHAR_8 );
if( ioctl( f,
TYCO_2698B_MODE, modepair ) |= OK ) { printf("\nERROR setting mode
registers\n"); exit(-1); }
TYCO_COMMAND
Allows applications to
send commands to the command register for a channel. This provides the full
set of commands as documented in the SCC2698B product specification. All
commands are #define'd in scc2698.h. The lower 8-bits of argument contains
the command byte to be placed in the command register by the driver.
TYCO_ASSERT_RTSN
Asserts the RTS
output. Can be used to enable the transmitter for an RS485 application. A
NULL 'argument' value is required.
TYCO_NEGATE_RTSN
Negates the RTS
output. Enables the receiver for an RS485 application. A NULL 'argument'
value is required.
TYCO_ENABLE_CTS
Enables CTS/RTS
control by setting bits MR1[7] receiver request to send control and MR2[4] clear
to send control. Receiver request to send control causes RTSN to be
automatically negated upon receipt of a valid start bit if the receiver
FIFO is full. RTSN is reasserted when an empty FIFO position is available.
This can be used to prevent overrun when the RTSN signal of the receiver
controls the CTS input of the transmitter. Clear to send control affects
transmitter operation. When CTSN is asserted, the transmitter is allowed to
send a character. When CTSN is negated, the transmitter is not allowed to
send.
The argument value to
TYCO_ENABLE_CTS is NULL.
FIOBAUDRATE
Selects a baud rate
from the list of possible rates supported by the 2698B. The rates that are
available include:
75,110,150,300,600,1200,1800,2000,2400,4800,9600,19200,38400
Interrupt Processing
It is important to
note here that there are some considerations for the application designer
using this IP-OctalSerial and driver. Due to the hardware design, it is
necessary that an interrupt service routine for this board respond to an
interrupt by polling all 8 ports of the interrupting IP for status. This is
because the IP provides a single interrupt vector used for both interrupt
levels. Since this is not enough information for the ISR to determine which
serial port has requested service, each interrupt status register must be
queried to determine the state of all 8 ports before releasing the
interrupt.
An ISR time of 10
microseconds or less is generally considered optimal for a realtime system.
This ISR can take considerably longer than that to poll all 8 ports and
service those that are needed. Since this time is potentially large for
some realtime applications and may impact some other applications or
drivers installed along with this one, it must be considered when assigning
interrupt levels and priorities.
For installations that
will install multiple Octal IP's on a VIPC610/616 carrier board, the
application engineer must be aware that the carrier allows only 7 of the 8
interrupt levels needed to support a fully populated carrier. The interrupt
assignments discussed above must then be modified with a revised carrier
board PAL. A PAL can be programmed for specific applications that map
interrupts differently. This may also necessitate modifications to the
driver, however, in order to implement proper interrupt servicing.
RS485 Application
Notes
For those applications
that use this driver and RS485 Octal IP's, there are certain considerations
to keep in mind when designing the application. RS485 differs from RS232
and RS422 in that there can be up to 32 RS485 "drops" connected
to a single pair of wires. This same pair of wires is also shared by the
transmitter/receiver so that there is in effect only half duplex
communications. This forces the introduction of a protocol by the application
layer to decide who is the transmitter with all other "drops"
defaulting to receive.
This topology and
protocol requirement also introduces a need to select either transmit or
receive mode in the Octal UART. Thus, the introduction of the pair of
ioctl's for TYCO_ASSERT_RTS and TYCO_NEGATE_RTS.
TYCO_ASSERT_RTS
asserts a hardware line to the transmit driver enabling the UART to
transmit.
TYCO_NEGATE_RTS drops
this line allowing the UART to receive.
It turns out that the
hardware design introduces another need for control when the UART is
transmitting. This is the need to disable the receiver. If the receiver is
not disabled during transmit, it generates a receiver interrupt for each
transmitted character. Since the application is typically not expecting to
receive its own data, the ring buffer is being filled with unwanted
characters. The solution to avoid receiver interrupts is to use the
TYCO_COMMAND ioctl with the argument set to RX_DISABLE and then RX_ENABLE
when transmission is complete. For some protocol applications however, it
may actually be desired to receive the characters that are being
transmitted so there is not a potential ring buffer overflow condition
introduced.
Test and Sample
Programs
The following test and
sample programs/scripts are included as a guide to usage of the various
features described above.
file: tstCall.s
#--- Load the driver
ld <
server_name:/serial/tyOctSerDrv.o
#--- Start the driver
tyOctSerDrv
#--- Initialize an
Industry Pack
tyOctSerPack
512,200,5,6
#--- Create devices
for all 8 ports
tyOctSerDevCreate
"/tyCo/octC0",0,512,512
tyOctSerDevCreate
"/tyCo/octC1",1,512,512
tyOctSerDevCreate
"/tyCo/octC2",2,512,512
tyOctSerDevCreate
"/tyCo/octC3",3,512,512
tyOctSerDevCreate
"/tyCo/octC4",4,512,512
tyOctSerDevCreate
"/tyCo/octC5",5,512,512
tyOctSerDevCreate
"/tyCo/octC6",6,512,512
tyOctSerDevCreate
"/tyCo/octC7",7,512,512
#--- Load the test
program
ld <
server_name:/serial/tyLoopGeneric.o
#--- Setup vxWorks in
round robin schedule
kernelTimeSlice(5)
#--- spawn a task for
each port to test multiple interrupts
sp
tyLoop,"/tyCo/octC0",0
sp
tyLoop,"/tyCo/octC1",1
sp
tyLoop,"/tyCo/octC2",2
sp
tyLoop,"/tyCo/octC3",3
sp
tyLoop,"/tyCo/octC4",4
sp
tyLoop,"/tyCo/octC5",5
sp
tyLoop,"/tyCo/octC6",6
sp tyLoop,"/tyCo/octC7",7
file: tstBC.s
# Test script to
exercise IP's in the B and C slots of a 610 carrier
#--- Load the driver
ld <
server-name:/serial/tyOctSerDrv.o
#--- Start the driver
tyOctSerDrv
#--- Initialize both
IP's
tyOctSerPack
256,200,3,4
tyOctSerPack
512,201,5,6
#--- Create devices on
both IP's
tyOctSerDevCreate
"/tyCo/octB0",0,512,512
tyOctSerDevCreate
"/tyCo/octB1",1,512,512
tyOctSerDevCreate
"/tyCo/octB2",3,512,512
tyOctSerDevCreate
"/tyCo/octB3",3,512,512
tyOctSerDevCreate
"/tyCo/octB4",4,512,512
tyOctSerDevCreate
"/tyCo/octB5",5,512,512
tyOctSerDevCreate
"/tyCo/octB6",6,512,512
tyOctSerDevCreate
"/tyCo/octB7",7,512,512
tyOctSerDevCreate
"/tyCo/octC0",8,512,512
tyOctSerDevCreate
"/tyCo/octC1",9,512,512
tyOctSerDevCreate
"/tyCo/octC2",10,512,512
tyOctSerDevCreate
"/tyCo/octC3",11,512,512
tyOctSerDevCreate
"/tyCo/octC4",12,512,512
tyOctSerDevCreate
"/tyCo/octC5",13,512,512
tyOctSerDevCreate
"/tyCo/octC6",14,512,512
tyOctSerDevCreate
"/tyCo/octC7",15,512,512
# #--- Load the
generic test routine
ld <
server_name:/serial/tyLoopGeneric.o
#--- Setup vxWorks in
round robin schedule
kernelTimeSlice(5)
#--- Spawn a task for
each port
sp tyLoop,"Hello
World! 1","/tyCo/octB0",0,1
sp tyLoop,"Hello
World! 2","/tyCo/octB1",1,1
sp tyLoop,"Hello
World! 3","/tyCo/octB2",2,1
sp tyLoop,"Hello
World! 4","/tyCo/octB3",3,1
sp tyLoop,"Hello
World! 5","/tyCo/octB4",4,1
sp tyLoop,"Hello
World! 6","/tyCo/octB5",5,1
sp tyLoop,"Hello
World! 7","/tyCo/octB6",6,1
sp tyLoop,"Hello World!
8","/tyCo/octB7",7,1
sp
tyLoop,"Goodbye World! 1","/tyCo/octC0",8,1
sp
tyLoop,"Goodbye World! 2","/tyCo/octC1",9,1
sp
tyLoop,"Goodbye World! 3","/tyCo/octC2",10,1
sp
tyLoop,"Goodbye World! 4","/tyCo/octC3",11,1
sp
tyLoop,"Goodbye World! 5","/tyCo/octC4",12,1
sp
tyLoop,"Goodbye World! 6","/tyCo/octC5",13,1
sp
tyLoop,"Goodbye World! 7","/tyCo/octC6",14,1
sp
tyLoop,"Goodbye World! 8","/tyCo/octC7",15,1
file: tyLoopGeneric.c
/* file:
tyLoopGeneric.c description:
Tests a serial port in
local loopback mode by transmitting a string of characters provided as a
argument and comparing the string received date: 6/6/94 author: jet
*/
#include
"vxWorks.h"
#include
"iv.h"
#include
"ioLib.h"
#include
"iosLib.h"
#include
"tyLib.h"
#include
"vme.h"
#include
"stdio.h"
#include
"string.h"
#include
"scc2698.h"
#define NUMBAUDS 13
int bauds[NUMBAUDS] =
{ 75,110,150,300,600,1200,1800,2000, 2400,4800,9600,19200,38400 };
void
tyLoop(char*,char*,int,int);
void tyLoop( char
*echoString, char *deviceName , int channel, int printOn)
{
int f;
int loopCounter;
int nbytes,rBytes;
char inString[256];
int n,modepair;
int baudIndex;
bfill( inString,
sizeof(inString), 0x00 );
baudIndex =
loopCounter = 0;
f =
open(deviceName,2,0644);
if( f == NULL )
{
printf("\nError
opening device... %s\n",deviceName);
printf("\n");
exit(-1);
}
/* setup port for
local loopback */
modepair = (
CHAN_MODE_LL | STOP_BITS_1 ) << 8;
modepair |= (
PAR_MODE_NO | BITS_CHAR_8 );
if( ioctl( f,
TYCO_2698B_MODE, modepair ) |= OK )
{
printf("\nERROR
setting mode registers\n");
exit(-1);
}
/* setup initial baud
rate */
if( ioctl( f,
FIOBAUDRATE, bauds[baudIndex] ) |= OK )
{
printf("\nERROR
setting baud rate\n");
exit(-1);
}
for(;;)
{
nbytes = write( f, echoString,
strlen(echoString) );
if( nbytes !=
strlen(echoString) )
{
printf("Error
writing, numbytes=%d\n",nbytes);
exit(-1);
}
nbytes = fioRead( f,
inString, strlen(echoString) );
if( nbytes <
strlen(echoString) )
{
printf("Error reading
inString, numbytes=%d\n",nbytes);
exit(-1);
}
else
{
if(
strncmp(&inString[0], echoString, strlen(echoString)) != 0 )
{
printf(",ERR%d,%s",channel,inString);
}
else
{
if( printOn
)printf(",%d",channel);
} }
loopCounter++;
bfill( inString,
sizeof(inString), 0x00 );
printf("\n->%d",loopCounter);
/* increment baud rate
*/
baudIndex++;
if( baudIndex >
NUMBAUDS ) baudIndex = 0;
printf("\nSetting
baud rate to -> %d", bauds[baudIndex] );
if( ioctl( f,
FIOBAUDRATE, bauds[baudIndex] ) |= OK )
{ printf("\nERROR
setting baud rate\n");
exit(-1);
} } }
file: tstTest.s
ld <
server_name:/serial/tyOctSerDrv.o
tyOctSerDrv
tyOctSerPack
256,200,3,4
tyOctSerPack
000,201,1,2
#
tyOctSerDevCreate
"/tyCo/octB0",0,8192,8192
tyOctSerDevCreate
"/tyCo/octB1",1,8192,8192
tyOctSerDevCreate
"/tyCo/octB2",2,8192,8192
tyOctSerDevCreate
"/tyCo/octB3",3,8192,8192
tyOctSerDevCreate
"/tyCo/octB4",4,8192,8192
tyOctSerDevCreate
"/tyCo/octB5",5,8192,8192
tyOctSerDevCreate
"/tyCo/octB6",6,8192,8192
tyOctSerDevCreate
"/tyCo/octB7",7,8192,8192
#
tyOctSerDevCreate
"/tyCo/octA0",8,8192,8192
tyOctSerDevCreate
"/tyCo/octA1",9,8192,8192
tyOctSerDevCreate
"/tyCo/octA2",10,8192,8192
tyOctSerDevCreate
"/tyCo/octA3",11,8192,8192
tyOctSerDevCreate
"/tyCo/octA4",12,8192,8192
tyOctSerDevCreate
"/tyCo/octA5",13,8192,8192
tyOctSerDevCreate
"/tyCo/octA6",14,8192,8192
tyOctSerDevCreate
"/tyCo/octA7",15,8192,8192
#
ld <
server_name:/serial/tyTestGeneric.o ld <
server_name:/serial/tyTestMonitor.o kernelTimeSlice(1)
# spawn the READER
task(s)
tyloop( devicename,
channelnum, baud, printflag, read/writeflag )
sp
tyLoop,"/tyCo/octA0",8,9600,0,1
sp
tyLoop,"/tyCo/octA1",9,9600,0,1
sp
tyLoop,"/tyCo/octA2",10,9600,0,1
sp
tyLoop,"/tyCo/octA3",11,9600,0,1
sp tyLoop,"/tyCo/octA4",12,9600,0,1
sp
tyLoop,"/tyCo/octA5",13,9600,0,1
sp
tyLoop,"/tyCo/octA6",14,9600,0,1
sp
tyLoop,"/tyCo/octA7",15,9600,0,1
# spawn the WRITER
task(s)
sp
tyLoop,"/tyCo/octB0",0,9600,0,0
sp
tyLoop,"/tyCo/octB1",1,9600,0,0
sp
tyLoop,"/tyCo/octB2",2,9600,0,0
sp
tyLoop,"/tyCo/octB3",3,9600,0,0
sp
tyLoop,"/tyCo/octB4",4,9600,0,0
sp
tyLoop,"/tyCo/octB5",5,9600,0,0
sp
tyLoop,"/tyCo/octB6",6,9600,0,0
sp
tyLoop,"/tyCo/octB7",7,9600,0,0
sp tyMonitor,1000
#
file: tyTestGeneric.c
/* file: tyTestGeneric.c
description: Tests
serial ports by being either a transmitter or receiver. This test routine
is for use when performing an external wrap test with a ribbon cable
wrapped from one 50-pin connector to another.
date: 6/9/94
author: jet
*/
#include
"vxWorks.h"
#include
"iv.h"
#include
"ioLib.h"
#include
"iosLib.h"
#include
"tyLib.h"
#include
"vme.h"
#include
"stdio.h"
#include
"string.h"
#include
"scc2698.h"
#include
"tyOctSer.h"
#define EXTERN
#include
"tyTest.h"
#define TESTBAUDS 11
#define NUMBAUDS 13
int bauds[NUMBAUDS] =
{ 75,110,150,300,600,1200,1800,2000, 2400,4800,9600,19200,38400 };
void
tyLoop(char*,int,int,int,int);
int multiRead( int,
unsigned char*, int, int);
void tyLoop( char
*deviceName , int channel, int baud, int printOn, int RWflag)
{
int f;
int loopCounter;
int nbytes,rBytes;
unsigned
charBuffer[256];
int n,modepair;
int baudIndex;
monitorType*Monitor;
if( RWflag == Reader )
{
bfill( (char*)Buffer,
sizeof(Buffer), 0x00 );
}
else
{
for(n=0;n<sizeof(Buffer);n++)
Buffer[n]=n;
/* bfill(
(char*)Buffer, sizeof(Buffer), 0x55 ); */
}
baudIndex = 8;
loopCounter = 0;
Monitor =
&monTable[ channel ];
Monitor->loopCount=
Monitor->baudRate=
Monitor->errorCount=
Monitor->readByteCounter=
Monitor->writeByteCounter=
Monitor->numRW=0;
if( RWflag == Reader )
{ Monitor->type =
READER; }
else {
Monitor->type = WRITER; }
f =
open(deviceName,2,0644);
if( f == NULL )
{
printf("\nError
opening device... %s\n",deviceName);
printf("\n");
exit(-1);
}
/* setup port for
local loopback */
modepair = (
CHAN_MODE_NORM | STOP_BITS_1 ) << 8;
modepair |= (
PAR_MODE_NO | BITS_CHAR_8 );
if( ioctl( f,
TYCO_2698B_MODE, modepair ) != OK )
{
printf("\nERROR
setting mode registers\n");
exit(-1);
}
/* setup initial baud
rate */
if( ioctl( f,
FIOBAUDRATE, baud ) != OK )
{
printf("\nERROR
setting baud rate\n");
exit(-1);
}
Monitor->baudRate =
baud;
for(;;)
{
if( RWflag == Writer )
{
/* disable receiver otherwise
each transmit causes a receive interrupt */
if( ioctl( f,
TYCO_COMMAND, RX_DISABLE ) != OK )
{
if( printOn) {
printf("\nERROR disabling Rx\n");}
Monitor->errorCount++;
}
if( ioctl( f,
TYCO_ASSERT_RTSN, NULL ) != OK )
{
if( printOn) { printf("\nERROR
Asserting RTS\n");}
Monitor->errorCount++;
}
nbytes = write( f,
(char*)Buffer, sizeof(Buffer) );
if( nbytes !=
sizeof(Buffer) )
{
if( printOn)
{printf("Error writing, numbytes=%d\n",nbytes);}
Monitor->errorCount++;
}
else{
Monitor->numRW++; }
Monitor->writeByteCounter
+= nbytes;
taskDelay(50);
}
else
{ /* READER */
if( ioctl( f,
TYCO_NEGATE_RTSN, NULL ) != OK )
{ if( printOn)
{printf("\nERROR Negating RTS\n");}
Monitor->errorCount++;
}
if( printOn )
{printf("\njetRead");}
nbytes = jetRead( f,
Buffer, sizeof(Buffer), printOn );
if( nbytes <
sizeof(Buffer) )
{ if( printOn)
{printf("Error
reading Buffer, numbytes=%d\n", nbytes);}
Monitor->errorCount++;
}
else
{
Monitor->numRW++;
/* check data */
for(n=0;n<sizeof(Buffer);n++)
{
if( Buffer[n] != n )
Monitor->errorCount++;
} }
Monitor->readByteCounter
+= nbytes;
bfill( (char*)Buffer,
sizeof(Buffer), 0x00 );
}/*end if RWflag*/
Monitor->loopCount
= ++loopCounter;
if( printOn )
printf("\n->%d",loopCounter);
}/*end for*/
}
int multiRead( int f,
unsigned char *Buffer, int length, int printOn )
{
int nbytes,totalBytes;
unsigned chargetmore;
char inPut[256],*I;
int
timesTried,timesAllowed;
getmore = TRUE;
totalBytes =
timesTried = 0;
timesAllowed = 10000;
I = inPut;
while( getmore )
{
nbytes =
read(f,I,length);
totalBytes += nbytes;
if( printOn
)printf("\nnBytes read->%d",nbytes);
if( totalBytes >=
length )
{
getmore = FALSE;
}
else
{
I += nbytes;
timesTried++;
if( timesTried >=
timesAllowed )
{
getmore = FALSE;
} } }
bcopy( inPut,
(char*)Buffer, length );
return( totalBytes );
}
1Sep96
|