發表文章

目前顯示的是 八月, 2009的文章

盡信書不如無書,任無書不如造書

書,載文記字之功用也,乃人造物。文雜,詞誤,字歧,義鈍,皆常事。況執筆者亦非聖賢,能悟不可書,能書不達義,無可厚非。面目和善者,或讀書,或習字,心於書之求道,而屢限自身悟不得者眾,誤習非方圓者則已,錯解其義者甚悲矣。

冰於水,終融而無跡,承源接續,乃不變之定律;異物於水,或溺,或濁,非道德也。同文重義,於閱者異,倘不思源不解續,文無義,無功徒勞;明文謬義,如溺濁水,正道不得入,正路不可取,雞鳴狗道之物。

常有莊周寓言,盛載冰水,卻為解義說書者染之,於後世沉浮,歸宗不可,清談自成其道,盡信書焉?追源無書,還原其貌,自然天成,閱者無不拍案叫絕,又何需多言?

無書追源亦無續,應當造書成命。既執書,必慎要點提綱,內求脈通,外求載無誤,內外同證,利己且濟世。

自愧常提文不慎,望步正軌而改之,文以示無書之道,自許。

實作偽 GLib Singly-Linked Lists

這些日子以來真的被 GLib 給寵壞,它將什麼東西都包成漂亮的 API,讓人用的很開心。但是在許多環境下,像是有限資源的 Embedded System 之中或是在單純的 DOS 裡,想要使用 GLib 可是難上加難,因此免不了要自己實作同樣的功能。而其中最常見的功能莫過於 Linked-list,雖然觀念和方法在所謂的『資料結構』教課本中有如『解數學的聯立方程式』一般被講到爛,但真要一步步做起來也不免覺得麻煩,於是空閒之於就寫好放著,以後 Copy & Paste 就好了。 :-)

既然已經很熟悉 GLib 的 API,就乾脆實作出一模一樣,也方便記憶和使用。
/* Singly-Linked Lists structure */
struct Myslist_ {
void *data;
struct Myslist *next;
};
typedef struct Myslist_ Myslist;

/* marco */
#define myslist_next(list) (list->next);

Myslist *myslist_prepend(Myslist *list, void *data)
{
Myslist *new;

new = (Myslist *)malloc(sizeof(Myslist));
new->data = data;
new->next = list;

return new;
} 然後可以這樣使用,修改自舊文『Glib 就是懶.資料處理好手 - GList 雙向鏈結(Doubly-Linked)』:
typedef struct {
char *name;
char *tel;
} ContactNode;

int main() {
Myslist *contactlist = NULL;
Myslist *list = NULL;
ContactNode *node;

/* Fred's contact information */
node = (ContactNode *)malloc(sizeof(ContactNode));
node->name = strdup("Fred Chien");
node->t…

LXDE on HTC Hero!

圖片
日前在 IRC [irc.freenode.net #lxde] 上有位網友『Andrea Florio』開心的宣布『LXDE running on HTC HERO』,然後公開了幾張手上的照片讓大家嘗鮮。更多 Porting 的細節和說明,可以參考『LXDE can do it! LXDE on Android smartphone!』一文。

文中提到的做法,是在開發『openSUSE@ARM project』過程中的成果,但目前運作的系統是 Debian 而非 OpenSUSE,另外也有提到 HTC Hero 的一些硬體資訊:
# cat /proc/cpuinfo
Processor : ARMv6-compatible processor rev 2 (v6l)
BogoMIPS : 526.25
Features : swp half thumb fastmult edsp java
CPU implementer : 0×41
CPU architecture: 6TEJ
CPU variant : 0×1
CPU part : 0xb36
CPU revision : 2
Cache type : write-back
Cache clean : cp15 c7 ops
Cache lockdown : format C
Cache format : Harvard
I size : 32768
I assoc : 4
I line length : 32
I sets : 256
D size : 32768
D assoc : 4
D line length : 32
D sets : 256Hardware : hero
Revision : 0080
Serial : 0000000000000000

不跟著主流走的 Embedded Hardware

個人電腦追求最快、最新、高規格,台灣廠商也很厲害的達成超值、大量、超低價,成本不但下殺血流成河,其毛利也真的是以『毛』為單位來計算。的確,個人電腦零組件因此能便宜到足夠打壓 嵌入式系統(Embedded System)的市場,若以同樣價格的硬體來比較,個人電腦的效能硬是勝過一大截。

Embedded System 向來以客制化、量身打造為主要優勢,就單純只論達到產品目標,Embedded Hardware 也因為能做到剛剛好合用,使其量產成本下壓。不過如今 Netbook 的出現,令 Intel Atom 大量投入輕省市場,單買現成的 x86 Hardware 已經不會比量產 Embedded Hardware 來得貴時,到底投入 Embedded System 有哪些好處就得再詳加思考了。

使用 Embedded System 不外乎是因為他的省電、輕巧、客制化,因為有許多廠商對硬體的要求其實並不高,如果能夠用更低廉價格和研發成本做出產品,使用 Embedded System 就是值得的。而這些需求其實大致上都可以有個簡單的分類:
運算功能影像處理(一般顯示、進階加速)通用外接 bus (USB、UART、MiniPCI...etc)其他有的沒有的晶片(通訊晶片等...etc)
過去產業的做法,是將以上需求選擇出來,然後重新設計 Layout,最後再自己生產自己的 Embedded Hardware,但往往因為自行擔負了研發成本、開模成本和生產成本,造成價格上根本不敵 PC 大廠的大量產線。那麼,為何還要獨斷獨行?不自己生產又想比 PC 更低價,要怎麼辦?

舉一個例子,有些產品可能只需要不高的『運算功能』加上『通訊晶片』,再更多只要可以一般顯示的『影像處理』即可。事實上,能夠達成這些功能的硬體,在市面上其實已經堆積成山,甚至有許多生產廠『大量庫存』家中,苦往肚子裡吞,不敢為外人所知。然後,等到下一季來到,這些退流行的『貨』更永不見天日。尋思,我們能否借助這些廠商的庫存貨,當做現成硬體,修改成其他產品再出貨呢?對雙方面,都有好處。

當然,以上做法只是針對這個 PC 和 Embedded System 交戰的過渡期,更仔細來分析,其實這有如設計產品的廠商們合併單,一起生產大量的硬體,以取得便宜的硬體,用更平實的說法就是『團購』。不過如此生產出來的硬體會有個問題,那就是無法同時合…

使用 Serial Port(RS-232) Terminal 原來可以這麼容易

現在還在用 [Gtkterm] 就遜掉了!既然立志當 Geek,要向『宅.色.舒服』看齊,那就一定要更宅一些,在 console mode 下搞定一切,才是正道呀!

其實,[GNU Screen] 除了用來掛 IRC 外,亦可以當做 Serial Port (RS-232) Terminal Program:
screen /dev/ttyUSB0 115200

雖然宅,但不要以為 screen 只能拿來掛 IRC 好嗎?

Emdebian - 快速建構你的嵌入式系統

圖片
毫無疑問,目前『Debian』已經成為當今最龐大的 Linux 體系之一,包括目前最為人所知的 Ubuntu,其表皮之下都是 Debian 的骨。Debian 支援超過十一種以上的硬體架構,包括了 i386/IA-32、m68k、sparc、Alpha、PowerPC、ARM、MIPS、hppa、IA-64、s390、AMD64,還有更多計劃支援但仍在移植中的平台,如:ppc64、SuperH、armeb、m32r、AVR32等。要用 Debian 打造任何一種硬體平台上的作業系統,可說是輕而易舉,甚至不必撰寫一行 Code 或學習使用 cross-compiler,只要會用 debootstrap 和 apt-get。

但是,除了傳統 x86 和幾個特定平台外,大多數的硬體架構都是用於嵌入式應用,其硬體資源相對較低,若將 x86 完整的系統移植過去,似乎沒有多大價值,軟體甚至可能因硬體限制(CPU、Memory、Storage)而無法使用。


因此,『Emdebian (Embedded Debian)』計畫誕生,該計畫首要目標是建構最小化的 Debian System,更進一步因應需求而打造出最輕量的嵌入式系統,並保留 Debian 的套件管理結構和特性。目前, Emdebian 分兩種版本:
Emdebian Grip - A smaller Debian-compatible distro

一個小型的 Debian distro,但完全與官方 Debian 保持相容性,這意味著仍然可以在這系統上直接安裝官方 Debian 的東西(包括 Stable、Unstable、Testing 等版本)。其改進了 apt 的工具程式,使基礎系統更輕量化,更進一步將許多套件重新打包,減少平時很少用到的系統文件和相依性。

目前 Grip 所支援的硬體平台有 arm, armel, i386, amd64, powerpc, mips, mipsel。

Emdebian Crush - An ultimately small, cross-built, Debian.

這是針對高要求嵌入式系統所特別開發的版本,為了能真正使用在嵌入式系統,引入了 Busybox 等輕量化的工具程式,捨棄許多原本 Debian 系統內的累贅。目前 Crush 只有支援 ARM 架構,且參考了各版本的 Debi…

COSCUP 2009 閉幕

圖片
這是演唱會入場嗎?沒看過 Open Source 活動要排過這麼長隊伍等著入場,聽說有人第一天早上六點就來排隊了!『COSCUP 2009』實在是盛況空前呀!
在第二天的早上議程,小弟有一場簡短的 LXDE Talk,時間太趕了!我們是唯一一場需要兩個講者的議程呀!

在最後,各工作人員上台一鞠躬,感謝大家的參與!因為多虧大家的支持,今年的 COSCUP 2009 順利閉幕!

明年,希望大家仍給予支持!明年再見!

COSCUP 2009 籌備團隊與工作人員合影

更多照片可去 Flickr 瀏覽:
http://www.flickr.com/photos/tags/coscup2009/

淺談 USB 通訊架構之定義(二)

圖片
之前『淺談 USB 通訊架構之定義(一)』已經提過 USB 大致上的概念和一些特性,以及如何從 Linux 上去嘗試驗證 USB Device 上的 Information,但還尚未談及 USB Device 是如何與 USB Host 做溝通。而且,初始化的過程也很重要,該過程會讓一個 USB Device 描述自己的『模式(Configuration)』和『介面(Interface)』以及更多配置上的關鍵訊息。雖然這些初始化過程和定義繁雜,但是拜 OS 優良的包裝所賜,一般驅動程式都可以假設已知或是透過簡單的 API 去取得這些資訊以進行開發,因為大多數初始化動作會自動由 OS Kernel 和 Firmware 所完成。

簡單的 USB Device 初始化流程
插上 USB 裝置Host 請裝置報告『裝置描述資訊(Device Descriptors)』(此過程又稱為 Enumeration)
由 Device Descriptors 得知『模式的數量(bNumConfigurations)』Host 請裝置回報『模式的描述資訊(Configuration Descriptors)』
由 Configuration Descriptors 得知『介面的數量(bNumInterfaces)』Host 請裝置回報『介面的描述資訊(Interface Descriptors)』
由 Interface Descriptors 得知『端點的數量(bNumEndpoints)』Host 請裝置回報『端點的描述資訊(Endpoint Descriptors)』
由 Endpoint Descriptors 得知『該端點的資料傳輸模式(bmAttributes)』等訊息等待驅動程式進行後續處理整個 USB Device 的描述結構可以圖表示:
當然,若不是 USB Device 設計者或是 USB Host Controller 晶片的 Firmware/Driver 開發人員,可以不用知道這麼多過程細節,因為無論是 Linux 還是其他作業系統,它們都會將這些最低階的過程包裝起來,等著驅動程式去使用,而 Linux Kernel 上負責此任務的就被稱為『USB core』。

註:因為古老的 DOS 在設計上沒有 USB 的支援,故沒有這種中間層的包裝,若要在上面開發 USB 驅動程式…

淺談 USB 通訊架構之定義(一)

圖片
USB(Universal Serial Bus) 的應用範疇以及價值已經不需要再多做說明,其身影從 HID(Human Interface Device)、隨身碟(USB Stick、Flash drive、Pen drive)到各種類比式或非連續訊號接收器(如: Webcam、Microphone、DVB Receiver),更進一步可以講到各種通訊裝置或外接設備,甚至是取代和模擬舊式通訊傳輸線(Serial Port)。USB 所有的 Spec 和相關資訊 ,可參考 http://www.usb.org/

USB 整體運作模式

一般來說 USB 的通訊結構有如 Server/Client,以 PC 上的情形為例,位於主機上的 USB 裝置稱為『USB Host』,我們可以在上面外接上數個裝置(與 USB Host 相連的裝置通常被稱為 USB Device 或 USB Client)。

底層上,『Host 負責主導整個 USB 結構的通訊』,它會輪詢所有的 USB Deivce 以檢查是否有裝置需要傳送資料,所有 USB Device 都必需要等待 Host 的命令,唯有 Host 同意時,USB Device 才可以開始傳送資料。



Host 的行為通常是由 USB Host Controller 在做控制,其控制器是一組控制晶片,而對於現代 PC ,USB Host Controller 的晶片通常都被 Layout 在主機板上,以 PCI Bus 的形式存在供作業系統控制,我們可以使用 lspci 看到它的存在:
00:1a.0 USB Controller: Intel Corporation 82801I (ICH9 Family) USB UHCI Controller #4 (rev 03)
00:1a.1 USB Controller: Intel Corporation 82801I (ICH9 Family) USB UHCI Controller #5 (rev 03)
00:1a.2 USB Controller: Intel Corporation 82801I (ICH9 Family) USB UHCI Controller #6 (rev 03)
00:1a.7 USB Controller: Intel Corporation 82801…

GLib 就是懶.g_timeout 週期性的做壞事

要是你有撰寫 JavaScript 的經驗,應該對 setTimeout() 一點都不陌生,簡而言之,該功能就是要『N 秒後』去呼叫某一個 function,該功能可以用到的地方很多,如寫一支時鐘程式時,每秒去更新顯示一次時間。當然,給懶人用的 GLIB 也有提供類似的功能,你可以在官方文件的『The Main Event Loop』一章找到詳細說明。

這是一段簡單的範例,每秒會 print 出一行 BAD! 字串:
#include <stdio.h>
#include <glib.h>

gboolean showme(gpointer user_data)
{
printf("BAD!\n");

/* TRUE 就繼續每秒跑一次;若是 return FALSE,則不再繼續執行 */
return TRUE;
}

int main(int argc, char **argv)
{
GMainContext *main_context;

/* 每秒跑一次 show() */
g_timeout_add(1000, showme, NULL);

/* 進入程式 Loop,例如:gtk_main() */
g_main_loop_run(g_main_loop_new (main_context, FALSE));
}
雖然 g_timeout 真正的底層實作並非如此,你還是可以想像它是建立一個新的 Thread,用 select() 去做 polling,至少在使用上有同等意義。此外,因為 g_timeout 是實作於 GLIB Main Loop 中,它無法非常精準的在多少秒後呼叫 function,通常會有一些極微小的延遲(幾乎感覺不到),不過對於極大多數的應用來說,非常足夠了。

Linux Kernel - fanotify 更全面性的檔案監控機制

若是有在追 kernel development 的動態,就可以發現到 Linux Kernel 將在 2.6.31 引入 fanotify 這個新特性,其本意是『fscking all notification system』,目的在實現更全面性的檔案監控機制。除了可監聽 file description 的 events,亦可以當 open 和 write 的 event 觸發時決定是否給予存取,對做安全控管的程式有很大的幫助。

當初 fanotify 會被提出是就因為要保護系統,供惡意程式偵測軟體和一些系統安全軟體所使用,又因為了達成該需求,使用舊有的監控機制會效能不彰,而重新實作了 fanotify,以排除舊有機制實作過於複雜的缺點。

fanotify 分成兩個部份『Directed』和『Global』, Directed 的部份就如同 inotify/dnotify,可以單獨去針對特定 inode 進行 event 監聽;而 Global 部份提供了對整個系統進行監聽 event 的機制,在意義上對於真正完整的檔案監控有莫大的幫助。

至於 kernel/user-space 的溝通實作上,fanotify 採用的方法是 socket protocol,屆時會有一個新的 PF_FANOTIFY family 被提供,讓 user-space 的應用程式所呼叫使用。

關於 fanotify 的 kernel patch 可以在此找到:
http://people.redhat.com/~eparis/fanotify/

或是可以參考 kernel.org 上的兩則 commit logs:
fsnotify: unified filesystem notification backend
fsnotify: generic notification queue and waitq

以『e 化』之名行公司整頓之實

最近什麼案子都接洽的結果,就是體會到了不少事情,也對許多案子有了一些心得,像是自網路發燒就炒個沒完的『e 化』,也讓人感觸良多。尤其到了 2009 年的現在,仍然還有企業或機構有『e 化』或是再嘗試『e 化』的需求,真令人想反省一下為什麼大多數『e 化』總是痛苦、無用或失敗的,導致有許多老闆對資訊人員叱之以鼻,痛惡至極。沒錯,到了今日 ERP、CRM、網站系統都成為了現代化的標準配備,總讓企業們覺得缺一不可,沒有一家企業不是對全資訊系統趨之若騖,但是卻都常被技術人員沖昏了頭,往錯誤的方向走。

『e 化』目的?

若是您的公司也導入了『e 化』的系統,趕上流行之餘,建議各個業主好好思考『e 化』成果是否真的具有價值。因為事實上,你可能會突然發現,自家公司並不需要『e 化』,需要的卻是以『e 化』之名行公司整頓之實。

你要的是什麼:
改善人
減少人力浪費減少人為疏失明確責任歸屬
改善事
加速訊息傳遞提升行政效率提升業務結案績效行政透明化
改善物
節省實體物質帶來的成本(時間、預算、空間)控管重要機密文件更重要的是,老闆和高階管理階層,可以借由『e 化』成果輕易掌控公司全局,這也是各個上司夢寐以求的。

『電腦必定會帶來效率』的迷思

許多人都在不知不覺中,有著『電腦必定會帶來效率』的迷思,似乎都以為將手上工作數位化就能提升工作績效,企業內部員工往往只是向『e 化』的開發者提出自己希望的功能,但卻不曉得之所以自己會希望有這功能,是因為身處於在一個錯誤或混亂的工作流程上。

平心而論,無論是用各種現成套裝軟體,還是量身定制自家資訊系統,既然決定要『e 化』,前述種種『e 化』的目的就是必需要達到。然而,接案者和各家公司的 MIS ,往往只是將傳統在辦公桌上做的事,移到了電腦螢幕上在做,便稱做『e 化』,其是否真的有為公司帶來任何效益不得而知,但肯定花了大量金錢和時間。其原因不難理解,一方面是接案者通常心中只想如何方便結案與驗收,開發模式就是創造一個個的獨立工具和功能去讓企業驗收;另一方面,MIS也可能只是以技術的角度建置和開發系統,沒考量到公司確實的需求。無論如何,這都將會造成日後系統不合用或過度開發的主要原因。

新的工業革命,而不是新的工具

回顧歷史,工業革命為人類和經濟產業帶來了重大的變革,最重要一點就是產線化和自動化,其帶來了史無前例的生產速度和產量,到了二十一世紀的今天,ISO 品質認證依然是許多工…

mips 和 mipsel 的差異

之前『arm 和 armel 的差異』一文有提過,ARM 的支援分成了『arm』和『armel』,其實,MIPS 也分成了『mips』和『mipsel』,只不過意義上和 ARM 有所不同,而 MIPS 的兩種支援指的是 big-endian 和 little-endian,mis"el" 指的就是『little-endian』之意。

MIPS 使用的 Endianness 因 Processor 而異,有 big-endian 也有 little-endian,甚至是可以同時兩種模式並行。舉例來說,SGI 的機器(SGI O2 with R5000, R5200 and RM7000 CPU)是運作於 big-endian mode;Cobalt RaQ/Qube2/RaQ2 是運作於 little-endian mode;雙模式並行的有 Broadcom BCM91250A(SWARM)/BCM91480B(BigSur) evaluation board。