This is the mail archive of the
ecos-devel@sourceware.org
mailing list for the eCos project.
Re: Closing devices
Le 20/06/2012 15:37, Frank Pagliughi a écrit :
On 06/19/2012 09:36 AM, Bernard Fouché wrote:
IMHO, beside a shutdown mechanism, one also needs to be able to get
control of what's going on between the hardware drivers and the
packages that use them. A low level application initialization
routine should be able to register callbacks to be triggered when
events occur in the drivers and in the package code managing them,
hence the application could handle the board or MCU specifically when
some expected event occurs. Today only part of this could be done in
platform code, but in such a way that it is very close to application
code, however without any clearly defined API.
Bernard
Thank you, Bernard.
I had not thought about reference counting in the drivers from
multiple lookup() calls, but yes, that would probably be required.
In this context - closable devices - it seems unfortunate that the
lookup() function has the side effect of opening the device. I can
imagine that some code might just be trying to get the devtab entry
for other purposes. Perhaps there needs to be another search function
that returns the entry without triggering the lookup() function?
The problem seems yet more general: anything can call cyg_io_lookup()
and since the API doesn't have from the beginning a function call to
report 'I don't need the devtab entry anymore', then even counting the
number of times lookup() is called won't help much: my suggestion do
move hw init code from init() to lookup() is very wrong...
Does the file I/O code serialize calls to lookup? I examined a few
device drivers the implement lookup() and don't see any explicit
mechanism to prevent race conditions, but that could be due to the
nature of the calls not requiring it. I suppose the drivers should
lock the scheduler when manipulating this new reference count.
Since when calling lookup() you mostly only get a reference to the
devtab entry, there isn't any race condition. If you look at
ser_16x5x.c, when lookup() is called, it calls serial_init() in the
upper layer, in serial.c . In serial.c, the concerned channel is
initialized only once by serial_init(), for whatever lower driver calls
it. I guess this has been done to allow calling lookup() at any time,
multiple times.
I acknowledge that the close of the low-level driver may not be
adequate, and the power management and GPIO pins are problematic.
I saw a recent discussion on the list about layering serial drivers,
and started wondering if the target-level issues might be handled
through layered drivers. Could I, perhaps, make a target-specific
driver that intercepted the shutdown() calls, called the lower-level
driver (which might just turn off the interrupt), then have the
upper-layer driver power-down the device and tri-state the GPIO pins?
Would that be similar to the application callbacks that you mention?
If not, please give more detail about what you're thinking in this
regard.
Well my callback scheme seems all wrong: the more I look, the more it
seems that nothing is able to track down exactly the hw driver use made
by upper layers (packages or application code). Since the application
needs to handle many details like GPIO pin setup, then it can also mask
the interrupt ;-). So much for a layered software model with low level
stuff done only in low level code...
Now if you tristate the pins, you are normally disabling the UART
feature since you put the pins in GPIO mode. And since the UART cell is
disconnected from the pins, it won't generate any interrupt: this is
what I do today to avoid modifying ser_16x_5x, but the UART cell remains
powered in the MCU which is a waste. I guess I'll end making my own copy
of ser_16x_5x for my specific target, and add _set_config() options to
put the driver in whatever state is required to disable or enable it.
Bernard