2012-05-06 21 views
3

首先,我不知道這是留在SO還是去SU:你告訴我。解決方案可能與編程有關。爲什麼在Linux上使用RS-232時CTRL + C不起作用?

我在嵌入式設備上執行Linux並使用RS-232 @ 9600 bauds與它進行通信。在Windows上使用PuTTY可以正常工作:我有一個shell,可以輸入和執行命令。

問題是:當我啓動一個命令時,我無法按CTRL + C。例如,ping某臺機器時,ping進入無限循環,並且我無法使用CTRL + C停止它。然而,在Bash提示符下,CTRL + C工作並進入下一行(因此它被傳送)。我還注意到,當我在運行命令時執行CTRL + C時,終端顯示^C。通過Telnet連接時,CTRL + C可以在任何地方正常工作。

我試過使用PuTTY的「特殊命令」休息,但它不起作用。我也嘗試了不同的終端模擬器,同樣的問題。

所以我想這個問題是以某種方式與內核相關的。有什麼我可以看看關於這個?

編輯:我正在運行BusyBox v1.13.2。的stty -a(RS-232)的輸出是:

speed 9600 baud; rows 24; columns 80; 
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; 
eol2 = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; 
lnext = ^V; flush = ^O; min = 1; time = 0; 
-parenb -parodd cs8 hupcl -cstopb cread clocal -crtscts 
-ignbrk brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon ixoff 
-iuclc -ixany -imaxbel 
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt 
echoctl echoke 

stty -a(遠程登錄)的輸出是:

speed 38400 baud; rows 24; columns 80; 
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; 
eol2 = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; 
lnext = ^V; flush = ^O; min = 1; time = 0; 
-parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts 
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff 
-iuclc -ixany -imaxbel 
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab3 bs0 vt0 ff0 
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt 
echoctl echoke 

我只注意到,如果我做ls -la /bin,這是一個很長的命令執行由於名單很長,我不能通過發出CTRL + C來破解,但我可以在保留鍵的時候進行。大約一秒後就會中斷。然而,這不適用於ping。

事實上,如果我做seq 1 1000,然後按Ctrl + C,現在看來似乎跳過多行的一個鏡頭在某個時刻:

93 
94 
95 
^C6 
897 
898 
899 

同樣的事情發生與ls -la /bin

lrwxrwxrwx 1 10042 2223   7 May 6 2012 dmesg -> busybox 
lrwxrwxrwx 1 10042 2223   7 May 6 2012 dos2unix -> busybox 
lrwxrwxrwx 1 10042 2223   7^C   7 May 6 2012 ipcrm -> busybox 
lrwxrwxrwx 1 10042 2223   7 May 6 2012 ipcs -> busybox 
lrwxrwxrwx 1 10042 2223   7 May 6 2012 iplink -> busybox 
+0

取決於您已經運行shell。你在設備上運行BusyBox嗎?什麼版本?灰或全Bash?添加更多信息。 –

+0

Ctrl-C由終端處理。串行連接沒有正常的終端,因此Ctrl-C(或實際上任何生成信號的按鍵序列)都不能正常工作。 –

+0

@eepp在下面編輯的內核中查看有關控制檯設備處理的舊郵件列表消息(對於先前刪除內核標記感到抱歉,只是將其放回) –

回答

2

嵌入式設備上的串行端口設置可能會忽略中斷字符,或者在收到中斷時不會導致中斷。您可以通過從設備的shell(或啓動腳本)運行stty程序或使用各種ioctl()參數編寫程序來更改此設置。

http://linux.die.net/man/1/stty

stty sane 

可能是最好的選擇。這設置了一堆「常規」設置。在constrast,如果你這樣做

stty raw 

在桌面Linux的shell窗口中,你可能會得到你看到你的嵌入式設備上的那種CTRL-C打印,但是,確實全無行爲。

不帶參數運行stty可能會打印出當前的設置,這可能很有趣 - 特別是比較串口與遠程登錄會話的結果。


更新:關於BusyBox的和BRKINT網絡搜索發現可能相關的事情:

Date: Thu, 31 Jan 2002 13:34:34 -0800 
From: Scott Anderson <scott_anderson at [removed]> 
Cc: linuxppc-dev at lists.linuxppc.org 
Subject: Re: why is tty->pgrp set to -1 for console? 

> What is the correct procedure to follow to get around this problem 
> and get ctrl-c working on console? 

It looks like everyone is taking a swing at this one, so I think I'll 
join in. First off, the easiest way I've found to track down why 
ctrl-c doesn't work is to just run "ps -j". For ctrl-c to work, you 
need a controlling terminal (the TTY column) and a process group. If 
you have a '?' in the TTY column, ctrl-c won't work. In the past I 
have seen this happen because of this code in drivers/char/tty_io.c: 
     if (device == SYSCONS_DEV) { 
       struct console *c = console_drivers; 
       while(c && !c->device) 
         c = c->next; 
       if (!c) 
         return -ENODEV; 
       device = c->device(c); 
       filp->f_flags |= O_NONBLOCK; /* Don't let /dev/console block */ 
       noctty = 1; 
     } 
Note that O_NOCTTY (no controlling terminal) is forced on whenever 
/dev/console is opened (noctty = 1). Possible workarounds: 
    1) Run getty on something other than /dev/console. For example, 
    if you console is on the first serial port, run getty on /dev/ttyS0. 
    I believe this is the "correct" answer. 
    2) You could also change getty to do a TIOCSCTTY ioctl explicitly after 
    it has opened the terminal. 
    3) You could remove the forcing of noctty on from tty_io.c 
+0

設置'noctty = 0;'實際上工作。非常感謝您指出了這一點!事實上,當我看着'ps -o tty'時,''TTY'列中有'?'。現在我看到了我的TTY正確的主要/未成年人。解決方法1)不起作用,2)在這種情況下更難。再次謝謝你。 – eepp

+1

**閱讀此**。事實上,我只是沒有考慮檢查BusyBox的解決方案,因爲我確信它是與我的特定器件(順便提一句,它是Xilinx UART Lite)的UART相關或內核相關的。但它似乎是一個已知的問題,甚至在[BusyBox的常見問題](http://www.busybox.net/FAQ.html#job_control)中也是如此。在我的情況下,第一個'exec'行工作得很好(即使他們說它不應該工作):CTRL + C回來。他們還提到'drivers/char/tty_io.c'中的'noctty = 0;'(現在'drivers/tty/tty_io.c':在'tty_open'中,只要確保調用了__proc_set_tty')。 – eepp

相關問題