VxWorks API Reference : OS Libraries
pipeDrv - pipe I/O driver
pipeDrv( ) - initialize the pipe driver
pipeDevCreate( ) - create a pipe device
pipeDevDelete( ) - delete a pipe device
The pipe driver provides a mechanism that lets tasks communicate with each other through the standard I/O interface. Pipes can be read and written with normal read( ) and write( ) calls. The pipe driver is initialized with pipeDrv( ). Pipe devices are created with pipeDevCreate( ).
The pipe driver uses the VxWorks message queue facility to do the actual buffering and delivering of messages. The pipe driver simply provides access to the message queue facility through the I/O system. The main differences between using pipes and using message queues directly are:
pipes are named (with I/O device names). pipes use the standard I/O functions -- open( ), close( ), read( ), write( ) -- while message queues use the functions msgQSend( ) and msgQReceive( ). pipes respond to standard ioctl( ) functions. pipes can be used in a select( ) call. message queues have more flexible options for timeouts and message priorities. pipes are less efficient than message queues because of the additional overhead of the I/O system.
Before using the driver, it must be initialized and installed by calling pipeDrv( ). This routine must be called before any pipes are created. It is called automatically by the root task, usrRoot( ), in usrConfig.c when the configuration macro INCLUDE_PIPES is defined.
Before a pipe can be used, it must be created with pipeDevCreate( ). For example, to create a device pipe "/pipe/demo" with up to 10 messages of size 100 bytes, the proper call is:
pipeDevCreate ("/pipe/demo", 10, 100);
Once a pipe has been created it can be opened, closed, read, and written just like any other I/O device. Often the data that is read and written to a pipe is a structure of some type. Thus, the following example writes to a pipe and reads back the same data:
{ int fd; struct msg outMsg; struct msg inMsg; int len; fd = open ("/pipe/demo", O_RDWR); write (fd, &outMsg, sizeof (struct msg)); len = read (fd, &inMsg, sizeof (struct msg)); close (fd); }The data written to a pipe is kept as a single message and will be read all at once in a single read. If read( ) is called with a buffer that is smaller than the message being read, the remainder of the message will be discarded. Thus, pipe I/O is "message oriented" rather than "stream oriented." In this respect, VxWorks pipes differ significantly from UNIX pipes which are stream oriented and do not preserve message boundaries.
Interrupt service routines (ISR) can write to pipes, providing one of several ways in which ISRs can communicate with tasks. For example, an interrupt service routine may handle the time-critical interrupt response and then send a message on a pipe to a task that will continue with the less critical aspects. However, the use of pipes to communicate from an ISR to a task is now discouraged in favor of the direct message queue facility, which offers lower overhead (see the manual entry for msgQLib for more information).
An important feature of pipes is their ability to be used in a select( ) call. The select( ) routine allows a task to wait for input from any of a selected set of I/O devices. A task can use select( ) to wait for input from any combination of pipes, sockets, or serial devices. See the manual entry for select( ).
Pipe devices respond to the following ioctl( ) functions. These functions are defined in the header file ioLib.h.
- FIOGETNAME
- Gets the file name of fd and copies it to the buffer referenced by nameBuf:
status = ioctl (fd, FIOGETNAME, &nameBuf);- FIONREAD
- Copies to nBytesUnread the number of bytes remaining in the first message in the pipe:
status = ioctl (fd, FIONREAD, &nBytesUnread);- FIONMSGS
- Copies to nMessages the number of discrete messages remaining in the pipe:
status = ioctl (fd, FIONMSGS, &nMessages);- FIOFLUSH
- Discards all messages in the pipe and releases the memory block that contained them:
status = ioctl (fd, FIOFLUSH, 0);
ioLib.h, pipeDrv.h
select( ), msgQLib, VxWorks Programmer's Guide: I/O System
pipeDrv( ) - initialize the pipe driver
STATUS pipeDrv (void)
This routine initializes and installs the driver. It must be called before any pipes are created. It is called automatically by the root task, usrRoot( ), in usrConfig.c when the configuration macro INCLUDE_PIPES is defined.
OK, or ERROR if the driver installation fails.
pipeDevCreate( ) - create a pipe device
STATUS pipeDevCreate ( char * name, /* name of pipe to be created */ int nMessages, /* max. number of messages in pipe */ int nBytes /* size of each message */ )
This routine creates a pipe device. It cannot be called from an interrupt service routine. It allocates memory for the necessary structures and initializes the device. The pipe device will have a maximum of nMessages messages of up to nBytes each in the pipe at once. When the pipe is full, a task attempting to write to the pipe will be suspended until a message has been read. Messages are lost if written to a full pipe at interrupt level.
OK, or ERROR if the call fails.
S_ioLib_NO_DRIVER - driver not initialized S_intLib_NOT_ISR_CALLABLE - cannot be called from an ISR
pipeDevDelete( ) - delete a pipe device
STATUS pipeDevDelete ( char * name, /* name of pipe to be deleted */ BOOL force /* if TRUE, force pipe deletion */ )
This routine deletes a pipe device of a given name. The name must match that passed to pipeDevCreate( ) else ERROR will be returned. This routine frees memory for the necessary structures and deletes the device. It cannot be called from an interrupt service routine.
A pipe device cannot be deleted until its number of open requests has been reduced to zero by an equal number of close requests and there are no tasks pending in its select list. If the optional force flag is asserted, the above restrictions are ignored, resulting in forced deletion of any select list and freeing of pipe resources.
Forced pipe deletion can have catastrophic results if used indescriminately. Use only as a last resort.
OK, or ERROR if the call fails.
S_ioLib_NO_DRIVER - driver not initialized S_intLib_NOT_ISR_CALLABLE - cannot be called from an ISR EMFILE - pipe still has other openings EBUSY - pipe is selected by at least one pending task