[Mono-dev] Patch for Bug 8207: Can't set 1000000 baud with System.IO.Ports.SerialPort.BaudRate

Christian Hofstaedtler ch---mono-devel at zeha.at
Tue Feb 24 20:45:09 UTC 2015


This patch (against mono-2.10.8.1 from Debian) allows setting
custom baud rates, and very likely would support a baudrate of
1000000.

I release this patch under the MIT license.


--- serial.c.orig	2013-01-30 12:06:52.379691461 +0100
+++ serial.c.orig	2013-01-30 13:05:50.383390154 +0100
@@ -17,6 +17,11 @@ 
 #endif
 #include <sys/ioctl.h>
 
+/* This is for ASYNC_*, serial_struct on linux */
+#if defined(__linux__)
+#include <linux/serial.h>
+#endif
+
 #include <glib.h>
 
 /* This is for FIONREAD on solaris */
@@ -151,6 +156,7 @@ 
 set_attributes (int fd, int baud_rate, MonoParity parity, int dataBits, MonoStopBits stopBits, MonoHandshake handshake)
 {
 	struct termios newtio;
+	gboolean custom_baud_rate = FALSE;
 
 	if (tcgetattr (fd, &newtio) == -1)
 		return FALSE;
@@ -227,8 +233,10 @@ 
 	    break;
 	case 50:
 	case 0:
-	default:
 	    baud_rate = B9600;
+	    break;
+	default:
+	    custom_baud_rate = TRUE;
 		break;
 	}
 
@@ -319,16 +327,54 @@ 
 	    newtio.c_iflag |= IXOFF | IXON;
 		break;
 	}
-	
-	if (cfsetospeed (&newtio, baud_rate) < 0 || cfsetispeed (&newtio, baud_rate) < 0 ||
-	    tcsetattr (fd, TCSANOW, &newtio) < 0)
+
+	if (custom_baud_rate == FALSE)
 	{
-		return FALSE;
+		if (cfsetospeed (&newtio, baud_rate) < 0 || cfsetispeed (&newtio, baud_rate) < 0)
+		{
+			return FALSE;
+		}
 	}
 	else
 	{
-	return TRUE;
+		/* On Linux, to set a custom baud rate, we must set the "standard" baud_rate
+		 * to 38400. */
+		if (cfsetospeed (&newtio, B38400) < 0 || cfsetispeed (&newtio, B38400) < 0)
+		{
+			return FALSE;
+		}
+	}
+
+	if (tcsetattr (fd, TCSANOW, &newtio) < 0)
+	{
+		return FALSE;
+	}
+
+	if (custom_baud_rate == TRUE)
+	{
+#if defined(__linux__)
+		struct serial_struct ser;
+
+		if (ioctl (fd, TIOCGSERIAL, &ser) < 0)
+		{
+			return FALSE;
+		}
+
+		ser.custom_divisor = ser.baud_base / baud_rate;
+		ser.flags &= ~ASYNC_SPD_MASK;
+		ser.flags |= ASYNC_SPD_CUST;
+
+		if (ioctl (fd, TIOCSSERIAL, &ser) < 0)
+		{
+			return FALSE;
+		}
+#else
+		/* Don't know how to set custom baud rate on this platform. */
+		return FALSE;
+#endif
 	}
+
+	return TRUE;
 }
 
 


More information about the Mono-devel-list mailing list