-   Programming (
-   -   Proper way of polling a device (

george_mercury 12-18-2004 05:49 AM

Proper way of polling a device
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?


Hko 12-18-2004 09: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:

#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: */

/* 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");

/* 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 02: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 02: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.

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
int main()
struct timeval tv;
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*/
printf ("%u%u\n",tv.tv_sec,tv.tv_usec);

dovidhalevi 12-13-2008 02: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 11:59 PM.