Rookie mistake: kernel to user-space notification

When I was implementing my first driver at work, I was a bit surprised that the OS (WinCE) wasn’t providing a mechanism for notifying the application from the driver. Of course, I cleverly used a named event to accommodate for the missing “feature” of the OS.

And of course, this was wrong. And I wasn’t alone in my mistake. I saw other colleagues, as well as people on the web (here is an example from Stackoverflow) trying to do the same. So I think this is a good mistake to share, especially for rookies in driver development.

There are reasons why the OS doesn’t offer such a mechanism by default[1]You can of course work around this, as I did. On WinCE you can use the globally available named event mechanism, on Linux you can abuse the signals somewhat etc. Some extensions to driver models … Continue reading. A driver is passive as seen from the outside, it will only serve requests from applications. So it doesn’t get to notify them. Ideally a simple device is modelled as a stream of characters by the driver, so the application can read from and write to it. For instance, if the application wants to know when new data is available for reading, it can use a blocking read (or a select call on POSIX systems). If this is not fitting to your situation, you can implement an IOCTL which blocks until new data is available. In any case, all calls are initiated from the application, and never from the driver.

On the other hand, in reality a driver is not passive at all: It continuously services HW interrupts. It might have some worker threads doing asynchronous work requested by applications. Forcing these activities into the passive model foreseen by the OS will actually make your driver more complex. For instance, you might have to implement some queues for holding data from the HW until the application requests them.

Conforming to the passive model is still the better option because:

  1. IPCs do not make good interfaces. Notifying from kernel- to user-space will force you to have an IPC-based interface from the driver to the application.
  2. You are trading internal complexity for external complexity: It’s always better to make the driver internally more complex, instead of increasing the complexity of the driver and applications together.
  3. Conforming to the OS model will provide you a wide range of integration possibilities and tools. Think about being able to test your driver just with the cat tool. This is the UNIX philosophy.[2]Peter H. Salus’ formulation quoted from Wikipedia: Write programs that do one thing and do it well. Write programs to work together. Write programs to handle text streams, because that is a … Continue reading.

Interested in your feedback. Please use the comments form below or contact me directly.

Footnotes

Footnotes
1 You can of course work around this, as I did. On WinCE you can use the globally available named event mechanism, on Linux you can abuse the signals somewhat etc. Some extensions to driver models to be able to notify applications are now also available, but IMHO ugly
2 Peter H. Salus’ formulation quoted from Wikipedia:
  1. Write programs that do one thing and do it well.
  2. Write programs to work together.
  3. Write programs to handle text streams, because that is a universal interface.

Leave a Reply

Your email address will not be published. Required fields are marked *

 

This site uses Akismet to reduce spam. Learn how your comment data is processed.