[En-Nut-Discussion] select() implementation integrated into svn trunk

Ole Reinhardt ole.reinhardt at embedded-it.de
Sun Dec 8 22:01:37 CET 2013


Hi all,

I finally re-integrated the devnut_select_or branch into the SVN trunk.

The changes mainly implement the posix like select() call, to wait for
multiple filedescriptors getting ready to read or write data.


Purpose:
========

select() can be used for asynchronous communication on several devices
(file descriptors) or sockets at the same time without blocking waiting
for read or write operations.

Until now, Nut/OS did not support waiting for data on several file
descriptors at the same time. You could either wait blocking for an I/O
operation or you had to wait (busy) using non-blocking mode.

In the latter, you had to manually retry a read() or write() operation
until it succeeded.

select() puts your thread to sleep, until a defined event happens on one
filedescriptor out of a set of observed file descriptors.

This way you can easily read from two UARTs at the same time in the same
thread without the need of looping in non-blocking mode, until some data
has been received.

Further you can also easily implement a TCP/IP server which can handle
several requests (sockets) at the same time without the need to create
an own thread for each connection.

select() will help you to save a lot of resources, a you can live with
less threads and do not need to do busy looping.


Supported devices:
==================

* usart: Currently all usart devices (which are based on dev/usart.c)
         are supported.

* sockets: TCP sockets are supported

Support for further devices can be added easily. Take dev/usart.c as an
example.


Samples:
========

As an example I implemented a rs232d version using select() instead of
multiple threads.


Further changes:
================

The architecture of the select() call, needed several changes in the way
filedescriptors are handled. Until now, a filedescriptor on Nut/OS was
an opaque pointer to a NUTFILE structure and a socket descriptor was an
opache pointer to a NUTVIRTUALDEVICE structure.

Instead of directly using these pointers, the new implementation
introduces a lookup table. A filedescriptor now is the index into this
lookup table. So filedescriptors now are counted upward beginning with
0. Closed descriptors are re-used later. This way, filedescriptors now
behave the same way, like on most other OS as well.


Impacts on existing application:
================================

Most existing applications won't ever notice any changes.



I hope people will find the new function usefull. It may help to save
lots of ressources (thread stack) in applications that handle multiple
I/O devices or streams at the same time.

Best regards,

Ole Reinhardt

-- 
kernel concepts GmbH            Tel: +49-271-771091-14
Sieghuetter Hauptweg 48         Mob: +49-177-7420433
D-57072 Siegen
http://www.embedded-it.de
http://www.kernelconcepts.de


More information about the En-Nut-Discussion mailing list