?? serial.c
字號:
ret = cfsetospeed(&termios, B115200); break;#if defined(B230400) case 230400: ret = cfsetospeed(&termios, B230400); break;#endif#if defined(B460800) case 460800: ret = cfsetospeed(&termios, B460800); break;#endif#if defined(B921600) case 921600: ret = cfsetospeed(&termios, B921600); break;#endif } if (ret < 0) { close(ports[port].fd); ports[port].fd = -1; return -1; } do { ret = tcsetattr(ports[port].fd, TCSANOW, &termios); } while (ret < 0 && errno == EINTR); if (ret < 0) { close(ports[port].fd); ports[port].fd = -1; return -1; }#endif ports[port].serial_in_ptr = ports[port].serial_in_buf; ports[port].serial_in_count = 0; return port;}/* Close serial connection */void serial_close(int port){ assert(port >= 0 && port < MAX_PORTS);#if defined(WIN32) if (ports[port].handle != INVALID_HANDLE_VALUE) { CloseHandle(ports[port].handle); ports[port].handle = INVALID_HANDLE_VALUE; }#else if (ports[port].fd >= 0) { close(ports[port].fd); ports[port].fd = -1; }#endif}/* Receive character, timeout is in in milliseconds, -1 means wait forever. Returns error code if timeout or error, and charcter code othervise */int serial_getchar(int port, int timeout){ assert(port >= 0 && port < MAX_PORTS); assert(timeout == -1 || timeout >= 0); if (ports[port].serial_in_count > 0) { ports[port].serial_in_count--; return (*ports[port].serial_in_ptr++ & 0xff); /* 8-bit transparent */ } ports[port].serial_in_count = serial_read(port, ports[port].serial_in_buf, sizeof(ports[0].serial_in_buf), timeout); if (ports[port].serial_in_count < 0) { /* Error */ return RP_VAL_SERIALGETCHARRET_ERR; } if (ports[port].serial_in_count == 0) { /* Timeout */ return RP_VAL_SERIALGETCHARRET_TMOUT; } ports[port].serial_in_ptr = ports[port].serial_in_buf; ports[port].serial_in_count--; return (*ports[port].serial_in_ptr++ & 0xff);}/* Receive character, timeout is in in milliseconds, -1 means wait forever. Returns error code if timeout or error, and charcter code othervise */int serial_read(int port, char *buf, size_t len, int timeout){#if defined(WIN32) int ret; COMMTIMEOUTS ctm; DWORD dtmp; BOOL res; assert(port >= 0 && port < MAX_PORTS); assert(ports[port].handle != INVALID_HANDLE_VALUE); assert(timeout == -1 || timeout >= 0); if (!(res = GetCommTimeouts(ports[port].handle, &ctm))) { assert(0); return -1; } assert(ctm.ReadIntervalTimeout == 20); assert(ctm.ReadTotalTimeoutMultiplier == 0); assert(ctm.WriteTotalTimeoutConstant == 0); assert(ctm.WriteTotalTimeoutMultiplier == 0); ctm.ReadTotalTimeoutConstant = timeout; if (!(res = SetCommTimeouts(ports[port].handle, &ctm))) { assert(0); return -1; } if (!(res = ReadFile(ports[port].handle, buf, len, &dtmp, NULL))) return -1; ret = dtmp;#else int ret; assert(port >= 0 && port < MAX_PORTS); assert(ports[port].fd >= 0); assert(timeout == -1 || timeout >= 0); if (timeout != -1) { struct timeval tv; struct timeval end; struct timeval cur; struct timezone tz; fd_set rset; /* It is quite possible that targets would install some signal handlers, so we have to ignore EINTR in all cases */ /* Let us calculate the timeout */ tv.tv_sec = timeout/1000; tv.tv_usec = (timeout%1000)*1000; /* Let us get current time */ if ((ret = gettimeofday(&cur, &tz)) < 0) return -1; /* Let us figure out end time */ end.tv_sec = cur.tv_sec + tv.tv_sec; end.tv_usec = cur.tv_usec + tv.tv_usec; if (end.tv_usec >= 1000000) { end.tv_sec++; end.tv_usec -= 1000000; } assert(end.tv_usec < 1000000); for (;;) { FD_ZERO(&rset); FD_SET(ports[port].fd, &rset); if ((ret = select(ports[port].fd + 1, &rset, NULL, NULL, &tv)) > 0) { assert(FD_ISSET(ports[port].fd, &rset)); break; } if (ret == 0) { /* Timeout */ return 0; } if (ret < 0 && errno != EINTR) return -1; /* We have been interrupted by a signal */ /* We have to recalculate the timeout */ if ((ret = gettimeofday(&cur, &tz)) < 0) return -1; if (cur.tv_sec > end.tv_sec || (cur.tv_sec == end.tv_sec && cur.tv_usec >= end.tv_usec)) { tv.tv_sec = 0; tv.tv_usec = 0; continue; } tv.tv_sec = end.tv_sec - cur.tv_sec; if (cur.tv_usec <= end.tv_usec) { tv.tv_usec = end.tv_usec - cur.tv_usec; } else { assert(tv.tv_sec > 0); tv.tv_sec--; tv.tv_usec = end.tv_usec + 1000000 - cur.tv_usec; } } } else { /* Forever */ for (;;) { fd_set rset; FD_ZERO(&rset); FD_SET(ports[port].fd, &rset); if ((ret = select(ports[port].fd + 1, &rset, NULL, NULL, NULL)) > 0) { assert(FD_ISSET(ports[port].fd, &rset)); break; } if (ret < 0 && errno != EINTR) return -1; assert(ret != 0); assert(errno == EINTR); } } /* We have to ignore EINTR here too */ do { ret = read(ports[port].fd, buf, len); } while (ret < 0 && errno == EINTR);#endif return ret;}/* Send character */void serial_putchar(int port, int c){ char b[4];#if defined(WIN32) DWORD dtmp; assert(port >= 0 && port < MAX_PORTS); assert(ports[port].handle != INVALID_HANDLE_VALUE); b[0] = c & 0xff; WriteFile(ports[port].handle, b, 1, &dtmp, NULL);#else int ret; assert(port >= 0 && port < MAX_PORTS); assert(ports[port].fd >= 0); b[0] = c & 0xff; ret = 0; do { ret = write(ports[port].fd, b, 1); } while (ret < 0 && errno == EINTR);#endif}/* Send buffer */int serial_write(int port, char *buf, size_t len){#if defined(WIN32) BOOL res; DWORD dtmp; assert(port >= 0 && port < MAX_PORTS); assert(ports[port].handle != INVALID_HANDLE_VALUE); assert(buf != NULL); assert(len > 0); res = WriteFile(ports[port].handle, buf, len, &dtmp, NULL); if (!res || dtmp != len) return FALSE;#else int ret; assert(port >= 0 && port < MAX_PORTS); assert(ports[port].fd >= 0); assert(buf != NULL); assert(len > 0); ret = 0; do { ret = write(ports[port].fd, buf, len); } while (ret < 0 && errno == EINTR); if (ret != (int) len) return FALSE;#endif return TRUE;}/* Discard input */void serial_flushinput(int port){ assert(port >= 0 && port < MAX_PORTS);#if defined(WIN32) assert(ports[port].handle != INVALID_HANDLE_VALUE); PurgeComm(ports[port].handle, PURGE_RXCLEAR);#else assert(ports[port].fd >= 0); tcflush(ports[port].fd, TCIFLUSH);#endif ports[port].serial_in_count = 0;}/* Send break */void serial_sendbreak(int port){ assert(port >= 0 && port < MAX_PORTS);#if defined(WIN32) assert(ports[port].handle != INVALID_HANDLE_VALUE); SetCommBreak(ports[port].handle); Sleep(500); ClearCommBreak(ports[port].handle);#else assert(ports[port].fd >= 0); tcsendbreak(ports[port].fd, 0);#endif}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -