| Store | Cart

Re: Win32::SerialPort baudrate problem

From: <Bbir...@aol.com>
Tue, 21 Jun 2005 23:16:05 EDT
I'm not sure if this is one query, two, or three - all in close proximity. But since the explanation is long - even if the "solution" is short - I'm only going to go through it once and copy all the identified threads.

> my problem is only on Windows98:

> when i try to set the baudrate on Win32::SerialPort to
> 115200 baud, it says "cannot set baudrate" to this
> value, that the value 115200 is invalid.

> when i run my program on WinXP or 2000, it works just
> fine, and has no problem setting serial comm to 115200
> baud, and no problem communicating at that speed.

> is this a problem with Windows 98, that it can't run
> serial ports at this speed?  or is something wrong
> with Win32::SerialPort in this respect?  

First, for those only interested in a quickie patch, add the following after opening the port at a "permitted" speed:

    $self->{"_L_BAUD"}{115200} = 115200;
    # I think it needs to be a number, not a string

This will add 115200 to the hash used to generate the array of "permitted" values. If you save it with this value, it probably won't "start" - save with legal values only.

And now for the gory details...(and I warned you it was long)

Most developers wrote their own MS-DOS serial drivers - some good, some bad, but with easy access to the hardware good ones were managable.

Microsoft shipped a serial driver with Windows 3.x that was truly awful. It received nearly universal distain from developers - and was mostly useless even for users. So application developers who needed serial support (most of them in the early to mid 1990s) wrote their own and automatically replaced the Microsoft versions.

But they weren't all compatible with each other - so the driver shipped (and installed) with application #2 broke the serial functionality of application #1. This made users less than pleased. Direct access to hardware was more difficult, too.

Even Microsoft could learn from a boondoggle this bad - so when Windows 95 was shipped it included not only a complete driver rewrite - it also used several completely new APIs (for serial, modem, parameter auto-detect, etc.). It was a very good driver and the APIs were forward-looking and well designed. Among the important features:

1. Hardware was very difficult to access except through the driver - so everyone
    would use the default (or a superset based on the default - and compatibility
    was likely).

2. The driver handled timeouts, background operations, and error handling properly
    so an fault-tolerant application could be written on top of it.

3. It used a virtual serial port model that was not limited to specific hardware or
    OS setups - one setup covered embedded to server to specialized requirements.
    This last one was important because in the early 1990s NT4 was intended to run
    on lots of varieties on non-PC-compatible (and even non-Intel-based) hardware.

Win32::SerialPort was written to this API (probably more faithfully than the final shipping version of NT4 and subsequent Microsoft releases - but Win9x: 95,98,ME
stayed pretty close). It is item #3 that is the root of the problem reported. The API has calls to the driver to report allowed operating parameters - including a list of available baudrates - so that non-PC-standard hardware, or even fixed rate setups, could be supported. Odd values like 134.5 baud and 256K baud can be configured into the driver. But the application is supposed to ask the driver for a list of allowed baudrates - and only request legal ones.

In 1995, most PC hardware had less than ideal serial hardware. So the default list for Win95 (and its derivatives like W98) only went up to 56K. A modem driver, acting like a superset, could add 115200 to the list (and modems did include better hardware). NT4 was installed in "server class" machines which also usually had superior serial hardware - so 115200 was in the NT4 list (and derivatives).

At some point, if I ever get enough tuits, I'll add a way to override the list that does "save" and "start" transparently. And does not break the Device::SerialPort version in the implementation. But for now, try the cheap hack.

-bill
I'm not sure if this is one query, two, or three - all in close proximity. 
But since the explanation is long - even if the "solution" is short - I'm only 
going to go through it once and copy all the identified threads.

> my problem is only on Windows98:> when i try to set the baudrate on Win32::SerialPort to> 115200 baud, it says "cannot set baudrate" to this> value, that the value 115200 is invalid.> when i run my program on WinXP or 2000, it works just> fine, and has no problem setting serial comm to 115200> baud, and no problem communicating at that speed.> is this a problem with Windows 98, that it can't run> serial ports at this speed?  or is something wrong> with Win32::SerialPort in this respect?   

First, for those only interested in a quickie patch, add the following after 
opening the port at a "permitted" speed:

    $self->{"_L_BAUD"}{115200} = 115200;
    # I think it needs to be a number, not a string

This will add 115200 to the hash used to generate the array of "permitted" 
values. If you save it with this value, it probably won't "start" - save with 
legal values only.

And now for the gory details...(and I warned you it was long)

Most developers wrote their own MS-DOS serial drivers - some good, some bad, 
but with easy access to the hardware good ones were managable.

Microsoft shipped a serial driver with Windows 3.x that was truly awful. It 
received nearly universal distain from developers - and was mostly useless even 
for users. So application developers who needed serial support (most of them 
in the early to mid 1990s) wrote their own and automatically replaced the 
Microsoft versions.

But they weren't all compatible with each other - so the driver shipped (and 
installed) with application #2 broke the serial functionality of application 
#1. This made users less than pleased. Direct access to hardware was more 
difficult, too.

Even Microsoft could learn from a boondoggle this bad - so when Windows 95 
was shipped it included not only a complete driver rewrite - it also used 
several completely new APIs (for serial, modem, parameter auto-detect, etc.). It was 
a very good driver and the APIs were forward-looking and well designed. Among 
the important features:

1. Hardware was very difficult to access except through the driver - so 
everyone
    would use the default (or a superset based on the default - and 
compatibility
    was likely).

2. The driver handled timeouts, background operations, and error handling 
properly
    so an fault-tolerant application could be written on top of it.

3. It used a virtual serial port model that was not limited to specific 
hardware or
    OS setups - one setup covered embedded to server to specialized 
requirements.
    This last one was important because in the early 1990s NT4 was intended 
to run
    on lots of varieties on non-PC-compatible (and even non-Intel-based) 
hardware.

Win32::SerialPort was written to this API (probably more faithfully than the 
final shipping version of NT4 and subsequent Microsoft releases - but Win9x: 
95,98,ME
stayed pretty close). It is item #3 that is the root of the problem reported. 
The API has calls to the driver to report allowed operating parameters - 
including a list of available baudrates - so that non-PC-standard hardware, or 
even fixed rate setups, could be supported. Odd values like 134.5 baud and 256K 
baud can be configured into the driver. But the application is supposed to ask 
the driver for a list of allowed baudrates - and only request legal ones.

In 1995, most PC hardware had less than ideal serial hardware. So the default 
list for Win95 (and its derivatives like W98) only went up to 56K. A modem 
driver, acting like a superset, could add 115200 to the list (and modems did 
include better hardware). NT4 was installed in "server class" machines which also 
usually had superior serial hardware - so 115200 was in the NT4 list (and 
derivatives).

At some point, if I ever get enough tuits, I'll add a way to override the 
list that does "save" and "start" transparently. And does not break the 
Device::SerialPort version in the implementation. But for now, try the cheap hack.

-bill 

Recent Messages in this Thread
Bbir...@aol.com Jun 22, 2005 03:16 am