⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tylib.c

📁 VxWorks操作系统内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    {    tyFlushRd (pTyDev);    tyFlushWrt (pTyDev);    }/********************************************************************************* tyFlushRd - clear out a tty device descriptor's read buffer*/LOCAL void tyFlushRd    (    FAST TY_DEV_ID pTyDev       /* ptr to tty dev descriptor to clear */    )    {    int prevErrno;    /* get exclusive access to the device */    semTake (&pTyDev->mutexSem, WAIT_FOREVER);    /* mark as flushing so read interrupts won't attempt to manipulate ring */    pTyDev->rdState.flushingRdBuf = TRUE;    rngFlush (pTyDev->rdBuf);    prevErrno = errno;    semTake (&pTyDev->rdSyncSem, NO_WAIT);    if (errno == S_objLib_OBJ_UNAVAILABLE)  /* OK if semaphore not avail. */	errno = prevErrno;    pTyDev->lnNBytes	= 0;    pTyDev->lnBytesLeft	= 0;    tyRdXoff (pTyDev, FALSE);	/* output an XON if necessary */    pTyDev->rdState.flushingRdBuf = FALSE;    semGive (&pTyDev->mutexSem);    }/********************************************************************************* tyFlushWrt - clear out a tty device descriptor's write buffer*/LOCAL void tyFlushWrt    (    FAST TY_DEV_ID pTyDev       /* ptr to tty dev descriptor to clear */    )    {    /* get exclusive access to the device */    semTake (&pTyDev->mutexSem, WAIT_FOREVER);    /* mark as flushing so tx interrupts won't attempt to manipulate ring */    pTyDev->wrtState.flushingWrtBuf = TRUE;    rngFlush (pTyDev->wrtBuf);    semGive (&pTyDev->wrtSyncSem);    pTyDev->wrtState.flushingWrtBuf = FALSE;    semGive (&pTyDev->mutexSem);    if (_func_selWakeupAll != NULL)	/* wake up any writers in select */	(* _func_selWakeupAll) (&pTyDev->selWakeupList, SELWRITE);    }/********************************************************************************* tyAbortFuncSet - set the abort function** This routine sets the function that will be called when the abort* character is received on a tty.  There is only one global abort function,* used for any tty on which OPT_ABORT is enabled.  When the abort character is* received from a tty with OPT_ABORT set, the function specified in <func> will* be called, with no parameters, from interrupt level.** Setting an abort function of NULL will disable the abort function.** RETURNS: N/A** SEE ALSO: tyAbortSet()*/void tyAbortFuncSet    (    FUNCPTR func        /* routine to call when abort char received */    )    {    tyAbortFunc = func;    }/********************************************************************************* tyAbortSet - change the abort character** This routine sets the abort character to <ch>.* The default abort character is CTRL-C.** Typing the abort character to any device whose OPT_ABORT option is set* will cause the shell task to be killed and restarted.* Note that the character set by this routine applies to all devices* whose handlers use the standard tty package tyLib.** RETURNS: N/A** SEE ALSO: tyAbortFuncSet()*/void tyAbortSet    (    char ch             /* char to be abort */    )    {    tyAbortChar = ch;    }/********************************************************************************* tyBackspaceSet - change the backspace character** This routine sets the backspace character to <ch>.* The default backspace character is CTRL-H.** Typing the backspace character to any device operating in line protocol* mode (OPT_LINE set) will cause the previous character typed to be* deleted, up to the beginning of the current line.* Note that the character set by this routine applies to all devices* whose handlers use the standard tty package tyLib.*** RETURNS: N/A*/void tyBackspaceSet    (    char ch             /* char to be backspace */    )    {    tyBackspaceChar = ch;    }/********************************************************************************* tyDeleteLineSet - change the line-delete character** This routine sets the line-delete character to <ch>.* The default line-delete character is CTRL-U.** Typing the delete character to any device operating in line protocol* mode (OPT_LINE set) will cause all characters in the current* line to be deleted.* Note that the character set by this routine applies to all devices* whose handlers use the standard tty package tyLib.*** RETURNS: N/A*/void tyDeleteLineSet    (    char ch             /* char to be line-delete */    )    {    tyDeleteLineChar = ch;    }/********************************************************************************* tyEOFSet - change the end-of-file character** This routine sets the EOF character to <ch>.* The default EOF character is CTRL-D.** Typing the EOF character to any device operating in line protocol mode* (OPT_LINE set) will cause no character to be entered in the current* line, but will cause the current line to be terminated (thus without a newline* character).  The line is made available to reading tasks.  Thus, if the EOF* character is the first character input on a line, a line length of zero* characters is returned to the reader.   This is the standard end-of-file* indication on a read call.  Note that the EOF character set by this routine* will apply to all devices whose handlers use the standard tty package tyLib.*** RETURNS: N/A*/void tyEOFSet    (    char ch             /* char to be EOF */    )    {    tyEofChar = ch;    }/********************************************************************************* tyMonitorTrapSet - change the trap-to-monitor character** This routine sets the trap-to-monitor character to <ch>.* The default trap-to-monitor character is CTRL-X.** Typing the trap-to-monitor character to any device whose OPT_MON_TRAP option* is set will cause the resident ROM monitor to be entered, if one is present.* Once the ROM monitor is entered, the normal multitasking system is halted.** Note that the trap-to-monitor character set by this routine will apply to all* devices whose handlers use the standard tty package tyLib.  Also note that* not all systems have a monitor trap available.** RETURNS: N/A*/void tyMonitorTrapSet    (    char ch             /* char to be monitor trap */    )    {    tyMonTrapChar = ch;    }/********************************************************************************* tyIoctl - handle device control requests** This routine handles ioctl() requests for tty devices.  The I/O control* functions for tty devices are described in the manual entry for tyLib.** BUGS:* In line protocol mode (OPT_LINE option set), the FIONREAD function* actually returns the number of characters available plus the number of* lines in the buffer.  Thus, if five lines consisting of just NEWLINEs were* in the input buffer, the FIONREAD function would return the value ten* (five characters + five lines).** RETURNS: OK or ERROR.** VARARGS2 - not all requests include an arg.*/STATUS tyIoctl    (    FAST TY_DEV_ID pTyDev,      /* ptr to device to control */    int request,                /* request code             */    int arg                     /* some argument            */    )    {    FAST int status = OK;    int oldOptions;    switch (request)	{	case FIONREAD:	    *((int *) arg) = rngNBytes (pTyDev->rdBuf);	    break;	case FIONWRITE:	    *((int *) arg) = rngNBytes (pTyDev->wrtBuf);	    break;	case FIOFLUSH:	    tyFlush (pTyDev);	    break;	case FIOWFLUSH:	    tyFlushWrt (pTyDev);	    break;	case FIORFLUSH:	    tyFlushRd (pTyDev);	    break;	case FIOGETOPTIONS:	    return (pTyDev->options);	case FIOSETOPTIONS:		 	/* now same as FIOOPTIONS */	    oldOptions = pTyDev->options;	    pTyDev->options = arg;	    if ((oldOptions & OPT_LINE) != (pTyDev->options & OPT_LINE))		tyFlushRd (pTyDev);	    if ((oldOptions & OPT_TANDEM) && !(pTyDev->options & OPT_TANDEM))		{		/* TANDEM option turned off: XON receiver and transmitter */		tyRdXoff (pTyDev, FALSE);	/* output XON if necessary */		tyWrtXoff (pTyDev, FALSE);	/* restart xmitter if nec. */		}	    break;	case FIOCANCEL:	    semTake (&pTyDev->mutexSem, WAIT_FOREVER);	    pTyDev->rdState.canceled = TRUE;	    semGive (&pTyDev->rdSyncSem);	    pTyDev->wrtState.canceled = TRUE;	    semGive (&pTyDev->wrtSyncSem);	    semGive (&pTyDev->mutexSem);	    break;	case FIOISATTY:	    status = TRUE;	    break;	case FIOPROTOHOOK:	    pTyDev->protoHook = (FUNCPTR) arg;	    break;	case FIOPROTOARG:	    pTyDev->protoArg = arg;	    break;	case FIORBUFSET:	    semTake (&pTyDev->mutexSem, WAIT_FOREVER);	    pTyDev->rdState.flushingRdBuf = TRUE;	    if (pTyDev->rdBuf)		rngDelete (pTyDev->rdBuf);	    if ((pTyDev->rdBuf = rngCreate (arg)) == NULL)		status = ERROR;	    pTyDev->rdState.flushingRdBuf = FALSE;	    semGive (&pTyDev->mutexSem);	    break;	case FIOWBUFSET:	    semTake (&pTyDev->mutexSem, WAIT_FOREVER);	    pTyDev->wrtState.flushingWrtBuf = TRUE;	    if (pTyDev->wrtBuf)		rngDelete (pTyDev->wrtBuf);	    if ((pTyDev->wrtBuf = rngCreate (arg)) == NULL)		status = ERROR;	    pTyDev->wrtState.flushingWrtBuf = FALSE;	    semGive (&pTyDev->mutexSem);	    break;	case FIOSELECT:	    if (_func_selTyAdd != NULL)	        (* _func_selTyAdd) (pTyDev, arg);	    break;	case FIOUNSELECT:	    if (_func_selTyDelete != NULL)	        (* _func_selTyDelete) (pTyDev, arg);	    break;	default:	    errnoSet (S_ioLib_UNKNOWN_REQUEST);	    status = ERROR;	}    return (status);    }/* raw mode I/O routines *//********************************************************************************* tyWrite - do a task-level write for a tty device** This routine handles the task-level portion of the tty handler's* write function.** INTERNAL* This routine is not the only place characters are put into* the buffer: the read echo in tyIRd may put chars in output* ring as well.  tyIRd is of course not blocked by the mutexSem,* and we don't want to lock out interrupts for the entire time* we are copying data to ring.  So we we set wrtBufBusy while we* are putting into the ring buffer, and tyIRd drops echo chars* while this flag is set.  The problem with this is that some* input chars may not get echoed.  This shouldn't be a problem* for interactive stuff, since it only occurs when there is* output going on.  But for a serial protocol that relied on* echo, like echoplex, it could be a problem.** RETURNS: The number of bytes actually written to the device.*/int tyWrite    (    FAST TY_DEV_ID pTyDev,      /* ptr to device structure */    char *buffer,               /* buffer of data to write  */    FAST int nbytes             /* number of bytes in buffer */    )    {    FAST int	bytesput;    int		nbStart = nbytes;    pTyDev->wrtState.canceled = FALSE;    while (nbytes > 0)        {	/* XXX	 * mutexSem is "safe" from task deletion, but sync semaphore can't be;	 * if task is deleted after getting syncSem but before getting mutexSem,	 * tty channel will be hung.	 */        semTake (&pTyDev->wrtSyncSem, WAIT_FOREVER);	semTake (&pTyDev->mutexSem, WAIT_FOREVER);        if (pTyDev->wrtState.canceled)            {	    semGive (&pTyDev->mutexSem);            errnoSet (S_ioLib_CANCELLED);            return (nbStart - nbytes);            }	/* set wrtBufBusy while are putting data into the ring buffer to	 * inhibit tyIRd echoing chars - see description of problem above	 */	pTyDev->wrtState.wrtBufBusy = TRUE;        bytesput = rngBufPut (pTyDev->wrtBuf, buffer, nbytes);	pTyDev->wrtState.wrtBufBusy = FALSE;	tyTxStartup (pTyDev);		/* if xmitter not busy, start it */        nbytes -= bytesput;        buffer += bytesput;        /* If more room in ringId, enable next writer. */	if (rngFreeBytes (pTyDev->wrtBuf) > 0)	    semGive (&pTyDev->wrtSyncSem);	semGive (&pTyDev->mutexSem);	}    return (nbStart);    }/********************************************************************************* tyRead - do a task-level read for a tty device** This routine handles the task-level portion of the tty handler's read* function.  It reads into the buffer up to <maxbytes> available bytes.** This routine should only be called from serial device drivers.** RETURNS: The number of bytes actually read into the buffer.*/int tyRead    (    FAST TY_DEV_ID pTyDev,      /* device to read         */    char *buffer,               /* buffer to read into    */    int maxbytes                /* maximum length of read */    )    {    FAST int	nbytes;    FAST RING_ID ringId;    FAST int	nn;    int		freeBytes;    pTyDev->rdState.canceled = FALSE;    FOREVER	{	/* XXX	 * mutexSem is "safe" from task deletion, but sync semaphore can't be;	 * if task is deleted after getting syncSem but before getting mutexSem,	 * tty channel will be hung.	 */	semTake (&pTyDev->rdSyncSem, WAIT_FOREVER);	semTake (&pTyDev->mutexSem, WAIT_FOREVER);	if (pTyDev->rdState.canceled)	    {	    semGive (&pTyDev->mutexSem);	    errnoSet (S_ioLib_CANCELLED);	    return (0);	    }	ringId = pTyDev->rdBuf;	if (!rngIsEmpty (ringId))	    break;	semGive (&pTyDev->mutexSem);	}    /* we exit the above loop with the mutex semaphore taken and certain     * that the ring buffer is not empty */    /* get characters from ring buffer */    if (pTyDev->options & OPT_LINE)	{	if (pTyDev->lnBytesLeft == 0)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -