2011年3月11日 星期五

linux serial port programming : CLOCAL 的設定

先來看 Carrier Detect (CD) signal line 的意義。
節錄自 "Serial Communication / Mark Nelson" 一書 :
"Unfortunatly, before the era of intelligent modems, some terminals
or other DTE equipment were designed to treat a modem as unusable
without CD. Devices such as these would not send or receive
characters to a modem that had CD low. Because of these anachronisms,
most modems built today can keep CD high at all times, whether or not
a carrier has been established.

Because these feature is sometimes the default mode of operation,
using CD for accurate detection of carrier presence is somewhat risky.
However, most users should be able to configure their modems so as to
disable this troublesome behavior
."

中文口白一下:以前時代,CD 是 modem (DCE 端) 用來告訴 終端機 (DTE 端) 說:
我有連到對方喔!但是後續的 modem (DCE) 有的已經不照這種約定了---
不管有沒有跟遠端連線,一律拉 CD 起來。
所以 DTE 根據 CD 判斷 DCE 有無與對方連線的方式,已經不可靠了。
所以現在 DTE 必須可以 configure設定,不要再看這個不可靠的 CD signal.

怎樣 configure ? Linux serial driver 提供這樣的 flag --- termios 屬性若有設定
CLOCAL ,在 2.6.28 generic_serial.c ::
uart_change_speed():
{    ...
    if (termios->c_cflag & CLOCAL)
        state->info->flags &= ~UIF_CHECK_CD;
    ...
}

那 UIF_CHECK_CD 有何作用呢?

uart_handle_dcd_change(struct uart_port *port, unsigned int status)
{  ...
    if (info->flags & UIF_CHECK_CD) {
        if (status)
            wake_up_interruptible(&info->port.open_wait);
        else if (info->port.tty)
            tty_hangup(info->port.tty);
    }
    ...
}

也就是說,有 UIF_CHECK_CD 時,就 wake up 正在等待 open 的 process,
或是 hangup tty,這些都是在 CD signal change 時本來預定的動作。
 
所以在這裡,設定 CLOCAL 可以 "遮蔽" 對於 CD 訊號的判斷。
若您的應用程式 open serial port 時,忘記設定 CLOCAL,
就會照者書上所說的操作定義 --- 因為 DTE 發現 DCE 的 CD 不見了,
就 hang up tty 了。
#




沒有留言:

張貼留言