使用 nfs rootfs 读取 tty 时出现问题

Issue when reading tty with nfs rootfs

对于嵌入式设备(内核 3.14 和带有 OpenEmbedded 的 rootfs),我开发了一个软件来读取 tty 驱动程序上的数据。当我在电路板上测试时,该软件运行正常。 如果我为 rootfs 使用 nfs 服务器,则软件会卡在读取 tty 文件的循环中。我不能用 'ctrl+c' 出去,我不能在控制台上写,我有这样的消息“nfs:服务器 192.168.1.40 没有响应,仍在尝试”

有人知道这个问题吗?

谢谢

我的软件:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/poll.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <time.h>

#define FALSE   0
#define TRUE    1

int print_help (int argc, char *argv[])
{
    printf("Test program for uart reception\n");
    printf("Usage :\n");
    printf("\t%s [-h -D -c]\n", argv[0]);
    printf("\t-D : use this tty device\n");
    printf("\t-c : control data to extract the trame\n");
    printf("\t-h : print help\n");
    return 0;
}

int wait_flag = TRUE ;

void signal_handler_IO (int status)
{
     //printf("received data from UART.\n");
     wait_flag = FALSE;
}

/*
 * The values for speed are B115200, B230400, B9600, B19200, B38400, B57600,
 * B1200, B2400, B4800, etc. The values for parity are 0 (meaning no parity),*
 * PARENB|PARODD (enable parity and use odd), PARENB (enable parity and use even),
 * PARENB|PARODD|CMSPAR (mark parity), and PARENB|CMSPAR (space parity).
 */
int set_interface_attribs (int fd, int speed, int parity)
{
    struct sigaction saio;
        struct termios tty;
        memset (&tty, 0, sizeof tty);


    /***/
    saio.sa_handler = signal_handler_IO;
    saio.sa_flags = 0;
    saio.sa_restorer = NULL;
    sigaction(SIGIO, &saio, NULL);

    fcntl (fd, F_SETFL, FNDELAY|FASYNC);
    fcntl (fd, F_SETOWN, getpid());
    /***/

        if (tcgetattr (fd, &tty) != 0)
        {
                printf("error from tcgetattr\n");
                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 [=10=]0 chars
        tty.c_iflag &= ~IGNBRK;         // disable break processing
        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)
        {
                printf("error from tcsetattr\n");
                return -1;
        }
        return 0;
}

/*
 * "Blocking" sets whether a read() on the port waits for the specified number
 * of characters to arrive. Setting no blocking means that a read() returns
 * however many characters are available without waiting for more, up to the
 * buffer limit.
 */
void set_blocking (int fd, int should_block)
{
        struct termios tty;
        memset (&tty, 0, sizeof tty);
        if (tcgetattr (fd, &tty) != 0)
        {
                printf ("error from tggetattr\n");
                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)
                printf ("error setting term attributes\n");
}


int main(int argc, char *argv[]) {
    int i, j, k;
    int fd;
    char c;
    signed char index_trame = -1;
    char trame[6];
    char initChaine[30] = "Frame received on uart :";
    char *ttyDevice = "/dev/ttyAPP0";
    char chaineCar[100];
    char receptCar[6];
    char buf[255];
    char processData[512];
    char restofData[6];
    int sizeofData = 0;
    char ctrl_trame = 0;
    int loop = 0;
    int ret = 0;
    int count = 0;
    FILE* saveFile = NULL;

    /* Parse arguments */
    if (argc < 0 || argc > 4) {
        printf("Invalid number of argument\n");
        print_help(argc, argv);
        return 0;
    }
    j = 0;
    for (i=1; i<argc; i++) {
        if (argv[i][0] == '-') {
            for (k=1; argv[i][k]; k++) {
                switch (argv[i][k]) {
                    case 'D':
                        ttyDevice = argv[i+1];
                        printf("Use %s device\n",ttyDevice);
                        break;
                    case 'c':
                        ctrl_trame = 1;
                        break;
                    case 'h':
                        print_help(argc, argv);
                        break;
                    default:
                        printf("Wrong option: -%c\n", argv[i][k]);
                        print_help(argc, argv);
                        return 0;
                }
            }
        } else {
        }
        j ++;
    }/**/

    /*run program*/
    printf(" Read serial port V0.6\n");

    saveFile = fopen("receptUart.txt", "w+");
    index_trame = 0;

    /* Ouverture de la liaison serie */
    if ( (fd=open(ttyDevice, O_RDONLY | O_NOCTTY | O_SYNC)) == -1 ) {
        printf("error open %s\n", ttyDevice);
        return -1;
    }

    set_interface_attribs (fd, B2400, 0);
    set_blocking (fd, 1);

    do {
            if (wait_flag == FALSE) {
                ret = read(fd, buf, 255);
                if (ctrl_trame) {
                    for (i=0;i<ret;i++)
                        processData[sizeofData+i] = buf[i];
                    sizeofData += ret;
                    for (i=0;i<sizeofData;i++) {
                        if ((sizeofData - i) < 6) {
                            break;
                        }
                        else if (processData[i] == 0xfa) {
                            count++;
                            printf ("Received frame n %d :", count);
                            for (j=0;j<6;j++) {
                                trame[j]=processData[i];
                                printf(" h%02x", processData[i]);
                                i++;
                            }
                            i--;
                            printf("\n");
                        }
                    }
                    for(j=i;j<sizeofData;j++)
                        processData[j-i] = processData[j];
                    sizeofData -= i;
                }
                else {
                    printf ("%i data received :", ret);
                    for (i=0;i<ret;i++) {
                        printf(" h%02x", buf[i]);
                    }
                    printf("\n");
                }
                wait_flag = TRUE;
            }
    }
    while (1);

    close(fd);
    printf("GoodBye\n");

    return EXIT_SUCCESS;
}

我发现了问题:devicetree 上的设置有问题。 UART 端口设置为使用 CTS/RTS 线路,以太网 PHY 连接到 CTS/RTS 引脚以进行控制。然后这个引脚被用于 2 个驱动程序,其中一个崩溃了。 我更改了 UART 设置,它起作用了