Support for Baud Rates above 250000 baud?
David le Comte
Tue Jan 9 23:19:00 GMT 2007
Thanks Brian for your comments and suggestions.
I apologise for not adding the output of cycheck -svr in my original
post. I have added it now (fred.txt).
I'm sorry for not indicating that my "changes" to termios.h were
only as an experiment. I didn't want to simply write that there
was no support for higher baud rates without making at least some
kind of partial attempt (on the odd chance that cfset[io]speed()
had already made the change). I reset termios.h back to its
original state after the experiemnt (partially) supported the
hypothesis that this higher baud rate support was not there.
Your mention of SetCommState() led me to www.microsoft.com
and its knowledge base where I found the following thread:
In particular I would like to draw notice to the comment by someone
"Simply specify 230400 for the baud rate (forget about any
CBS_ constant). But the driver must support it, otherwise
it's pointless. I'm using bauds like 230400, 460800, 921600
without any problem."
My interpretation from this thread, and Microsoft's description
of the DCB.BaudRate field of the DCB, is that they (Microsoft)
do not have (as yet?) formal support for baud rates above 115200.
This is consistent with the code fragment of fhandler_serial.cc
that Brian has posted where the baud rate of 230400 is coded without
use of a "define"d CBR_nnnnn constant.
So, it would seem to me that SetCommState() simply passes the
raw number that is in the DCB.DaudRate field to the driver(s) provided
by the vendor(s), and that they seem(?), in the main(?) to have
adopted the convention that they will (if possible) set the baud
rate that is passed as an actual value in this field. This seems
to me to be a perfectly reasonable way of passing the baud rate
to the driver.
I'm wondering if the most general way of modifying fhandler_serial.cc
(and cf[io]speed()?) is to do what SetCommState() is doing, ie,
if the value that is passed is NOT equivalent to one of the Bnnnnn
"define"s, then assume it is a literal speed and pass that.
This would mean changing "speed_t" to be an unsigned int (can we
now assume that is 32bit?) rather than char?, and removing and/or
changing any parsing that cfset[io]speed() are doing.
The "default:" case in the switch statement in Brian's code
fragment might then be changed to only do somae basic sanity
checking, ie check that the value is in some arbitrary range,
and if so just pass that raw value on.
I guess though that fiddling with things like "speed_t" maybe
dangerous? It might make thinks like stty not work?
Brian suggested that one should start by defining higher order
bit rates. I've done some googling and the only bit rates
I can find above 115200, are:
but I probably would suggest adding,
as a bit of future-proofing.
If there are any other rates people have come across,
then please post them.
David le Comte
David le Comte wrote:
> > I am running Cygwin on a PC that is running Windows XP. My Cygwin
> > version is "CYGWIN_NT-5.1" and it was downloaded and installed late last
No, it's not. The output from uname tells us nothing about which
version of Cygwin (or any of the other of dozens of packages you might
have installed), rather it simply means that you are running Windows NT
version 5.1, aka Windows XP. The current version of Cygwin is 1.5.23-2,
and if you want to include helpful information try attaching the output
of "cygcheck -svr" as requested in the posting instructions.
> > Adding entries into termios.h for higher
> > baudrates using the convention that B460800 was 0x01006,
> > B500000 was 0x01007, and B921600 was 0x01008
> > caused errors.
> > #define B230400 0x01004
> > #define B256000 0x01005
> > /* 3 new entries - as an experiement to see if it works */
> > #define B460800 0x01006
> > #define B500000 0x01007
> > #define B921600 0x01008
> > The calls to cfsetispeed() and cfsetospeed() failed. Not unsurprising,
> > as one could assume that they had been using the original termios.h when
> > they were compiled.
This is a Very Bad Idea in general. You can't just add new defines to a
header file and expect it to work. The header is an indication of what
a library supports, it is a one-way street.
> > 1) Is there a build available for Cygwin (on a Windows platform) that
> > has support for higher baud rates? If so, does anyone know where I
> > could find it?
That's kind of an odd question. Cygwin is open source and of course
people are free to take it and patch it to do whatever they want, so
it's certainly possible that someone has patched their Cygwin to allow
other baud rate settings. But if they did it would be a separate
project and off-topic for this list, and I'm not aware of any such thing
Occasionally new features are added to the code which have yet to be
included in released versions, in which case users are directed to try
the new code in the Cygwin snapshots which are provided on cygwin.com,
but in this case that's not an issue as I'm not aware of any recent
changes to this part of the code.
> > 2) Assuming there is no such build available, are there plans to add
> > support for higher baud rates? If so, does anyone know when?
> > 2) Would it be difficult to download the appropriate source files, modify
> > them, and make my own Cygwin build? (The idea of doing this terrifies
> > me by the way). If it is possible, could someone give me some pointers
> > on how to do this?
If you read the Win32 API docs for SetCommState()
<http://msdn2.microsoft.com/en-us/library/aa363436.aspx> and struct DCB:
<http://msdn2.microsoft.com/en-us/library/aa363214.aspx> you see the
canonical list of #defined baud rates that Win32 supports. But there's
also this tidbit: "This member can be an actual baud rate value, or one
of the following indexes."
So from this we can see that Win32 supports arbitrary baud rates (with a
certain list of #defined standard ones) whereas the POSIX termios.h /
speed_t API that Cygwin is emulating does not have the capability to set
the rate arbitarily. Thus, any baud rate can be supported, but the code
has to exist to do the mapping of the symbolic constant. You can see
this happening in fhandler_serial.cc, which does the actual mapping of
termios to filling the Win32 struct DCB:
state.BaudRate = CBR_110;
state.BaudRate = CBR_300;
state.BaudRate = CBR_600;
state.BaudRate = CBR_1200;
state.BaudRate = CBR_2400;
state.BaudRate = CBR_4800;
state.BaudRate = CBR_9600;
state.BaudRate = CBR_19200;
state.BaudRate = CBR_38400;
state.BaudRate = CBR_57600;
state.BaudRate = CBR_115200;
state.BaudRate = 230400 /* CBR_230400 - not defined */;
/* Unsupported baud rate! */
termios_printf ("Invalid t->c_ospeed %d", t->c_ospeed);
Thus it appears that it should be easily possible to add a Bxxxxx define
for any desired baud rate, as long as you update termios.h and
fhandler_serial.cc to know about it. So yes, you could just make this
change and rebuild a local cygwin1.dll that supports it. Building
cygwin1.dll is not much different than any other autoconf-style package
and there are instructions in the Users Guide (or the FAQ, I can't
remember.) It would be better however to somehow figure out a list of
the missing standard baud rates that are in common use and submit a
patch to add them upstream, rather than just ad hoc adding whatever you
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
-------------- next part --------------
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Problem reports: http://cygwin.com/problems.html
More information about the Cygwin