星期一, 7月 26, 2010

Linux Driver基礎篇-編譯與掛載

先前介紹了一個簡單的字元範例,這個範例不需要任何硬體線路單純只使用printk函數輸出,一個標準的HELLO WORLD程式。那建立完範本該如何編譯? 如何掛載? 如何使用? 往後一一講解。

首先我的開發環境是使用ubuntu,核心版本是2.6.24,PC環境基本上用哪個版本的套件對以下步驟無多大影響,在這先以PC環境為主,往後在介紹ARM的cross compiler。而我們開發的是linux driver,因此編譯的時候linux核心src是不能缺少,所編譯的driver版本與核心版本必須是近似甚至相同的,反則會面臨雖然編譯程公卻無法掛載的命運,所幸PC環境上的套件都會有src,因此這部分無需擔心。

現在先將先開啟一新的資料夾,並將先前介紹的範本檔案建立存入該資料夾中。在開一個新檔案叫Makefile,對linux開發不熟的可能對此檔不清楚,這是make編譯程式的批次檔,方便開發使用,該檔案內容如下:

TARGET=demo
KDIR:=/lib/modules/$(shell uname -r)/build PWD:=$(shell pwd) obj-m:=$(TARGET).o default: make -C $(KDIR) M=$(PWD) modules clean: rm -rf *.o *.ko modules.* Modules.* *.mod.c
存檔即可,此批次檔TARGET設的參數將為該資料夾編譯後的檔名,在此設定為demo,編譯後產生demo.ko為我們所要掛載的driver module。之後在該資料夾下打入make即可編譯成功。
在Linux下掛載driver的相關命令如下:
1. 掛載:insmod <檔名>
2. 狀態:lsmod
3. 卸載:rmmod <名稱>
當然,如果你使用的事ubuntu,以上命令前要加sudo。打入 sudo insmod demo.ko,輸入管理者密碼即可成功掛載。當然畫面上不會出現任何訊息,因為printf是寫入核心態,我們的畫面是使用者態,核心的printf只能從log或dmesg命令查看,因此打入dmesg,就可以看到掛載訊息了。至於相同的,卸載就打入 sudo rmmod demo,從dmesg也可以看到成功卸載的log。

Linux Driver 字元型基礎篇

1. 引入標頭檔

在撰寫 driver 前必須先 include 一些標頭檔:

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
2. 撰寫控制元件的函式

struct file_operations 即為定義各個 function pointer 的 structure。

static ssize_t drv_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
{
printk("device read\n");
return count;
}

static ssize_t drv_write(struct file *filp, const char *buf, size_t count, loff_t *ppos)
{
printk("device write\n");
return count;
}

static int drv_open(struct inode *inode, struct file *filp)
{
printk("device open\n");
return 0;
}

int drv_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
printk("device ioctl\n");
return 0;
}

static int drv_release(struct inode *inode, struct file *filp)
{
printk("device close\n");
return 0;
}

struct file_operations drv_fops =
{
read: drv_read,
write: drv_write,
ioctl: drv_ioctl,
open: drv_open,
release: drv_release,
};
3. 撰寫初始化、結束元件的函式
#define MAJOR_NUM          60
#define MODULE_NAME "DEMO"
static int demo_init(void) {
if (register_chrdev(MAJOR_NUM, "demo", &drv_fops) < 0) {
printk("<1>%s: can't get major %d\n", MODULE_NAME, MAJOR_NUM);
return (-EBUSY);
}
printk("<1>%s: started\n", MODULE_NAME);
return 0;
}
static void demo_exit(void) {
unregister_chrdev(MAJOR_NUM, "demo");
printk("<1>%s: removed\n", MODULE_NAME);
}
module_init(demo_init);
module_exit(demo_exit);

其中 MAJOR_NUM 即為 driver 所對應的 device 的 major number

    星期四, 7月 22, 2010

    康希牧師─選擇正確伴侶(1)

    雖然我已不是一個基督信徒,但屏除信仰問題,教會牧師傳教者傳受家庭觀念、兩性相處、群體相處的方式是非常正面,很值得學習。這篇「選擇正確伴侶」是新加坡城市「豐收教會」創辦人康希牧師所演講,先前跟某動物借DVD來看的,加上前段「家庭的目的」共三片DVD,其實看DVD比較能感受牧師精彩的內容,非常值得推薦。對於DVD有興趣請物找我,動物已在米國我借不到摟,以下為網路上的口譯版本,第一篇題到選擇伴侶的「三點迷思」和「八個不會有結果」的狀況,在此供有興趣的人參考摟:

    [本文]

    我相信婚姻是美好無比的,上帝從一開始就設立了婚姻,因為上帝是良善的所以絕不會害我們,創世記二章15節”耶和華上帝將那人安置在伊甸園,使他修理、看守”上帝給亞當一個工作這是一個很具挑戰性的工作,他不只是一個園丁而已,而是「伊甸園企業王國」總裁,他是主要的植物學家,也是主要的生物學家,他負責將所有的動植物歸類命名和分類,你可以說亞當命好,畢竟他是住在天堂樂園中,他的生活舒適又豪華,他擁有世上一切的財富,整個黃金打造的園子都是他的,他可以在黃金地面上溜冰。而且他也很健康,不會生病他擁有健康和財富都很完美,除了一件事...亞當孤單一人,十分寂寞;18節:耶和華上帝說那人獨居不好,我要為他造一個配偶幫助他21節:耶和華上帝使他沉睡他就睡了,於是取下他的一條肋骨又把肉合起來,耶和華上帝就用那人身上所取的肋骨造成一個女人領她到男人跟前,亞當說這是我骨中的骨,肉中的肉可以稱她為「女人」,因為她是從「男人」身上取出來的。上帝難道不知道夏娃來了後魔鬼會去試探她?

    祂當然知道!上帝難道不知道夏娃會落入試探,全人類會因為亞當而受到罪的咒詛?上帝當然都知道!祂知道創造女人是一個冒險,但上帝比較關心亞當的品格,而非舒適。人會寂寞往往是因為築牆而不是造橋,有品格的人才會搭起橋樑和別人溝通,有品格的人才會不只為自己活而是關心別人,跟別人分享,捨己付出和保護,有品格的人才會聆聽、溝通、愛和饒恕;如果亞當單獨一人,他會饒恕別人嗎?不會;他會需要保護別人嗎?不會;他會需要供應別人嗎?不會。

    亞當本來可以獨自享受一切的舒適和財富,但上帝比較在乎亞當的品格而非舒適的生活,否則何必創造夏娃呢?亞當哪需要婚姻?他在工作上有成就感、他的工作有挑戰性、他有錢有勢,而且他住在樂園中。但健康富裕有錢有勢的人也可能是壞胚子,富裕成功的人也可能人品很差。亞當擁有事業和財富一樣都不缺,他蒙受很大的祝福,但上帝在他身上看見一個缺點:亞當必須結婚才能培養出男人該有的一切品格。

    所以婚姻是祝福還是咒詛呢?婚姻是上帝所賜的福氣!在穩固健全的婚姻中會經歷到滿足和喜樂,情感、人際關係、身體各方面;但最重要的是:好的婚姻可以培養品格使你成為合神心意的人,使你在屬靈上成長,當耶穌再來時可以做祂美麗的新娘,阿們嗎?請注意一下,目前為止我談的是美滿的婚姻,穩固、蒙福、健全的婚姻,你的婚姻可以像在天堂一樣幸福,但前提是選對終身伴侶,問題是沒有人教我們如何選擇好的終身伴侶;大多數人買車比擇偶花更多的時間和精神,人人都想活得快樂也希望婚姻幸福,沒有人一開始就打算,將來要讓愛情走入墳墓,多少人早上醒來沒事幹時,會突發奇想說我要去做一些讓自己傷心的事我要去找個對象來折磨我,沒有人會刻意這麼做,但其實很多人選錯了對象,卻不明白為什麼感情不順利,根本原因就是選錯了對象!

    選對終身伴侶我要先說一件事可能會讓很多人嚇一跳,上帝不會替你選終身伴侶!上帝不會替你選終身伴侶!祂知道誰最適合你但最後的選擇權在你手上,上帝把擇偶的責任全部交給你,如果有個男生來對妳說上帝說妳是我的理想對象,給他一個耳光,然後走開,不要相信有些先知預言說,上帝已經為你預備某某人,上帝要你跟他結婚...別單單因為某個先知預言,就跟某人結婚,我們不是看輕先知預言,但這不是上帝的做法:箴言十八章22節:覓得賢妻的,就是覓得幸福,也是蒙了耶和華的恩惠,誰要去找呢?就是你,你得去找。箴言廿五章2節把事隱藏,是上帝的榮耀,把事察清,是君王的光榮誰要查清楚?是你,上帝會引導你、指示你,你要讀聖經,上帝很少把人帶到你面前說,就是她,現在就跟她結婚,上帝會給你原則和指示,但最後的選擇在你手上,不去找,就只好單身一輩子,婚姻誓約中講得很清楚,一旦做了選擇不論好壞都要相守一生。有個女人告訴法官說:我要離婚,為什麼?我不喜歡他,可是你發了誓言不論好壞都要相守一生;沒錯,但情況比我原來想的糟太多了!所以,我們怎麼知道誰才是合適的伴侶?人是怎麼墜入愛河的?我舉幾個例子好了:我在健身房運動時認識了珍,看她勁力十足跳著有氧舞蹈我就深深被她吸引;蘇琳是我表姐結婚時的伴娘著粉紅色洋裝的她閃閃動人,我對她一見鍾情;艾瑞克和我被主管指定做同一個計劃,他擅長解決難題,很有創意這一點很吸引我;我的前夫自私又霸道,我喜歡史丹利是因為他人很好非常善體人意。可以因為上述這些原因開始交往嗎? 我的答案是:不行

    珍的男友只知道她精力充沛;蘇琳的男友只知道她穿粉紅色洋裝很漂亮;艾瑞克的女友只是仰慕他的工作能力,但他的情感能力呢?史丹利的女友只知道他和前夫很不一樣,但對方到底適不適合這又是另外一回事,今天我要跟大家分享三個致命的愛情迷思:愛情的迷思是指大多數人,對愛情所抱持的錯誤想法,結果使我們無法明智擇偶,明智擇偶! 我今天要談三個致命的愛情迷思:

    第一個迷思是---真正的愛情能征服一切
    真正的愛情能征服一切,只要有愛情就行了,我們心裡都希望這是真的,只要我們愛對方婚姻就會幸福,只要我很愛對方他酗酒也沒關係,他老是批評我也沒關係只要我更愛他就好了,即使我不被他的外表吸引也沒關係,即使他過去兩年都遊手好閒也沒關係,即使她脾氣暴躁,老是發脾氣也沒關係,即使他常常拈花惹草也沒關係,即使我想要孩子但對方不要也沒關係,即使他很難表達情感也沒關係,我只要一直愛他就好了、只要我夠愛她就行了!即使她跟前男友藕斷絲連、即使他大我卅歲也沒關係、即使我們信仰不同也沒有關係,愛情能征服一切!
    我講一個聖經上的故事,創世記廿四章以撒到了適婚年齡,以撒和利百加都到了適婚年齡,但有一個問題,他住在迦南而她住在米索波大米,一對正值適婚年齡的男女,但居住地相隔遙遠,爸爸亞伯拉罕很浪漫,他對以撒說:兒子,你該結婚了;以撒說:這附近的女孩我沒有一個看上眼,亞伯拉罕說:不用擔心我會派忠心的僕人以利以謝去找到你的夢中情人!以利以謝走了,後來找到工作勤快的利百加;這個愛情故事具有一切使婚姻美滿的條件,以利以謝把利百加帶到以撒面前,兩人一見鍾情就結婚了,使婚姻美滿的一切條件都有了,雙方父母都同意,上帝行神蹟,帶領以利以謝找到工作勤快的對象,而且他們兩人情投意合、一見鍾情;簡直是天造地設的一對,但他們的婚姻幸福嗎?想知道故事的結局嗎?以撒後來把利百加拱手讓給一個王當妾,利百加教唆兒子對父親說謊,她的所作所為分裂了好好的一個家,大家都以為只要有愛情就行了,這是一個迷思,光有浪漫的愛情不能保證婚姻美滿,你若相信這個迷思,後果是...

    第一,你不會認真處理關係上的問題,你不會認真處理關係上的問題!牧師只要我們夠相愛衝突和個性差異就沒關係吧?錯了!!大大有關係,人人都會變老,臉皮鬆弛頭髮越來越稀疏臉上漸漸有皺紋,突然間外表的吸引力不見了,接下來會怎樣呢?第二,當愛情漸漸褪色你會開始苛求自己,只要我再多愛他一點就可以挽救這段關係,你不斷自我要求要更愛他、更關心他,一切都會恢復正常只要我再多愛她一點就可以挽救這個情況,但現實是,光有愛情不能使感情持久彼此還要合適並且有委身的決心。

    第二個迷思--- 一見鍾情才是真愛
    你怎麼知道就是他了?我就是知道嘛,當我的他(她)出現時我一定會知道,你看愛情片,聽情歌;所見所聞都是浪漫的愛情,你單身寂寞,編織愛情夢;這個迷思的危險是:第一印象不見得能持續下去,很多夫妻彼此不滿意,很多基督徒夫妻也是一樣;他們以為第一印象很好將來感情就會幸福,我知道我們會很幸福因為他給我的第一印象好極了,我們彼此非常來電一定會幸福的,但因為沒有面對現實,感情還是走不下去;這個迷思的第二個危險是,你可能會錯過真正能持久的愛,你可能錯過真正的愛有些會友來找我和師母談:牧師,我真的很喜歡那個男生但我們是不是應該只當朋友就好?我們從小一起長大他怎麼可能做我的男朋友?她怎麼可能做我的女朋友?牧師,我跟他應該是朋友怎麼可能談戀愛呢?
    但大家都說你們兩人看起來很速配真是天造地設的一對,你們應該在一起可是我沒有天雷勾動地火的來電感覺,我沒有感受到什麼火花;很多人對「一見鍾情」的想法上了癮,如果不是一見鍾情就不覺得是真愛:走在路上,看見一個女生...旁邊的人變成一片模糊,只想追求一見鍾情的愛情會帶來很大的危險,你可能因此錯過可以培養出來的真愛,只因當初沒有一見鍾情的感覺,其實激情幾秒鐘內就可以產生但真愛需要花時間,真愛需要花時間!一見鍾情迷思的第三個危險是你可能只是愛上某個形象而已,有時你自以為愛上某人,其實只是愛那個形象而已長得怎樣、做什麼工作、有多少錢、開什麼車、人生的經驗...,你是被對方的形象吸引所以你可以得意的吹噓:我男朋友是個醫生、我女朋友有魔鬼身材、我男朋友在公司業績最好,你根本就沒注意到對方是怎樣的一個人,他的業績也許最好但人品可能很差呢!但你愛上了他的形象,第一次見面時也許,可以感覺到對方的特質,我不是批評一見鍾情,也許你注意到他的一些特質,比如聲音、頭髮的香味、她的眼睛、他寬大的肩膀...,但真愛需要花時間培養

    第三個迷思是---完美的配偶可以完全滿足你
    只要找到完美的配偶就可以在各方面得到滿足,所以很多人不自覺的希望配偶能滿足他各方面的需要,如果事與願違就感到生氣、失望;真愛不是讓你予取予求的,真愛是要付出和分享,你若選對伴侶,他可以滿足你很多的需要但並不是所有的需要,他可以滿足你很多的需要但不是全部!婚前你的心靈若感到空虛聽清楚!婚前你的心靈若感到空虛,婚後仍然會感到空虛!婚後還是會感到空虛!!有些人說:我好寂寞和空虛我需要男朋友、女朋友,我需要結婚...,其實一旦結了婚你還是一樣感到寂寞,人類心靈中的空缺只有把生命交由聖靈掌管時才能被聖靈填滿,以弗所書三章17-19節:使基督因你們的信住在你們心裏,叫你們的愛心有根有基,能以和眾聖徒一同明白,基督的愛是何等長闊高深,並知道這愛是過於人所能測度,便叫上帝一切所充滿的充滿了你們。誰能夠大大充滿你使你全然滿足呢?只有上帝和祂的愛做得到!
    再來我要談八種不會有結果的感情,這是我今天的重點,八種不會有結果的感情:

    第一,你在乎對方比較多
    你在乎對方比較多,你們在談戀愛卻不確定對方的想法,你覺得你們兩個很合適但他好像不以為然,他不在時,你會很想他,但你不在時,對他好像沒差別,他出差,你想寫信給他,但他不是這樣,反而很高興可以暫時離開,這表示什麼?表示這段感情不會有結果,醒醒吧!阿摩司書三章3節說二人若不同心,豈能同行呢?所以兩人要有相同的感受,但有時候總會有一方愛另一方較多的情形,即使是我和師母,有時候是她愛我比較多,有時候是我愛她比較多,在健全的感情中會有這種交替的現象,輪流扮演追求和被追求的角色,你不可能總是扮演追求者或是被追求者,在健全的感情中會輪流一方愛另一方較多的情形;如果有一方總是扮演追求者,這樣的感情一定不健全,這種感情並不平衡不會有結果,如果長久持續下去你會覺得受到對方的控制,你會對愛感到飢渴,你會感到憤怒、受騙、痛苦,你愛對方,但對方不愛你,如果你在乎對方比較多這樣的感情不會有結果!

    第二,你愛的是對方的潛力
    這種情形我在教會裡看了很多,你愛的是對方的潛力而不是對方真正的樣子,你愛的是對方未來可能的樣子,他根本不是你的伴侶而是你改造的對象,我看過很多女生嫁給某個對象是因為她心裡覺得他將來會是個成功的佈道家,結果他成了她改造的對象,翻到羅馬書一章,談到這個你們就很安靜,姐妹們,妳是某人的改造對象嗎?弟兄們,你是某人的改造對象嗎?羅馬書一章23節"將不能朽壞之上帝的榮耀變為偶像,彷彿必朽壞的人"有偶像會怎樣?看25節"他們將上帝的真實變為虛謊"我們絕不能有偶像否則會開始相信謊言;耶利米書卅七章9節說"耶和華如此說:你們不要自欺"你跟一個人交往時,要愛和尊重對方的本相而不是他未來的樣子,你可以期望他繼續成長,但你必須滿意他現在的樣子,我們每次做婚前輔導都會問"如果對方五十年內都不會改變,你會滿意嗎?"
    如果你一直希望能改變對方才會覺得比較滿意,那就不是愛,而是賭博用雙方的快樂當做賭注,如果你喜歡某個人先誠實問自己這個問題:如果這個人永遠不會改變我還願意跟他共度一生嗎?如果這個女孩子永遠不會改變,我會滿意嗎?如果你愛的是對方的潛力這種感情不會有結果!

    第三,你想要幫助對方
    你想要幫助對方,你常常覺得對方很可憐嗎?你覺得自己有責任幫助對方振作起來嗎?你會不會害怕如果離開對方他會受不了打擊?如果答案都是肯定的你恐怕是個「救難狂」,不可自拔的想去拯救某個人,有「救難狂」的人不會去找一個合適的對象而是找一個他所同情可以幫助的對象,你會找一個受過創傷的人脆弱、依賴、不被愛、委屈,你就由憐生愛,她會對你心生感激,你會覺得自己很偉大:她需要我,沒有我,她活不下去!這樣的感情像是一項救援任務而不是一段健全、平衡的感情,所以我們教會不鼓勵弟兄輔導姐妹,或者姐妹輔導弟兄,因為有七成的人會由憐生愛,一旦陷入就很難脫身,因為你會有罪惡感,覺得拋棄了對方會嚴重傷害到對方,你進退兩難,擔任救援任務的人往往是把同情誤以為愛,這裡要牢記的關鍵是「尊重」;你愛的對象必須是你能夠尊重的人,你必須以對方為榮,我很以我太太為榮,我知道她也很以我為榮,我們雖然不完美,但我真的佩服她、欣賞她,我不是崇拜她,但我以她為榮。何西阿書六章4-6節"主說:以法蓮哪,猶大啊,我可向你怎樣做呢?因為你們的良善如同早晨的雲霧,又如速散的甘露,我喜愛良善,不喜愛祭祀,我喜愛你認識上帝,勝於燔祭"

    你的伴侶不要你的救援而要你真正了解他,如果你只是想要幫助對方這種感情不會有結果!

    第四,把對方當崇拜的對象
    把對方當崇拜的對象,所以你看報刊上常會報導年輕的女明星愛上導演、大學生愛上教授、新進的女業務員愛上行銷經理、秘書愛上老闆,愛上所崇拜的對象這種感情很難維持正常,因為兩人之間無法平等對待,男女雙方必須平等對待才行,我是指態度,我不是說身分地位不同的人不能談戀愛,而是不能過度崇拜對方,我不希望師母跟我相處時看我是個高不可攀的牧師,我是一個牧師但不是她的牧師,她用平等的地位跟我說話,否則我們的感情不會有結果,會愛上所崇拜對象的人通常自信心低落,他們覺得自己很糟糕;耶穌說:你們要愛人如己,你若不能愛自己、對自己好你怎麼去愛別人?你必須愛自己、欣賞自己像你愛對方、欣賞對方一樣,對方必須停止扮演高高在上的角色,如果你過度崇拜對方這種感情不會有結果!

    第五,你只是被對方的外表吸引
    每個人都會這樣,對嗎?你被對方的外表吸引,她那雙眼睛...穿透我的心靈目光交接的一剎那我就知道今生非她莫娶…;第一次聽見他彈吉他我知道就是他了,我一直想找個音樂家的對象;那晚看見珍妮佛跳舞,她正是我夢寐以求的,漂亮又性感,我馬上就知道我們很速配,我一直想娶個模特兒,所以我第一次看見她時就知道非她莫娶了;如果你發現自己被對方的某個特質深深吸引,要問自己,對方若沒有那雙藍色的大眼睛、漂亮的頭髮或磁性的聲音,若不是模特兒、不會打籃球、不是空中小姐...我還會跟他(她)在一起嗎?箴言卅一章30節"艷麗是虛假的,美容是虛浮的,惟敬畏耶和華的婦女必得稱讚"

    第六,如果你和對方有短暫朝夕相處的機會
    這樣的感情不會有結果,你和對方一起分擔某個工作,常常要一起加班,在這當中,你覺得愛上了對方;你去度假三個禮拜,到了一個漂亮的海灘可以看見日出日落,你就住在海灘旁,你認識了一個也來度假的男人,你們早上一起出去騎單車好幾個小時,晚上一起在海灘上烤漢堡吃,你從來沒有這麼快樂過,你說:我覺得...我好像墜入情網了;短暫的朝夕相處是指在特殊的情況下湊在一塊,並不是常規的情況,在短暫的時間內朝夕相處產生了濃厚的感情結果墜入情網,但這樣的感情不能持久,我不是說你不可能在度假或工作上遇見另一半,但危險在於短時間內的朝夕相處無法使你完全了解對方的個性

    第七,你是為了叛逆才選擇這個對象
    父母老是跟你強調要找有錢有勢的對象,偏偏你每個男朋友都是窮光蛋;從小父母就對你管教嚴格,偏偏你每個女朋友都很隨便;父母很保守和嚴厲,偏偏你每個男朋友都狂放不羈;從小父親就耳提面命,傳香火是最重要的一件事,他說:我要看見孫子才會死得瞑目,偏偏你的女朋友不是不能生就是不想生;我的意思不是說背景不同的人感情不會有結果,但你所選的對象,如果老是令父母生氣,你很可能只是想叛逆,當你不能控制自己的選擇,當你覺得一定要證明什麼來反擊,你並不是真心愛對方,這段感情注定沒有結果!

    第八,對方不是自由身
    我把這個留到最後才講,是因為這根本不能算是感情,選擇終身伴侶的第一個前提是對方是自由身,有些人故意裝作不知道「自由身」是什麼意思,所以我在這裡要給你「自由身」的定義,「自由身」是什麼意思?就是可以自由和你交往,完全沒有跟別人交往、沒有結婚、沒有訂婚、沒有固定的交往對象、沒有和別人上床、單身、只和你一人交往,懂了嗎?下面的例子就不是自由身了:妳愛上的那個男人答應會早點和另一個女人分手,或者他說他不愛那個女人,他愛的是妳,這種人不是自由身;再舉個例子,妳愛上一個男人,他原來的對象接受妳的存在,我們在教會這麼久各種光怪陸離的藉口都聽過,妳愛上一個男人,他不打算和原來的對象分手但他想跟妳在一起一陣子,或者他剛跟某人分手但可能破鏡重圓,這種人不是自由身,別和已婚或有對象的人交往,不管是什麼情況或藉口結果都是一樣,你注定要心碎,這我可以保證,別忘了,當你和一個已經有對象的人交往你只是接收了另一個對象用剩的部分,你只擁有別人用剩的部分,你值得更好的對象,阿們嗎?

    排除了這些之後,你心想還有剩下可以給我的嗎?當然有,還有很多健全的感情等著每一個人,真正的感情不只是同情對方,不只是想要照顧對方,不只是愛對方的潛力、能力、外表,不只是想要氣氣父母,你們兩人是真正相愛能滿足彼此的需要你若未婚,還沒有交往的對象,你覺得自己像是教會的壁紙,現在是開始尋找的時機了,因為選擇權在你手上,責任在你身上,但你要選對人,如果你目前有交往的對象,而且你是今天談到的八種感情之一,你原先不明白為什麼常吵架,這樣的感情不會有結果別浪費時間,去找輔導,結束這段感情,還有更好的對象在等你;如果你已婚,而且當初是這八種感情之一,上帝可以行神蹟,祂是個行神蹟的上帝,驢子可以說話,河水可以變乾,烏鴉可以叼來食物,你的婚姻可以走下去

    星期三, 9月 10, 2008

    重新啟動WinCE系統

    WinCE系統若想要重新啟動,沒有.NET的Managed函數可用,須倚靠 Coredll.dll的KernelIoControl完成,以下是用Managed包裝後的重啟函數,使用方法很簡單,直接呼叫ResetSystem()即可:

    Private Const FILE_DEVICE_HAL As Integer = &H101
    Private Const METHOD_BUFFERED As Integer = 0 Private Const FILE_ANY_ACCESS As Integer = 0
    Private Function CTL_CODE( _ ByVal DeviceType As Integer, _ ByVal Func As Integer, _ ByVal Method As Integer, _ ByVal Access As Integer) As Integer
    Return (DeviceType << 16) Or (Access << 14) Or (Func << 2) Or Method
    End Function
    Declare Function KernelIoControl Lib "CoreDll.dll" _ (ByVal dwIoControlCode As Integer, _ ByVal lpInBuf As IntPtr, _ ByVal nInBufSize As Integer, _ ByVal lpOutBuf As IntPtr, _
    ByVal nOutBufSize As Integer, _ ByRef lpBytesReturned As Integer _ ) As Integer
    Private Function ResetSystem() As Integer
    Dim bytesReturned As Integer = 0 Dim IOCTL_HAL_REBOOT As Integer = CTL_CODE(FILE_DEVICE_HAL, _ 15, METHOD_BUFFERED, FILE_ANY_ACCESS)
    Return KernelIoControl(IOCTL_HAL_REBOOT, IntPtr.Zero, 0, _
    IntPtr.Zero, 0, bytesReturned) End Function

    星期二, 9月 09, 2008

    .NET強大簡單的多執行緒功能

    多執行緒(MultiThread)是系統效能的強力工具,可以將原本低效率的程式以分工的方式提升數倍,對於核心開發的工作,如WinCE,多執行緒變成不可不熟悉的技術,例如處理IO,當大量資料進入系統的時候,總不能讓User看到系統發呆的難看景象吧~那誰要買我們的系統呢?

    還好,微軟強大的軟體工程師幫你簡化的這方面的問題,對於多執行緒的開發,兩行指令就能處置,當然,除了「開線」外,其他還有很多必須知道的事,例如非同步執行緒的資料同步問題、各執行緒與UI之間的溝通等等,在此先稍微開場,如何開多線。

    標準的執行緒開啟:

    Dim mythread As New System.Threading.Thread(AddressOf myProccess)

    mythread.Start()

    Private Sub myProccess()

    .....

    End Sub

    指令相當簡單,開啟一個新的執行緒去執行myProccess()副程式,當然你可以用mythread.Name為這個執行緒命名,其中執行緒也含有一些方法,如Abort,但在經驗來講WinCE中似乎並非每次都管用,所以我的建議myProccess副程式最好內寫好退出執行緒的路子,免的出現關閉程式還是沒辦法結束副執行緒的窘境。

    第二個方法執行緒集區(ThreadPool),是用隨時會有大量執行緒需求,而每個執行緒執行時間短且都會釋放時,會選擇使用ThreadPool,以前想達程ThreadPool的要考慮的問題很多,NET已經簡化這些問題了,事實上當開啟一NET程式,CLR已經提供我們一顆CPU 25條的ThreadPool使用,其使用方式也很簡單:

    Dim myCallback As New System.Threading.WaitCallback(AddressOf myProccess)

    System.Threading.ThreadPool.QueueUserWorkItem( myCallback , Sendata)

    Private Sub myProccess(Byval state as Object)

    .....

    End Sub

    其中WaitCallback是執行緒集區執行緒執行的回呼方法,若要建立委派,您可以將回呼方法傳遞至 WaitCallback 建構函式,比較需要注意的是其副程式要含有傳入參數state,這是必要格式。之後只要使用ThreadPool.QueueUserWorkItem即可交給CLR管理我們的ThreadPool,程式非常簡潔就能提升效能,M$真的是太貼心了。

    星期日, 9月 07, 2008

    P/Invoke與簡單型別說明

    呼叫未受限制程式碼是.NET開發WinCE相當常遇到,原因無他,幾乎所有WinCE硬體開發出的Driver或DLL都是用未受限制的Win32API提供服務,現改寫成.NET DLL的非常少,一方面未受限制的程式效能確實遠遠超過.NET,另一方面敝人認為.NET跳脫原本執行環境Sandbox界線而呼叫未受限公用程式的能力相當強,兩種原因下,系統開法者並不需要特別專為.NET開發DLL。

    定義範例如下:

    [DllImport ("coredll.dll")]
    Private static extern void SetWindowText(IntPtr handle, string s);

    以上不詳述dllimport的語法,基本上如此設定便夠應付大部分未受限API。

    在使用P/Invoke執行WinCE或Win32API卻發現結果不正確,經常都是函數引數的型別定義不正確,下表為其定義轉換參考:

    
    
    win32 types specification clr type
    char, int8, sbyte 8-bit signed integer system.sbyte
    short, short int, int16, short 16-bit signed integer system.int16
    int, long, long int, int32, long32, int 32-bit signed integer system.int32
    __int64, int64, longlong 64-bit signed integer system.int64
    unsigned char, uint8, byte 8-bit unsigned integer system.byte
    unsigned short, uint16, ushort, word, atom, __wchar_t 16-bit unsigned integer system.uint16
    unsigned, unsigned int, uint32, ulong32, dword32, ulong, dword, uint 32-bit unsigned integer system.uint32
    unsigned __int64, uint64, dwordlong, ulonglong 64-bit unsigned integer system.uint64
    float, float single-precision floating point system.single
    double, long double, double double-precision floating point system.double

    最重要的是引述位元數必須相同對應,函數才能正常傳值。

    星期四, 9月 04, 2008

    又突然暴跌一千點

    這幾天挺忙的所以沒注意股票,朋友提點最近空頭走勢,賣掉一半股票,但沒想到會突然摔到六千二,瞬間從小賺便成大賠,早知道就多賣掉一點 >_< 。算了,這時候就想到司令的一席話:

    投資最大敵人就是自己,切記

    1.多轉折做多
    2.空轉折出場
    3.空頭不要期待太多
    4.空頭只能小玩
    5.七千五以上不操作小型股(低檔買上上去除外)
    6.暴跌只能操作大型股
    7.長空一年以上改做小型股
    8.不意識型態操作
    9.不攤平
    10.不抱持僥倖
    11.不賭
    12.不借錢投資
    13.不投資不懂的東西

    VB.NET簡單存取Byte變數中各Bit

    Sub WriteBit(ByRef Data As byte,ByVal BitIndex As Integer, ByVal NewBit As Boolean)

    If NewBit = True Then
    Data = Data And Math.Pow(2, BitIndex)
    Else
    Data = Data And (&HFF - Math.Pow(2, BitIndex))
    End If

    End Sub


    Function ReadBit(ByRef Data As byte,ByVal BitIndex As Integer) as Boolean

    return (Data And Math.Pow(2, BitIndex))) / Math.Pow(2, BitIndex)

    End Sub

    星期三, 9月 03, 2008

    組合語言站存器介紹

    1.通用暫存器

    共有四個,其名稱分別是 AX、BX、CX、DX,在組合語言程式中大致沒有太大的差別,但是其中只有 AX ( accumulator,也稱為累加器) 可作為除法或乘法中的被除數與被乘數,當 16 位元不夠大時,常常用 DX:AX 來表示 32 位元。此外這四個暫存器,只有 BX ( base register,也稱為基底暫存器) 可以被作為位址存取之用。CX 也稱為計數暫存器 ( count register),用於計算迴圈之次數或字串處理之次數。DX 也稱為資料暫存器 ( data register),可用來存取埠。

    這四個暫存器也可以分成兩個 8 位元的暫存器來使用,例如 AX 可被分成較低的 8 位元稱為 AL,以及較高的 8 位元 AH 來使用。其餘 BX、CX、DX 也都類似。

    2.指標與索引暫存器

    有五個,其名稱分別是 SP、BP、IP、SI、DI。前面兩個 SP (stack pointer,稱為堆疊指標)與(base pointer,也稱為基底指標)是與堆疊(stack)有關的暫存器,以獲得詳細的堆疊資料。堆疊是一塊區域,用來暫時存放資料之用,在 8086/8088 中,堆疊是由最高位址中開始存放,每次都必須存入一個字組的長度,並用一組指標,來表示堆疊已經使用到那兒了,這組指標就是 SS:SP。也就是說,當成是要將資料存入堆疊時,該資料應該存放在 SS:SP 所指的位址再低 2 個位元組,然後 CPU 再使 SP 之內容減 2,使 SP 再指到下一個未使用的空間。

    那什麼情形會要將資料存入堆疊內呢?有好幾種情形,例如呼叫副程式時,會預先把返回位址存入堆疊﹔呼叫中斷時也是如此。BP 通常用於呼叫副程式時,傳遞參數之用。

    IP (instruction pointer,稱為指令指標) 配合 CS 變成 CS:IP,指向將要執行的 8086/8088 位址。當 CPU 要執行程式時,必須到記憶體去提取要執行的指令,而要到那一個記憶體位址去提取指令呢?這時 CPU 就會到 CS:IP 指到的位址去提取。在程式中,一般是沒有辦法改變 CS:IP 的值,除非是跳躍 (jmp、jz等) 指令或是呼叫 (call、ret等) 指令。

    SI (source index,稱為來源索引暫存器) 和 DI (destination index,稱為目的索引暫存器) 通常是用來當作位址指標,也可用作加減法。這五個暫存器,每一個都不能分開來當作兩個 8 位元的暫存器使用。

    3.區段暫存器

    有 CS、DS、ES、SS 四個,分別表示程式碼(code segment register)、資料(data segment register)、額外(extra segment register)、堆疊(stack segment register)區段之用。在 DOS 系統中,每一個區段容量只有 64KBytes。

    當資料區段不夠用時,就可以用額外區段來補足,例如想要將一個區段的某些內容複製到另一區段中,就可以同時指定 DS、ES 分別表示這兩個區段。

    4.旗標暫存器

    旗標暫存器 (flag register) 是一個 16 位元的暫存器,但只有其中九個位元有用到,它們分散在這十六個位元中,採用這種分散方式是為了與舊式的 8080 CPU 的旗標相同。這 9 個旗標可分為三類:狀態旗標 ( status flag )、控制旗標 ( control flag ) 與系統旗標 ( system flag )。狀態旗標包含 CF、PF、AF、ZF、SF 和 OF,它們會受到算術、比較或邏輯運算結果狀態的影響,而使旗標被設定 ( set,其值為 1 ),或被清除 ( clear,其值為零 )。第 10 位元的 DF 用來控制掃描、搬移、搜尋字串的方向,屬於控制旗標。至於 IF、TF 為設計作業系統、除錯時才需要用到,屬於系統旗標,一般應用程式很少使用。底下簡單介紹這些旗標:

    名稱

    位元

    狀態

    說明

    進位旗標
    carry flag
    CF

    0 CF=1,CY
    CF=0,NC

    當運算發生進位或借位時,ZF 被設為 1;反之設為 0。例如兩數相加:

            mov     ax,8000h
            add     ax,8000h
    

    8000h+8000h 應為 10000h,發生進位,雖然 AX 為 0,但是會使 CF 設為一,表示進位。

    同位旗標
    parity flag
    PF

    2 PF=1,PE
    PF=0,PO
    運算的結果換成二進位後,最低的 8 個位元中,若有偶數個 1,則此位元設為 1,反之為 0。

    輔助進位旗標
    auxiliary carry flag
    AF

    4 AF=1,AC
    AF=0,NA
    當運算過程中,第 3 位元與第 4 位元之間發生進位或借位時,AF 被設為 1,否則被設為 0,常用於 BCD 的運算。

    零旗標
    zero flag
    ZF

    6 ZF=1,ZR
    ZF=0,NZ
    運算結果為零時,ZF 會被設定為 1。若比較相同兩數, ZF 也會被設為一,若比較不相同的兩數,ZF 會被清除為零。例如:
            mov     ax,8000h
            add     ax,8000h
    

    相加後,AX 為零,故 ZF 設為一。

    符號旗標
    sign flag
    SF

    7 SF=1,NG
    SF=0,PL
    運算結果的最高位元為 1 時,SF 會被設為 1 ( 表示負數 ),否則被清除。

    陷阱旗標
    trap flag
    TF

    8   用於單步追蹤除錯時,所以也稱為追蹤旗標 ( trace flag ),例如在 MS-DOS 的 DEBUG 中,就是利用 TF 達到單步追蹤的目的。當 TF 設為一時,每執行一個指令便會發生中斷,此中斷就將執行該指令後暫存器列出。

    中斷旗標
    interrupt flag
    IF

    9 IF=1,EI
    IF=0,DI
    當 IF 被設定時,可遮罩的硬體中斷才能使 CPU 產生中斷效果;反之所有可遮罩的硬體中斷均會被抑制。但是不可遮罩中斷以及 CPU 產生的例外卻完全不受 IF 影響。

    方向旗標
    direction flag
    DF

    10 DF=1,DN
    DF=0,UP
    當 DF 被清除時 ( 即 DF=0 ),處理字串的索引暫存器會遞增,往高位址方向處理,反之則遞減。

    溢位旗標
    overflow flag
    OF

    11 OF=1,OV
    OF=0,NV

    當運算結果無法容納於目的運算元中,此旗標會被設為一。大致可分三種情形:(1)兩同號數相加或兩異號數相減,(2)乘除運算時,所得的積或商超過運算元存放範圍,在移位或旋轉指令時,最高位元值受到更動 ( 0 變成 1 或 1 變成 0 )。

    在此列出 DEBUG 中執行 r 指令後的意義:

    -r [Enter]
    AX=0000  BX=0000  CX=0025  DX=0000  SP=FFFE  BP=0000  SI=0000  DI=0000
    DS=10F7  ES=10F7  SS=10F7  CS=10F7  IP=0100   NV UP EI PL NZ NA PO NC
    10F7:0100 EB19           JMP    0119
    

    英文字母NV UP EI PL等等就是旗標的狀態,請看下表:

    旗標名稱 設定(1) 清除(0)
    CF,進位(是/否)
    PF,同位(偶數/基數)
    AF,輔助進位(是/否)
    ZF,零(是/否)
    SF,符號(是/否)
    IF,中斷(允許/抑制)
    DF,方向(遞減/遞增)
    OF,溢位(是/否)
    CY
    PE
    AC
    ZR
    NG
    EI
    DN
    OV
    NC
    PO
    NA
    NZ
    PL
    DI
    UP
    NV

    組合語言基本指令

    一,數據傳送指令集
    1.MOV

    功能: 把源操作數送給目的操作數
    語法: MOV 目的操作數,源操作數
    格式: MOV r1,r2
    MOV r,m
    MOV m,r
    MOV r,data

    2.XCHG

    功能: 交換兩個操作數的數據
    語法: XCHG
    格式: XCHG r1,r2 XCHG m,r XCHG r,m


    3.PUSH,POP

    功能: 把操作數壓入或取出堆棧
    語法: PUSH 操作數 POP 操作數
    格式: PUSH r PUSH M PUSH data POP r POP m


    4.PUSHF,POPF,PUSHA,POPA

    功能: 堆棧指令群
    格式: PUSHF POPF PUSHA POPA

    5.LEA,LDS,LES

    功能: 取地址至寄存器
    語法: LEA r,m LDS r,m LES r,m


    6.XLAT(XLATB)

    功能: 查表指令
    語法: XLAT XLAT m

    二,算數運算指令
    1..ADD,ADC

    功能: 加法指令
    語法: ADD OP1,OP2 ADC OP1,OP2
    格式: ADD r1,r2 ADD r,m ADD m,r ADD r,data
    影響標志: C,P,A,Z,S,O

    2..S U B,SBB

    功能:減法指令
    語法: S U B OP1,OP2 SBB OP1,OP2
    格式: S U B r1,r2 S U B r,m S U B m,r S U B r,data S U B m,data
    影響標志: C,P,A,Z,S,O

    3.INC,DEC

    功能: 把OP的值加一或減一
    語法: INC OP DEC OP
    格式: INC r/m DEC r/m
    影響標志: P,A,Z,S,O


    4.NEG

    功能: 將OP的符號反相(取二進制補碼)
    語法: NEG OP
    格式: NEG r/m
    影響標志: C,P,A,Z,S,O


    5.MUL,IMUL

    功能: 乘法指令
    語法: MUL OP IMUL OP
    格式: MUL r/m IMUL r/m
    影響標志: C,P,A,Z,S,O(僅IMUL會影響S標志)


    6.DIV,IDIV

    功能:除法指令
    語法: DIV OP IDIV OP
    格式: DIV r/m IDIV r/m


    7.CBW,CWD

    功能: 有符號數擴展指令
    語法: CBW CWD


    8.AAA,AAS,AAM,AAD

    功能: 非壓BCD碼運算調整指令
    語法: AAA AAS AAM AAD
    影響標志: A,C(AAA,AAS) S,Z,P(AAM,AAD)


    9.DAA,DAS

    功能: 壓縮BCD碼調整指令
    語法: DAA DAS
    影響標志: C,P,A,Z,S

    三,位運算指令集
    1.AND,OR,XOR,NOT,TEST

    功能: 執行BIT與BIT之間的邏輯運算
    語法: AND r/m,r/m/data OR r/m,r/m/data XOR r/m,r/m/data TEST r/m,r/m/d
    ata NOT r/m
    影響標志: C,O,P,Z,S(其中C與O兩個標志會被設為0) NOT指令不影響任何標志位


    2.SHR,SHL,SAR,SAL

    功能: 移位指令
    語法: SHR r/m,data/CL SHL r/m,data/CL SAR r/m,data/CL SAL r/m,data/CL
    影響標志: C,P,Z,S,O


    3.ROR,ROL,RCR,RCL

    功能: 循環移位指令
    語法: ROR r/m,data/CL ROL r/m,data/CL RCR r/m,data/CL RCL r/m,data/CL
    影響標志: C,P,Z,S,O

    四,程序流程控制指令集
    1.CLC,STC,CMC

    功能: 設定進位標志
    語法: CLC STC CMC
    標志位: C

    2.CLD,STD

    功能: 設定方向標志
    語法: CLD STD
    標志位: D


    3.CLI,STI

    功能: 設定中斷標志
    語法: CLI STI
    標志位: I


    4.CMP

    功能: 比較OP1與OP2的值
    語法: CMP r/m,r/m/data
    標志位: C,P,A,Z,O


    5.JMP

    功能: 跳往指定地址執行
    語法: JMP 地址


    6.JXX

    功能: 當特定條件成立則跳往指定地址執行
    語法: JXX 地址
    注:
    A: ABOVE,當C=0,Z=0時成立
    B: BELOW,當C=1時成立
    C: CARRY,當弁時成立 CXZ: CX寄存器的值為0(ZERO)時成立
    E: EQUAL,當Z=1時成立
    G: GREATER(大於),當Z=0且S=0時成立
    L: LESS(小於),當S不為零時成立
    N: NOT(相反條件),需和其它符號配合使用
    O: OVERFLOW,O=1時成立
    P: PARITY,P=1時成立
    PE: PARITY EVEN,P=1時成立
    PO: PARITY ODD,P=0時成立
    S: SIGN,S=1時成立
    Z: ZERO,Z=1時成立

    7.LOOP

    功能: 循環指令集
    語法: LOOP 地址


    8.LOOPE(Z)

    地址 LOOPNE(Z) 地址
    標志位: 無


    9.CALL,RET

    功能: 子程序調用,返回指令
    語法: CALL 地址 RET RET n
    標志位: 無


    10.INT,IRET

    功能: 中斷調用及返回指令
    語法: INT n IRET
    標志位: 在執行INT時,CPU會自動將標志寄存器的值入棧,在執行IRET時則會將堆
    棧中的標志值彈回寄存器

    五,字符串操作指令集
    1.MOVSB,MOVSW,MOVSD

    功能: 字符串傳送指令
    語法: MOVSB MOVSW MOVSD
    標志位: 無


    2.CMPSB,CMPSW,CMPSD

    功能: 字符串比較指令
    語法: CMPSB CMPSW CMPSD
    標志位: C,P,Z,S,O


    3.SCASB,SCASW

    功能: 字符串搜索指令
    語法: SCASB SCASW
    標志位: C,P,Z,S,O


    4.LODSB,LODSW,STOSB,STOSW

    功能: 字符串載入或存貯指令
    語法: LODSB LODSW STOSB STOSW
    標志位: 無


    5.REP,REPE,REPNE

    功能: 重復前綴指令集
    語法: REP 指令S REPE 指令S REPNE 指令S
    標志位: 依指令S而定