?? tylib.c
字號:
/* tyLib.c - tty driver support library *//* Copyright 1984 - 2001 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------03j,07feb01,spm merged from version 03i of tor2_0_x branch (base version 03h): added removal of pty device (SPR #28675)03i,30jun99,cno telnet to output return-newline instead of newline-return (SPR27682)03h,14jul97,dgp doc: correct bold, S_ioLib_UNKNOWN_REQUEST, & "^" to "CTRL-"03g,20jun96,jmb harmless errno from tyFlushRd getting back to users (SPR #6698)03f,09dec94,rhp fixed doc for FIOCANCEL (SPR #3828) fixed library descriptions of tyIRd() and tyITx() (SPR #2484)03e,19jul94,dvs fixed doc for FIORBUFSET and FIOWBUFSET (SPR #2444).03d,21jan93,jdi documentation cleanup for 5.1.03c,24oct92,jcf added peculiar 3xx hack to make serial driver work.03b,23aug92,jcf removed select stuff so tyLib will standalone. made excJobAdd call indirect.03a,18jul92,smb Changed errno.h to errnoLib.h.03z,04jul92,jcf scalable/ANSI/cleanup effort.03y,26may92,rrr the tree shuffle03x,04oct91,rrr passed through the ansification filter -changed functions to ansi style -changed VOID to void -changed copyright notice03w,01aug91,yao fixed to pass 6 args to excJobAdd() call.03v,03apr91,jaa documentation cleanup; doc review by dnw.03u,10aug90,kdl added forward declarations for functions returning void.03t,15jul90,dnw lint: removed unused variable in tyIoctl03s,05jul90,dnw fixed potential races in read and write. isolated all interrupt lockouts in 3 new routines: tyRdXoff/tyWrtXOff/tyTxStartup optimized code. rewrote library documentation.03r,26jun90,dab removed tyDevDelete().03q,26jun90,jcf changed binary semaphore interface.03p,02apr90,rdc changed to use binary semaphores. hjb beefed up ioctl documentation.03o,29mar90,rdc reworked to lower interrupt latency. took out "semNeeded" mechanism, created seperate mutual exclusion and synchronization semaphores. Interrupt level now checks to make sure task level isn't flushing or replacing ring buffers.03n,19mar90,dab added tyDevDelete().03m,16mar90,rdc added select support.03l,27jul89,hjb added FIOPROTOHOOK, FIOPROTOARG, FIOWFLUSH, FIORFLUSH, FIORBUFSET, FIOWBUFSET support for SLIP.03k,14oct88,gae fixed bug in FIOCANCEL; couldn't cancel twice in a row.03j,07sep88,gae documentation.03i,01sep88,gae documentation; changed RNG_MACRO parameters to int's.03h,30may88,dnw changed to v4 names.03g,28may88,dnw removed NOT_GENERIC stuff.03f,04may88,jcf changed semInits to semClear.03e,29mar88,gae added FIOISATTY to tyIoctl repertoire.03d,26feb88,jcf changed reboot to excToDoAdd (reboot ..) so reboot routines can print stuff out.03c,22feb88,dnw fix coding conventions to keep f2cgen happy.03b,23nov87,ecs added VARARGS2 to tyIoctl to keep lint happy.03a,23oct87,ecs fixed mangen problems in tlRdRaw/tyRead & tyIRdRaw/tyIRd. documentation. jcf changed call sysToMonitor into reboot02z,03oct87,gae added FIO[GS}ETOPTIONS.02y,24jul87,gae made ty{Backspace,DeleteLine,Eof}Char's global for shellLib.c.02x,25jun87,ecs changed tyIRdRaw to return ERROR on full ring buffer.02w,05jun87,ecs added FIOCANCEL to tyIoctl.02v,13may87,dnw fixed checksum bug caused by new "correct" compiler. +gae02u,23mar87,jlf documentation.02t,23feb87,jlf improved documentation of tyAbortFunc....deleted pre 87 history - see RCS*//*This library provides routines used to implement drivers for serialdevices. It provides all the necessary device-independent functions of anormal serial channel, including:.PD .1.iP "" 4ring buffering of input and output.iPraw mode.iPoptional line mode with backspace and line-delete functions.iPoptional processing of X-on/X-off.iPoptional RETURN/LINEFEED conversion.iPoptional echoing of input characters.iPoptional stripping of the parity bit from 8-bit input.iPoptional special characters for shell abort and system restart.PD.LPMost of the routines in this library are called only by device drivers.Functions that normally might be called by an application orinteractive user are the routines to set special characters, ty...Set().USE IN SERIAL DEVICE DRIVERSEach device that uses tyLib is described by a data structure of type TY_DEV.This structure begins with an I/O system device header so that it can be addeddirectly to the I/O system's device list. A driver calls tyDevInit() toinitialize a TY_DEV structure for a specific device and then calls iosDevAdd()to add the device to the I/O system.The call to tyDevInit() takes three parameters: the pointer to the TY_DEVstructure to initialize, the desired size of the read and write ring buffers,and the address of a transmitter start-up routine. This routine will becalled when characters are added for output and the transmitter is idle. Thereafter, the driver can call the following routines to perform theusual device functions:.iP "tyRead()" 12user read request to get characters that have been input.iP "tyWrite()"user write request to put characters to be output.iP "tyIoctl()"user I/O control request.iP "tyIRd()"interrupt-level routine to get an input character.iP "tyITx()"interrupt-level routine to deliver the next output character.LPThus, tyRead(), tyWrite(), and tyIoctl() are called from the driver's read,write, and I/O control functions. The routines tyIRd() and tyITx() are calledfrom the driver's interrupt handler in response to receive and transmitinterrupts, respectively.Examples of using tyLib in a driver can be found in the source file(s) included by tyCoDrv. Source files are located in src/drv/serial.TTY OPTIONSA full range of options affects the behavior of tty devices. Theseoptions are selected by setting bits in the device option word using theFIOSETOPTIONS function in the ioctl() routine (see "I/O Control Functions"below for more information). The following is a list of availableoptions. The options are defined in the header file ioLib.h..iP `OPT_LINE' 20 3Selects line mode. A tty device operates in one of two modes: raw mode(unbuffered) or line mode. Raw mode is the default. In raw mode, each byteof input from the device is immediately available to readers, and the input isnot modified except as directed by other options below. In line mode, inputfrom the device is not available to readers until a NEWLINE character isreceived, and the input may be modified by backspace, line-delete, andend-of-file special characters..iP `OPT_ECHO'Causes all input characters to be echoed to the output of the same channel.This is done simply by putting incoming characters in the output ring as wellas the input ring. If the output ring is full, the echoing is lost withoutaffecting the input..iP `OPT_CRMOD'C language conventions use the NEWLINE character as the line terminatoron both input and output. Most terminals, however, supply a RETURN characterwhen the return key is hit, and require both a RETURN and a LINEFEED characterto advance the output line. This option enables the appropriate translation:NEWLINEs are substituted for input RETURN characters, and NEWLINEs in theoutput file are automatically turned into a RETURN-LINEFEED sequence..iP `OPT_TANDEM'Causes the driver to generate and respond to the special flow controlcharacters CTRL-Q and CTRL-S in what is commonly known as X-on/X-off protocol. Receiptof a CTRL-S input character will suspend output to that channel. Subsequent receiptof a CTRL-Q will resume the output. Also, when the VxWorks input buffer is almostfull, a CTRL-S will be output to signal the other side to suspend transmission.When the input buffer is almost empty, a CTRL-Q will be output to signal the otherside to resume transmission..iP `OPT_7_BIT'Strips the most significant bit from all bytes input from the device..iP `OPT_MON_TRAP'Enables the special monitor trap character, by default CTRL-X. When this characteris received and this option is enabled, VxWorks will trap to the ROM residentmonitor program. Note that this is quite drastic. All normal VxWorksfunctioning is suspended, and the computer system is entirely controlled by themonitor. Depending on the particular monitor, it may or may not be possible torestart VxWorks from the point of interruption. The default monitor trapcharacter can be changed by calling tyMonitorTrapSet()..iP `OPT_ABORT'Enables the special shell abort character, by default CTRL-C. When this characteris received and this option is enabled, the VxWorks shell is restarted. This isuseful for freeing a shell stuck in an unfriendly routine, such as one caught inan infinite loop or one that has taken an unavailable semaphore. For moreinformation, see the.I "VxWorks Programmer's Guide: Shell.".iP `OPT_TERMINAL'This is not a separate option bit. It is the value of the option wordwith all the above bits set..iP `OPT_RAW'This is not a separate option bit. It is the value of the option word withnone of the above bits set.I/O CONTROL FUNCTIONSThe tty devices respond to the following ioctl() functions. The functionsare defined in the header ioLib.h..iP `FIOGETNAME' 20 3Gets the file name of the file descriptor and copies it to the buffer referenced to by <nameBuf>:.CS status = ioctl (fd, FIOGETNAME, &nameBuf);.CEThis function is common to all file descriptors for all devices..LP.iP "`FIOSETOPTIONS', `FIOOPTIONS'" 20Sets the device option word to the specified argument. For example, the call:.CS status = ioctl (fd, FIOOPTIONS, OPT_TERMINAL); status = ioctl (fd, FIOSETOPTIONS, OPT_TERMINAL);.CEenables all the tty options described above, putting the device in a "normal"terminal mode. If the line protocol (OPT_LINE) is changed, the inputbuffer is flushed. The various options are described in ioLib.h..iP `FIOGETOPTIONS'Returns the current device option word:.CS options = ioctl (fd, FIOGETOPTIONS, 0);.CE.iP `FIONREAD'Copies to <nBytesUnread> the number of bytes available to be read in thedevice's input buffer:.CS status = ioctl (fd, FIONREAD, &nBytesUnread);.CEIn line mode (OPT_LINE set), the FIONREAD function actually returns the numberof characters available plus the number of lines in the buffer. Thus, if fivelines of just NEWLINEs were in the input buffer, it would return the value 10(5 characters + 5 lines)..iP `FIONWRITE'Copies to <nBytes> the number of bytes queued to be output in the device'soutput buffer:.CS status = ioctl (fd, FIONWRITE, &nBytes);.CE.iP `FIOFLUSH'Discards all the bytes currently in both the input and the output buffers:.CS status = ioctl (fd, FIOFLUSH, 0);.CE.iP `FIOWFLUSH'Discards all the bytes currently in the output buffer:.CS status = ioctl (fd, FIOWFLUSH, 0);.CE.iP `FIORFLUSH'Discards all the bytes currently in the input buffers:.CS status = ioctl (fd, FIORFLUSH, 0);.CE.iP `FIOCANCEL'Cancels a read or write. A task blocked on a read or write may bereleased by a second task using this ioctl() call. For example, atask doing a read can set a watchdog timer before attempting the read;the auxiliary task would wait on a semaphore. The watchdog routinecan give the semaphore to the auxiliary task, which would then use thefollowing call on the appropriate file descriptor:.CS status = ioctl (fd, FIOCANCEL, 0);.CE.iP `FIOBAUDRATE'Sets the baud rate of the device to the specified argument. For example, thecall:.CS status = ioctl (fd, FIOBAUDRATE, 9600);.CESets the device to operate at 9600 baud. This request has no meaning on apseudo terminal..iP `FIOISATTY'Returns TRUE for a tty device:.CS status = ioctl (fd, FIOISATTY, 0);.CE.iP `FIOPROTOHOOK'Adds a protocol hook function to be called for each input character.<pfunction> is a pointer to the protocol hook routine which takes twoarguments of type <int> and returns values of type STATUS (TRUE orFALSE). The first argument passed is set by the user via the FIOPROTOARGfunction. The second argument is the input character. If no furtherprocessing of the character is required by the calling routine (the inputroutine of the driver), the protocol hook routine <pFunction> shouldreturn TRUE. Otherwise, it should return FALSE:.CS status = ioctl (fd, FIOPROTOHOOK, pFunction);.CE.iP `FIOPROTOARG'Sets the first argument to be passed to the protocol hook routine set byFIOPROTOHOOK function:.CS status = ioctl (fd, FIOPROTOARG, arg);.CE.iP `FIORBUFSET'Changes the size of the receive-side buffer to <size>:.CS status = ioctl (fd, FIORBUFSET, size);.CE.iP `FIOWBUFSET'Changes the size of the send-side buffer to <size>:.CS status = ioctl (fd, FIOWBUFSET, size);.CE.LPAny other ioctl() request will return an error and set the status toS_ioLib_UNKNOWN_REQUEST.INCLUDE FILES: tyLib.h, ioLib.hSEE ALSO: ioLib, iosLib, tyCoDrv,.pG "I/O System"*//* LINTLIBRARY */#include "vxWorks.h"#include "ioLib.h"#include "memLib.h"#include "rngLib.h"#include "wdLib.h"#include "sysLib.h"#include "excLib.h"#include "intLib.h"#include "string.h"#include "errnoLib.h"#include "rebootLib.h"#include "selectLib.h"#include "tyLib.h"#include "private/funcBindP.h"/* special characters */#define XON 0x11 /* ctrl-Q XON handshake */#define XOFF 0x13 /* ctrl-S XOFF handshake *//* global variables */char tyBackspaceChar = 0x08; /* default is control-H */char tyDeleteLineChar = 0x15; /* default is control-U */char tyEofChar = 0x04; /* default is control-D */int mutexOptionsTyLib = SEM_Q_FIFO | SEM_DELETE_SAFE;/* local variables */LOCAL char tyAbortChar = 0x03; /* default is control-C */LOCAL char tyMonTrapChar = 0x18; /* default is control-X */LOCAL int tyXoffThreshold = 80; /* max bytes free in input buffer * before XOFF will be sent in * OPT_TANDEM mode */LOCAL int tyXonThreshold = 100; /* min bytes free in input buffer * before XON will be sent in * OPT_TANDEM mode */LOCAL int tyWrtThreshold = 20; /* min bytes free in output buffer * before the next writer will * be enabled */LOCAL FUNCPTR tyAbortFunc = NULL; /* function to call when abort char * received *//* we keep track of the maximum number of chars received after we sent * out xoff. This was used to debug a lazy unix system that * sent as many as 60 characters after we had sent xoff. * we'll leave the code in just for grins. */LOCAL int tyXoffChars = 0; /** TEMP **/LOCAL int tyXoffMax = 0; /** TEMP **//* forward static functions */static void tyFlush (TY_DEV_ID pTyDev);static void tyFlushRd (TY_DEV_ID pTyDev);static void tyFlushWrt (TY_DEV_ID pTyDev);static void tyRdXoff (TY_DEV_ID pTyDev, BOOL xoff);static void tyWrtXoff (TY_DEV_ID pTyDev, BOOL xoff);static void tyTxStartup (TY_DEV_ID pTyDev);/********************************************************************************* tyDevInit - initialize the tty device descriptor** This routine initializes a tty device descriptor according to the* specified parameters. The initialization includes allocating read and* write buffers of the specified sizes from the memory pool,* and initializing their respective buffer descriptors.* The semaphores are initialized and the write semaphore is given* to enable writers. Also, the transmitter start-up routine pointer is set* to the specified routine. All other fields in the descriptor are zeroed.** This routine should be called only by serial drivers.** RETURNS* OK, or* ERROR if there is not enough memory to allocate data structures.*/STATUS tyDevInit ( FAST TY_DEV_ID pTyDev, /* ptr to tty dev descriptor to init */ int rdBufSize, /* size of read buffer in bytes */ int wrtBufSize, /* size of write buffer in bytes */ FUNCPTR txStartup /* device transmit start-up routine */ ) { /* clear out device */ bzero ((char *) pTyDev, sizeof (TY_DEV)); /* allocate read and write ring buffers */ if ((pTyDev->wrtBuf = rngCreate (wrtBufSize)) == NULL) return (ERROR); if ((pTyDev->rdBuf = rngCreate (rdBufSize)) == NULL) return (ERROR); /* initialize rest of device descriptor */ pTyDev->txStartup = txStartup; /* initialize semaphores */ semBInit (&pTyDev->rdSyncSem, SEM_Q_PRIORITY, SEM_EMPTY); semBInit (&pTyDev->wrtSyncSem, SEM_Q_PRIORITY, SEM_EMPTY); semMInit (&pTyDev->mutexSem, mutexOptionsTyLib); /* initialize the select stuff */ if (_func_selWakeupListInit != NULL) (* _func_selWakeupListInit) (&pTyDev->selWakeupList); tyFlush (pTyDev); return (OK); }/********************************************************************************* tyDevRemove - remove the tty device descriptor** This routine removes an existing tty device descriptor. It releases the* read and write buffers and the descriptor data structure.** RETURNS* OK, or ERROR if expected data structures are not found*/STATUS tyDevRemove ( TY_DEV_ID pTyDev /* ptr to tty dev descriptor to remove */ ) { /* clear out device */ if (pTyDev->rdBuf == NULL) return (ERROR); if (pTyDev->wrtBuf == NULL) return (ERROR); /* remove read and write ring buffers */ semTake (&pTyDev->mutexSem, WAIT_FOREVER); pTyDev->rdState.flushingRdBuf = TRUE; pTyDev->wrtState.flushingWrtBuf = TRUE; if (pTyDev->rdBuf) rngDelete (pTyDev->rdBuf); if (pTyDev->wrtBuf) rngDelete (pTyDev->wrtBuf); semGive (&pTyDev->mutexSem); return (OK); }/********************************************************************************* tyFlush - clear out a tty device descriptor's buffers** This routine resets a tty device's buffers to be empty and in the* "initial" state. Thus any characters input but not read by a task,* and those written by a task but not yet output, are lost.** RETURNS: N/A*/LOCAL void tyFlush ( FAST TY_DEV_ID pTyDev /* ptr to tty dev descriptor to clear */ )
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -