Email me: jollen # jollen.org

more: Jollen 的 Embedded Linux 教育訓練

« February 2008 | (回到Blog入口) | April 2008 »

March 2008 歸檔

March 1, 2008

Linux 驅動程式的中斷處理, #1: request_irq 基本觀念

在Linux device driver 中,名為 “interrupt handler” 的 routine 負責處理(回應)實體的硬體中斷。當裝置中斷被觸發時,interrupt handler 便會執行,而 interrupt handler 就工作便是回應該中斷的請求(request)。

Interrupt handler 執行於 interrupt mode,並無 process context 資訊,因此,在 interrupt mode 下執行的執行碼需注意以下 3 點:

1. 由於沒有 process context 的關係,因此無法存取 user space。
2. 無法存取 current 巨集。current 巨集是一個指向自己的 kernel symbol。
3. 不能呼叫 scheduler 做排程,也不能做 sleeping waiting。由於 down/up 的 semaphore API 是 sleeping waiting 的版本,因此在 interrupt mode 必須改用 spinlock,spinlock 是以 busy waiting 的方式做 wait operation。

Linux device driver 安裝 interrupt handler 的方式是呼叫 request_irq() 函數,透過此函數來佔用 IRQ,並且安裝interrupt handler。

Request IRQ

request_irq() 用法如下:

int request_irq( unsigned int   irq,
                 void           (*handler)(int, void *, struct pt_regs *),
                 unsigned long  irqflags,
                 const char    *devname,
                 void          *dev_id);

irqflags 參數說明:

1. SA_INTERRUPT
2. SA_SHIRQ
3. SA_SAMPLE_RANDOM

在 Linux 驅動程式的 framework 中,呼叫 request_irq() 安裝 interrupt handler 的位置為:

1. init_module()
2. fops->open

若是「共用中斷」(shared IRQ),只能在 fops->open 裡呼叫 request_irq()。在 fops->open 裡請求 IRQ ,相對的也要在 fops->release 裡呼叫 free_irq() 將佔用的 IRQ 釋放。

March 2, 2008

Linux 驅動程式的中斷處理, #2: 深入淺出中斷模式

Interrupt handler 的工作是負責處理裝置的中斷請求,並將結果回報(feedback)給裝置。一般而言,裝置產生中斷時,都是與資料讀寫有關的請求。Interrupt handler 便要根據中斷的特性,來判斷此中斷是要請求驅動程式將資料寫入至裝置,或是由裝置讀取資料。

Linux 驅動程式的 interrupt handler 實作原則如下:

1. 在 interrupt handler 裡,叫醒真正負責此中斷的 task 後立即結束執行。
2. Interrupt handler 應儘量執行最少的程式碼。
3. Interrupt handler 若執行過久,會造成中斷的關閉時間過長,因此可能會遺失緊接著產生的中斷請求。
4. 若 interrupt handler 裡有過長的計算動作或執行過久的程式碼,則應使用 tasklet 或 task queue 將該段程式碼做排程,留待其它時間再執行。如此便可避免interrupt handler執行時間過久。

此外,在中斷模式下做同步控制時,還要考慮是否會佔用過久 CPU 時間的問題。為什麼中斷模式下寫 code 需要注意這個議題呢?請看以下的說明。

Counting Semaphore

在作業系統教科書中,提及二種 semaphore 的做法:

1. blocking counting semaphore,即 Linux 的 down/up 版本。
2. spinlock counting semaphore,即 Linux 的 spinlock。

Spinlock counting semaphore 屬於傳統作法,spinlock 讓 waiting 的動作(P operation)以 busy-loop 方式實作,因此會佔用 CPU 資源;blocking counting semaphore 則是將 waiting 的動作以 blocking(sleeping) 的方式來進行。

在Linux kernel 裡,blocking counting semaphore 採用 wait queue 來實作,即以 sleep 方式做P operation。Wait queue 機制對驅動程式來說,原始用意為實作 process(user-space)的 blocking read 與 blocking write,這樣的 behavior 機制經常出現在實作 process 讀取裝置資料的場合;當 process 進行 blocking I/O 讀寫(synchronous I/O)時,由於 kernel-space 是以 sleeping 方式進行等待,因此能把 CPU 交給其它人使用,並將 process 排程到 I/O queue(waiting queue),因此不獨佔或浪費 CPU 時間。

在中斷模式下,因為不能使用 sleeping 版本的 semaphore,所以必須使用 spinlock,在此情況下,便會遭遇到 interrupt handler 佔用 CPU 時間太久的問題。

March 3, 2008

Linux 驅動程式的中斷處理, #3: Bottom Half 的觀念

為了能寫出很棒的 interrupt handle,Linux 採用一種稱為 bottom half 的觀念來實作 interrupt handler。

bottom_half.PNG

Linux 將完整的 interrupt handler 切成2個部份(half):top half 與 bottom half。Top half 是在呼叫 request_irq() 時所指定的 interrupt handler 函數,bottom half 則是由 top half 所排程(scheduling),真正負責回應中斷的 task。

一般來說,top half 的基本實作原則如下:

1. 儲存裝置相關資料,這個部份會涉及「中斷不同步」的議題,在這裡先不做解釋。
2. 將 bottom half 排程後結束執行。

Top half 是真正接受中斷請求的 task,因此應避免執行過久。由 top half 的實作原則可以看出,top half 真正要做的工作其實只有排程 bottom half,因此執行的速度將會非常快。Top half 與 bottom half 的最大差別為,bottom half 在執行時,interrupt 是開啟的,因此 CPU 仍然可以接受中斷請求。

由此也可以看出另外一個 bottom half 機制的特點:當 bottom half 尚未結束執行時,top half 仍然可以處理中斷請求。另外,bottom half 就是 interrupt handler,因此「也視為」在 interrupt mode 下執行。

March 5, 2008

Openmoko 開放 Neo 手機工業設計

過去,手機的工業設計(Industrial Design)都是封閉的,設計原稿走不出深宮大院,設計師拿不到設計原稿,一般人也很難一探手機工業設計的原始樣貌。不過,現在事情不一樣了。在 open source 手機軟體平臺深耕許久的 Openmoko 今天正式發佈一則新聞「Openmoko Unlocks Neo Mobile Phone Industrial Design」,Openmoko 以 ShareAlike Creative Commons (創用CC)授權開放 Neo 手機的工業設計原稿,讓設計師可以自由修改 Neo 工業設計。

創用CC不是一件新鮮事,但是將產品的工業設計原稿以創用CC授權對外公開,還是史上頭一遭。這次所公開的工業設計是 Neo1973 的設計,並提供 CAD 檔供下載 [http://downloads.openmoko.org/CAD/]。

不過早在此新聞稿發佈的幾個禮拜前,Openmoko 早就已經將 CAD 檔公開在首頁上(openmoko.com),社群上的人也很快得到這個消息並下載 CAD 檔,其中也有大學教授,將 Neo 的 CAD 應用在實務教學上。在這則新聞稿發佈的幾天前,一位大學教授 Guillermo 也將他所設計的 Neo 概念機回饋給 Openmoko;Guillermo 教授也提到:

"I am amazed at the depth of your commitment to open design. This must be the first time in history that a company has opened its intellectual property to this extent. Openmoko's revolutionary posting of the CAD files gives a whole new generation of Industrial Design students incredible insight into how it's done as well as an opportunity to contribute with new concepts."

「這是人類歷史上第一次有公司將他們寶貴的智財開放」。

March 15, 2008

[教育訓練紀錄] nonblocking wait: try lock

今天在進行 GNU Toolchains 與 Embedded Linux Programming 教育訓練課程時,提及以 shared memory 實作 IPC 時的同步問題。針對 unrelated process 的同步存取控制,一種古老的做法「locking」能簡單地應用在此同步問題上。

當寫入端做出 locking(如:lock file)時,讀取端便要等待 locking 被解除,因此這是一個 blocking wait 的架構。不過,若將「wait for unlucking」改成「try lock」,便能在中間的空閒時間「做點事情」,程式也不會晾著沒事做。

lock_trylock.png

一種簡單的程式架構,以「try lock」來做同步控制,讓程式閒著也要想辦法幹點活兒。另一個類似的觀念為 pthread semaphore 的 sem_trywait()

延伸閱讀

2007.01.16: Shared Memory 的 Race Condition

March 20, 2008

開放手機:談東方開源

今年的2月19到20日,中國開源軟件推廣聯盟(COPU, China OSS Promotion Union)與Linux基金會(the Linux Foundation)在北京共同舉辦「Linux Developer Symposium(Linux開發者研討會)」。全球三大手機聯盟LiPS、LiMO與OhA都到場發表演說。LiPS在會中提到「中國目前已經是全球最大的手機市場了。」顯見未來中國在手機產業,不管是消費者端、技術端或是規格標準面,都扮演重要的角色。

在手機市場策略方面,鎖定中國市場會是很好的做法,但是若想要由龐大的中國市場分享利益(market share),恐怕並不是一件簡單的事情。

去年全球手機出貨量大約11億支,其中有5.5億支是被賣到中國,佔了將近一半的數量,這還不包括「無法統計」的部份。中國市場由於受「在地文化」的影響很深,因此外來的手機廠商比較難以切入中國市場。中國的開源軟件風氣也很興盛,但與西方的開源文化確有很大的不同。

中國的開源軟件文化主要是由國家單位以及軟件公司推動,再加上本地文化的影響,造就出一個中國自已的特殊開放源碼文化。中國很重視「本地化」這件事情,所謂的本地化,只做「中文化」是不夠的,心須是中國本土「製作」的才是本地化軟件。

許多公司想要運用開放源碼策略進軍中國,但總是吃閉門𡙡。根本原因在於「開放源碼這件事情在中國已經自成體系」,直接拿西方那套策略套用在中國是行不通的。西方的開源是由社群(community)驅動,由社群裡發展出商業模式;但在中國或是台灣,開源是直接拿取開源軟件進行商業用途,直接透過企業或聯盟驅動。

《待續》

March 22, 2008

開放手機:Linux Mobile Phone

中國手機市場如此迷人,又該如何切入呢?開放手機平臺便是一個絕佳的機會。拿掉開放手機這件事不說,中國手機市場,不管是低價或高階手機,都已經被國際大廠佔據,很難從中再找到發揮的空間。此外,中國白牌與黑牌手機的特殊市場,更把中國手機的市場空間壓縮得更小,在中國,超過5000萬台的黑手機,消滅掉了一些中小型的手機廠的生存空間。

因此,透過開放平臺的Linux手機,在更低價手機端(高度一致性的軟硬體平臺),或是不同市場需求的高階手機市場,會是一個很好的機會。自從去年十一月份, Google 正式公開 Android 計畫後,「開放手機平臺(Open Mobile Platform)」的概念開始受到重視。幾個月下來,隨著媒體的報導,讓開放手機平臺概念的大量且持續的曝光,越來越多人在網路上討論這樣的概念,而真 正的引爆點則是 Android 原型機的現身。今年的 Mobile World Congress 展上出現了 Android 的原型機。

Linux手機的技術議題

Linux 作業系統在開放手機平臺佔有舉足輕重的角色,Android 的系統層使用 Linux 2.6 作業系統核心,OpenMoko 平臺也是採用 Linux 2.6 作業系統核心,另外一個重要的開放手機平臺 GMAE 也是基於 Linux 作業系統。

Linux kernel在技術端有幾個主要的議題,在北京的 Linux Developer Symposium上被提出討論。由於官方的Linux kernel更新速度相當頻繁,因此造成不同版本間的一些相容性問題。此外, Linux kernel的社群對Linux kernel的貢獻量已經到了一個很可怕的地步,因此還延伸出另外一個問題。許多patch的檢視與提交(commit)需要很長的時間,造成許多非官方的Linux kernel到處流竄。其它問題,包含在會議上幾個重要的Linux kernel開發者討論到的即時性與電源管理問題,以及本土化支援等。

Linux 開放手機的前景

開放手機的議題由Google的Android帶起全球性的熱烈討論,根據ABI Research的預測數據指出,在2012年以前(2007-2012),Linux手機將以每年超過75%的複合成長率成長,到2012年時,Linux手機在智慧型手機市場將佔有31%的市佔率,即大約3.31億支的Linux智慧型手機被賣出。

Linux手機未來也會受到微軟系統的正面挑戰,其中包括微軟指出,Linux侵犯了大約235項微軟的專利,這些都是未來開放手機的潛在挑戰。

《待續》

March 30, 2008

[教育訓練紀錄] 交叉編譯(cross compile)thttpd

本週進行 root filesystem 相關的教育訓練,今天給的課堂練習是 thttpd 的交叉編譯(cross compile)。thttpd 採用標準的 GNU autoconf 來產生 Makefile,因此,交叉編譯 thttpd 的方式是蠻簡單的。配合課堂提供的 cross toolchain(gcc 3.4.1),我們先定義以下有關 cross toolchain 路徑檔檔名的 Makefile 變數:

TOOL_TOP = /opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-9tdmi-linux-gnu
CC = $(TOOL_TOP)/bin/arm-9tdmi-linux-gnu-gcc
AR = $(TOOL_TOP)/bin/arm-9tdmi-linux-gnu-ar
LD = $(TOOL_TOP)/bin/arm-9tdmi-linux-gnu-ld
AS = $(TOOL_TOP)/bin/arm-9tdmi-linux-gnu-as
STRIP = $(TOOL_TOP)/bin/arm-9tdmi-linux-gnu-strip
RANLIB = $(TOOL_TOP)/bin/arm-9tdmi-linux-gnu-ranlib
TARGET_ARCH = arm-linux

接著再定義與 thttpd 的 'CFLAGS' 參數:

THTTPD_CFLAGS = -Os -Wall -mtune=arm9tdmi -march=armv4 \
                -fomit-frame-pointer -fsigned-char -fPIC

我們希望能有一個比較彈性以及系統化的做法,因此採用 Makefile 的系統來實作,不考慮編寫 script 的方式。接著,再定義一個 target,用來設定 thttpd 的 autoconf:

configured-thttpd:
        (export CC=$(CC); \
        export AR="$(AR)"; \
        export AS=$(AS); \
        export LD=$(LD); \
        export STRIP=$(STRIP); \
        export RANLIB=$(RANLIB); \
        export CFLAGS="$(THTTPD_CFLAGS)"; \
        ./configure \
                --prefix=/ \
                --host=$(TARGET_ARCH) );

我們想要用 'install' 指令來安裝 thttpd 執行檔到 root filesystem,因此 '--prefix' 參數的定義對我們講並不重要。Makefile 有良好的 dependencies 系統,所以我再撰寫一段 rule 如下:

thttpd: configured-thttpd
        make

接著,將以上的 Makefile 內容存檔,例如存成 thttpd.cross,再將這個檔案放到 thttpd 原始碼根目錄下,執行 make 並引用 thttpd.cross 的 'thttpd' target:

$ make -f thttpd.cross thttpd

一轉眼,我們得到 thttpd 的執行檔了。再將此 thttpd 執行檔加到 root filesystem 裡即可,別忘了,thttpd 需要幾個 shared library,把他們也加到 root filesystem 裡!還有,thttpd 會去讀取 user database(/etc/passwd 等),所以也要把 NSS 的 files 程式庫(libnss_files.so)加到 root filesystem 裡!

利用 Makefile 系統取代直接敲命令(或編寫 script)的麻煩做法,讓整個過程看起來簡單又清楚!

關於 March 2008

此頁面包含了在March 2008發表於Jollen's Blog的所有日記,它們從老到新列出。

前一個存檔 February 2008

後一個存檔 April 2008

更多信息可在 主索引 頁和 歸檔 頁看到。

Top | 授權條款 | Jollen's Forum: Blog 評論、討論與搜尋
Copyright(c) 2006 www.jollen.org