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 了。
#




2011年1月24日 星期一

Difference between .bash_profile and .bashrc Files

以下內容是從這裏節錄出來的:

.bash_profile is executed for login shells, while .bashrc is executed for interactive non-login shells.

就是說,當你使用 login console 或用 ssh login 時, .bash_profile 會被調用。
如果只是在 GNOME, KDE 或 emacs 裏面,打開一個 shell command 時, .bashrc 會被調用。

那麼作 global 設定時,就是這兩種情形分別對應到 /etc/profile 與 /etc/bash.bashrc 啦!
其中,若是需要在 login 時,也希望 bashrc 被調用,就可以在 profile 裏面 source bashrc.

2011年1月23日 星期日

git 更改遠端資訊 的指令

為了轉移到新的伺服器,git 的 repository 要搬到新位置,所以 local 端的 repository 指標要換掉,下列指令依序就是轉換的步驟:

#> git remote -v
顯示目前指向哪些遠端的 repository? (URL 格式)

#> git remote rm origin
移除 URL 資訊

#> git remote add origin git@git-server:project_name
改變 URL 資訊,指向新位置 (若是用 gitosis ,就可以直接建立新的遠端 repository ,否則遠端的新增的 repository 必須先用 git init 或 git init --bare 處理過)
(目前為止,都還沒有對 remote repository 產生任何影響)

#> git push origin master
把 local repository 更新到 remote 端(這裡,才實際的更新了 remote repository)

Install sun-java5-* in debian squeeze

Debian Squeeze 已經把 sun-java5-* (亦即 java 1.5 )拿掉了,統統換成了 sun-java6-* (亦即 java 1.6)「註:這裡 * 代表 jre, bin, jdk, demo 等等部份」。
可是 Android 開發環境會檢查 java 環境,仍然需要 java 1.5 ,怎麼辦呢?
可以用 dpkg --force-depends 強制安裝 sun-java5-*  ,方法如下:

1. 首先下載 Lenny 版本的 package :
sun-java5-bin_1.5.0-22-0lenny1_i386.deb
sun-java5-jre_1.5.0-22-0lenny1_all.deb
sun-java5-demo_1.5.0-22-0lenny1_i386.deb
sun-java5-jdk_1.5.0-22-0lenny1_i386.deb

2  因為 bin 依賴於 jre , jre 依賴於 bin, jdk 依賴於 demo, demo 依賴於 jdk 。
所以用強制 depends 選項(把依賴關係列為 warning 而非 error )就可以順利安裝,指令為:
#> dpkg --force-depends -i  sun-java5-bin_1.5.0-22-0lenny1_i386.deb\
  sun-java5-jre_1.5.0-22-0lenny1_all.deb\
  sun-java5-demo_1.5.0-22-0lenny1_i386.deb\
  sun-java5-jdk_1.5.0-22-0lenny1_i386.deb

3. 切換內定 java version :
#> sudo update-java-alternatives -s java-1.5.0-sun
如果出現一堆跟 firefox plugin 的錯誤訊息,像這樣:
update-alternatives: error: alternative /usr/lib/jvm/java-1.5.0-sun/jre/plugin/i386/ns7/libjavaplugin_oji.so for firefox-javaplugin.so not registered, not setting.
...
不用管它,因為我們 compile Android 時應該不會用到 firefox 的 java plugin。

4. 驗證 java version :
#> javac -version
應該就可以看到 java 1.5 的訊息了!
#


2010年11月26日 星期五

忽然想要列印 man page 怎麼辦?

老 Unix 玩家應該覺得很簡單,但對於新手的我還是要紀錄一下:
1. 先由命令查閱要列印的 man page 再哪裡? 例如 :
tom@glest:~/temp$ man -w groff
/usr/share/man/man1/groff.1.gz
2. 原來是有壓縮的,知道後就可以印了:
tom@glest:~/temp$ zcat `man -w groff` | groff -m man -T ps - | lpr

這裡 groff 是排版用的指令,輸入格式為 man page ,輸出格式為 ps 。
That's it !

p.s. 當然你的 lpr 要正確才行,如果有裝好 cups,下列命令就可以看到系統印表機狀態:
tom@glest:~/temp$ iceweasel http://localhost:631/admin



2010年11月19日 星期五

一些 C preprocessor 的用法

在 wireshark source 裡面,看到有些奇怪的 C 語言寫法 : 查不到定義的 _U_。在這裡當備忘錄記一下:
hostname$ cat foo.c
int  foo(int a _U_, int b _U_, int c)
{
    return c + 17;
}
#hostname$ gcc -D_U_=  -c -O2 -Wall -W foo.c
  foo.c: In function `foo':
  foo.c:2: warning: unused parameter `a'
  foo.c:2: warning: unused parameter `b'

上面定義 _U_  為"什麼東東都沒有" ,結果出現 compiler warning.

#hostname$ gcc -D_U_="__attribute((unused))" -c -O2 -Wall -W foo.c
#hostname$ gcc --version
2.95.1f

這裡 _U_ 被定義為 attribute of "suppress unused variable warning",所以就沒有 compiler warning 了!
那為何不使用的參數不拿掉呢? 不知道耶! 猜想是為了將來需要時不用動到很多 callers 就可以修改 function code 吧!







2010年8月26日 星期四

emacsclient font configurations

This text applies to version after Emacs 23.1
首先,我們可以把下列一行加入 ~/.bashrc
  alias ex='emacsclient -a "" -c "$@"'

解釋一下:
當我們使用 emacsclient 時,必須有一個 emacs server 啟動才可以用。
emacsclient 的參數有一個 -a "" 表示萬一 emacs server 沒有啟動,
就使用 `alternate editor' ,它可以是 vi, pico ... ,若是空字串 ("") ,表示 `那就叫一個 emacs server 起來好了'.
另外 參數 -c 表示 `create a new frame' 而不是用 server 的 frame.
至於後面要打開的檔案(可以一次指定開多個檔案來編輯),就用 bash 提供的 $@ 來代入即可。

第二,設定字型,因為 emacs server 可以在 X 之前就啟動了,因此,
很合理的,它不理會你指定在 X 環境下的字型。
現在的 X 環境下有兩種字體系統:核心字體系統與 Xft 字體系統。Xft 有許多優良的特性(向量,反鋸齒等),
所以 Emacs 23.1 開始支援 Xft as its font base. (see XftGnuEmacs).
只要在你的  ~/.Xresources 指定就好,例如,我們打算用 DejaVu Sans Mono 字型 :
    Emacs.FontBackend: xft
    Emacs.font: DejaVu Sans Mono-14

(謎:怎樣查出這個字型呢? M-x describe-font 然後給個 mono 讓它 match 出完整的字型敘述)

第三,設定 frame 的特性,我們希望打開 frame 時,是黑底白字,不要 tool bar, 不要 scroll bar ...
這些都與預設值不同,該怎麼設定呢?
emacs 的 default-frame-alist 裡面紀錄了 `新開一個 frame 所需的參數',設定這個就對了!
在你的 ~/.emacs 內這樣指定
(let ((frame '((left . 0)
               (top . 0)
               (width . 110)
               (height . 30)
               (tool-bar-lines . nil)
               (vertical-scroll-bars . nil)
               (background-color . "black")
               (foreground-color . "white")          
)))
  (setq default-frame-alist frame)
  (setq initial-frame-alist frame)

)

說明一下,[ GNU Emacs 手冊 ]查得到所有的 frame parameters。
第一次開啟的 frame(應該是 server frame)  參數會參考 `initial-frame-alist' ,往後開啟 frames(emacsclient frame)都會參考 `default-frame-alist' .

完工了!記得重新開啟 X 讓 .Xresources 生效啊啊~