This is the mail archive of the ecos-devel@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Closing devices


On 06/19/2012 09:36 AM, Bernard Fouché wrote:

Le 18/06/2012 16:34, Frank Pagliughi a écrit :
Hello All,

I'm looking for ideas on how to close and re-open devices on eCos. The needs for this are (1) to support swappable/removable devices, (2) to have a consistent way to put devices into a low-power state when they are not being used, and (3) to prevent devices from using the CPU when they are not needed.

On a current project for a battery-powered device, I have a need for all of this: a CompactFlash that can be removed; a GPS that sends data constantly, but only needs to be read once every few hours; and many of the peripherals need to be put in a consistent state prior to going into a low power mode.

I've been able to accomplish all of this with ugly application-level code, but thought that a much better solution would be to propagate the close() call of a devfs device down to the driver, so you could do this:
Hello Frank,

I have the exact same needs and I also made my changes in the application code at the moment, for the same reasons. However if we look at the low level details:

- The Init() function of a driver is called at boot time, a time you don't want to initialize much things if you don't know yet if you'll need them a few moment later. init() isn't visible from anything else than the startup procedure of eCos.

- lookup() is called when the application 'opens' a channel of a driver. Usually nothing much is done at low level since the assumption is that init() made the job before. However it's possible to rework the drivers to change this and future drivers could be written with this in mind.

- Since a devtab entry can be looked up many times, even by different threads, it is probably necessary to have a driver to count the number of times it is looked up and the number of times it is shutdown. When the count reaches zero, then the driver knows it can power off things.

- drivers that are shared between different targets do not know about target specific features, by design they focus on the parts that are common to all targets they can be used on. Such a driver expects that the MCU pin setup (and other details) has already been done earlier in the board init code, it has no way to query something to run again this procedure. If you need to close an UART, you probably also want to reconfigure the MCU's pins. You may also want to power off the UART (from the MCU point of view) if the MCU allows it. So even if shutdown() is implemented, such a driver wouldn't do much regarding power savings, at best it could only mask or disable an interrupt, the most important savings must be handled elsewhere. Even if the board init code could be accessible, how one could ask this code to perform a partial initialization? (for instance to avoid reconfiguring all UARTs while a single one is to be re-initialized).

- power management is very MCU/board/application specific and project specific code will have different things to do. For instance if you have an external RS232 device, you save more power by turning off the level converter between the UART and the RS232 connector. Of course it's better to be able to turn off both the UART in the MCU and the level converter. If you don't have a level converter, you may want to reconfigure the MCU pins, for instance to avoid having power drawn from the UART TX pin if the connected device is also powered off. You may also want to setup pull-up/down on the pins to stabilize the signals: it means changing the pin setup of the MCU to change them from 'UART' to 'GPIO' and then configure the pull up/down feature. You may also want to change peripheral clock settings for disabled peripheral in the MCU, to spare a bit more so you have to re configure also clocking registers when the peripheral must come back in line.

- There is CYGPKG_POWER. Each driver implementing some kind of power management can be modified to support this package. But I don't see how this package can interact with the platform code layer. How can a target using a shared driver can make use of this package for the shared driver?

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?

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.

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.

Thanks,
Frank



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]