views:

41

answers:

1

Hello,

for the embedded MIPS-based platform I'm implementing a small program to poll GPIO, i.e. I'm using chip vendor's user level GPIO library with basic functionality (open /dev/gpio, read, write pin etc.). The design is straightforward:

int gpio_fd;
fd_set rfds;

gpio_fd = gpio_open(...);

while (1) {
    FD_ZERO(&rfds);
    FD_SET(gpio_fd, &rfds);

    if (select(gpio_fd + 1, &rfds, NULL, NULL, NULL) > 0) {
        if (FD_ISSET(gpio_fd, &rfds)) {
            /* read pins and similar */
        }
    }
}

But I'm facing a serious problem - this application when ran with '&' at the end, i.e. put it in background, consumes 99% CPU, this is obviously because of tight loop, but I observed the similar approach in many networking code and it worked fine.

Am I missing something, can it be a defect of the gpio library ?

Actually, just a single "while(1) ; " does the same effect. Can it be the "natural" behavior of the kernel?

Thanks.

+1  A: 

The select call should block until the file descriptor is readable.

What may be happening is that the device driver does not support the select call, and so it exits immediately rather than blocking.

Another possibility is that the call to gpio_open does not actually give you a real Unix file descriptor. If that were open("/dev/gpio", O_RDWR) or something like that I'd have a lot more faith in it.

Omnifarious
@Omnifarious, I've just skimmed through the gpio device driver and have not found 'poll/select' implementations. I think your assumption is correct, thanks for the hint !
Mark
@Mark - There may not be a specific implementation, just some sort of way for the device driver to signal to the OS that it's readable. If I knew more about Linux device drivers I could give more specific advice than that. I do know though that there are file descriptor types that do not implement any way for poll/select to work on them. For example file descriptors referring to actual on-disk files.
Omnifarious
@Omnifarious, I have just thought that 'select' could be intentionally non implemented in the GPIO library, IMHO gpio file handle is always ready, unlike for example socket. What would you say ?
Mark
@Mark - Well, it makes sense to me. I just hate coming to conclusions without actually knowing for certain. One thing you could check is if the `/* read pins and similar */` code is ever executed. If it isn't, then something interesting is going on for sure because select is returning without setting any bits.
Omnifarious
I ended up with usleep() in the main loop, which did the job - the program now doesn't consume that much CPU. I guess I'd stick with it for awhile, as long as it works :-)
Mark