This is the mail archive of the
ecos-devel@sourceware.org
mailing list for the eCos project.
Re: Closing devices
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...
Well, several device drivers do postpone "final" initialization until
the lookup() function. But many more don't make a distinction at all.
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.
Sorry. I meant the individual implementations of lookup() calls in the
drivers that do use it. I didn't see any that locked the scheduler
before they started fiddling with registers on the device. Though
admittedly, I didn't look through too many drivers.
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...
I just want to reiterate that I am trying to find a mechanism by which I
can add the capability to write *new* drivers that can close their
devices, without breaking the existing code.
So all the drivers that already exist would work in the exact same way -
they are fully opened after init() and the first call to lookup(), and
they never close.
But if you want to write new drivers that can be closed, or modify
select ones that are already written than there is a mechanism to do so,
even if there are some constraints on using these new devices. For
example, if multiple threads are using a device and one thread calls the
yet-to-be-implemented cyg_io_shutdown() funtion, obviously the device
would be closed for all the threads.
New applications that make use of the device "close" feature would need
to be conscious of this and properly protect and share the closable objects.
It's just maddening to me that when you use the File IO layer, and you
call close(fd) on your device, nothing gets propogated to the driver and
it still keeps chugging away, servicing interrupts, and consuming CPU
time and electric power, even though the application thought that it
"closed" the device.
Does that make sense?
Frank