LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   Proper way of polling a device (http://www.linuxquestions.org/questions/programming-9/proper-way-of-polling-a-device-267662/)

george_mercury 12-18-2004 04:49 AM

Proper way of polling a device
 
Hi!
I have to read data from serial port, and so I have implement some kind for data polling rutene for the ttyS0. I know how to check if data has arrived in buffer, and I know how to read that data, but how do I write the data polling rutene to be as low CPU resource consuming as possible?

If I write a while loop and an ioctl in it to check if data has arrived, than this would probably consume almost all CPU resources. Plus I have no way of checking for a timeout ( in case the device isn't responding ). I could use the signal system call, but I don't know how it's suitable for data polling, although the man page says that it is.

Can anyone gime me some points how I should write my data polling rutene?

George

Hko 12-18-2004 08:23 AM

It's possible to have your program sleep completely (i.e. not using any CPU) until one of the control-lines of the serial port changes state from low-->high or high-->low (or a signal has arrived). So if you can use this in your program, you don't have to poll at all.

Assuming fd is a valid file descriptor that has /dev/ttyS0 (or another serial port) open for reading, you can do:
Code:

#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <sys/file.h>
#include <linux/serial.h>

/* .... */

int mask

/* We want to wait until either one of the following control lines changes state: */
mask = TIOCM_CAR | TIOCM_DSR | TIOCM_CTS | TIOCM_RNG;

/* The ioctl() call below sleeps and does not return until one of
 * the control lines metioned in mask changes state.
 * or a signal was received, or an error has ocurred.
 */
if (ioctl(fd, TIOCMIWAIT, mask) == -1) {
    if (errno == EINTR) {
        /*
        * Woken up by a signal, do something, maybe just
        * resume waiting again.
        */
    } else {
        /* Other error, report it and exit */
        perror("ioctl - TIOCMIWAIT");
        exit(1);
    }
}

/* Once we get here, one of the control lines in 'mask' has changed state */
/* Act accordingly from here */

Hope you can use this for your purpose.

bm17 12-18-2004 01:31 PM

Check out the functions cfmakeraw() and tcsetattr(). These should allow you to fine-tune the timing parameters of the serial line. I usually do serial communication in a subthread. This allows me to minimize scheduling latency in case the exact time of data arrival is important.

krisi 12-18-2004 01:48 PM

If you like to wait and than to apply the loop again ,so put the sleep() function somwere in the loop and it's ok.
In the brackets use a number to set the number of seconds until the loop continue/start again.
Example:

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
int main()
{
struct timeval tv;
gettimeofday(&tv,NULL);
tv.tv_usec=(tv.tv_usec+500)/1000;
printf ("%u%u\n",tv.tv_sec,tv.tv_usec);
sleep(3); /* In this line the program will stop for 3 seconds and than it wil continue*/
gettimeofday(&tv,NULL);
tv.tv_usec=(tv.tv_usec+500)/1000;
printf ("%u%u\n",tv.tv_sec,tv.tv_usec);
exit(0);
}

dovidhalevi 12-13-2008 01:13 PM

How to STOP the thing
 
I am working on a kde4-plasma applet that monitors a modem for telephony usage. So I have this very loop, lifted from xingd, waiting for rings. Works like a charm.

Problem is, when plasma or the test applet viewer want to close the program, this wait thread is still running. No very nice behavior indeed.

I tried placing a simple break in the EINTR code. Nothing changed.

xringd had set a lot of singals with handlers and such. Is this what I need to do? I do not need a specific handler as such if I can simply test the signal that triggered the EINTR. Question is was there such a signal when the program was closed, objects destroyed, or need I set it?


All times are GMT -5. The time now is 12:27 PM.