From 2119ab0364b6a161091a89a7018be14d49bdc7b3 Mon Sep 17 00:00:00 2001 From: Uwe Hermann Date: Wed, 12 Jan 2011 00:43:00 +0100 Subject: [PATCH] MinGW/Windows: Serial port portability fixes. Add serial_read()/serial_write() which have different implementations on MinGW/Windows. Add some more error code handling and documentation. --- hardware/common/serial.c | 64 ++++++++++++++++++++++---- hardware/link-mso19/link-mso19.c | 6 +-- hardware/openbench-logic-sniffer/ols.c | 8 ++-- sigrok-proto.h | 2 + 4 files changed, 64 insertions(+), 16 deletions(-) diff --git a/hardware/common/serial.c b/hardware/common/serial.c index 0b9b1c8c..853c26af 100644 --- a/hardware/common/serial.c +++ b/hardware/common/serial.c @@ -51,11 +51,14 @@ char *serial_port_glob[] = { GSList *list_serial_ports(void) { + GSList *ports; + #ifdef _WIN32 /* TODO */ + ports = NULL; + ports = g_slist_append(ports, strdup("COM1")); #else glob_t g; - GSList *ports; unsigned int i, j; ports = NULL; @@ -66,9 +69,9 @@ GSList *list_serial_ports(void) ports = g_slist_append(ports, strdup(g.gl_pathv[j])); globfree(&g); } +#endif return ports; -#endif } int serial_open(const char *pathname, int flags) @@ -86,11 +89,17 @@ int serial_open(const char *pathname, int flags) #endif } +/* + * Close the serial port. + * Returns 0 upon success, -1 upon failure. + */ int serial_close(int fd) { #ifdef _WIN32 - CloseHandle(hdl); + /* Returns non-zero upon success, 0 upon failure. */ + return (CloseHandle(hdl) == 0) ? -1 : 0; #else + /* Returns 0 upon success, -1 upon failure. */ return close(fd); #endif } @@ -103,16 +112,49 @@ int serial_flush(int fd) { #ifdef _WIN32 /* Returns non-zero upon success, 0 upon failure. */ - if (PurgeComm(hdl, PURGE_RXCLEAR | PURGE_TXCLEAR) == 0) - return -1; - else - return 0; + return (PurgeComm(hdl, PURGE_RXCLEAR | PURGE_TXCLEAR) == 0) ? -1 : 0; #else /* Returns 0 upon success, -1 upon failure. */ return tcflush(fd, TCIOFLUSH); #endif } +/* + * Write a number of bytes to the specified serial port. + * Returns the number of bytes written, or -1 upon failure. + */ +int serial_write(int fd, const void *buf, size_t count) +{ +#ifdef _WIN32 + DWORD tmp = 0; + + /* FIXME */ + /* Returns non-zero upon success, 0 upon failure. */ + WriteFile(hdl, buf, count, &tmp, NULL); +#else + /* Returns the number of bytes written, or -1 upon failure. */ + return write(fd, buf, count); +#endif +} + +/* + * Read a number of bytes from the specified serial port. + * Returns the number of bytes read, or -1 upon failure. + */ +int serial_read(int fd, void *buf, size_t count) +{ +#ifdef _WIN32 + DWORD tmp = 0; + + /* FIXME */ + /* Returns non-zero upon success, 0 upon failure. */ + return ReadFile(hdl, buf, count, &tmp, NULL); +#else + /* Returns the number of bytes read, or -1 upon failure. */ + return read(fd, buf, count); +#endif +} + void *serial_backup_params(int fd) { #ifdef _WIN32 @@ -137,8 +179,10 @@ void serial_restore_params(int fd, void *backup) } /* - * flowcontrol 1 = rts/cts 2 = xon/xoff - * parity 0 = none, 1 = even, 2 = odd + * Set serial parameters. + * + * flowcontrol: 1 = rts/cts, 2 = xon/xoff + * parity: 0 = none, 1 = even, 2 = odd */ int serial_set_params(int fd, int speed, int bits, int parity, int stopbits, int flowcontrol) @@ -148,6 +192,7 @@ int serial_set_params(int fd, int speed, int bits, int parity, int stopbits, if (!GetCommState(hdl, &dcb)) { /* TODO: Error handling. */ + return SIGROK_ERR; } /* TODO: Rename 'speed' to 'baudrate'. */ @@ -178,6 +223,7 @@ int serial_set_params(int fd, int speed, int bits, int parity, int stopbits, if (!SetCommState(hdl, &dcb)) { /* TODO: Error handling. */ + return SIGROK_ERR; } #else struct termios term; diff --git a/hardware/link-mso19/link-mso19.c b/hardware/link-mso19/link-mso19.c index ba50a8ac..16176ffa 100644 --- a/hardware/link-mso19/link-mso19.c +++ b/hardware/link-mso19/link-mso19.c @@ -83,7 +83,7 @@ static int mso_send_control_message(struct sigrok_device_instance *sdi, w = 0; while (w < s) { - ret = write(fd, buf + w, s - w); + ret = serial_write(fd, buf + w, s - w); if (ret < 0) { ret = SIGROK_ERR; goto free; @@ -145,7 +145,7 @@ static int mso_check_trigger(struct sigrok_device_instance *sdi, return ret; buf[0] = 0; - if (read(sdi->serial->fd, buf, 1) != 1) /* FIXME: Need timeout */ + if (serial_read(sdi->serial->fd, buf, 1) != 1) /* FIXME: Need timeout */ ret = SIGROK_ERR; *info = buf[0]; @@ -611,7 +611,7 @@ static int receive_data(int fd, int revents, void *user_data) revents = revents; - s = read(fd, in, sizeof(in)); + s = serial_read(fd, in, sizeof(in)); if (s <= 0) return FALSE; diff --git a/hardware/openbench-logic-sniffer/ols.c b/hardware/openbench-logic-sniffer/ols.c index d95e0827..403c2b58 100644 --- a/hardware/openbench-logic-sniffer/ols.c +++ b/hardware/openbench-logic-sniffer/ols.c @@ -119,7 +119,7 @@ static int send_shortcommand(int fd, uint8_t command) g_debug("ols: sending cmd 0x%.2x", command); buf[0] = command; - if (write(fd, buf, 1) != 1) + if (serial_write(fd, buf, 1) != 1) return SIGROK_ERR; return SIGROK_OK; @@ -135,7 +135,7 @@ static int send_longcommand(int fd, uint8_t command, uint32_t data) buf[2] = (data & 0xff0000) >> 16; buf[3] = (data & 0xff00) >> 8; buf[4] = data & 0xff; - if (write(fd, buf, 5) != 5) + if (serial_write(fd, buf, 5) != 5) return SIGROK_ERR; return SIGROK_OK; @@ -280,7 +280,7 @@ static int hw_init(char *deviceinfo) g_poll(fds, devcnt, 1); for (i = 0; i < devcnt; i++) { if (fds[i].revents == G_IO_IN) { - if (read(fds[i].fd, buf, 4) == 4) { + if (serial_read(fds[i].fd, buf, 4) == 4) { if (!strncmp(buf, "1SLO", 4) || !strncmp(buf, "1ALS", 4)) { if (!strncmp(buf, "1SLO", 4)) @@ -515,7 +515,7 @@ static int receive_data(int fd, int revents, void *user_data) if (revents == G_IO_IN && num_transfers / num_channels <= limit_samples) { - if (read(fd, &byte, 1) != 1) + if (serial_read(fd, &byte, 1) != 1) return FALSE; sample[num_bytes++] = byte; diff --git a/sigrok-proto.h b/sigrok-proto.h index cbd49a09..ed06bd0f 100644 --- a/sigrok-proto.h +++ b/sigrok-proto.h @@ -123,6 +123,8 @@ GSList *list_serial_ports(void); int serial_open(const char *pathname, int flags); int serial_close(int fd); int serial_flush(int fd); +int serial_write(int fd, const void *buf, size_t count); +int serial_read(int fd, void *buf, size_t count); void *serial_backup_params(int fd); void serial_restore_params(int fd, void *backup); int serial_set_params(int fd, int speed, int bits, int parity, int stopbits,