2010-06-05 40 views
6

Tôi đã viết một ứng dụng phải sử dụng các cổng nối tiếp trên Linux, đặc biệt là các cổng ttyUSB. Các hoạt động đọc và ghi được thực hiện với vòng lặp select()/read() chuẩn và write(), và có lẽ không có gì sai trong chúng, nhưng mã khởi tạo (hoặc thiếu một số phần của nó) làm hỏng một cái gì đó trong hệ thống con tty. Dưới đây là:Trình tự khởi tạo đúng cho cổng nối tiếp Linux


    vuxboot(string filename, unsigned baud = B115200) : _debug(false) { 
    _fd = open(filename.c_str(), O_RDWR | O_NOCTTY); 
    if(_fd < 0) throw new io_error("cannot open port"); 

    // Serial initialization was written with FTDI USB-to-serial converters 
    // in mind. Anyway, who wants to use non-8n1 protocol? 

    tcgetattr(_fd, &_termios); 

    termios tio = {0}; 
    tio.c_iflag = IGNPAR; 
    tio.c_oflag = 0; 
    tio.c_cflag = baud | CLOCAL | CREAD | CS8; 
    tio.c_lflag = 0; 

    tcflush(_fd, TCIFLUSH); 
    tcsetattr(_fd, TCSANOW, &tio); 
    } 

Một tcsetattr(_fd, TCSANOW, &_termios) khác nằm trong phá hủy, nhưng không liên quan.

Có hoặc không có khởi tạo thuật ngữ này, những điều lạ xảy ra trong hệ thống sau khi ứng dụng thoát. Đôi khi đồng bằng cat (hoặc hd) thoát ngay lập tức in không có gì hoặc cùng một công cụ mỗi lần, đôi khi nó đang chờ đợi và không hiển thị bất kỳ dữ liệu nào chắc chắn được gửi lên cổng; và close() (read() cũng vậy, nhưng không phải mọi lần) phát ra một số lạ WARNING tới dmesg referring to usb-serial.c.

Tôi đã kiểm tra phần cứng và phần vững hàng chục lần (ngay cả trên các máy khác nhau) và tôi chắc chắn nó đang hoạt động như dự định; hơn nữa, tôi đã tháo phần sụn để chỉ in cùng một tin nhắn.

Tôi làm cách nào để sử dụng cổng nối tiếp mà không hủy bất kỳ thứ gì? Cảm ơn.

Trả lời

0

OK. Đây có thể không phải là một giải pháp hoàn hảo ... chắc chắn là không. Tôi chỉ cần ném ra bộ chuyển đổi FT232 (chiên nó, thực sự), và sử dụng một dựa trên CP2102. Nó chỉ hoạt động ngay bây giờ (và cũng rẻ hơn 6 lần).

1

Tôi không chắc chắn những gì là sai với đoạn mã của mình có nhưng điều này có thể có ích, nếu bạn chưa nhìn thấy nó: Serial Programming Guide for POSIX Operating Systems

tôi phải làm một số cổng nối tiếp interfacing khá gần đây và this library làm việc tốt, có thể phục vụ như một ví dụ khác.

+0

Tôi vừa sao chép hầu hết mã ở trên từ hướng dẫn đó. Nó chỉ là _not rằng good_, hoặc tôi thiếu một cái gì đó? .. Tôi sẽ kiểm tra thư viện đó, nhưng nó là GPL'd, và ứng dụng của tôi sử dụng Expat (aka MIT); và giao diện của nó cũng không tốt chút nào. Ví dụ. Tôi muốn chỉ định ttyUSB như một chuỗi: nó có thể nhận được các tên khác nhau với cấu hình udev khác nhau hoặc đôi khi. – whitequark

+0

Vâng, tôi phải thừa nhận có một số bit khó hiểu trong hướng dẫn đó nhưng vẫn là tài nguyên toàn diện nhất mà tôi có thể tìm thấy. Về thư viện: Có lẽ bạn có thể sử dụng nó như là một 'kiểm tra sanity', chỉ để xem liệu điều đó có phá vỡ hệ thống của bạn không? – Hamza

+0

Vâng, tôi đã kiểm tra và có thể xác nhận rằng mã khởi tạo giống nhau trong thư viện đó và trong mã của tôi, ngoại trừ 'O_NDELAY' (=' O_NONBLOCK'). Tôi đã có tùy chọn đó trong quá khứ, và kết quả thậm chí còn kỳ lạ hơn: vô nghĩa đã được gửi đến và nhận từ thiết bị, các lỗi được trả về bởi 'read()', và thậm chí nhiều hơn 'CẢNH BÁO' trong syslog. – whitequark

2

Chạm vào một dòng WARN_ONcó thể có nghĩa là bạn đã gặp lỗi hạt nhân. Tôi biết rằng đã có nhiều công việc để cải thiện trình điều khiển nối tiếp USB gần đây; Tôi khuyên bạn nên thử một hạt nhân mới hơn và/hoặc yêu cầu trên danh sách gửi thư [email protected]

+0

Sự cố này thường xảy ra đối với những người sử dụng Bảng Beagle, nơi hầu hết mọi thứ được kết nối đều được kết nối qua USB. Tôi cũng khá chắc chắn anh ta đánh một trong những lỗi có thể xảy ra trong hệ thống con đó. –

+1

Lịch sử cho hạt nhân ổn định cho thấy không có thay đổi nào được thực hiện sau ca. 2009-10. Ngoài ra, khi tôi sử dụng 'minicom' hoặc các công cụ tương tự," lỗi "không phát sinh. – whitequark

0

Cũng giống như một lưu ý phụ thực sự, kiểm tra lỗi của bạn trên open không hoàn toàn đúng - điều kiện lỗi được báo hiệu bằng giá trị trả về -1. (0 là một fd hoàn toàn hợp lệ, thường là kết nối với thiết bị nhập chuẩn.)

+0

Cảm ơn, đã khắc phục điều đó. – whitequark

0

Bạn có thể muốn thử:

vuxboot(string filename, unsigned baud = B115200) : _debug(false) { 
    _fd = open(filename.c_str(), O_RDWR | O_NOCTTY); 
    if(_fd < 0) throw new io_error("cannot open port"); 

    // Serial initialization was written with FTDI USB-to-serial converters 
    // in mind. Anyway, who wants to use non-8n1 protocol? 

    tcgetattr(_fd, &_termios); 

- termios tio; 
+ termios tio; 
+ memcpy(&tio, &_termios, sizeof(struct termios)); 

    tio.c_iflag = IGNPAR; 
    tio.c_oflag = 0; 
    tio.c_cflag = baud | CLOCAL | CREAD | CS8; 
    tio.c_lflag = 0; 

    tcflush(_fd, TCIFLUSH); 
    tcsetattr(_fd, TCSANOW, &tio); 
} 

Điều này làm cho nó để bất kỳ lĩnh vực bất ngờ của termios trên hệ thống của bạn có được giá trị phần nào hợp lý.

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