2013-05-21 159 views
2

我有一個問題,我的uart閱讀(覆盆子pi)。它工作正常,但它停在一個循環,並等待數據... 我做了一個選項O_NDELAY,但即使如此停止。閱讀UART塊

我使用兩個終端窗口:

  • 一個用於UART方案
  • 在第二i寫:

    echo '123445' > /dev/ttyAMA0 (覆盆子裨UART端口)

完整代碼如下。

#include <stdio.h> 
#include <unistd.h>    //Used for UART 
#include <fcntl.h>    //Used for UART 
#include <termios.h>  //Used for UART 


int main(int argv, char * argc[]) 
{ 
// Setting Up The UART 

    //------------------------- 
    //----- SETUP USART 0 ----- 
    //------------------------- 
    //At bootup, pins 8 and 10 are already set to UART0_TXD, UART0_RXD (ie   the alt0 function) respectively 
    int uart0_filestream = -1; 

    //OPEN THE UART 
    //The flags (defined in fcntl.h): 
    // Access modes (use 1 of these): 
    //  O_RDONLY - Open for reading only. 
    //  O_RDWR - Open for reading and writing. 
    //  O_WRONLY - Open for writing only. 
    // 
    // O_NDELAY/O_NONBLOCK (same function) - Enables nonblocking mode. When set read requests on the file can return immediately with a failure status 
    //           if there is no input immediately available (instead of blocking). Likewise, write requests can also return 
    //           immediately with a failure status if the output can't be written immediately. 
    // 
    // O_NOCTTY - When set and path identifies a terminal device, open() shall not cause the terminal device to become the controlling terminal for the process. 


    uart0_filestream = open("/dev/ttyAMA0", O_RDWR | O_NOCTTY | O_NDELAY);  //Open in non blocking read/write mode 
    if (uart0_filestream == -1) 
    { 
     //ERROR - CAN'T OPEN SERIAL PORT 
     printf("Error - Unable to open UART. Ensure it is not in use by another application\n"); 
    } 

    //CONFIGURE THE UART 
    //The flags (defined in termios.h - see http://pubs.opengroup.org/onlinepubs/007908799/xsh/termios.h.html): 
    // Baud rate:- B1200, B2400, B4800, B9600, B19200, B38400, B57600, B115200, B230400, B460800, B500000, B576000, B921600, B1000000, B1152000, B1500000, B2000000, B2500000, B3000000, B3500000, B4000000 
    // CSIZE:- CS5, CS6, CS7, CS8 
    // CLOCAL - Ignore modem status lines 
    // CREAD - Enable receiver 
    // IGNPAR = Ignore characters with parity errors 
    // ICRNL - Map CR to NL on input 
    // PARENB - Parity enable 
    // PARODD - Odd parity (else even) 
    struct termios cfg; 

    //get existing configuration setup 
    tcgetattr(uart0_filestream, &cfg); 

    //fcntl(deviceFD, F_SETFL, FNDELAY); 
    fcntl(uart0_filestream, F_SETFL, 0); 

    ////set both incoming and outgoing baud rates... 
    cfsetispeed(&cfg, B115200); 
    cfsetospeed(&cfg, B115200); 

    cfg.c_cflag |= (CLOCAL | CREAD); 

    ////8N1 (8 data bits, No parity, 1 stop bit) 
    cfg.c_cflag &= ~PARENB; 
    cfg.c_cflag &= ~CSTOPB; 
    cfg.c_cflag &= ~CSIZE; 
    cfg.c_cflag |= CS8; 

    cfg.c_cflag &= ~CRTSCTS; //~CNEW_RTSCTS; //disable hardware flow control 

    //use RAW unbuffered data mode (eg, not canonical mode) 
    cfg.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG | IGNBRK); 

    cfg.c_iflag &= ~(IGNPAR | IXON | IXOFF | IXANY); 

    //raw (unprocessed) output mode 
    cfg.c_oflag &= ~OPOST; 

    tcsetattr(uart0_filestream, TCSANOW, &cfg); 

    //Transmitting Bytes 

    //----- TX BYTES ----- 
    unsigned char tx_buffer[20]; 
    unsigned char *p_tx_buffer; 

    p_tx_buffer = &tx_buffer[0]; 
    *p_tx_buffer++ = 'H'; 
    *p_tx_buffer++ = 'e'; 
    *p_tx_buffer++ = 'l'; 
    *p_tx_buffer++ = 'l'; 
    *p_tx_buffer++ = 'o'; 

    if (uart0_filestream != -1) 
    { 
     int count = write(uart0_filestream, &tx_buffer[0], (p_tx_buffer - &tx_buffer[0]));  //Filestream, bytes to write, number of bytes to write 
     if (count < 0) 
     { 
      printf("UART TX error\n"); 
     } 
    } 
    //Receiving Bytes 

    //----- CHECK FOR ANY RX BYTES ----- 
    while(1) { 

    printf("loop\n"); 

    if (uart0_filestream != -1) 
    { 
     // Read up to 255 characters from the port if they are there 
     unsigned char rx_buffer[256]; 
     int rx_length = read(uart0_filestream, (void*)rx_buffer, 255);  //Filestream, buffer to store in, number of bytes to read (max) 


     if (rx_length < 0) 
     { 
      //An error occured 
      printf("UART RX error\n"); 
     } 
     else if (rx_length == 0) 
     { 
      //No data waiting 
      printf("no data UART RX test commit\n"); 
     } 
     else 
     { 
      //Bytes received 
      rx_buffer[rx_length] = '\0'; 
      printf("%i bytes read : %s\n", rx_length, rx_buffer); 
      //break; 
     } 
    } 
    sleep(1); 
} 
//Closing the UART if no longer needed 

    //----- CLOSE THE UART ----- 
    close(uart0_filestream); 

    return 0; 
} 
+0

您是否收到任何數據?當你迴應一些數據 –

+0

是的,當我發送的東西,我把它在屏幕上。循環進行一次,然後再次停止。梅比它是覆盆子pi的問題。但是我從樹莓派網站獲取了示例代碼。 –

+0

您可以使用O_NONBLOCK標誌使讀取操作無阻塞。 並且由於讀取是非阻塞的,因此您必須在讀取之前使用選擇操作 –

回答

0

您可以使用O_NONBLOCK標誌使讀/寫操作無阻塞。

+0

我使用這兩個O_NDELAY/O_NONBLOCK創建了我的程序,但它不工作。與信號工程的解決方案http://stackoverflow.com/questions/15119412/setting-serial-port-interruption-in-linux/15455672#15455672 –

+0

好吧!偉大的... :) –

+1

信號在讀的讀阻塞在linux操作中使用,它不會返回雖然底層的串行端口是關閉的。在這種情況下,我們有兩種選擇,要麼使用'signals',要麼使用'select'操作。但我認爲你的目標是使用非阻塞閱讀,因此我不建議選擇使用:) –

1

我以前有同樣的問題,問題與代碼無關,解決方法就是禁用串口登錄, /etc/inittab有一個文件,用nano打開這個文件並找到這一行:

T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100 

並且在開始這行的時候放了一個#字符,而不是保存並重新啓動,它工作起來很奇怪。