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:

   while (true) {
        int fd = open("/dev/ser0", O_RDONLY);
        read(fd, buf, BUF_LEN);

        // power down the port
        close(fd);

        sleep(60);
   }

I think this can be done pretty easily by adding a "shutdown" function to the devtab entries:

   typedef struct cyg_devtab_entry {
        // ...
        Cyg_ErrNo        (*lookup)(struct cyg_devtab_entry **tab,
                                   struct cyg_devtab_entry *sub_tab,
                                   const char *name);
        Cyg_ErrNo        (*shutdown)(struct cyg_devtab_entry *tab);
        // ...
   } CYG_HAL_TABLE_TYPE cyg_devtab_entry_t;


The existing macros CHAR_DEVTAB_ENTRY, BLOCK_DEVTAB_ENTRY, etc, can just insert an empty function into the shutdown slot, whereas a new set of macros can accept the shutdown pointer:

   #define
   
CHAR_CLOSABLE_DEVTAB_ENTRY(_l,_name,_dep_name,_handlers,_init,_lookup,_shutdown,_priv)
   ...
   #define
   
BLOCK_CLOSABLE_DEVTAB_ENTRY(_l,_name,_dep_name,_handlers,_init,_lookup,_shutdown,_priv)
   ...

The assumption is that anything done in the shutdown would be undone in a subsequent lookup so that the devices could bre closed then re-opened, and that the shutdown would mark the entry as "unavailable":

   tab->status &= ~CYG_DEVTAB_STATUS_AVAIL;


Assuming that this is a good way to handle this I would need to know how to hook this into the upper-level device and file operations. What would be needed?

Thanks,
Frank

Reply via email to