如何设置串口的阻塞读取会在SIGALRM上中断?

时间:2016-04-27 14:27:55

标签: c serial-port

嗨我(不成功地)试图设置这个东西,但是有太多的旗帜,我迷失了它。我需要做的是 -

  • 打开具有指定波特率,奇偶校验和停止位的串行端口。

  • 在指定的时间内进行多次读写(在 毫秒)。

  • 如果时间到期,请再次启动(使用不同的数据......)。如果 时间不会过期,剩下的剩余时间都会睡觉。

这是我到目前为止所做的:

像这样设置串口:

int serial_set_attributes(int terminal_file_descriptor, int speed, short int databits, short int stopbit, short int parity, short int RTS)
{
        struct termios tty;

        memset (&tty, 0, sizeof(tty));

        if (tcgetattr (terminal_file_descriptor, &tty) == 0)
        {
                cfsetospeed (&tty, speed);
                cfsetispeed (&tty, speed);

                /* test */


                // disable IGNBRK for mismatched speed tests; otherwise receive break
                // as \000 chars
                tty.c_iflag &= ~IGNBRK;                             // ignore break signal
                tty.c_iflag &= ~(IXON | IXOFF | IXANY | ICRNL);     // shut off xon/xoff ctrl and mapping CR to NL on input.

                tty.c_oflag = 0;                                    // no remapping, no delays

                tty.c_cflag &= ~CSIZE;
                tty.c_cflag |= databits;
                tty.c_cflag |= (CLOCAL | CREAD);                    // ignore modem controls,
                tty.c_cflag &= ~(PARENB | PARODD);
                tty.c_cflag |= parity;
                tty.c_cflag &= ~CSTOPB;
                //tty.c_cflag |= stopbit;
                if (RTS)
                        tty.c_cflag |= CRTSCTS;
                else
                        tty.c_cflag &= ~CRTSCTS;

                tty.c_lflag = 0;            // no signaling chars, no echo,
                tty.c_cc[VMIN]  = 0;        // read doesn't block
                tty.c_cc[VTIME] = 10;       // 0.5 seconds read timeout

                if (tcsetattr (terminal_file_descriptor, TCSANOW, &tty) == 0)
                {
                        return 0;
                }
        }
        return -1;
}

像这样设置闹钟:

static volatile int g_alarm_flag=0;
static void alarm_handler(int signum){
    printf("alarm\n"); //I know I should not do this, just for debug
    g_alarm_flag = 1;
}

int set_alarm(useconds_t interval){

    struct sigaction sa = {.sa_handler = alarm_handler};
    if (sigaction(SIGALRM, &sa, NULL) == -1){perror("Cant set up signal handling on alarm\n");exit(1);}
    g_alarm_flag = 0;
    struct itimerval it_val;
    it_val.it_value.tv_sec =     interval/1000000;
    it_val.it_value.tv_usec =    interval % 1000000;   
    it_val.it_interval = it_val.it_value; 
    if (setitimer(ITIMER_REAL, &it_val, NULL) == -1) {
        perror("error calling setitimer()");
        exit(1);
    }
    return 0; 
}

并按照以下方式启动程序:

int output_fd = open(OUTPUT,O_RDWR | O_NOCTTY);
if (output_fd < 0){perror("Cant open a serial port");
//    exit(1);
}
set_alarm(60000);
serial_set_attributes(output_fd, BAUDRATE, CS8, 1, 0, 0);
printf("here63\n");
char a;
printf("%d\n",(int)read(output_fd,&a,1));

使用此设置,警报不会仅在{VTIME标志中的时间内中断read()。 我无法使用select(),因为我需要在所需的时间内执行多项操作。代码最后一行的read()返回0(当行上没有任何内容时)。我的解决方案here有点讨厌...... 我的系统是Linux mint 64位,使用gcc。

0 个答案:

没有答案