2010-10-31 37 views
16

Tôi đã gặp sự cố khi chức năng mở không bao giờ trả về khi tôi cố gắng mở cổng nối tiếp. Nó không xảy ra mọi lúc, và vấn đề sẽ biến mất trong một thời gian nếu tôi tháo USB đến bộ chuyển đổi nối tiếp và cắm nó trở lại trong mã của tôi trông như thế này:.chức năng mở() treo (không bao giờ trả về) khi cố gắng mở cổng nối tiếp trong Mac OS X

fileDescriptor = open(bsdPath, O_RDWR | O_NOCTTY); 

nơi bsdPath là/dev/cu .KeySerial1. Tôi đã thử thêm tùy chọn O_NONBLOCK vào lệnh mở, nhưng nó vẫn bị treo.

Tất nhiên tôi muốn hiểu tại sao điều này xảy ra. Niềm tin của tôi là bất cứ vấn đề gì, với O_NONBLOCK được chỉ định, mở sẽ trả về bất kể ngay cả khi nó không thể mở cổng. Nếu không thể mở cổng, tệpDescriptor phải là -1 và errno nên được đặt (tôi kiểm tra điều này ngay sau khi cuộc gọi mở). Tất nhiên, điều này không xảy ra. Giả định của tôi có đúng không? Có một số lý do đã biết để mở() không bao giờ trả lại ngay cả với O_NONBLOCK được chỉ định khi gặp lỗi không?

Sử dụng phiên bản mới nhất của trình điều khiển PL-2303 với PL-2303 dựa trên bộ điều hợp nối tiếp trên 10.7.2, tôi đã có thể tái tạo lại vấn đề này ngay hôm nay. Một vài lưu ý:

  • Khi bị treo trong cuộc gọi open(), quá trình này không bị gián đoạn khi sử dụng lệnh-. (control-C).
  • Chạy ps -avx hiển thị mã trạng thái quy trình của U cho quy trình. Tôi không chắc mã này có nghĩa là gì. Nó không xuất hiện trong các trang của người đàn ông cho số ps do Googling tìm thấy. Không có danh sách các mã trạng thái quá trình trong trang hướng dẫn cho ps trên máy của tôi. Có lẽ nó dành riêng cho phiên bản Mac (10.4+?) Của ps?
  • Tôi lưu ý rằng khi chạy ngay trước lần xuất hiện đầu tiên của sự cố này, cuộc gọi của tôi tới ioctl() để đặt lại các tùy chọn trên cổng về trạng thái của chúng trước khi tôi thay đổi chúng để sử dụng trong chương trình của tôi bị treo. Tôi đã phải giết chương trình (thông qua trình gỡ rối của Xcode). Ngay sau đó, vào lần khởi chạy tiếp theo của chương trình, open() bị treo ...

Trả lời

6

Sự cố có thể xảy ra trong trình điều khiển thiết bị. Bạn chính xác về cách O_NONBLOCK nên hoạt động, nhưng điều đó phụ thuộc vào trình điều khiển để thực hiện điều đó một cách chính xác. Sẽ rất hữu ích khi biết phiên bản OS X nào và thiết bị USB nào đang được sử dụng.

Quy trình chuẩn sẽ đảm bảo rằng thiết bị được cắm trực tiếp vào cổng USB CPU (không phải là hub), kiểm tra cáp và kiểm tra các trình điều khiển đã cập nhật.

Ngoài ra, khi open() đang chặn, quá trình có thể bị gián đoạn bởi control-c không? Nếu bạn xem quy trình với "ps -aux" trong khi bị chặn, trường "STAT" có nội dung gì?

+0

Cảm ơn câu trả lời. Tôi đã quan sát nó với một Keyspan USA-19HS trên 10.6 và 10.7, và đã có một báo cáo từ một người dùng cùng với một dấu vết ngăn xếp cho thấy cùng một vấn đề bằng cách sử dụng một adapter PL-2303 dựa trên 10.7. Tôi sẽ cố gắng tái tạo lại nó để tìm câu trả lời cho hai câu hỏi của bạn. –

+0

Tôi đã cập nhật câu hỏi với một số quan sát mới. Cảm ơn một lần nữa. –

+0

'U' có nghĩa là quá trình này là "không bị gián đoạn", thường có nghĩa là nó đang chờ trình điều khiển thiết bị phản hồi. OS X hơi khác thường khi các trình điều khiển có thể chạy trong không gian ứng dụng, bên ngoài hạt nhân. Hạt nhân đã truyền các lệnh gọi 'open()' và 'ioctl()' cho trình điều khiển và sau đó báo cho quá trình của bạn đợi kết quả. Nghe có vẻ như người lái xe đã treo, để lại quá trình của bạn treo (nhưng hạt nhân là an toàn).Tôi tìm thấy thread này về PL-2303 làm chính xác những gì bạn đang nhìn thấy trên 10,7 Lion. Có thể nó sẽ giúp: http://xbsd.nl/2011/07/pl2303-serial-usb-on-osx-lion.html –

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