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

📄 tclwinserial.c

📁 最新版的BCC, bcc-src-1.0.29c.rar,基于sparc平台处理器leon2,leon3,v7,v8等系列的linux环境下交叉编译工具
💻 C
📖 第 1 页 / 共 5 页
字号:
 * *---------------------------------------------------------------------- */static DWORD WINAPISerialWriterThread(LPVOID arg){    SerialInfo *infoPtr = (SerialInfo *)arg;    HANDLE *handle = infoPtr->handle;    DWORD bytesWritten, toWrite;    char *buf;    OVERLAPPED myWrite; /* have an own OVERLAPPED in this thread */    for (;;) {        /*         * Wait for the main thread to signal before attempting to write.         */        WaitForSingleObject(infoPtr->evStartWriter, INFINITE);        buf = infoPtr->writeBuf;        toWrite = infoPtr->toWrite;        myWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);        /*         * Loop until all of the bytes are written or an error occurs.         */        while (toWrite > 0) {            /*            *  Check for pending writeError            *  Ignore all write operations until the user has been notified            */            if (infoPtr->writeError) {                break;            }            if (blockingWrite(infoPtr, (LPVOID) buf, (DWORD) toWrite,                     &bytesWritten, &myWrite) == FALSE) {                infoPtr->writeError = GetLastError();                break;            }            if (bytesWritten != toWrite) {                /* Write timeout */                infoPtr->writeError = ERROR_WRITE_FAULT;                break;            }            toWrite -= bytesWritten;            buf += bytesWritten;        }        CloseHandle(myWrite.hEvent);        /*         * Signal the main thread by signalling the evWritable event and         * then waking up the notifier thread.         */        SetEvent(infoPtr->evWritable);        /*         * Alert the foreground thread.  Note that we need to treat this like         * a critical section so the foreground thread does not terminate         * this thread while we are holding a mutex in the notifier code.         */        Tcl_MutexLock(&serialMutex);        Tcl_ThreadAlert(infoPtr->threadId);        Tcl_MutexUnlock(&serialMutex);    }    return 0;                   /* NOT REACHED */}/* *---------------------------------------------------------------------- * * TclWinSerialReopen -- * *  Reopens the serial port with the OVERLAPPED FLAG set * * Results: *  Returns the new handle, or INVALID_HANDLE_VALUE *  Normally there shouldn't be any error,  *  because the same channel has previously been succeesfully opened. * * Side effects: *  May close the original handle * *---------------------------------------------------------------------- */HANDLETclWinSerialReopen(handle, name, access)    HANDLE handle;    CONST TCHAR *name;    DWORD access;{    ThreadSpecificData *tsdPtr;    tsdPtr = SerialInit();    /*     * Multithreaded I/O needs the overlapped flag set    * otherwise ClearCommError blocks under Windows NT/2000 until serial    * output is finished    */    if (CloseHandle(handle) == FALSE) {        return INVALID_HANDLE_VALUE;    }    handle = (*tclWinProcs->createFileProc)(name, access,                 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);    return handle;}/* *---------------------------------------------------------------------- * * TclWinOpenSerialChannel -- * *  Constructs a Serial port channel for the specified standard OS handle. *      This is a helper function to break up the construction of *      channels into File, Console, or Serial. * * Results: *  Returns the new channel, or NULL. * * Side effects: *  May open the channel * *---------------------------------------------------------------------- */Tcl_ChannelTclWinOpenSerialChannel(handle, channelName, permissions)    HANDLE handle;    char *channelName;    int permissions;{    SerialInfo *infoPtr;    ThreadSpecificData *tsdPtr;    DWORD id;    tsdPtr = SerialInit();    infoPtr = (SerialInfo *) ckalloc((unsigned) sizeof(SerialInfo));    memset(infoPtr, 0, sizeof(SerialInfo));    infoPtr->validMask = permissions;    infoPtr->handle = handle;    /*     * Use the pointer to keep the channel names unique, in case     * the handles are shared between multiple channels (stdin/stdout).     */    wsprintfA(channelName, "file%lx", (int) infoPtr);    infoPtr->channel = Tcl_CreateChannel(&serialChannelType, channelName,            (ClientData) infoPtr, permissions);    infoPtr->readable = 0;     infoPtr->writable = 1;    infoPtr->toWrite = infoPtr->writeQueue = 0;    infoPtr->blockTime = SERIAL_DEFAULT_BLOCKTIME;    infoPtr->lastEventTime = 0;    infoPtr->lastError = infoPtr->error = 0;    infoPtr->threadId = Tcl_GetCurrentThread();    infoPtr->sysBufRead = infoPtr->sysBufWrite = 4096;    SetupComm(handle, infoPtr->sysBufRead, infoPtr->sysBufWrite);    PurgeComm(handle, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR             | PURGE_RXCLEAR);    /*     * default is blocking     */    SetCommTimeouts(handle, &no_timeout);    if (permissions & TCL_READABLE) {        infoPtr->osRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);    }    if (permissions & TCL_WRITABLE) {        /*         * Initially the channel is writable        * and the writeThread is idle.        */         infoPtr->osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);        infoPtr->evWritable = CreateEvent(NULL, TRUE, TRUE, NULL);        infoPtr->evStartWriter = CreateEvent(NULL, FALSE, FALSE, NULL);        InitializeCriticalSection(&infoPtr->csWrite);        infoPtr->writeThread = CreateThread(NULL, 8000, SerialWriterThread,            infoPtr, 0, &id);    }    /*     * Files have default translation of AUTO and ^Z eof char, which     * means that a ^Z will be accepted as EOF when reading.     */    Tcl_SetChannelOption(NULL, infoPtr->channel, "-translation", "auto");    Tcl_SetChannelOption(NULL, infoPtr->channel, "-eofchar", "\032 {}");    return infoPtr->channel;}/* *---------------------------------------------------------------------- * * SerialErrorStr -- * *  Converts a Win32 serial error code to a list of readable errors * *---------------------------------------------------------------------- */static voidSerialErrorStr(error, dsPtr)    DWORD error;           /* Win32 serial error code */    Tcl_DString *dsPtr;    /* Where to store string */{    if( (error & CE_RXOVER) != 0) {                Tcl_DStringAppendElement(dsPtr, "RXOVER");    }    if( (error & CE_OVERRUN) != 0) {                Tcl_DStringAppendElement(dsPtr, "OVERRUN");    }    if( (error & CE_RXPARITY) != 0) {                Tcl_DStringAppendElement(dsPtr, "RXPARITY");    }    if( (error & CE_FRAME) != 0) {                Tcl_DStringAppendElement(dsPtr, "FRAME");    }    if( (error & CE_BREAK) != 0) {                Tcl_DStringAppendElement(dsPtr, "BREAK");    }    if( (error & CE_TXFULL) != 0) {                Tcl_DStringAppendElement(dsPtr, "TXFULL");    }    if( (error & CE_PTO) != 0) {    /* PTO used to signal WRITE-TIMEOUT */                Tcl_DStringAppendElement(dsPtr, "TIMEOUT");    }    if( (error & ~(SERIAL_READ_ERRORS | SERIAL_WRITE_ERRORS)) != 0) {                char buf[TCL_INTEGER_SPACE + 1];                wsprintfA(buf, "%d", error);                Tcl_DStringAppendElement(dsPtr, buf);    }}/* *---------------------------------------------------------------------- * * SerialModemStatusStr -- * *  Converts a Win32 modem status list of readable flags * *---------------------------------------------------------------------- */static voidSerialModemStatusStr(status, dsPtr)    DWORD status;          /* Win32 modem status */    Tcl_DString *dsPtr;    /* Where to store string */{    Tcl_DStringAppendElement(dsPtr, "CTS");    Tcl_DStringAppendElement(dsPtr, (status & MS_CTS_ON)  ?  "1" : "0");    Tcl_DStringAppendElement(dsPtr, "DSR");    Tcl_DStringAppendElement(dsPtr, (status & MS_DSR_ON)   ? "1" : "0");    Tcl_DStringAppendElement(dsPtr, "RING");    Tcl_DStringAppendElement(dsPtr, (status & MS_RING_ON)  ? "1" : "0");    Tcl_DStringAppendElement(dsPtr, "DCD");    Tcl_DStringAppendElement(dsPtr, (status & MS_RLSD_ON)  ? "1" : "0");}/* *---------------------------------------------------------------------- * * SerialSetOptionProc -- * *  Sets an option on a channel. * * Results: *  A standard Tcl result. Also sets the interp's result on error if *  interp is not NULL. * * Side effects: *  May modify an option on a device. * *---------------------------------------------------------------------- */static intSerialSetOptionProc(instanceData, interp, optionName, value)    ClientData instanceData;    /* File state. */    Tcl_Interp *interp;         /* For error reporting - can be NULL. */    CONST char *optionName;     /* Which option to set? */    CONST char *value;          /* New value for option. */{    SerialInfo *infoPtr;    DCB dcb;    BOOL result, flag;    size_t len, vlen;    Tcl_DString ds;    CONST TCHAR *native;    int argc;    char **argv;        infoPtr = (SerialInfo *) instanceData;        /*     * Parse options    */    len = strlen(optionName);    vlen = strlen(value);    /*     * Option -mode baud,parity,databits,stopbits    */    if ((len > 2) && (strncmp(optionName, "-mode", len) == 0)) {                if (! GetCommState(infoPtr->handle, &dcb)) {            if (interp) {                Tcl_AppendResult(interp,                     "can't get comm state", (char *) NULL);            }            return TCL_ERROR;        }        native = Tcl_WinUtfToTChar(value, -1, &ds);        result = (*tclWinProcs->buildCommDCBProc)(native, &dcb);        Tcl_DStringFree(&ds);                if (result == FALSE) {            if (interp) {                Tcl_AppendResult(interp,                    "bad value for -mode: should be baud,parity,data,stop",                    (char *) NULL);            }            return TCL_ERROR;        }        /* Default settings for serial communications */         dcb.fBinary = TRUE;        dcb.fErrorChar = FALSE;        dcb.fNull = FALSE;        dcb.fAbortOnError = FALSE;        if (! SetCommState(infoPtr->handle, &dcb) ) {            if (interp) {                Tcl_AppendResult(interp,                     "can't set comm state", (char *) NULL);            }            return TCL_ERROR;        }        return TCL_OK;    }        /*     * Option -handshake none|xonxoff|rtscts|dtrdsr    */    if ((len > 1) && (strncmp(optionName, "-handshake", len) == 0)) {                if (! GetCommState(infoPtr->handle, &dcb)) {            if (interp) {                Tcl_AppendResult(interp,                     "can't get comm state", (char *) NULL);            }            return TCL_ERROR;        }        /*         * Reset all handshake options        * DTR and RTS are ON by default        */        dcb.fOutX = dcb.fInX = FALSE;        dcb.fOutxCtsFlow = dcb.fOutxDsrFlow = dcb.fDsrSensitivity = FALSE;        dcb.fDtrControl = DTR_CONTROL_ENABLE;        dcb.fRtsControl = RTS_CONTROL_ENABLE;        dcb.fTXContinueOnXoff = FALSE;        /*         * Adjust the handshake limits.        * Yes, the XonXoff limits seem to influence even hardware handshake        */        dcb.XonLim = (WORD) (infoPtr->sysBufRead*1/2);        dcb.XoffLim = (WORD) (infoPtr->sysBufRead*1/4);                if (strnicmp(value, "NONE", vlen) == 0) {            /* leave all handshake options disabled */        } else if (strnicmp(value, "XONXOFF", vlen) == 0) {            dcb.fOutX = dcb.fInX = TRUE;        } else if (strnicmp(value, "RTSCTS", vlen) == 0) {            dcb.fOutxCtsFlow = TRUE;            dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;        } else if (strnicmp(value, "DTRDSR", vlen) == 0) {            dcb.fOutxDsrFlow = TRUE;            dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;        } else {            if (interp) {                Tcl_AppendResult(interp, "bad value for -handshake: ",                    "must be one of xonxoff, rtscts, dtrdsr or none",                    (char *) NULL);                return TCL_ERROR;            }        }                if (! SetCommState(infoPtr->handle, &dcb)) {            if (interp) {                Tcl_AppendResult(interp,                     "can't set comm state", (char *) NULL);            }            return TCL_ERROR;        }        return TCL_OK;    }        /*     * Option -xchar {\x11 \x13}    */    if ((len > 1) && (strncmp(optionName, "-xchar", len) == 0)) {

⌨️ 快捷键说明

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