2015-10-06 5 views
0

Для встроенного устройства (ядро 3.14 и rootfs с OpenEmbedded) я разрабатываю программное обеспечение, которое считывает данные на tty-драйвере. Эта мягкая система работает правильно, когда я тестирую ее на плате. Если я использую nfs-сервер для rootfs, то soft застрял в цикле, который читает файл tty. Я не могу выйти с помощью «ctrl + c», я не могу писать на консоли, и у меня есть такое сообщение «nfs: server 192.168.1.40 не отвечает, все еще пытается»Проблема при чтении tty с nfs rootfs

Есть ли кто-то, кто знает Эта проблема ?

Благодаря

Моя программа:

#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 \000 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; 
} 
+0

Возможно, проблема связана с общей библиотекой. Запустите программу с помощью префикса команды 'strace', чтобы посмотреть, что происходит. Или попробуйте выполнить компиляцию/связывание с опцией '-static'. – sawdust

+0

Я видел что-то внешне похожее, когда вы вызываете устройство, которое начинает извергать сумасшедшее количество прерываний (и/или слишком длительное время в его обработчике прерываний), он заглушает прерывание сетевого контроллера и прекращает работу сетевого трафика ядра ; вы не можете вернуться на консоль, потому что вы сбросили сеть и потеряли корневую файловую систему. – Notlikethat

ответ

0

Я нашел проблему: это плохая настройка на devicetree. Порт UART установил для использования линии CTS/RTS, а PHOT-ethernet подключен к выходу CTS/RTS для управления. Затем этот вывод был использован для 2-х драйверов, и один из них был поврежден. Я изменяю настройку UART, и это работает