Read/Write Serial Port from Kernel

Hi,
I am new in windows hardware programming. I want to develop kernel driver to read/write from serial port. Please guide me how to start.

Thanks
Hesham Rafi

For what purpose? Debug logging? Talk to a device on the other side? You talk to the serial port by opening a handle to it , configuring it, and then sending io (read/write/ioctls)

d

debt from my phone


From: xxxxx@gmail.com
Sent: 11/2/2012 12:46 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Read/Write Serial Port from Kernel

Hi,
I am new in windows hardware programming. I want to develop kernel driver to read/write from serial port. Please guide me how to start.

Thanks
Hesham Rafi


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

xxxxx@gmail.com wrote:

I am new in windows hardware programming. I want to develop kernel driver to read/write from serial port. Please guide me how to start.

Your serial ports already have drivers. What is it you are hoping to
accomplish? Tell us the larger goal, and we can offer some advice.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

I’m trying to learn accessing hardware from widnows kernel.
So trying to program COM port (UART) and develop toy serial communication driver.
I studied about the UART programming little bit. Prepared the RS232 cable. Using RS232 emulator (termianal) , I’m able to send receive data over serial port.
Now to start with, I’m planning to develop write operation in my toy serial driver.
My approacch for this is :

driver entry (){
initialise the UART (baud rate, stop bit etc) by writing to line control register (LCR) of UART (0x3FA)
}

write_detach_fn( UINT data){
write_uchar(0x3F8, data);
}

For testing I will disable the default windows serial driver and install mine.

to begin with, not really want to worry about the robustness, synchornization etc.
Just want to see the data on terminal on other computer thru my driver.

My queries are:
Is my this approach correct?
How do program the UART register? Currently struggling configuring it.
Any one has simple driver code that explains this?
Any links to write this driver?

Thanks in advance.

A serial port driver is not a trivial project. You have to deal with the
issues of simultaneous input and output, hard-real-time windows
(especially at 115K), etc. Even the simplest “toy” driver is going to be
challenging. You will have to do internal buffering because you will not
be guaranteed to have a ReadFile IRP with buffers available.

Note that by saying that you are going to initiate everything in
DriverEntry, it means that you are writing an obsolete legacy driver. In
modern drivers, you cannot assume the hardware is available at
DriverEntry. You have to handle Power and PnP IRPs, because initializing
things in DriverEntry not only presumes that the hardware is available, it
assumes that somehow, by magic, the hardware retains all its settings
across sleep, deep sleep, and hibernate events, when, in fact, it is YOUR
responsibility to make sure this state is properly preserved!

If you don’t worry about synchronization, you are doomed from the very
start, because it is impossible to write a serial driver that does not
require synchronization, both at the individual read and write streams,
but to the shared hardware. It’s not just that you can build a toy driver
without this; you cannot build a driver at all without synchronization.
You have to have queues that are handled at PASSIVE_LEVEL, and manipulated
at DISPATCH_LEVEL. You have shared hardware state. And “disabling” the
built-in driver is a nontrivial exercise, or it least it was the last time
I looked.

It is not even clear the 0x3F8 will work correctly. There is no
write_uchar function as far as I know; this would be WRITE_PORT_UCHAR.
Your code does not suggest how the function would be called.

As to “how to program the UART register”, that is cloaked in deep mystery.
Well, not really. You can read the documents on it, but you have to
worry about a lot of fiddly detail, which is why real hardware is rarely a
good approach to practice; you have a LOT of studying to do (I used to
write UART code for other operating systems, and was working at the
bare-metal level with UART chips, and getting everything right took a long
time and a lot of experimentation and reading). You could look at the
source for the Microsoft serial port driver. And when you look at it,
look at its complexity. It is not a good driver to read to learn driver
basics, because it is doing so much–plus it has timeouts and other
interesting goodies that ripple through the code.

I wrote a lot of drivers for real hardware over several decades, and in
addition to the real complexities, there are several things to keep in
mind:

  1. The documentation lies
  2. You cannot understand the documentation, anyway
  3. If you think you understand the documentation, consult the previous two
    rules
  4. The documentation, and examples when available, assume that there is no
    other contention for CPU resources. In a real system, you have to deal
    with this contention.
  5. The problem cannot be simplified by ignoring key requirements such as
    synchronization
  6. If you think you can simplify the problem, consult the previous rule

A serial port is simply not a good “introductory example”. And you really
need to be using KMDF for new drivers, not doing things in DriverEntry as
we used to do in NT 4.0 in the 1990s.
joe

I’m trying to learn accessing hardware from widnows kernel.
So trying to program COM port (UART) and develop toy serial communication
driver.
I studied about the UART programming little bit. Prepared the RS232 cable.
Using RS232 emulator (termianal) , I’m able to send receive data over
serial port.
Now to start with, I’m planning to develop write operation in my toy
serial driver.
My approacch for this is :

driver entry (){
initialise the UART (baud rate, stop bit etc) by writing to line control
register (LCR) of UART (0x3FA)
}

write_detach_fn( UINT data){
write_uchar(0x3F8, data);
}

For testing I will disable the default windows serial driver and install
mine.

to begin with, not really want to worry about the robustness,
synchornization etc.
Just want to see the data on terminal on other computer thru my driver.

My queries are:
Is my this approach correct?
How do program the UART register? Currently struggling configuring it.
Any one has simple driver code that explains this?
Any links to write this driver?

Thanks in advance.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

The in box UART driver is a public WDK sample, http://code.msdn.microsoft.com/windowshardware/Serial-73a4564d . It can answer all of your questions.

I would suggest starting with a KMDF driver and starting your work in EvtDevicePrepareHardware. There is no guarantee that the serial hardware is powered on during your DriverEntry. You need to participate in pnp and power to get correct access to hw.

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Wednesday, November 7, 2012 10:32 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Read/Write Serial Port from Kernel

I’m trying to learn accessing hardware from widnows kernel.
So trying to program COM port (UART) and develop toy serial communication driver.
I studied about the UART programming little bit. Prepared the RS232 cable. Using RS232 emulator (termianal) , I’m able to send receive data over serial port.
Now to start with, I’m planning to develop write operation in my toy serial driver.
My approacch for this is :

driver entry (){
initialise the UART (baud rate, stop bit etc) by writing to line control register (LCR) of UART (0x3FA) }

write_detach_fn( UINT data){
write_uchar(0x3F8, data);
}

For testing I will disable the default windows serial driver and install mine.

to begin with, not really want to worry about the robustness, synchornization etc.
Just want to see the data on terminal on other computer thru my driver.

My queries are:
Is my this approach correct?
How do program the UART register? Currently struggling configuring it.
Any one has simple driver code that explains this?
Any links to write this driver?

Thanks in advance.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

xxxxx@gmail.com wrote:

I’m trying to learn accessing hardware from widnows kernel.
So trying to program COM port (UART) and develop toy serial communication driver.

Allow me to recommend an alternative strategy.

There are a large number of USB experimenter’s kits out there in the
world. Most of these kits have LEDs, switches, buttons, and knobs to
allow you to play with various different control techniques. USB
drivers are much less complicated than serial drivers, but would still
give you the experience of controlling hardware. Plus, these kits are
fun to play with. And, perhaps the biggest advantage is that USB is a
technology with a future. RS-232 had its 50th birthday this year.
There’s nothing new to be done there.

For a bit more money, you can even get one with a small LCD panel.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Thanks for reply Joseph, Doron and Tim.
I have done to write value on serial port using WRITE_PORT_UCHAR through set baurd rate etc.
So now I want to develop Read and writing functionalty with required IRP.

@Doron: Your given link is related to WDF sample and I think it is full serial port driver. Through this sample it is very difficult to understand the comcept of readng and writing.

Thanks
Hesham Rafi

xxxxx@gmail.com wrote:

Thanks for reply Joseph, Doron and Tim.
I have done to write value on serial port using WRITE_PORT_UCHAR through set baurd rate etc.
So now I want to develop Read and writing functionalty with required IRP.

@Doron: Your given link is related to WDF sample and I think it is full serial port driver. Through this sample it is very difficult to understand the comcept of readng and writing.

Well, yes, because driving a serial port is complicated. You have to
let the user set the baud rate, parity, stop bits, start bits, etc. You
have to support flow control (hardware and software). You have to
decide how to handle parity problems. You have to have buffering, both
read and write. You have to handle asynchronous requests and timeouts.
You have to handle interrupts for performance.

It depends on what you really want to do. If you want to have your
driver provide a full serial port that can be used with GetCommState,
SetCommState, ReadFile, and WriteFile, then there are a lot of standard
ioctls that you must support. That’s what the full serial port driver
does, and that’s what is required to work with programs like Hyperterminal.

HOWEVER, if you are just trying to experiment, you don’t have to go that
far. You can decide that your test application is just going to send a
single ioctl with a single buffer, and your driver will write that
buffer one character at a time, without exposing the whole serial port
functionality. That’s not very far from what you have now.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Ten years ago, people were still using RS-232 and RS-485 to build embedded
systems. The arrival of prebuilt TCP/IP stacks for embedded systems
(either free or at very nominal cost from the OS or chip vendor) and USB
have made RS-232 nearly totally dead. The only thing I used to use a
modem for was sending faxes, but since everyone who cares is on email, I
disconnected my RS-232 modem about ten years ago and put it on a shelf in
the basement. I have not missed it. But my argument was that RS-232 is a
nontrivial device to write a driver for, and would be a seriously
difficult project, beyond the scope of what a beginner should be trying.

I was, at one time in the 1990s, an expert on serial ports and modems.
There are some skills that are not worth retaining. I think the last time
I wrote code for RS-232 was about 1997.

I agree: USB is the way to go.
joe

xxxxx@gmail.com wrote:
> I’m trying to learn accessing hardware from widnows kernel.
> So trying to program COM port (UART) and develop toy serial
> communication driver.

Allow me to recommend an alternative strategy.

There are a large number of USB experimenter’s kits out there in the
world. Most of these kits have LEDs, switches, buttons, and knobs to
allow you to play with various different control techniques. USB
drivers are much less complicated than serial drivers, but would still
give you the experience of controlling hardware. Plus, these kits are
fun to play with. And, perhaps the biggest advantage is that USB is a
technology with a future. RS-232 had its 50th birthday this year.
There’s nothing new to be done there.

For a bit more money, you can even get one with a small LCD panel.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

The reason the example looks complicated is that managing a serial port,
as already pointed out, is a complicated business. It is simply not a
good “learning experience” if you are trying to learn to play with
hardware, because the complexities overwhelm the conceptual gain, and you
will spend so much time reinventing what is a complicated driver (for it
to be useful at all, even in a toy context) that dealing with hardware
becomes an irrelevant problem.

I have a friend who is a pilot, and an IFR instructor. She says “You may
think the challenge of IFR” [which is charactized by flying only by
instruments, and frequently inside clouds with no external references]
“are learning to fly with no outside references. This is not the case.
We can teach that in 4-5 hours. The remainder of the 80 hours of standard
training are learning to read weather, file flight plans, understand radio
protocols, dealing with the transfer from takeoff control to in-flight
control and in-flight control to approach control, learing how to read the
landing charts, and mastering all of these.” She points out that if the
instrument approach chart says “If you reach altitude MSL and
have not seen the landing lights of the airport, abort your approach with
a climbing turn to the right.” That’s because there are mountains on the
left.

In my talk about Windows drivers that I do for the operating systems class
at CMU (all of drivers in 50 minutes!) I show this by having a little
animated plane fly into the mountains, and what appears when it hits is a
bluescreen.

Windows drivers are rarely about talking to hardware; I could teach you
everything you need to know in about half an hour. The rest is protocols,
the care-and-feeding of IRPs. In fact, the Windows viewpoint is solely
that a driver is responsible for the care and feeding of IRPs; if, along
the way, it happens to touch hardware, that is of no interest whatsoever
to the OS. But screw up the IRP protocol and you fly into the mountains.

Look at the nature of the questions in this NG. They rarely, perhaps
never, talk about communicating to the hardware. But they are always
concerned about completion routines, MDLs, how to ask NDIS to do
something, etc. They are “protocol” questions about the care and feeding
of IRPs.

Now, that said, talking to hardware imposes a lot of requirements, such as
getting bits out of the FIFO fast enough, and these influence your driver
architecture. But in the case of serial ports, this is essential detail
irrelevant to the “learning experience” but critical to the driver being
useful. You can’t choose to ignore any aspect of these requirements
(which represent OS-to-device protocols) and survive the experience.
Bottom line: setting bits in device registers is trivial. Getting the
device-to-OS protocol right can be hard, and unless you are doing a very
simple driver, getting the driver-to-OS protocol right can be daunting.
joe

> Thanks for reply Joseph, Doron and Tim.
> I have done to write value on serial port using WRITE_PORT_UCHAR through
> set baurd rate etc.
> So now I want to develop Read and writing functionalty with required IRP.
>
> @Doron: Your given link is related to WDF sample and I think it is full
> serial port driver. Through this sample it is very difficult to understand
> the comcept of readng and writing.
>
> Thanks
> Hesham Rafi
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>