This is the mail archive of the
ecos-discuss@sourceware.org
mailing list for the eCos project.
Re: Closing/disabling a device
On 12/13/2011 11:57 AM, Bernard Fouché wrote:
Le 12/12/2011 16:14, Frank Pagliughi a écrit :
Hey All,
I'm looking to interface a serial GPS unit to an Atmel AT91 using
eCos. GPS units constantly stream out data at 4800 baud, but I
actually only need to get data from the unit once every few hours to
check time and position. The idea is to have a thread wake up, read
the data, then go back to sleep. The code (ported from Linux) uses
the stdio FILE input routines (fopen, fgetc, etc)
But the data arriving consistently from the GPS is filling up the
buffer in the AT91 serial driver and I can't figure out how to empty
or clear it. I tried CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH, and also
to just close the port (fclose) while the thread is sleeping.
I have started looking at the driver to see if the ability to
flush/drain the buffers is implemented, but I think I would prefer
the second option - closing down the driver to disable interrupts for
that serial port while it's not needed.
I don't see a low-level mechanism to do this. Am I missing something?
Is there low-level code that trickles down to a driver when an
application calls close() or fclose() on a device?
I have the same problem (not for one for a single serial port but 4 of
them plus many other peripherals). eCos starts all the drivers it
knows as soon as it boots. It seems that the solution would be to
implement CYGPKG_POWER in the concerned drivers, however I wonder how
one could do it in a clean way when the UART is the generic 16x5x
serial driver (dunno if AT91 has such a driver) since power control is
specific to each MCU/CPU family. The quick and ugly solution is to
hack the UART registers from the application when the driver has to be
silenced and to restore them later when needed. The CYGPKG_POWER
package is available but AFAIK there is no example of an
implementation in the public eCos repository.
Well, my immediate concern is CPU cycles, but I'm working on a low-power
device, so I will start to worry about the battery in a few months when
the basics are operational. My immediate concern is that the CPU is
spending significant time servicing the interrupt (constantly) for a
device that I intend to read for a few minutes once every six hours!
I could try to disable the interrupt for that serial port from the app,
but it defeats the purpose of encapsulating everything in a device driver.
I think the solution would be a close function for devices:
Cyg_ErrNo cyg_io_close(cyg_io_handle_t handle);
This can halt the device by disabling interrupts, etc. I suppose,
though, that an empty, default implementation that does nothing would
then have to be provided for every driver currently in the repository?
And then that creates the problem of being able to open the device again
after it has been closed. Perhaps the lookup function can just be called
again, but it seems that the device lookup function performs a "query",
"initialize", and "open" function in one call. These could maybe be
split into two or three separate functions?
As you mention, there is also the issue of power-saving modes. Even the
eCos reference manual indicates future modifications:
The lookup() function is called whenever the cyg_io_lookup()
function is called with this device name. The lookup function may
cause the device to come “on line” which would then allow I/O
operations to proceed. Future versions of the I/O system will allow
for other states, including power saving modes, etc.
Devices could offer optional callbacks for power-down and power-up, like
the Linux suspend/resume callbacks. But there would probably need to be
the system-wide power management API to orchestrate the whole thing.
That sounds great, but way beyond what I was thinking at the moment.
Frank
--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss