|
Finding the right evolutionary niche
This article was contributed by Neil Brown
It has been
observed
that "Linux is evolution, not intelligent design". Evolution may seem
to be an effective way to allow many developers to work in parallel to
produce a coherent whole, but it does not necessarily produce a well
structured elegant orthogonal design. While the developers do try to
limit the more overt duplication of functionality there are often
cases where functionality overlaps, as the
ongoing
reflections
on RAID unification bear witness.
A different perspective on the challenges associated with this
tendency to concurrent evolution can be seen if we examine the『timed
gpio』piece of the various attempts to
bring Android closer to mainline.
The Android developers appear to have made a deliberate decision to
add functionality as completely separate drivers rather than modifying
existing drivers. This undoubtedly makes it easier for them to
forward-port to newer versions of the kernel, and also provides the
setting for a simple case study when the attempt is made to merge the
functionality upstream.
The "timed gpio" driver is really more than just a
driver. Firstly it includes a new "device class" named "timed output"
which can drive an arbitrary output for a set period of time (in
milliseconds). Secondly it includes a driver for this class which
drives a given GPIO (General Purpose Input/Output) line according to
the rules for the class. So we should really be thinking of『timed
output』as the required functionality.
The primary purpose for this functionality is apparently to control a
vibrator, as
used in mobile phones to alert the owner to conditions such as an
incoming call. On the hardware side, the vibrator is connected to some
GPIO line, and can be turned on or off by asserting or de-asserting
that line.
The first query that would be raised about such a possible submission (after
checking for white-space errors of course) is whether the Linux kernel
really needs another device class, or whether some existing device
class can be enhanced to meet the need. This is notably a different
attitude to the traditional Unix "tools" approach where the preferred
first step is to combine existing tools to achieve a goal, and only
merge the functionality into those tools when it has been proved.
With Linux driver classes there is no general mechanism for combining existing
drivers - there is no equivalent of the "pipe" or the standard data
format of "new-line separated lines of text" to aid in combining
things. So the only way to avoid continually reinventing from scratch
is to incrementally enhance existing functionality.
When casting around for existing device classes the first possibility
is clearly the "gpio" class. This allows direct control of GPIO lines
and can (when the device is suitably configured) drive lines as
outputs, sample them as inputs, and even detect level changes using
poll(). A simple solution for a vibrator would be to use "gpio" as it
is, and leave the timing up to user space. That is, some daemon could
provide a service to start the vibrator and then stop it shortly
afterward.
One problem with this approach is that it is not fail-safe.
User-space programs are generally seen as less reliable than the
kernel. The daemon could be killed while the vibrator is left on and
it would then stay on, wasting quite a lot of battery capacity and
irritating the user.
How much this is a serious issue is unclear, but it does seem to have
been important enough to the Android engineers to justify writing a
new driver so it should not be quickly dismissed.
Adding a timer function to the "gpio" class might be possible, though
is probably a bad choice. Timing is not intrinsic to the concept of
GPIOs and, if it were allowed into the class, it would be difficult to
justify not letting all sorts of other arbitrary features in. So it
seems best to keep it out, and in any case there is another class which
already supplies a very similar concept.
The "leds" class already performs a variety of timed output functions.
It is intended for driving LEDs and can set them or "on" or "off" or,
where supported, a range of brightness values in between. "leds" has a
rich "trigger" mechanism so that an LED can be made to flash depending
on the state of various network ports, the activity of different
storage devices, or the charge status of different power supplies. They
can also be triggered using a timer. This class already can drive a
GPIO on the assumption that it applies power to an LED, and could
easily be used to apply power to a vibrator as well (maybe we would
have to acknowledge that it was a Lively Energetic Device to get past
the naming police).
There is a precedent for this, as the original Openmoko phones - the Neo
and the Freerunner - use a "leds" driver to control the vibrator, as
does the Nokia N900.
Unfortunately the "leds" class doesn't actually meet the need, as it is
not possible to start the timer without passing through a state where
a user-space crash would leave the vibrator running endlessly. When
the "timer" trigger is enabled it starts with default values of 500ms
for "on" and 500ms for "off" which can then be adjusted.
If the application fails before resetting the "off" time, the vibrator will
come back on shortly. So for the
purposes of failing safe it is no better than the "gpio" class.
In the hope of addressing this - which could be seen as a design bug
in the "leds" class - Shuah Khan recently posted a
patch
to add a "timer-no-default" trigger and also to allow the "off" time to
be set to "forever". This would enable using the "leds" timer mechanism
to drive a vibrator with no risk of it staying on indefinitely.
Out of the discussion on the linux-kernel list arose the observation - not
mentioned
before in the discussions on mainlining Android - that there is another
class that can be and is being used to drive vibrators. This is,
somewhat surprisingly, the "input" subsystem.
Choosing a name for a subsystem that will not go out-of-date is a recurring
problem, which
can be seen in, for example, the "scsi" subsystem of Linux;
that subsystem now also
drives SATA disks and USB attached storage. Similarly the "input"
subsystem is also used for some outputs such as the LEDs on a keyboard
(those that light "caps lock" or "num lock"), the speaker in the PC
platform that is used for "beeping", and, more recently, for the
force-feedback functionality of some joysticks and other game
controllers. As Dmitry Torokhov (current maintainer of the "input"
class) suggests,
it is better to think of it as an "hid" (Human Interface Device)
class which happens to be named "input".
The force feedback framework in the input class provides for a range of
physical or "haptic" signals to be sent back to the user of the
device, one of which is the "rumble" which is really another name for
a vibration. This effect can be triggered in various ways and
importantly can be set to be activated for a fixed period of time.
That is, it can operate in a fail-safe mode.
So it seems that a device class suitable for vibrators already
exists. It isn't able to drive simple GPIO lines yet, however that is
unlikely to be far away. Dmitry has already
posted
a patch to create a rumble-capable input device from PWM (pulse
width modulation) hardware, and doing the same for a GPIO is a very
small step.
It is interesting that, though this question has been raised at various
times in various forums over the last year or so, this seems to be the
first time that using an input device with a rumble effect has been
suggested in the same context. It highlights the fact that there is
so much functionality in Linux that nobody really knows about all of
it, and finding the bit that meets a particular need is not always
straightforward. It also highlights the observation, which has been
made many times before, that sometimes the best way to get a useful
response is to post a credible patch. People seem to be more keen to
take a patch seriously than to enter into a less-focused discussion.
Whether the Android team will come on board with the rumble effect and
drop their timed gpio patch is not yet known. What is known is that
finding the right niche for new functionality does require
persistence.
(Log in to post comments)
|