Kết quả bất ngờ kiểm tra loopback nối tiếp bằng cách sử dụng echo và cat


17

Vì vậy, tôi có một cổng nối tiếp chuẩn RS232 được lặp lại chính nó bằng cách chạy một dây từ Tx đến Rx. Tôi đang kiểm tra loopback bằng cách chạy echocattrong hai thiết bị đầu cuối riêng biệt:

cat /dev/ttyS1
echo "hi" > /dev/ttyS1

Vấn đề của tôi là với đầu ra. Tôi hy vọng sẽ thấy một "hi" quay trở lại trên thiết bị đầu cuối đang chạy nhưng con mèo tôi nhận được điều này:

hi
[2 newlines]
hi
[4 newlines]
hi
[8 newlines]
hi
[16 newlines]
hi
[32 newlines]
hi

... và cứ thế cho đến khi tôi ctrl+ c cat.

Sau khi ngắt mèo, nếu tôi chạy lại, nó sẽ không xuất ra "hi" cho đến khi tôi chạy echo lần thứ hai.

Điều này có bình thường không? Bất cứ ý tưởng tại sao tôi nhìn thấy hành vi này?

Chỉnh sửa : Theo dòng mới, ý tôi là ASCII 0x0A. Không có lợi nhuận vận chuyển trong đầu ra này.


Nó có thể được gây ra bởi có hai quá trình mở cùng một thiết bị? Điều gì nếu bạn chạy tip /dev/ttyS1( ~.để thoát) và thử gõ dữ liệu ở đó? Nó sẽ được hiển thị trong thiết bị đầu cuối của bạn khi dây được kết nối, vì nó nhận được những gì nó đã truyền.
mrb

3
Bạn có thực sự nhận được dòng mới, hoặc một cặp vận chuyển trở lại / dòng mới? Sự khác biệt rất quan trọng ở cấp độ bạn đang làm việc. Hãy thử "cat / dev / ttyS1> somefile" sau đó thực hiện "od -x somefile" để xem chính xác byte nào được phát ra từ tệp thiết bị TTY. Ngoài ra, thực hiện "stty -F / dev / ttyS1 -a". Đọc trang man cho "stty" và xem những gì đầu ra của stty nói với bạn, cho mỗi cài đặt nhỏ. Comms nối tiếp RS232 là khó khăn.
Bruce Ediger

Câu trả lời:


21

Nhờ bình luận thứ hai của Bruce, tôi đã có thể tự mình tìm ra vấn đề.

Sau khi chạy stty -a -F /dev/ttyS1, có 3 tùy chọn tôi tìm thấy để đóng góp cho vấn đề: "echo", "onlcr" và "icrnl".

Vì cổng nối tiếp này được lặp lại chính nó, đây là những gì đã xảy ra sau khi chạy echo "hi" > /dev/ttyS1:

  1. Các echolệnh gắn thêm một dòng mới vào cuối của thông điệp theo mặc định, vì vậy "hi" + LF được gửi ra đến / dev / ttyS1
  2. Vì "onlcr" đã được đặt, thiết bị nối tiếp đã chuyển đổi LF thành CRLF nên thông điệp vật lý được gửi ra dòng Tx là "hi" + CRLF
  3. Vì "icrnl" đã được đặt, nên thông báo vật lý nhận được trên dòng Rx đã chuyển đổi CR thành LF. Vì vậy, thông điệp được xuất ra bởi 'cat' là "hi" + LFLF.
  4. Vì "echo" đã được đặt, tin nhắn nhận được trên Rx ("hi" + LFLF), sau đó được gửi trở lại trên dòng Tx.
  5. Vì onlcr, "hi" + LFLF trở thành "hi" + CRLFCRLF.
  6. Vì icrnl, "hi" + CRLFCRLF đã trở thành "hi" + LFLFLFLF
  7. Vì tiếng vang, "hi" + LFLFLFLF sau đó đã được gửi ra Tx

Và như thế...

Để khắc phục sự cố này, tôi đã chạy lệnh sau:

stty -F /dev/ttyS1 -echo -onlcr

Việc vô hiệu hóa "echo" sẽ ngăn chặn một vòng lặp vô hạn của các tin nhắn và việc vô hiệu hóa "onlcr" sẽ ngăn thiết bị nối tiếp chuyển đổi từ LF sang CRLF trên đầu ra. Bây giờ catnhận được một "hi" (với một dòng mới!) Cho mỗi lần tôi chạy echo.

CR = lợi nhuận vận chuyển (ASCII 0x0D); LF = nguồn cấp dữ liệu hoặc dòng mới (ASCII 0x0A)


-icrnlđã lừa tôi
tcpaiva

3

Tôi cũng gặp vấn đề tương tự với việc ghép các tệp thành một tty nối tiếp để thử nghiệm. Ngoài câu trả lời được chấp nhận:

Nếu bạn đang kiểm tra đầu ra nối tiếp bằng cách thực hiện một cái gì đó như : cat somefile.txt > /dev/ttyS0, nó sẽ có một lượng dữ liệu byte không mong muốn nếu bạn đang kiểm tra các giá trị byte chính xác.

Với sttyviệc thực hiện đơn giản stty raw -F /dev/ttyS0sẽ ngăn thiết bị đầu cuối chèn / thay thế các ký tự (ví dụ [...] 0x0A [...]-> [...] 0x0D 0x0A [...]). Các rawlá cờ làm thay đổi chế độ của nhà ga nên không có đầu vào và đầu ra xử lý được thực hiện.


1
Hmm ... không có vẻ như stty rawsẽ vô hiệu hóa tiếng vang theo mặc định. Bạn có thể cần phải làm stty raw -echo.
BMiner
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.