简体   繁体   English

C在Linux中无法从串行端口读取数据

[英]C Failing to Read Data from Serial Port in Linux

I'm using the following C code borrowed from here: how to open, read, and write from serial port in C 我正在使用从这里借来的以下C代码: 如何从C中的串行端口打开,读取和写入

with some slight modifications so that the program waits for keyboard input, then writes this data to a serial port and waits to read it back. 进行一些细微的修改,以便程序等待键盘输入,然后将此数据写入串行端口并等待将其读回。 Here's my code: 这是我的代码:

#include <errno.h>
#include <termios.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>



int
set_interface_attribs (int fd, int speed, int parity)
{
        struct termios tty;
        memset (&tty, 0, sizeof tty);
        if (tcgetattr (fd, &tty) != 0)
        {
                error_message ("error %d from tcgetattr", errno);
                return -1;
        }

        cfsetospeed (&tty, speed);
        cfsetispeed (&tty, speed);

        tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;     // 8-bit chars
        // disable IGNBRK for mismatched speed tests; otherwise receive break
        // as \000 chars
        tty.c_iflag &= ~IGNBRK;         // ignore break signal
        tty.c_lflag = 0;                // no signaling chars, no echo,
                                        // no canonical processing
        tty.c_oflag = 0;                // no remapping, no delays
        tty.c_cc[VMIN]  = 0;            // read doesn't block
        tty.c_cc[VTIME] = 5;            // 0.5 seconds read timeout

        tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl

        tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
                                        // enable reading
        tty.c_cflag &= ~(PARENB | PARODD);      // shut off parity
        tty.c_cflag |= parity;
        tty.c_cflag &= ~CSTOPB;
        tty.c_cflag &= ~CRTSCTS;

        if (tcsetattr (fd, TCSANOW, &tty) != 0)
        {
                error_message ("error %d from tcsetattr", errno);
                return -1;
        }
        return 0;
}

void
set_blocking (int fd, int should_block)
{
        struct termios tty;
        memset (&tty, 0, sizeof tty);
        if (tcgetattr (fd, &tty) != 0)
        {
                error_message ("error %d from tggetattr", errno);
                return;
        }

        tty.c_cc[VMIN]  = should_block ? 1 : 0;
        tty.c_cc[VTIME] = 5;            // 0.5 seconds read timeout

        if (tcsetattr (fd, TCSANOW, &tty) != 0)
                error_message ("error %d setting term attributes", errno);
}


int main{

    char *portname = "/dev/tty0"
    int fd = open (portname, O_RDWR | O_NOCTTY | O_SYNC);
    if (fd < 0)
    {
            error_message ("error %d opening %s: %s", errno, portname, strerror (errno));
            return;
    }

    set_interface_attribs (fd, B115200, 0);  // set speed to 115,200 bps, 8n1 (no parity)
    set_blocking (fd, 0);                // set no blocking

    while (1){
        char data[20];
        if (fgets(data, sizeof data, stdin)){
            int m = write(fd, data, sizeof data);
            printf("%d chars written\n", m);
            char buf[100];
            sleep(10);
            int n = read (fd, buf, sizeof buf);
            printf("%d chars read", n);
        }
    }
}

The problem is that while the keyboard input is successfully written to serial file, after sleeping for 10 seconds the program still reports that it has read 0 chars. 问题在于,尽管键盘输入已成功写入串行文件,但在睡眠10秒钟后,程序仍报告其已读取0个字符。 Why is this? 为什么是这样? Do I need to actually have a physical device waiting on the other end of the port which receives the data and returns something, or is it fine to write to and read from the serial port with the same program? 我是否真的需要一个物理设备在端口的另一端等待接收数据并返回某些内容,还是可以使用同一程序在串行端口进行读写操作? Thanks in advance for any help! 在此先感谢您的帮助!

EDIT: 编辑:

Ok so now I've created a second program which waits for data on the serial port sent by the above program, but this program is still unable to read the data sent to it. 好的,现在我创建了第二个程序,等待上述程序发送的串行端口上的数据,但是该程序仍然无法读取发送给它的数据。 Here's the code: 这是代码:

#include <errno.h>
#include <termios.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>



int
set_interface_attribs (int fd, int speed, int parity)
{
        struct termios tty;
        memset (&tty, 0, sizeof tty);
        if (tcgetattr (fd, &tty) != 0)
        {
                error_message ("error %d from tcgetattr", errno);
                return -1;
        }

        cfsetospeed (&tty, speed);
        cfsetispeed (&tty, speed);

        tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;     // 8-bit chars
        // disable IGNBRK for mismatched speed tests; otherwise receive break
        // as \000 chars
        tty.c_iflag &= ~IGNBRK;         // ignore break signal
        tty.c_lflag = 0;                // no signaling chars, no echo,
                                        // no canonical processing
        tty.c_oflag = 0;                // no remapping, no delays
        tty.c_cc[VMIN]  = 0;            // read doesn't block
        tty.c_cc[VTIME] = 5;            // 0.5 seconds read timeout

        tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl

        tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
                                        // enable reading
        tty.c_cflag &= ~(PARENB | PARODD);      // shut off parity
        tty.c_cflag |= parity;
        tty.c_cflag &= ~CSTOPB;
        tty.c_cflag &= ~CRTSCTS;

        if (tcsetattr (fd, TCSANOW, &tty) != 0)
        {
                error_message ("error %d from tcsetattr", errno);
                return -1;
        }
        return 0;
}

void
set_blocking (int fd, int should_block)
{
        struct termios tty;
        memset (&tty, 0, sizeof tty);
        if (tcgetattr (fd, &tty) != 0)
        {
                error_message ("error %d from tggetattr", errno);
                return;
        }

        tty.c_cc[VMIN]  = should_block ? 1 : 0;
        tty.c_cc[VTIME] = 5;            // 0.5 seconds read timeout

        if (tcsetattr (fd, TCSANOW, &tty) != 0)
                error_message ("error %d setting term attributes", errno);
}


int main{

    char *portname = "/dev/tty0"
    int fd = open (portname, O_RDWR | O_NOCTTY | O_SYNC);
    if (fd < 0)
    {
            error_message ("error %d opening %s: %s", errno, portname, strerror (errno));
            return;
    }

    set_interface_attribs (fd, B115200, 0);  // set speed to 115,200 bps, 8n1 (no parity)
    set_blocking (fd, 0);                // set no blocking


    char buf[20];
    int n = 0;
    while (n == 0){
        n = read(fd, buf, sizeof buf);
    }
    printf("%d chars read\n", n);

    return 0;

}

When I run this and right afterwards run the first program and write some data to the serial port, this program just stays in the while loop forever and never reads in any data. 当我运行此程序并随后运行第一个程序并将一些数据写入串行端口时,该程序将永远停留在while循环中,并且从不读取任何数据。 Help? 救命?

No , you do not need to actually have a physical device waiting on the other end of the port which receives the data. ,您不需要在接收数据的端口的另一端实际等待物理设备。

Yes , you need to actually have a physical device waiting on the other end of the port to return something. 是的 ,您实际上需要在端口的另一端等待一台物理设备来返回内容。 (It could be a wire looping transmit and receive (pins 2 & 3 on 9-pin.) (这可能是导线循环发送和接收(9针上的针2和3)。

Yes , it fine to write to and read from the serial port with the same program. 是的 ,可以使用同一程序在串行端口进行读写操作。

As to " Why is this?": there is nothing sending data to your program via the serial interface. 关于“ 这为什么 ?”:没有任何东西通过串行接口发送数据到您的程序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM