2007年8月21日 星期二

一個強制型別轉換與運算子優先性的有趣問題?

請問下列result與result1的值分別是多少?
Ex:
char data = 0xC1;
int result = 0, result1 = 0;

result = (int)(data);
result1 = (int)(data & 0xFF);
.
.
.
.
.
.
答案是result = -63, result = 193
您知道為什麼嗎?

2007年8月3日 星期五

Bitwise運算的限制

今天為了寫幾個API,並為了作資料動態長度的判別,因而使用到Bitwise的運算,以便檢測資料的長度,然而確一而在地發生錯誤,經反複測試及確認,原來Bitwise的運算不可以運用於"long long"型別的變數,僅可以適用於"char"/"short"/"int"/"long"幾種型別;因此,為了解決動態資料長度的判斷,改以Bit Shift的方式來解決。
(Data >> 32) > 0 ===> 8 bytes
(Data >> 16) > 0 ===> 4 bytes
(Data >> 8) > 0 ===> 2 bytes
(Data >> 0) > 0 ===> 1 bytes

2007年6月8日 星期五

如何在Multi-thread的架構下,以pthread實作Event

如何在Multi-thread的架構下,以pthread實作Event的作法:
我們常在其它的Embedded OS中使用Event的機制來達到Process之間的通訊,但在Linux中卻沒有Event的機制可供使用,此時您可以以這個方法來達成!

.我們可以宣告一個指定數目的Array做為Event的宣告。
.而Array中的每一個Element就當作是一個Event Bit。
.然後,我們可以為每一個欲等待的Event建立一個monitor thread,然後使用thread的condition Variable來等待該Event被設立。
.當Event被設立(Condition Variable的狀態為TRUE時),monitor thread就會被喚醒,它就可以通知等待此Event的thread。

詳細Sample Code待日後找個時間再Post出來!

2007年6月1日 星期五

如何解決在Java中出現亂碼的問題?

這個問題發生的原因是在Java的字型目錄中少了中文字型,可以將系統的字型連結過去,即可解決!
$cd /usr/java/jre1.6.0_01/lib/fonts/
$ln -s /usr/share/fonts/truetype/arphic/bkai00mp.ttf bkai00mp.ttf
$ln -s /usr/share/fonts/truetype/arphic/uming.ttf uming.ttf

重新啟用Java程式即可使用中文!

如何解決在linux上無法使用Freemind的問題?

最近為了在Linux上使用Freemind,從網路下載了最新版的Freemind下來使用,不料,新版的Freemind需要新版的JAVA才能使用(新版的Freemind使用了新的JAVA功能),此時竟發現新版的JAVA並未被放入Debian套件庫中(似乎是一些License的顧慮,Sun好像沒有完全開放),這下子Freemind卡在Java套件而無法使用。
為解決這個問題,我到了http://www.java.com/zh_TW/網站下載Java Runtime Environment Version 6 Update 1,我下載了jre-6u1-linux-i586.bin來使用,依下列步驟執行安裝:
$su
$cd /usr
$mkdir java
$cd java
$cp ~/jre-6u1-linux-i586.bin .
$chmod a+x jre-6u1-linux-i586.bin
$./jre-6u1-linux-i586.bin

將/usr/bin目錄下的java連結連結到所安裝的目錄
$cd /usr/bin
$mv java java-old
$ln -s /usr/java/jre1.6.0_01/bin/java java

這時侯再去執行Freemind就可以正確執行了!

如何知道PIPE或Socket的另一端已經斷線或關閉fd?

當您使用write()API來進行資料的傳送時,若此時PIPE或Socket發生斷線,或是對方關閉fd時,除了write()API會回傳error外,另外會收到errno=EPIPE的錯誤碼及SIGPIPE訊號會被觸發,這裡要小心,SIGPIPE訊號的預設對應動作是關閉程式,如果您沒有打算關閉程式,應該要把SIGPIPE的Handler改為SIG_IGN。

2007年5月15日 星期二

輕輕鬆鬆撰寫Host端的USB Device Driver---向系統註冊Device Driver篇

最近為了發展ICE的Device Driver,花了一些時間研究這個Topic,先前找了一些文件,的確對我助益良多,但畢竟是早期的文件,一些相關的API與資料結構都已經不一樣,無法完全套用,因此記錄一下這陣子嘗試撰寫Driver的心得!
1.以Module的型式撰寫Driver,以方便測試:
請參考前面提到如何撰寫Module程式的步驟來進行!別忘了init_module()/cleanup_module()兩個API
2.為自己的裝置定義Vendor ID及Product ID(注意!必須與裝置內的FW一致)
static struct usb_device_id danny_ids[] = {
{USB_DEVICE (Danny_ID, 0x12345)},
{ }
};
3.宣告ID Table
MODULE_DEVICE_TABLE (usb, danny_ids);
4.為自己的裝置宣告一個device driver (先定義兩個USB裝置插拔時會呼叫到的API,裡面暫時是空的)
static struct usb_driver DannyDriver = {
.name = "Danny Device",
.probe = danny_probe,
.disconnect = danny_disconnect,
.id_table = danny_ids,
};
5.在init_module()中向系統註冊Device Driver
usb_register(&DannyDriver);
6.別忘了!也要在cleanup_module()中加入從系統移除Device Driver的動作
usb_deregister(&DannyDriver);

程式撰寫到這裡,將driver掛載入系統後,插拔USB裝置,應該已有所反應,當裝置插入時,danny_probe()會被呼叫到;當移除裝置時,danny_disconnect()會被呼叫 ------- 待緒.....

2007年5月2日 星期三

不用USB View也能看到USB Device的資訊!

在Linux 2.6版的檔案系統中,您可以檢視
/proc/bus/usb/目錄下的devices檔案,裡面會儲存所有USB Devices的資訊。
Command:
less /proc/bus/usb/devices

2007年4月21日 星期六

如何在Linux 2.6的kernel上,編譯出module?

----先進行環境設定(以後可以略過這一步驟)
1.先安裝libncurses5-dev套件。
#>apt-get install libncurses5-dev
2.下載kernel source至/usr/src目錄中。
#>cd /usr/src
#>ftp ftp.kernel.org
username:anonymous
password:(void)
ftp> cd pub/linux/kernel/v2.6/
ftp> binary
ftp> get linux-2.6.xxxxx.tar.gz
ftp> bye
3.將kernel source解開。
#>tar xzvf linux-2.6.xxxxx.tar.gz
4.編譯kernel source。
#>cd linux-2.6.xxxxx
#>make menuconfig
#>make
4.做一個Symbolic Link的目錄
#>cd /lib/modules/2.6.xxxxx/
#>ln -s /usr/src/linux-2.6.xxxxx build

----撰寫及安裝程式
5.撰寫模組程式,別忘了下列兩個最基本的函式。
int init_module(void);
void cleanup_module(void);
.....
6.撰寫Makefile檔。(使用2.6版kernel source的編譯設定)
obj-m += xxxxx.o

all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
7.編譯程式。
#>make
8.它將會產出xxxxx.ko(xxxxx.ko是Linux 2.6版模組預設的附檔名,在Linux 2.4版時是xxxxx.o)。
9.將其與Linux Kernel連結。
#>insmod xxxxx.ko
10.檢查其是否確實存在。
#>lsmod | grep --color "xxxxx"
11.將其移出Linux Kernel。
#>rmmod xxxxx

printk( ) 的Priority

寫Driver時,可以以printk( )來顯示訊息進行debug,當其priority數值小於console_loglevel時,就會被顯示出來。其相關的priority數值定義如下:
#define KERN_EMERG "<0>" /* system is unusable */
#define KERN_ALERT "<1>" /* action must be taken immediately */
#define KERN_CRIT "<2>" /* critical conditions */
#define KERN_ERR "<3>" /* error conditions */
#define KERN_WARNING "<4>" /* warning conditions */
#define KERN_NOTICE "<5>" /* normal but significant condition */
#define KERN_INFO "<6>" /* informational */
#define KERN_DEBUG "<7>" /* debug-level messages */

2007年4月14日 星期六

2007年4月11日 星期三

Precise Exception與Imprecise Exception的差異

Exception可分為二類:一者為precise exception,另一者為imprecise exception。
.precise exception指的是當某一個指令(會觸發exception的指令)仍在處理器pipeline執行的過程中,即發出change control flow的event,並且進入exception handler。Ex:指令格式錯誤時,所發出的Instruction Exception。
.imprecise exception指的是當某一個指令(會觸發exception的指令)在處理器pileline執行完後,才發出change control flow的event,然後才進入exception handler中執行。Ex:在讀取資料時,所發生的bus error。

2007年4月10日 星期二

有關Cache的read/write through/back/allocate的意義

所謂的read/write cache的hit/miss,指的是CPU要read/write某一位址的資料,若此時cache裡的資料剛好是該位址的資料,則稱為cache hit,若此時cache裡的資料不是該位址的資料,則稱為cache miss。
.當cache hit時,若CPU要讀取某一位址的資料時,會直接從cache中讀取資料。
.當cache miss時,若CPU要讀取某一位址的資料時,又可分為二種方式:一種是read through,這種方式會直接將資料從主記憶體端讀進CPU;另一種是no read through,這種方式會先將資料從主記憶體端讀進cache,然後再從cache讀進CPU。
.當cache hit時,若CPU要寫入資料到某一位址時,可分為二種方式:一種是write through,此種方式資料會立刻寫到cache及主記憶體中;另一種是write back,此種方式會先將資料寫入cache中,然後再將同一位址的資料整批一起寫入主記憶體中(非立即寫入)。
.當cache miss時,若CPU要寫入資料到某一位址時,可分為二種方式:一種是no write allocate,此種方式會直接將資料寫到主記憶體中,不會再從記憶體中載入到cache,另一種方式是write allocate,此種方式會先將資料從主記憶體中載入到cache,然後再依cache hit的規則,將資料寫出。