串口在启动时没有响应

时间:2014-12-27 09:19:53

标签: linux serial-port raspberry-pi

我使用以下功能打开串口

int open_port (unsigned char * port)
{
    int fd = open(port,O_RDWR | O_NOCTTY | O_NDELAY);

    if(fd == -1)
    {
            return PORT_ERR;
    }
    else
    {

            struct termios new_termios;
            struct termios orig_termios;

            tcgetattr(0, &orig_termios);
            memcpy(&new_termios, &orig_termios, sizeof(new_termios));

            cfmakeraw(&new_termios);

            cfsetispeed(&new_termios,B9600);
            cfsetospeed(&new_termios,B9600);

            tcsetattr(fd, TCSANOW, &new_termios);

            return fd;
    }
}

我正在使用Debian(raspberrypi)发行版在Cubieboard2上运行该程序。当我手动运行程序时,它工作正常。但是当程序在init.d脚本启动时启动时,它可以正常运行并执行其他任务(读取和写入文件),但它不会读取串行端口上发送的任何数据。

lsof /dev/ttyUSB1

还显示我的程序正在使用该端口。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

您应该更完整地初始化 termios 结构,例如 cflags ,VMIN和VTIME,如this working code中所示,或使用 perror()系统调用

    rc = tcgetattr(sfd, &tty);
    if (rc < 0) {
        perror("failed to get attr");
        exit (-2);
    }
    savetty = tty;    /* preserve original settings for restoration */

    spd = B115200;
    cfsetospeed(&tty, (speed_t)spd);
    cfsetispeed(&tty, (speed_t)spd);

    cfmakeraw(&tty);

    tty.c_cc[VMIN] = 1;    /* wait for at least 1 char */
    tty.c_cc[VTIME] = 10;  /* or 1 sec after a char */

    tty.c_cflag &= ~CSTOPB;
    tty.c_cflag &= ~CRTSCTS;    /* no HW flow control */
    tty.c_cflag |= CLOCAL | CREAD;

    rc = tcsetattr(sfd, TCSANOW, &tty);
    if (rc < 0) {
        perror("failed to set attr");
        exit (-3);
    }

您还应该测试所有系统调用的每个返回代码,尤其是遇到问题时。


再次查看代码, tcgetattr()的第一个参数显然不正确:

        tcgetattr(0, &orig_termios);

防御性编码(例如验证参数和检查返回调用)有助于捕获可能消耗大量调试时间的这些类型的愚蠢错误。


<强>附录

我想我理解为什么代码似乎在第一种情况下工作,何时启动&#34;手动&#34;来自外壳。
文件描述符值0是STDIN_FILENO的值 因此tcgetattr(0, &orig_termios)语句将检索 stdin termios 值。 (最初我假设你总是有一个未检测到的错误返回,所以结构将不加修改地返回。)大概你在嵌入式系统上执行了这个,其中控制台是一个串口(并且stdin的返回值是一个串口&#39) ; S)。

当我在PC上运行此代码时, cflags 会在禁用CREAD标志的情况下提供,这应该会在以后引起问题。请注意,设置 cflags 是我的建议之一。 VMIN和VTIME分别返回为8和4,但这些异常值不会像CREAD标志那样致命。 stdin视频控制台还有其他不常见的 termios 值,少数会被你的(最小)初始化代码纠正,或者由于使用了非规范模式,大多数异常值都无关紧要。