2012-10-22 25 views
13

Đây là những gì chức năng của tôi trông như thế để mở cổng nối tiếp (sử dụng Ubuntu 12.04):Xoá các cổng nối tiếp của bộ đệm

int open_port(void) 
{ 
    int fd; /* File descriptor for the port */ 

    fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY); 

    if (fd == -1) 
    { 
    // Could not open the port.   
    perror("open_port: Unable to open /dev/ttyUSB0 - "); 
    } 
    else 
    fcntl(fd, F_SETFL, 0); 

    struct termios options; 

    tcgetattr(fd, &options); 
    //setting baud rates and stuff 
    cfsetispeed(&options, B19200); 
    cfsetospeed(&options, B19200); 
    options.c_cflag |= (CLOCAL | CREAD); 
    tcsetattr(fd, TCSANOW, &options); 

    tcsetattr(fd, TCSAFLUSH, &options); 

    options.c_cflag &= ~PARENB;//next 4 lines setting 8N1 
    options.c_cflag &= ~CSTOPB; 
    options.c_cflag &= ~CSIZE; 
    options.c_cflag |= CS8; 

    //options.c_cflag &= ~CNEW_RTSCTS; 

    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); //raw input 

    options.c_iflag &= ~(IXON | IXOFF | IXANY); //disable software flow control 

    return (fd); 
} 

gì vấn đề là, là khi tôi chạy chương trình này và nếu thiết bị nối tiếp của tôi đã được cắm vào, bộ đệm có nội dung trong đó. Tôi cần một cách để xóa bộ đệm trước khi tôi bắt đầu đọc nó. Tôi nghĩ rằng việc sử dụng tcsetattr(fd, TCSAFLUSH, &options); sẽ khắc phục vấn đề này, bằng cách xóa bộ đệm IO trước khi khởi tạo cổng, nhưng không có may mắn như vậy. Có cái nhìn sâu sắc nào không?

Trả lời

16

Tôi nghĩ rằng tôi đã tìm ra. Vì lý do nào đó, tôi cần thêm thời gian trễ trước khi xả. Hai dòng này thêm trước khi trở fdvẻ đã làm các trick:

sleep(2); //required to make flush work, for some reason 
    tcflush(fd,TCIOFLUSH); 
+11

hy vọng một người nào đó có thể khai sáng cho chúng tôi lý do tại sao điều này hoạt động :-) –

+0

+1 Tôi cũng hơi bối rối vì điều này. –

+1

Tôi nghĩ rằng đó là lỗi này trong hạt nhân Linux: xem http://lkml.iu.edu//hypermail/linux/kernel/0707.3/1776.html –

2

Nguyên nhân của vấn đề này nằm trong việc sử dụng một cổng nối tiếp USB. Nếu bạn sử dụng một cổng nối tiếp thông thường, bạn sẽ không gặp phải vấn đề này.

Hầu hết các trình điều khiển cổng nối tiếp USB không hỗ trợ xả nước đúng cách, có thể vì không có cách nào biết liệu vẫn còn dữ liệu trong thanh ghi thay đổi nội bộ, FIFO hoặc trong hệ thống con USB.

Xem thêm trả lời của Greg cho một vấn đề tương tự được báo cáo trước đó here.

sleep của bạn có thể khắc phục được sự cố, nhưng đó chỉ là công việc. Thật không may là không có giải pháp nào ngoài việc sử dụng cổng nối tiếp thông thường.

1

Tôi đã gặp phải các triệu chứng tương tự với bảng Arduino Uno đặt lại trên open(). Tôi đã nhận được dữ liệu sau khi cuộc gọi mở() đã được tạo trước khi bảng Arduino đã được đặt lại và do đó trước khi open() đã được gọi.

Theo dõi vấn đề với các cuộc gọi ioctl() Tôi đã biết rằng dữ liệu chưa được đưa vào bộ đệm đầu vào theo thời gian tcflush() được gọi. Vì vậy, tcflush() đã làm việc nhưng không có dữ liệu để tuôn ra. Một giấc ngủ của 1000 chúng tôi sau khi cuộc gọi mở() dường như giải quyết vấn đề. Điều này là do sự chậm trễ cho phép dữ liệu đến trước khi tcflush() được gọi và do đó tcflush() đã thực sự xóa bộ đệm đầu vào.

Bạn có thể gặp phải sự cố tương tự.

Các vấn đề liên quan