11.20.2009

餿主意讚

生活中充滿了需求和問題,下面論壇提供一個平台來討論這些事,在這裡寫下你遇到的問題,並 寫下你覺得可以解決這個問題的主意,記得愈誇張越好,因為這裡是"餿主意".
這個論壇的目的?
1. fun
2. 練習創意
3. 商機無限


Google 網上論壇

餿主意讚
造訪此群組

9.14.2009

工作是為了什麼





最近好像又閒下來了..
有時會想,到底工作是為了什麼…

其實不用想太多,工作其實就是工作,沒別的

工作吧!!

7.09.2009

業餘跟職業的差別

最近看了Robert Kiyosaki 的文章裡提到的一段話,感同深受

"People say amateurs play for the love of the game and professionals play for money. That is not true. Amateurs are amateurs because they do not love the game enough. When it is cold and rainy, a professional golfer will play. The amateur will not. When they are sick, the professional will play. The amateur stays in bed. When they are losing, the professional will practice harder and enter more tournaments. The amateur will quit and take up tennis."

記得還是小學的時候,很喜歡玩棒球,常常在中午大熱天,同學想休息的時候,拉著他們一起去玩。很懷念那時單純渴望的感覺。那時如果我爸繼續讓我打球,也許現在我也是王建民 :P

現在看看自己再做的事,不至於厭惡,但也沒有小時的熱誠。我也算是業餘在我這一行 = ="

5.21.2009

USB On-The-Go Basics - Cable

在 USB 的世界裡,有分Host跟Peripheral ,任何的傳輸動作都是 Host先 send 封包出來,所以知道誰是 Host 誰是 Peripheral 是很重要的在USB的protocol 裡, 再因為 USB cable 是決定OTG devcie是當A-Device(Host)還是B-Device(peripheral)的依據,所以我們先認識一下USB OTG 的 cable.



  1. 一般標準的USB cable 的頭就有分A 頭跟B 頭,A頭就是接Host, B頭就是接peripheral.





  2. 後來多了一個叫 mini-USB 的B頭,是給像隨身聽這類小產品用的,也都只是當peripheral




  3. 後來又出了一個叫 OTG mini-AB receptacle.就是專給 OTG deivce 用的母頭. 它可接mini-A公頭也可接mini-B公頭



  4. 下圖上方,是Camera 當 Host, Printer當 Peripheral ,它可能的功能就是讓Camera 裡的照片直接透過Printer印出。下方那一個,兩個Camera 都是用OTG Mini-AB 母頭,也就是可插A頭也可插B頭,那要怎麼區分誰是 Host? 誰是 Peripheral呢? 就是靠 cable 的接頭來決定。在A頭跟B頭裡面的 ID pin 是不同的,A頭裡 ID是pull low, B頭裡ID是pull hi。而 device 再依照ID pin 來決定自己是Host 還是peripheral。



  5. 因為Mini-AB母頭可接A or B, 在這樣的情形下 user 有可能會接反,如下圖,原本Camera是要當Host,因為接反插入 B 頭而變為 Peripheral, 而 Printer 也是一樣,那不就不能動了。好再OTG 架構也想到這個問題,所以提供了一個叫 Host Negotiation Protocol (HNP) 來結決這個問題,讓 user 不用換 calbe 也可繼續用。






5.12.2009

設計者的悲哀

在吉米丘的blog 上看到的,好笑到不行



真是道盡設計者的悲哀

5.11.2009

USB OTG flow at Qaulcomm

BOOL Cl13611OTG::ISTProcess() @ Cl13611.cpp (\wm\platform\qcmsm\src\drivers\usb\highspeed\otg)

-> BOOL Cl13611OTG::UpdateInput()
-> BOOL Cl13611OTG::EventNotification()

-> BOOL USBOTG::EventNotification() @ Usbotg.cpp (\wm\public\common\oak\drivers\usbotg\mdd)

do

-> BOOL Cl13611OTG::UpdateInput() @ Cl13611.cpp (\wm\platform\qcmsm\src\drivers\usb\highspeed\otg)
-> USBOTG_STATES USBOTG::StateChange(USBOTG_STATES usbOtgState) @ Usbotg.cpp (\wm\public\common\oak\drivers\usbotg\mdd)
-> BOOL USBOTG::EnterState(USBOTG_STATES usbOtgState)
if (OTG state has changed)

BOOL Cl13611OTG::NewStateAction(USBOTG_STATES usbOtgState , USBOTG_OUTPUT usbOtgOutput) @Cl13611.cpp (\wm\platform\qcmsm\src\drivers\usb\highspeed\otg)

-> BOOL Cl13611OTG::SetupTransCtr(USBOTG_OUTPUT usbOtgOutput)

if(usbOtgOutput.bit.drv_vbus)(A-device is driving Vbus)

turn on Vbus

else

turn off Vbus


if (usbOtgOutput.bit.loc_sof = true) (loccal device is generating activity on the bus)

LoadUnloadHCD(TRUE)

else

LoadUnloadUSBFN(TRUE)

-> BOOL USBOTG::NewStateAction(USBOTG_STATES usbOtgState , USBOTG_OUTPUT usbOtgOutput )


else
break while()



while(OTG state != USBOTG_states_unknow)


5.05.2009

USB and Chargering

在USBIF 裡有測到下列狀況的VBUS電流:
1. USB 有認到時的電流: 100mA/500mA
2. USB 沒(還沒)認到時的電流: 100mA/500mA
3. 電腦 suspend 時的電流: 2.5mA
4. 正常運作時的電流: 100mA/500mA

所以有兩個地方,USB 需通知charging driver
1. 電腦認到 USB 時
2. 電腦 suspend 時

*以下是 Quallcomm 認到通知的flow(quallcomm 是以有被設了new address 才開始充電)

UfnPdd_SetAddress() @Msm_usbhs.cpp (\wm\platform\qcmsm\src\drivers\usb\highspeed\fn)

-> UfnPDD_NotifyChargerCurrent(), 帶pdd->dChargerCurrent進去,init 在 s_deviceRegParams @Msm_subhs.cpp, 目前設定100, 意思是 100 mA

-> DeviceIOControl 帶IOCTL_OTG_SET_REMOTE_DEV_A_INFO 參數,和要充的電流大小
Cl13611OTG::IOControl() @Cl13611.cpp (\wm\platform\qcmsm\src\drivers\usb\highspeed\otg)

這裡會收到 IOCTL_OTG_SET_REMOTE_DEV_A_INFO , pBufIn 就是要充的電流大小

*以下是 電腦 suspend 通知的 flow
UfnPDD_NotifySuspend() @Msm_usbhs.cpp (\wm\platform\qcmsm\src\drivers\usb\highspeed\fn)
這個不是WINAPI ,找不到從哪裡call 來,可能是 Quallcomm 的lib

-> UfnPDD_NotifyChargerCurrent(), 帶current 變數進去,如果是suspend, current=0
如果不是,current=100

-> DeviceIOControl 帶IOCTL_OTG_SET_REMOTE_DEV_A_INFO 參數,和要充的電流大小
Cl13611OTG::IOControl() @Cl13611.cpp (\wm\platform\qcmsm\src\drivers\usb\highspeed\otg)

這裡會收到 IOCTL_OTG_SET_REMOTE_DEV_A_INFO , pBufIn 就是要充的電流大小

4.29.2009

add external jar file as part of a system library

FWIW, it appears that if you add the external jar file as part of a user library, specify that the user library is a system library, and add the user library to the Java Build Path then it will work.


For completeness to do this you can do the following:
1. Right-click the project in Eclipse and select "Build Path -> Add Libraries...".
2. Select User Library from the list and click Next.
3. Click the "User Libraries..." button.
4. Click "New..." in the User Libraries dialog.
5. Give the user library a name and select the System library checkbox and click OK.
6. Highlight the newly added user library in the list and click the "Add JARs..." button and add the desired jar files.
7. Click OK on the User Libraries dialog.
8. Make sure the new user library is checked in the Add Library dialog and click Finish.

4.28.2009

AVD(Android Viutual Device)的注意事項

當你正在選擇system image target for 你的AVD時,請心存下列三項

Keep these points in mind when you are selecting a system image target for your AVD:

1. target 的 API level 很重要,因為你的應用程式沒辦法在比它的 API Level 還少的 system image 上跑,在應用程式的 manifest 檔的 attribute 裡的 minSdkVersion 有定義.想知道更多資訊有關 system API Level 跟應用程式 minSdkVersion 之間的關系,請看Specifying Minimum System API Version

The API Level of the target is important, because your application will not be able to run on a system image whose API Level is less than that required by your application, as specified in the minSdkVersion attribute of the application's manifest file. For more information about the relationship between system API Level and application minSdkVersion, see Specifying Minimum System API Version.

2. 強烈鼓勵,建立至少一個AVD, 它的 API Level 大於你的應用程式, 因為這可以讓你測試你的應用程式的forward-compatibility. forward-compatibility 的測試可用來保證,使用者透過system update download 你的應用程式之後,可以運作正常。

Creating at least one AVD that uses a target whose API Level is greater than that required by your application is strongly encouraged, because it allows you to test the forward-compatibility of your application. Forward-compatibility testing ensures that, when users who have downloaded your application receive a system update, your application will continue to function normally.

3. 如果你的應用程式宣告了一個 user-library 元件在它的 manifest 檔,那這個應用程式只能跑在有外部 library 的 system image.如果你要你的應用程試跑在你建立的 AVD 上, 請確定應用程式的 uses-library element 還有所選的 system image target 有無 includes 那個 library.

If your application declares a uses-library element in its manifest file, the application can only run on a system image in which that external library is present. If you want your application to run on the AVD you are creating, check the application's uses-library element and select a system image target that includes that library.

4.27.2009

實作一個假的 character driver 在emulator 上跑

大致上的做法就是將自己 build 的 kernel 放到 emulator, 然後再將自製假的 driver 放進 emulator 裡跑

1. 將 .config 從模擬器裡抓出來
因為模擬器裡的 kernel 的 CONFIG_MODULE 是關掉的。所以我們需要將它打開,否則不能 insmod 。
開了之後就要重 build 出 kernel image (zImage). 而要 build kernel 就需要模擬器裡的 kernel 的 .config。

先下載 Android 的 sdk , 因為 emulator 就在 SDK 裡,可到下面網址 download(註:我是以SDK 1.1為例子,SDK 1.5 還沒試過)


http://developer.android.com/sdk/1.1_r1/index.html



a. 解壓之後,執行 emulator


D:\workplace\android-sdk-windows-1.1_r1\tools>emulator


b. 在 emulator 執行的狀況下抓/proc/config.gz ,放到 \pulldata下


D:\workplace\android-sdk-windows-1.1_r1\tools>adb pull /proc/config.gz



2. 改 CONFIG_MODULES
將 config.gz 解壓之後放到 /mydroid/kernel 下, 然後找 CONFIG_MODULES ,並改為


CONFIG_MODULES=y



3. 改 kernel 的 Makefile
因為我們是跑 arm archtecture ,所以要改 tool chain
在 /mydroid/kernel/Makefile 裡,將 ARCH 跟 CROSS_COMPILE 改為下面


ARCH ?=arm
CROSS_COMPILE ?=../prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-


然後將 LDFLAGS_BUILD_ID mark 掉,如下


# LDFLAGS_BUILD_ID = $(patsubst -Wl$(comma)%,%,$(call ld-option, -Wl$(comma)--build-id,))


4. build kernel
(1) 先清乾淨


$make mrproper


(2) 將第二步驟的 config 改名為 .config ,放到 /mydroid/kernel 下
(3) make


$make


一開始會問你一些問題,一律都答N
build 完之後,會在 /mydroid/kernel/arch/arm/boot 找到 image, 叫 zImage

5. build fake driver
(1) 從 Linux Device Driver Programming 一書裡,copy 個範例 driver, source C 如下


/*
* devone.c
*
*/
#include linux/init.h
#include linux/module.h
#include linux/types.h
#include linux/kernel.h
#include linux/fs.h
#include linux/cdev.h
#include asm/uaccess.h

MODULE_LICENSE("Dual BSD/GPL");

static int devone_devs = 1; /* device count */
static int devone_major = 0; /* dynamic allocation */
static int devone_minor = 0;
static struct cdev devone_cdev;

ssize_t devone_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
int i;
unsigned char val = 0xff;
int retval;

for (i = 0 ; i < count ; i++) {
if (copy_to_user(&buf[i], &val, 1)) {
retval = -EFAULT;
goto out;
}
}

retval = count;
out:
return (retval);
}

struct file_operations devone_fops = {
.read = devone_read,
};

static int devone_init(void)
{
dev_t dev = MKDEV(devone_major, 0);
int alloc_ret = 0;
int major;
int cdev_err = 0;

alloc_ret = alloc_chrdev_region(&dev, 0, devone_devs, "devone");
if (alloc_ret)
goto error;
devone_major = major = MAJOR(dev);

cdev_init(&devone_cdev, &devone_fops);
devone_cdev.owner = THIS_MODULE;
devone_cdev.ops = &devone_fops;
cdev_err = cdev_add(&devone_cdev, MKDEV(devone_major, devone_minor), 1);
if (cdev_err)
goto error;

printk(KERN_ALERT "devone driver(major %d) installed.\n", major);

return 0;

error:
if (cdev_err == 0)
cdev_del(&devone_cdev);

if (alloc_ret == 0)
unregister_chrdev_region(dev, devone_devs);

return -1;
}

static void devone_exit(void)
{
dev_t dev = MKDEV(devone_major, 0);

cdev_del(&devone_cdev);
unregister_chrdev_region(dev, devone_devs);

printk(KERN_ALERT "devone driver removed.\n");

}

module_init(devone_init);
module_exit(devone_exit);





Makefile 如下,你需要改 KERNELDIR ,這需要指到已經好的kernel,還有命令之前一定要是"tab"


KERNELDIR=/home/arik/Workspace/aydroid/kernel/
PWD := $(shell pwd)

obj-m := devone.o

modules:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules


clean:
rm -rf *.o *~ core.depend .*.cmd *.ko *.mod.c .tmp_versions




6. 將我們 build 的 zImage 放進 emulator 上跑


D:\workplace\android-sdk-windows-1.1_r1\tools>emulator.exe -kernel D:\workplace\
android-sdk-windows-1.1_r1\tools\lib\images\zImage


-kernel 後面的參數就是指到之前 build 出來的 kernel image

7. 把 busybox 放進 emulator
因為待會要用 busybox 的 mknod 指令( emulator 好像沒有), 所以要將 busybox 放進 emulator
(1) 讓 emulator 的 /system 這個目錄變成可 read/write. 開另一個 cmd 下


D:\workplace\android-sdk-windows-1.1_r1\tools>adb remount
* daemon not running. starting it now *
* daemon started successfully *
remount succeeded


(2) 下載 busybox


http://benno.id.au/android/busybox


(3) 把 busybox 放進 emulator


D:\workplace\android-sdk-windows-1.1_r1\tools>adb push busybox /system/bin
1703 KB/s (0 bytes in 1745016.001s)


(4) 更改 busybox 權限,否則不能用


D:\workplace\android-sdk-windows-1.1_r1\tools>adb shell
# chmod 566 /system/bin/busybox
chmod 566 /system/bin/busybox
#_



8. 把 ko 檔放進 emulator
跟放 busybox 一樣, 把假 driver 放進, 注意 emulator 裡只有 /system 目錄才可對外讀寫, 這裡我是放在 /system/bin


D:\workplace\android-sdk-windows-1.1_r1\tools>adb push devone.ko /system/bin
117 KB/s (0 bytes in 3763.000s)



9. 載入 module
跟在 linux 下做的一樣


D:\workplace\android-sdk-windows-1.1_r1\tools>adb shell
# busybox insmod /system/bin/devone.ko
busybox insmod /system/bin/devone.ko
# busybox lsmod
busybox lsmod
Module Size Used by Not tainted
devone 2624 0
#


10. 將 driver 掛上
掛上之前,要先知道它的 major id


# busybox cat /proc/devices
busybox cat /proc/devices
Character devices:
1 mem
4 /dev/vc/0
4 tty
5 /dev/tty
5 /dev/console
5 /dev/ptmx
7 vcs
10 misc
13 input
29 fb
90 mtd
128 ptm
136 pts
252 devone
253 ttyS
254 rtc

Block devices:
1 ramdisk
7 loop
31 mtdblock
43 nbd
179 mmc
#


知道是 252 之後,就 mknod 上去


# busybox mknod /dev/devone c 252 0
busybox mknod /dev/devone c 252 0
# busybox ls -l /dev/devone
busybox ls -l /dev/devone
crw-rw-rw- 1 0 0 252, 0 Apr 30 02:26 /dev/devone
#


4.23.2009

compile android & kernel

* build android
If you just want to force the generation of the systemimage without
rebuilding anything, you should just be able to do
make snod
(snod == systemimage-nodeps)

清除之前make 習
make clean

*build kernel
(1)
.config 要從模擬器上的kernel 拿

cd \tools
adb pull /proc/config.gz pulldata\config.gz

下完config.gz 就會在\tools\pulldata\裡
config.gz 就是.config,將它解壓並copy 到你要 build 的kernel 目錄下
其中有個flag CONFIG_MODULE 要設成y ,才可手動載入module

(2)
make mrproper (clean)
make msm_defconfig ARCH=arm
make ARCH=arm CROSS_COMPILE=../prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-

(3)載入映像檔到模擬器中:
映像檔位置: (1) 依照android官方網頁的說明,映像檔是放在lib/images下,在我的電腦(os: xp)上是位於

C:\WT\SoftWare\eclipse\android-sdk-windows-1.1_r1\tools\lib\images。

用指令來指定image的方式如下:

emulator -image system.img -data userdata.img -ramdisk ramdisk.img

如果要重載kernel的image則如下:

emulator -kernel /zImage


如果直接把image檔覆蓋掉在lib/images的檔案也能正常執行。如果使用指令則會啟動模擬器並載入參數路徑所指的映像檔,如下,其實上原本存在於lib/images的映像檔並沒有被參數載入的覆蓋掉!

emulator -image backup\system.img




這裡有講到如何build image for emulator

編譯android原始碼到模擬器上執行
http://www.cookbus.com/show-85-1.html

4.22.2009

android permission

我試著建立一個假的character device.
然後想讓它可以被使用在 Android emulator上。

首先, 我在.config 檔加了CONFIG_MODULES,並重編譯了Android Kernel
然後, 我寫了個module 來控制"/dev/mydev"(它扮演著一個 80char 的buffer),並跨平台組譯成arm 架構。

我ran了emulator ,然後將 busybox 放進去(用來建立/dev/mydev 透過 mknod),並用insmod 載入module

目前,透過使用 open/close/write/等.. shell 和 common activities 都可以對它互動

我想要建一個特別的permission給這個device,然後人不能透過 common Activities 來讀取它。
有任何的文件/提醒/連結嘛?

我知道Android 有一個特別的HAL,但沒有文件。

I'm trying to create a fake character device.
I want to make it usable within the provided Android emulator.

Firstly, I recompiled the Android Kernel editing the .config file,
adding CONFIG_MODULES.
Then, I wrote a module managing "/dev/mydev" (it acts as a 80 char
buffer) and crosscompiled it for arm architecture.
I ran the emulator and pushed busybox (for creating the /dev/mydev
with mknod) and loaded the module with insmod.


Now, both shell and common activities can interact with it, by using
standard open/close/write/etc...


I would like to create a specific permission for that device and make
it not readable from common Activities.
Is there some documentation/hints/links?


I know Android has a specific HAL but there's no documentation.




就application style permissions來說,你一般要做的就是去define一個新的gid, 就是你的device 會被發布的gid(如此它就不會被讀/寫),
加一個entry 在 \frameworks\base\data\etc\permissions.xml 去對映到 permission string,
然後加一個item在 frameworks/base/core/res/AndroidManifest.xml 來描述這個permission.
gid 的group 是被defined 在user space, 有個 system/init 來defines 這些standard groups.

For application style permissions, what you generally do is define a new gid
that your device is published under (so it is not world readable/writeable),
add an entry to etc/permissions.xml mapping that gid to a permission string,
and add an item in the frameworks AndroidManifest.xml describing that
permission.

The meaning of groups is purely defined by user space. There is a
system/init header that defines the standard groups.

4.19.2009

股票模擬遊戲

最近開始再研究股票

就再想怎麼沒有一個網站模擬台股來弄個線上遊戲,每天life 跟真實台股連線
每個人從20萬台幣開始玩,最後也有融資融卷等工具可用

這樣就有地方可以練習,又可累積經驗,但又不用擔心真的了錢
等練到贏率大於80%時就可真的下場投資了

最好是可以真的摸擬實際的市場機制,也就是說當這個遊戲愈多人玩,表示愈多散戶投入,那也應該要反應在遊戲裡面
或者不要反應,也許會比較準對於練習來說


找了一下,如果要玩美股的話有這個網站

Practice Investing, Stock Market Game


如果不用自己的錢去玩,真的可以學到東西嘛?
如何讓人真的serious 去玩就像真的一樣?

4.13.2009

How Linux kernel Init

要了解kernel 如何init
先了解kernel image 的架構


vmlinux 是kernel 本身再加了一些符號什麼的
然後把那些符號拿掉就成了image 的binary
之後用gzip 壓成piggy.gz
然後用asmbaly build 成piggy.o


*bootstrap loader and bootloader的不同
bootloader 只負責POWER ON

*bootstrap loader(second-stage loader),head.o @bootstrap loader
1.creat the proper environment to decompress,
2.relocate the kernel,
3.pass control to head.o@kernel




*head.o @kernel

1.Checks for valid processor and architecture
2.Creates initial page table entries
3.Enables the processor's memory management unit (MMU)
4.Establishes limited error detection and reporting
5.Jumps to the start of the kernel proper, main.c

在這個時候只有有限的memory maping.. 所以如果想在這加個firmwave 去down load到特定的device,是會crash的
要init driver 就透過device driver model

*start_kernel() @ .../init/main.c

USB 裝置會挑電腦?

常聽人說我的手機接我的電腦不能連 ActiveSync,但接別台電腦就可連
就說這隻手機會挑電腦

其實這只說對了一部份

當連線的時候,如果USB的訊號差,則USB的protocol 一般都可cover 掉,只要重傳就好了,只是效能沒那麼好而已
但如果訊號差都一定的程度,那就會連不起來
所以我們知道USB的protocol 對壞的訊號有一定的容忍度。

而訊號的好壞取決於三個部份,手機端(device), cable/cradle, 電腦端(host)
手機的lay out 是不是符合標準
cable/ cradle 是不是有太多connector 轉接
電腦端是不是也轉接connector (一般桌機,USB port 前面的比後面的訊號差 )
這三個部份加起來,如果訊號壞到超過potocol的容忍度,就連不起來了

而理論上來說,device 及cable 再出貨時就是要有最佳的匹配,將errors 降到最低,
這樣就有空間,留給電腦的部份,也就比較不會挑電腦了

4.12.2009

用英文,而不是學英文

一直覺得英文只是個工具
而工具,有人用的好,也有人用的不好
重點就是"用"

一個字或片語或句子結構 會不會用就決定你英文的好壞

但沒人規定說要用一個工具就一定要很會用
重點就是看你用它來做什麼


以TOEFL 為例,
就是要了解各個學科的字
及熟練如何表達自己的意思

而TOEIC,
則要多了解商業領域的字
及日常生活的用語


一些有趣的元素可以加入
1. 玩-動機, 新奇好玩
2. 演戲-角色扮演
3.

4.09.2009

工人還是功能

最近同事去巴里島度蜜月,回來帶了些雕刻飾品。
說到,當地的人雕刻東西很厲害,一面石牆不打草稿,就刻出了很漂亮的圖案。

我想這有兩種形況
1. 他已經看到他想要的圖案在石牆上,所以他就刻出他要的東西,而且也可以刻出任何他想要的東西,是藝術家,東西是藝術品。
2. 這個圖案他已經做了很多遍,已經很熟每個需要刻的位置,他只是repeat 出每個動作,可以做的很快,甚至於可以寫出SOP,只是會的圖案有限,這種人是工人,東西是產品。

我相信很多時候,是兩個同時存在在同一個人上,只是比例問題而已。
想想自己,身為工程師,有多少時間是再trace code, debug, try and error, 又有多少時間是真的從無到有做出自己想要的東西出來。

4.07.2009

測USBIF 注意事項

最近再整理筆記,趁這個機會整理一下測USBIF 的部份

1. 還沒插入USB cable 之前,USB充電應關閉,一直到set configured 之後才可開啟。
2. 用電池的產品,USB充電不可超過100mA(會影響test J/K)。
3. D+D- 的訊號線應離PHY愈近愈好,且不可串接或並接任何東西(例如bead),Handy 用coaxial cable 在機子裡跑是一大敗筆, (影響Rx sensitivity)。
4. Connector 如果可以的話,盡量用標準的USB connector,如果不是標準的,Vbus和Ground 也要先touch 在cable 插入時。
5. 有cable 的產品,再測眼圖時用FAR END來測,沒cable 的產品(大母哥) 用NEAR END測。
6. 連線完cable 拔掉之後,D+ D-應為low。
7. 在Ch9裡, default power 應該為 “BUS/SELF POWER” ,而current power 如果是SELF POWER,則Vbus 的電流不可超過100mA,如果是BUS POWER 則不可超過500mA. 但在PC suspend 時,兩者定義都不可超過2.5mA。

4.06.2009

Android HAL

有人問說有沒有一個標準的方法來加一個driver 給上層android AP用,答案是沒有。



如果我要建一個新的device, 符合Android HAL, 我知道, 我應該使用下列方法的其中一個:
1. App - Runtime Service - lib
2. App - Runtime Service - Native Service - lib
3. App - Runtime Service - Native Daemon - lib

If I want to create a new device, conforming to Android HAL, I should
use one of the following approaches:
1. App - Runtime Service - lib
2. App - Runtime Service - Native Service - lib
3. App - Runtime Service - Native Daemon - lib


但是,除了現存的devices 以外, 要改所以需要改的檔案,來增加一個新的device,似乎不容易。

我想要寫一個user-mode 的driver,而不是用kernel-mode driver model.
然後想要讓它可以在enulator 上跑。

Except for the existing devices, it is not easy to identify all the
files which need to be modified for adding a new one.
I am also interested in writing a User-Mode Driver, instead of using a
Kernel-Mode Driver model.
For now, I want to make it work in the emulator.


所以,我加了一個假的device ,有點像是sensor device。然後,我試著建立一個library (就叫fake)來處理所有必要的功能。然後把它放在 /hardware/libhardware/fake, /hardware/libhardware/include/fake, 另外還有Android.mk 放在裡面,Android.mk相關連到/dev/fak 和 /dev/input/fake(第一個for data, 第二個for 控制)

My fake device will be similar to "sensor" device.
I tried to create a library calling it "fake" and managing all
necessary features.
I put them into /hardware/libhardware/fake, /hardware/libhardware/
include/fake, with its Android.mk.
It relies on /dev/fake and /dev/input/fake (one for data, the second
one for control).


第一個問題,在Android Project Group裡有標準的方式加一個新的device嘛(kernel and/or user mode)?(檔案該放的目錄,如何加makefiles, 等等? device /dev/input/compass 是哪個driver再管理的?)有沒有一個stub 是專門再加新的dvice 及相關的Manager/Services,給上層的Application?

First question. There's a standard way in Android Project Group for
adding a new device (kernel and/or user model)? (Folders where files
should be placed, tips for makefiles, etc? The device /dev/input/
compass is managed by which driver?)
There's a stub for implementing a new device and related Manager/
Services, to higher levels up to Application?




The abstraction layers in Android are admittedly inconsistent. Audio
and camera both use a C++ pure virtual interface (e.g.
AudioHardwareInterface.h), while other places like LED's and blitter
functions have a C struct of function pointers.
Android 的抽像層不可否任地是前後茅盾的。Audio 和camera 都是C++純虛擬介面,但其它地方像LED 和blitter 就有function pointers 的 C 結構.

Because we run the actual device image in the emulator, any devices
that aren't backed by a kernel driver in the emulator need a fake
device (such as camera). For audio, we have a kernel driver for the
emulator, but other devices like the G1 have a user space layer on top
of the kernel driver. In this case, for the emulator, there is a shim
that translates AudioHardwareInterface calls to kernel calls.
因為我們是在模擬器上跑一個實體device 的image,任何在模擬器背後沒有kernel driver 的devices 都需要一個假的device(像是camera)。對audoi來說,我們有kernel driver在模擬器上,但是其它的device 像是G1 在kernel driver 的上方有個user space 層。
就這個case 來說,就有個小程式轉換AudioHardwareInterface 到呼叫kernel calls.


How you surface the driver features to the application will depend on
what you are trying to do. Most hardware features are abstracted by a
native service, for example Surfaceflinger for 2D graphics,
AudioFlinger for audio, CameraService (because CameraFlinger just
sounded wrong) for the camera. This allows us to enforce security
using the binder interface and to abstract away a lot of differences
so that applications don't have to be written to work with specific
hardware.
要如何寫driver 功能的介面給application ,取決於你打算怎麼做。大部份的硬體功能都有抽象層在現有的service裡。例如 2D graphics 有 SurfaceFlinger,audio 有AudioFlinger, camera有CameraService(因為CameraFlinger聽起來很奇怪)。在這樣的架構下,讓我們在用binder interface 時有一定的安全性,並將大部份的不同性抽象化,好讓applications 不用管硬體


I haven't looked at the compass code, but I can take you through the
camera as an example.
我還沒實際去看這個部份的code, 但是我可以給你一個以camera 為例子的例子,來說明


At the top of the stack is android.hardware.Camera, which is the Java
object that the application instantiates when it wants to take a
picture. This is a thin wrapper around android_hardware_Camera.cpp
which is the JNI interface. This in turn is a wrapper around libs/ui/
Camera.cpp which is the proxy for the remote object in the camera
service. And yes, libs/ui is a strange place for it, but it has some
circular dependencies on Surfaceflinger, so that's where it ended up.

在最上層是 android.hardware.Camera, 就是當application 拍照時會跑的Java object。它就是個小的wrapper在 android_hardware_Camera.cpp,也就是JNI介面。接下來,有另一個wrapper 在libs/ui/Camera.cpp,這個cpp是一個代理,專門for camera service 的remote object用。沒錯,放在libs/ui是蠻奇怪的,不過沒辦法,有些環境相依性的問題關於Surfaceflinger, 所以就這麼定了。


Now it gets interesting because there is a binder interface called
ICamera.h (pure virtual) which is implemented in ICamera.cpp which is
the marshalling code for the IPC binder calls. Let's just take it on
faith that the calls from the client result in a marshalled
ICameraClient object appearing on the server side of the interface.
Upon establishing a connection - provided that the application has
permission to use the camera - the camera service instantiates a
CameraHardwareInterface derived object, which is the HAL for the
actual camera hardware. The camera service takes care of preview
display and other low-level house-keeping functions that would be
difficult to do in a Java app.
現在,有趣的是,有個binder interface 叫做ICamera.h (純虛擬的),它被寫在ICamera.cpp裡,而ICamera.cpp 是marshalling code for IPC binder 呼叫的。我們只要相信,從client 來的呼叫,會導致一個marshalled 的ICameraClient object 顯示在server端的介面上。在建立連結上(所謂連結就是application 提到許可來使用camera),camera service會具現化 CameraHardwareInterface 而取得object, 這個object 就是實體camera 硬體用的HAL。而camera service 會處理preview 顯示,還有其它低階的內在功能(Java app會比較困難處理的部份)。


The camera hardware driver can either be implemented as a kernel
driver with a thin user space shim driver, or it can be implemented as
a user space driver with a thin kernel driver (primarily to control
access).
Camera hardware driver 可以寫成一個kernel driver 跟一個小user space 的driver, 或是寫成user space driver 跟一個小kernel dirver(主要是控制存取部份).


This is one of the more complex device models. Other devices (like the
LEDs) have a much simpler model.
這是比較複雜的device models的其中一個。其它的devices(像是LEDs)就有比較簡單model



>如果我要建一個新的device, 符合Android HAL, 我知道, 我應該使用下列方法的其中一個:
> 1. App - Runtime Service - lib
> 2. App - Runtime Service - Native Service - lib
> 3. App - Runtime Service - Native Daemon - lib

這要看形況,大部份的流程會像這樣:
app -> java api (manager) -> java service -> HAL module -> kernel

It depends, most of the time you'll need to do something like:

app -> java api (manager) -> java service -> HAL module -> kernel


有時候,以sensors為case來說,會有一個額外的native daemon, 但是在這個特別的case裡, it's an implementation detail (the sources for that daemon are proprietary).(看不懂什麼意思:p)

Sometimes (it's the case for the sensors), there is an extra native
daemon, but in this particular case, it's an implementation detail
(the sources for that daemon are proprietary).


有時候,native service 可以直接替換到java service,這要歸功於binder interfaces(它在程式語言上是很彈性的,所以service 可以被寫成java to c++,而不會破壞相容性,反之亦然)

Sometimes, the "java service", can be replaced directly by a "native
service", thanks to the binder interfaces (they're agnostic to the
languages involved, so a service can even be rewritten from java to
C++ or vice-versa, without breaking compatibility).


在一些cases 下,也是有可能跳過整個java service,如果HAL module 可以處理多個clients 以及相關的權限。

In some cases, it is also possible to skip the "java service"
entirely, if the HAL module can handle multiple clients and all the
permissions involved.


也有可能兩個方式都混在一起並用,以sensors 的例子來說; service 可以跟硬體建立connection , 但是app 卻可以直接跟HAL module 溝通傳資料。

It is also possible to have a mix and match, this is the case for the
sensors; the service is used to establish a connection with the
hardware, but all the data moving is done by talking directly to the
HAL module from the the app.


所以,結論就是,沒一定的規則。這要看你是想達成什麼樣的結果。

So, in short, there are no rules. It depends on what you're trying to
accomplish.

3.24.2009

PXA310 USB register 設定

Init:
1. reset
2. switch to sync mode
3. set SE0
4. 中斷開起
連起:
1. Set 3319 to Peripheral HS
2. clean XLLP_U2DOTGCR_UTMID
3. Start
4. 連的一開始3319 會變成low power mode(可能是controller 設的?)
此時如果 set XLLP_U2DOTGCR_UTMID,這次連線就是full speed, 可能是斷了chip JK的訊號


XLLP_U2DOTGCR_UTMID 和 XLLP_U2DOTGCR_ULE 有點搞不清礎

XLLP_U2DOTGCR_UTMID 感覺像是個開關, controller to 3319 這條路的開關
SPEC 說 set它是防止U2DC 的UTMI的register 去寫3319的ULPI 的register.
但要連起時卻又要clean 掉?

UDE | XLLP_U2DOTGCR_ULE
---------------------------
0 0 hold reset
0 1 can commulicate to 3319
1 0 can commulicate to 3319?
1 1 can commulicate to 3319?

3.19.2009

ActiveSync plugin/out


plug out
03/19/2009 21:43:51.735 - UsbComm: Change DTR to 0.
03/19/2009 21:43:51.735 - UsbComm: Closed device.
03/19/2009 21:43:51.767 - USB: Event 32772, name \\?\USB#Vid_05e0&Pid_2000#2f5b1900-11fe-0801-4d4f-303937303863#{25dbce51-6c8f-4a72-8a6d-b54c2b4fc835}
03/19/2009 21:43:51.767 - USB: Device Remove Complete notification
03/19/2009 21:43:52.001 - USB: RNDIS device id \\?\USB#Vid_05e0&Pid_2000#2f5b1900-11fe-0801-4d4f-303937303863#{a5dcbf10-6530-11d2-901f-00c04fb951ed}

plug in
03/19/2009 21:44:13.622 - USB: RNDIS device id \\?\USB#Vid_05e0&Pid_2000#2f5b1900-11fe-0801-4d4f-303937303863#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
03/19/2009 21:44:13.825 - USB: Event 32768, name \\?\USB#Vid_05e0&Pid_2000#2f5b1900-11fe-0801-4d4f-303937303863#{25dbce51-6c8f-4a72-8a6d-b54c2b4fc835}
03/19/2009 21:44:13.825 - USB: Device Arrival notification
03/19/2009 21:44:13.825 - UsbComm: Open device .
03/19/2009 21:44:13.825 - UsbComm: Change DTR to 1.
03/19/2009 21:44:13.840 - Serial: Starting device detection at 115200.
03/19/2009 21:44:13.840 - UsbComm: Change DTR to 1.

3.18.2009

ActiveSync 的log

記錄一下Activesync 切換模式的log


//////////////////////////////Rndis to Serial @WCESCOMM.log

03/19/2009 13:56:22.199 - USB: RNDIS device id \\?\USB#Vid_05e0&Pid_200d#2f5b1900-11fe-0801-4d4f-303937303863#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
03/19/2009 13:56:22.433 - USB: found RNDIS device id USB\Vid_05e0&Pid_200d&Rev_0000
03/19/2009 13:56:22.433 - USB RNDIS: Device Removal notification
03/19/2009 13:56:23.543 - USB: RNDIS device id \\?\USB#Vid_05e0&Pid_2000#2f5b1900-11fe-0801-4d4f-303937303863#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
03/19/2009 13:56:23.699 - USB: Event 32768, name \\?\USB#Vid_05e0&Pid_2000#2f5b1900-11fe-0801-4d4f-303937303863#{25dbce51-6c8f-4a72-8a6d-b54c2b4fc835}
03/19/2009 13:56:23.715 - USB: Device Arrival notification
03/19/2009 13:56:23.715 - UsbComm: Open device .
03/19/2009 13:56:23.715 - Serial: Starting device detection at 115200.
03/19/2009 13:56:23.715 - UsbComm: Change DTR to 1.
03/19/2009 13:56:23.715 - UsbComm: Change DTR to 1.
03/19/2009 13:56:24.230 - AutobaudDetect: Found character .
03/19/2009 13:56:24.230 - AutobaudDetect: Found character .
03/19/2009 13:56:24.230 - AutobaudDetect: Found character I.
03/19/2009 13:56:24.230 - AutobaudDetect: Found character .
03/19/2009 13:56:24.230 - AutobaudDetect: Found character .
03/19/2009 13:56:24.230 - AutobaudDetect: Found character .
03/19/2009 13:56:24.230 - Serial: Unimodem handshake at 115200.
03/19/2009 13:56:24.230 - Proxy: Change connection state 1.
03/19/2009 13:56:24.230 - Proxy: Created dynamic proxy on port 5655.
03/19/2009 13:56:24.246 - Proxy: Created dynamic proxy on port 3000.
03/19/2009 13:56:24.246 - Proxy: Created dynamic proxy on port 3001.
03/19/2009 13:56:24.246 - Proxy: Created dynamic proxy on port 3002.
03/19/2009 13:56:24.246 - Proxy: Created dynamic proxy on port 3003.
03/19/2009 13:56:24.246 - Proxy: Created dynamic proxy on port 3004.
03/19/2009 13:56:24.246 - Proxy: Created dynamic proxy on port 3005.
03/19/2009 13:56:24.246 - Proxy: Created dynamic proxy on port 3006.
03/19/2009 13:56:24.261 - Proxy: Created dynamic proxy on port 3007.
03/19/2009 13:56:24.261 - Proxy: Created dynamic proxy on port 3008.
03/19/2009 13:56:24.261 - Proxy: Created dynamic proxy on port 3009.
03/19/2009 13:56:24.261 - Proxy: Created dynamic proxy on port 3010.
03/19/2009 13:56:24.261 - Proxy: Created dynamic proxy on port 3011.
03/19/2009 13:56:24.261 - Proxy: Created dynamic proxy on port 3012.
03/19/2009 13:56:24.261 - Proxy: Created dynamic proxy on port 3013.
03/19/2009 13:56:24.261 - Proxy: Created dynamic proxy on port 3014.
03/19/2009 13:56:24.277 - Proxy: Created dynamic proxy on port 3015.
03/19/2009 13:56:24.277 - Proxy: Created dynamic proxy on port 3016.
03/19/2009 13:56:24.277 - Proxy: Created dynamic proxy on port 3017.
03/19/2009 13:56:24.277 - Proxy: Created dynamic proxy on port 3018.
03/19/2009 13:56:24.277 - Proxy: Created dynamic proxy on port 3019.
03/19/2009 13:56:24.277 - Proxy: Created dynamic proxy on port 3020.
03/19/2009 13:56:24.277 - Proxy: Created dynamic proxy on port 3021.
03/19/2009 13:56:24.293 - Proxy: Created dynamic proxy on port 3022.
03/19/2009 13:56:24.293 - Proxy: Created dynamic proxy on port 3023.
03/19/2009 13:56:24.293 - Proxy: Created dynamic proxy on port 3024.
03/19/2009 13:56:24.293 - Proxy: Created dynamic proxy on port 3025.
03/19/2009 13:56:24.293 - Proxy: Created dynamic proxy on port 3026.
03/19/2009 13:56:24.293 - Proxy: Created dynamic proxy on port 3027.
03/19/2009 13:56:24.293 - Proxy: Created dynamic proxy on port 3028.
03/19/2009 13:56:24.308 - Proxy: Created dynamic proxy on port 3029.
03/19/2009 13:56:24.308 - Proxy: Created dynamic proxy on port 3030.
03/19/2009 13:56:24.308 - Proxy: Created dynamic proxy on port 3031.
03/19/2009 13:56:24.308 - Proxy: Created dynamic proxy on port 6510.
03/19/2009 13:56:24.308 - Proxy: Created dynamic proxy on port 6511.
03/19/2009 13:56:24.308 - Proxy: Created dynamic proxy on port 6512.
03/19/2009 13:56:24.308 - Proxy: Created dynamic proxy on port 6513.
03/19/2009 13:56:24.324 - Proxy: Created dynamic proxy on port 6514.
03/19/2009 13:56:24.324 - Proxy: Created dynamic proxy on port 6515.
03/19/2009 13:56:24.324 - Proxy: Created dynamic proxy on port 6516.
03/19/2009 13:56:24.324 - Proxy: Created dynamic proxy on port 6517.
03/19/2009 13:56:24.324 - Proxy: Created dynamic proxy on port 6518.
03/19/2009 13:56:24.324 - Proxy: Created dynamic proxy on port 6519.
03/19/2009 13:56:24.324 - Proxy: Created dynamic proxy on port 6520.
03/19/2009 13:56:24.324 - Proxy: Created dynamic proxy on port 6521.
03/19/2009 13:56:24.340 - Proxy: Created dynamic proxy on port 6522.
03/19/2009 13:56:24.340 - Proxy: Created dynamic proxy on port 6523.
03/19/2009 13:56:24.340 - Proxy: Created dynamic proxy on port 6524.
03/19/2009 13:56:24.340 - Proxy: Created dynamic proxy on port 6525.
03/19/2009 13:56:24.340 - Proxy: Created dynamic proxy on port 6526.
03/19/2009 13:56:24.340 - Proxy: Created dynamic proxy on port 6527.
03/19/2009 13:56:24.340 - Proxy: Created dynamic proxy on port 6528.
03/19/2009 13:56:24.355 - Proxy: Created dynamic proxy on port 6529.
03/19/2009 13:56:24.355 - Proxy: Created dynamic proxy on port 6530.
03/19/2009 13:56:24.355 - Proxy: Created dynamic proxy on port 6531.
03/19/2009 13:56:24.355 - Proxy: Created dynamic proxy on port 6532.
03/19/2009 13:56:24.355 - Proxy: Created dynamic proxy on port 6533.
03/19/2009 13:56:24.355 - Proxy: Created dynamic proxy on port 6534.
03/19/2009 13:56:24.355 - Proxy: Created dynamic proxy on port 6535.
03/19/2009 13:56:24.371 - Proxy: Created dynamic proxy on port 6536.
03/19/2009 13:56:24.371 - Proxy: Created dynamic proxy on port 6537.
03/19/2009 13:56:24.371 - Proxy: Created dynamic proxy on port 6538.
03/19/2009 13:56:24.371 - Proxy: Created dynamic proxy on port 6539.
03/19/2009 13:56:24.371 - Proxy: Created dynamic proxy on port 6540.
03/19/2009 13:56:24.371 - Proxy: Created dynamic proxy on port 6541.
03/19/2009 13:56:24.371 - Proxy: Created dynamic proxy on port 1026.
03/19/2009 13:56:27.840 - TCP: ....S., 192.168.55.101(1035) => 192.168.55.100(7438) Seq=12347588-12347588 Ack=0 Win=32768 Len=48
03/19/2009 13:56:27.840 - Proxy: Connection Attempt on port 7438, dest ip 0x6437a8c0
03/19/2009 13:56:27.840 - TCP: .A..S., 192.168.55.100(7438) => 192.168.55.101(1035) Seq=17445625-17445625 Ack=12347589 Win=8760 Len=44
03/19/2009 13:56:27.933 - TCP: ....S., 192.168.55.101(1036) => 192.168.55.100(990) Seq=12367730-12367730 Ack=0 Win=32768 Len=48
03/19/2009 13:56:27.933 - Proxy: Connection Attempt on port 990, dest ip 0x6437a8c0
03/19/2009 13:56:27.949 - TCP: .A..S., 192.168.55.100(990) => 192.168.55.101(1036) Seq=17445734-17445734 Ack=12367731 Win=8760 Len=44
03/19/2009 13:56:28.824 - CesProxy: Accept on port 7438, IsWinsock 0, hResult 0
03/19/2009 13:56:28.824 - CesProxy: Accept on port 990, IsWinsock 0, hResult 0
03/19/2009 13:56:28.918 - TCP: ....S., 192.168.55.101(1037) => 192.168.55.100(990) Seq=12668475-12668475 Ack=0 Win=32768 Len=48
03/19/2009 13:56:28.933 - TCP: .A..S., 192.168.55.100(990) => 192.168.55.101(1037) Seq=17446718-17446718 Ack=12668476 Win=8760 Len=44
03/19/2009 13:56:29.918 - CesProxy: Accept on port 990, IsWinsock 0, hResult 0
03/19/2009 13:56:29.918 - TCP: ....S., 192.168.55.101(1039) => 192.168.55.100(990) Seq=12958012-12958012 Ack=0 Win=32768 Len=48
03/19/2009 13:56:29.918 - TCP: .A..S., 192.168.55.100(990) => 192.168.55.101(1039) Seq=17447703-17447703 Ack=12958013 Win=8760 Len=44
03/19/2009 13:56:31.011 - CesProxy: Accept on port 990, IsWinsock 0, hResult 0
03/19/2009 13:56:31.027 - TCP: ....S., 192.168.55.101(1040) => 192.168.55.100(990) Seq=13270839-13270839 Ack=0 Win=32768 Len=48
03/19/2009 13:56:31.027 - TCP: .A..S., 192.168.55.100(990) => 192.168.55.101(1040) Seq=17448812-17448812 Ack=13270840 Win=8760 Len=44
03/19/2009 13:56:31.027 - CesProxy: Accept on port 990, IsWinsock 0, hResult 0


////////////////////////////////////Serial to Rndis @WCESCOMM.log
03/19/2009 13:58:09.806 - UsbComm: Change DTR to 0.
03/19/2009 13:58:09.806 - UsbComm: Closed device.
03/19/2009 13:58:09.806 - Proxy: Change connection state 0.
03/19/2009 13:58:09.806 - CesProxy: Close PPP socket 990
03/19/2009 13:58:09.821 - CesProxy: Accept on port 990, IsWinsock 0, hResult 80072714
03/19/2009 13:58:09.821 - CesProxy: Close PPP socket 7438
03/19/2009 13:58:09.821 - CesProxy: Accept on port 7438, IsWinsock 0, hResult 80072714
03/19/2009 13:58:09.821 - CesProxy: Close Win socket 1026
03/19/2009 13:58:09.821 - CesProxy: Accept on port 1026, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.821 - CesProxy: Close Win socket 6541
03/19/2009 13:58:09.821 - CesProxy: Accept on port 6541, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.837 - CesProxy: Close Win socket 6540
03/19/2009 13:58:09.837 - CesProxy: Accept on port 6540, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.837 - USB: Event 32772, name \\?\USB#Vid_05e0&Pid_2000#2f5b1900-11fe-0801-4d4f-303937303863#{25dbce51-6c8f-4a72-8a6d-b54c2b4fc835}
03/19/2009 13:58:09.837 - CesProxy: Close Win socket 6539
03/19/2009 13:58:09.852 - USB: Device Remove Complete notification
03/19/2009 13:58:09.852 - CesProxy: Accept on port 6539, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.852 - CesProxy: Close Win socket 6538
03/19/2009 13:58:09.852 - CesProxy: Accept on port 6538, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.852 - CesProxy: Close Win socket 6537
03/19/2009 13:58:09.852 - CesProxy: Accept on port 6537, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.852 - CesProxy: Close Win socket 6536
03/19/2009 13:58:09.868 - CesProxy: Accept on port 6536, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.868 - CesProxy: Close Win socket 6535
03/19/2009 13:58:09.868 - CesProxy: Accept on port 6535, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.868 - CesProxy: Close Win socket 6534
03/19/2009 13:58:09.868 - CesProxy: Accept on port 6534, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.868 - CesProxy: Close Win socket 6533
03/19/2009 13:58:09.868 - CesProxy: Accept on port 6533, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.884 - CesProxy: Close Win socket 6532
03/19/2009 13:58:09.884 - CesProxy: Accept on port 6532, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.884 - CesProxy: Close Win socket 6531
03/19/2009 13:58:09.884 - CesProxy: Accept on port 6531, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.884 - CesProxy: Close Win socket 6530
03/19/2009 13:58:09.884 - CesProxy: Accept on port 6530, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.884 - CesProxy: Close Win socket 6529
03/19/2009 13:58:09.899 - CesProxy: Accept on port 6529, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.899 - CesProxy: Close Win socket 6528
03/19/2009 13:58:09.899 - CesProxy: Accept on port 6528, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.899 - CesProxy: Close Win socket 6527
03/19/2009 13:58:09.899 - CesProxy: Accept on port 6527, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.899 - CesProxy: Close Win socket 6526
03/19/2009 13:58:09.899 - CesProxy: Accept on port 6526, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.915 - CesProxy: Close Win socket 6525
03/19/2009 13:58:09.915 - CesProxy: Accept on port 6525, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.915 - CesProxy: Close Win socket 6524
03/19/2009 13:58:09.915 - CesProxy: Accept on port 6524, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.915 - CesProxy: Close Win socket 6523
03/19/2009 13:58:09.915 - CesProxy: Accept on port 6523, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.915 - CesProxy: Close Win socket 6522
03/19/2009 13:58:09.915 - CesProxy: Accept on port 6522, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.915 - CesProxy: Close Win socket 6521
03/19/2009 13:58:09.931 - CesProxy: Accept on port 6521, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.931 - CesProxy: Close Win socket 6520
03/19/2009 13:58:09.931 - CesProxy: Accept on port 6520, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.931 - CesProxy: Close Win socket 6519
03/19/2009 13:58:09.931 - CesProxy: Accept on port 6519, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.931 - CesProxy: Close Win socket 6518
03/19/2009 13:58:09.931 - CesProxy: Accept on port 6518, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.931 - CesProxy: Close Win socket 6517
03/19/2009 13:58:09.946 - CesProxy: Accept on port 6517, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.946 - CesProxy: Close Win socket 6516
03/19/2009 13:58:09.946 - CesProxy: Accept on port 6516, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.946 - CesProxy: Close Win socket 6515
03/19/2009 13:58:09.946 - CesProxy: Accept on port 6515, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.946 - CesProxy: Close Win socket 6514
03/19/2009 13:58:09.946 - CesProxy: Accept on port 6514, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.946 - CesProxy: Close Win socket 6513
03/19/2009 13:58:09.946 - CesProxy: Accept on port 6513, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.962 - CesProxy: Close Win socket 6512
03/19/2009 13:58:09.962 - CesProxy: Accept on port 6512, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.962 - CesProxy: Close Win socket 6511
03/19/2009 13:58:09.962 - CesProxy: Accept on port 6511, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.962 - CesProxy: Close Win socket 6510
03/19/2009 13:58:09.962 - CesProxy: Accept on port 6510, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.977 - CesProxy: Close Win socket 3031
03/19/2009 13:58:09.977 - CesProxy: Accept on port 3031, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.977 - CesProxy: Close Win socket 3030
03/19/2009 13:58:09.977 - CesProxy: Accept on port 3030, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.977 - CesProxy: Close Win socket 3029
03/19/2009 13:58:09.977 - CesProxy: Accept on port 3029, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.977 - CesProxy: Close Win socket 3028
03/19/2009 13:58:09.977 - CesProxy: Accept on port 3028, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.993 - CesProxy: Close Win socket 3027
03/19/2009 13:58:09.993 - CesProxy: Accept on port 3027, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.993 - CesProxy: Close Win socket 3026
03/19/2009 13:58:09.993 - CesProxy: Accept on port 3026, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.993 - CesProxy: Close Win socket 3025
03/19/2009 13:58:09.993 - CesProxy: Accept on port 3025, IsWinsock 1, hResult 80072714
03/19/2009 13:58:09.993 - CesProxy: Close Win socket 3024
03/19/2009 13:58:10.009 - CesProxy: Accept on port 3024, IsWinsock 1, hResult 80072714
03/19/2009 13:58:10.009 - CesProxy: Close Win socket 3023
03/19/2009 13:58:10.009 - CesProxy: Accept on port 3023, IsWinsock 1, hResult 80072714
03/19/2009 13:58:10.009 - CesProxy: Close Win socket 3022
03/19/2009 13:58:10.009 - CesProxy: Accept on port 3022, IsWinsock 1, hResult 80072714
03/19/2009 13:58:10.009 - CesProxy: Close Win socket 3021
03/19/2009 13:58:10.024 - CesProxy: Accept on port 3021, IsWinsock 1, hResult 80072714
03/19/2009 13:58:10.024 - CesProxy: Close Win socket 3020
03/19/2009 13:58:10.024 - CesProxy: Accept on port 3020, IsWinsock 1, hResult 80072714
03/19/2009 13:58:10.024 - CesProxy: Close Win socket 3019
03/19/2009 13:58:10.024 - CesProxy: Accept on port 3019, IsWinsock 1, hResult 80072714
03/19/2009 13:58:10.024 - CesProxy: Close Win socket 3018
03/19/2009 13:58:10.024 - CesProxy: Accept on port 3018, IsWinsock 1, hResult 80072714
03/19/2009 13:58:10.040 - CesProxy: Close Win socket 3017
03/19/2009 13:58:10.040 - CesProxy: Accept on port 3017, IsWinsock 1, hResult 80072714
03/19/2009 13:58:10.040 - CesProxy: Close Win socket 3016
03/19/2009 13:58:10.040 - CesProxy: Accept on port 3016, IsWinsock 1, hResult 80072714
03/19/2009 13:58:10.040 - CesProxy: Close Win socket 3015
03/19/2009 13:58:10.040 - CesProxy: Accept on port 3015, IsWinsock 1, hResult 80072714
03/19/2009 13:58:10.040 - CesProxy: Close Win socket 3014
03/19/2009 13:58:10.040 - CesProxy: Accept on port 3014, IsWinsock 1, hResult 80072714
03/19/2009 13:58:10.056 - CesProxy: Close Win socket 3013
03/19/2009 13:58:10.056 - CesProxy: Accept on port 3013, IsWinsock 1, hResult 80072714
03/19/2009 13:58:10.056 - CesProxy: Close Win socket 3012
03/19/2009 13:58:10.056 - CesProxy: Accept on port 3012, IsWinsock 1, hResult 80072714
03/19/2009 13:58:10.056 - CesProxy: Close Win socket 3011
03/19/2009 13:58:10.056 - CesProxy: Accept on port 3011, IsWinsock 1, hResult 80072714
03/19/2009 13:58:10.056 - CesProxy: Close Win socket 3010
03/19/2009 13:58:10.056 - CesProxy: Accept on port 3010, IsWinsock 1, hResult 80072714
03/19/2009 13:58:10.071 - CesProxy: Close Win socket 3009
03/19/2009 13:58:10.071 - CesProxy: Accept on port 3009, IsWinsock 1, hResult 80072714
03/19/2009 13:58:10.071 - CesProxy: Close Win socket 3008
03/19/2009 13:58:10.071 - CesProxy: Accept on port 3008, IsWinsock 1, hResult 80072714
03/19/2009 13:58:10.071 - CesProxy: Close Win socket 3007
03/19/2009 13:58:10.071 - CesProxy: Accept on port 3007, IsWinsock 1, hResult 80072714
03/19/2009 13:58:10.071 - CesProxy: Close Win socket 3006
03/19/2009 13:58:10.071 - CesProxy: Accept on port 3006, IsWinsock 1, hResult 80072714
03/19/2009 13:58:10.087 - CesProxy: Close Win socket 3005
03/19/2009 13:58:10.087 - CesProxy: Accept on port 3005, IsWinsock 1, hResult 80072714
03/19/2009 13:58:10.087 - CesProxy: Close Win socket 3004
03/19/2009 13:58:10.087 - CesProxy: Accept on port 3004, IsWinsock 1, hResult 80072714
03/19/2009 13:58:10.087 - CesProxy: Close Win socket 3003
03/19/2009 13:58:10.087 - CesProxy: Accept on port 3003, IsWinsock 1, hResult 80072714
03/19/2009 13:58:10.087 - CesProxy: Close Win socket 3002
03/19/2009 13:58:10.087 - CesProxy: Accept on port 3002, IsWinsock 1, hResult 80072714
03/19/2009 13:58:10.087 - CesProxy: Close Win socket 3001
03/19/2009 13:58:10.102 - CesProxy: Accept on port 3001, IsWinsock 1, hResult 80072714
03/19/2009 13:58:10.102 - CesProxy: Close Win socket 3000
03/19/2009 13:58:10.102 - CesProxy: Accept on port 3000, IsWinsock 1, hResult 80072714
03/19/2009 13:58:10.102 - CesProxy: Close Win socket 5655
03/19/2009 13:58:10.102 - CesProxy: Accept on port 5655, IsWinsock 1, hResult 80072714
03/19/2009 13:58:10.102 - CesProxy: Close PPP socket 990
03/19/2009 13:58:10.102 - CesProxy: recv failed on PPP socket 990, err = 10053
03/19/2009 13:58:10.102 - CesProxy: Close Win socket 990
03/19/2009 13:58:10.102 - CesProxy: recv failed on Win socket 990, err = 10053
03/19/2009 13:58:10.118 - CesProxy: Close PPP socket 990
03/19/2009 13:58:10.118 - CesProxy: recv failed on PPP socket 990, err = 10053
03/19/2009 13:58:10.118 - CesProxy: Close Win socket 990
03/19/2009 13:58:10.118 - CesProxy: recv failed on Win socket 990, err = 10053
03/19/2009 13:58:10.118 - CesProxy: Close PPP socket 990
03/19/2009 13:58:10.118 - CesProxy: recv failed on PPP socket 990, err = 10053
03/19/2009 13:58:10.118 - CesProxy: Close Win socket 990
03/19/2009 13:58:10.118 - CesProxy: recv failed on Win socket 990, err = 10053
03/19/2009 13:58:10.118 - CesProxy: Close PPP socket 990
03/19/2009 13:58:10.134 - CesProxy: recv failed on PPP socket 990, err = 10053
03/19/2009 13:58:10.134 - CesProxy: Close Win socket 990
03/19/2009 13:58:10.134 - CesProxy: recv failed on Win socket 990, err = 10053
03/19/2009 13:58:10.134 - CesProxy: Close PPP socket 7438
03/19/2009 13:58:10.134 - CesProxy: recv failed on PPP socket 7438, err = 10053
03/19/2009 13:58:10.134 - CesProxy: Close Win socket 7438
03/19/2009 13:58:10.134 - CesProxy: recv failed on Win socket 7438, err = 10053
03/19/2009 13:58:10.243 - USB: RNDIS device id \\?\USB#Vid_05e0&Pid_2000#2f5b1900-11fe-0801-4d4f-303937303863#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
03/19/2009 13:58:11.931 - USB: RNDIS device id \\?\USB#Vid_05e0&Pid_200d#2f5b1900-11fe-0801-4d4f-303937303863#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
03/19/2009 13:58:12.087 - USB: found RNDIS device id USB\Vid_05e0&Pid_200d&Rev_0000
03/19/2009 13:58:20.493 - USB RNDIS: Device Arrival notification



////////////////////////////////RNDIS to SErial @WCESMgr
03/19/2009 14:01:32.122 **************** Logging Started ****************
03/19/2009 14:01:32.122 Process C:\Program Files\Microsoft ActiveSync\WCESMgr.exe p(3032)
03/19/2009 14:01:32.122 ActiveSync second instance started, Cmd line: '/onconnect'
03/19/2009 14:01:32.122 ActiveSync second instance exiting
03/19/2009 14:01:32.122 **************** Logging Stopped ****************
03/19/2009 14:01:34.153 Creating new partnership for device 0x0 (Pocket_PC, PocketPC).
03/19/2009 14:01:35.481 p(3472) t(2672) TraceToFile -> ERROR in CCSP::ParseNodes : hr = 0x80140507 - Devicecm.cpp(1598)
03/19/2009 14:01:35.481 Found PIM at 'C:\PROGRA~1\MICROS~3\Office12\OUTLOOK.EXE'
03/19/2009 14:01:35.481 Found PIM at 'C:\PROGRA~1\MICROS~3\Office12\OUTLOOK.EXE'
03/19/2009 14:01:37.981 DTPT: Setting DTPT network to {18AD9FBD-F716-ACB6-FD8A-1965DB95B814}
03/19/2009 14:01:37.981 DTPT: Incomming proxy server string: proxy.iec2.iac:80
03/19/2009 14:01:37.981 DTPT: Setup proxy to send to server. Src={18AD9FBD-F716-ACB6-FD8A-1965DB95B814} Dest={436EF144-B4FB-4863-A041-8F905A62C572} Proxy=proxy.iec2.iac:80 Socks=proxy.iec2.iac:1080 HR=0x00000000
03/19/2009 14:01:37.981 DTPT: Send DTPT Network={18AD9FBD-F716-ACB6-FD8A-1965DB95B814}. Result=0x00000000
03/19/2009 14:01:37.981 DTPTMultiHoming: Send Value=0 Result=0x00000000

//////////////////////////////Serial to RNDIS @WCESMgr
03/19/2009 14:03:12.770 **************** Logging Started ****************
03/19/2009 14:03:12.770 Process C:\Program Files\Microsoft ActiveSync\WCESMgr.exe p(4468)
03/19/2009 14:03:12.770 ActiveSync second instance started, Cmd line: '/onconnect'
03/19/2009 14:03:12.770 ActiveSync second instance exiting
03/19/2009 14:03:12.770 **************** Logging Stopped ****************
03/19/2009 14:03:13.223 Creating new partnership for device 0x0 (Pocket_PC, PocketPC).
03/19/2009 14:03:14.270 p(3472) t(4796) TraceToFile -> ERROR in CCSP::ParseNodes : hr = 0x80140507 - Devicecm.cpp(1598)
03/19/2009 14:03:14.270 Found PIM at 'C:\PROGRA~1\MICROS~3\Office12\OUTLOOK.EXE'
03/19/2009 14:03:14.270 Found PIM at 'C:\PROGRA~1\MICROS~3\Office12\OUTLOOK.EXE'
03/19/2009 14:03:15.910 DTPT: Setting DTPT network to {18AD9FBD-F716-ACB6-FD8A-1965DB95B814}
03/19/2009 14:03:15.910 DTPT: Incomming proxy server string: proxy.iec2.iac:80
03/19/2009 14:03:15.910 DTPT: Setup proxy to send to server. Src={18AD9FBD-F716-ACB6-FD8A-1965DB95B814} Dest={436EF144-B4FB-4863-A041-8F905A62C572} Proxy=proxy.iec2.iac:80 Socks=proxy.iec2.iac:1080 HR=0x00000000


CHAPTER 1An Introduction to Device Drivers @Linux device drivers 3rd

最近開始要study Linux 的東西, 先從這本Linux device drivers 3rd開始看
順便練一下英文。



CHAPTER 1An Introduction toDevice Drivers
第一章 Device driver 的介紹


One of the many advantages of free operating systems, as typified by Linux, is that their internals are open for all to view.
免費的OS,像Linux, 的眾多優點之一就是code 都是開放的.

The operating system, once a dark and mysterious area whose code was restricted to a small number of programmers, can now be readily examined, understood, and modified by anybody with the requisite skills.
OS, 一個黑暗又神祕的領域,這個領域總是被掌握在少數幾位工程師身上,如今可以容易的被任何有能力的人,檢視、了解及修改.

Linux has helped to democratize operating systems.
Linux 已經成為大眾化的OS.

The Linux kernel remains a large and complex body of code, however, and would-be kernel hackers need an entry point where they can approach the code without being overwhelmed by complexity. Often, device drivers provide that gateway.
Linux kernel 總是很複雜的,對於那些想要成為kernel 專家的人,需要一個起點來了解kernel是比較容易的,而通常這個點就是device drivers.

Device drivers take on a special role in the Linux kernel.
在Linux kernel 裡 Device drivers 扮演了一個特別的角色.

They are distinct “blackboxes” that make a particular piece of hardware respond to a well-defined internal programming interface; they hide completely the details of how the device works.
它們跟所謂的"黑盒子"不同,它們讓一個特定的硬體對應到定義的好的內部程式介面; 它們能夠完全的穩藏硬體的動作。

User activities are performed by means of a set of standardized calls that are independent of the specific driver; mapping those calls to device-specific operations that acton real hardware is then the role of the device driver.
上層的使用者可以在一系列標準的function calls 上運作,而每一個function call 則是對印到獨立的且特定的硬體; 這也就是device driver所做的事。

This programming interface is such that drivers can be built separately from the rest of the kernel and “plugged in”at runtime when needed.
這個programming interface 可以分別build. 當需要時只要 "plugged in"就可. 即使是在rumtmie的時候。

This modularity makes Linux drivers easy to write, to the point that there are now hundreds of them available.
在這樣的模組化情況下,linux drivers 就很容易的去寫它。到目前為止已有幾百個drivers 可用了.

There are a number of reasons to be interested in the writing of Linux device drivers.
有很多理由讓你對設計Linux device drivers 有興趣 。

The rate at which new hardware becomes available (and obsolete!) alone guarantees that driver writers will be busy for the foreseeable future.
硬體不斷的出新換舊,更顯示出可預期的未來,driver 工程師們會一直很忙。

Individuals may need to know about drivers in order to gain access to a particular device that is of interest to them.
他們需要了解drivers ,才能對他們有興趣的device,進行存取

Hardware vendors, by making a Linux driver available for their products, can add the large and growing Linux user base to their potential markets.
讓想要支援Linux的硬體製造商,可以將那些使用Linux 的人,加入他們的潛在市場。

And the opensource nature of the Linux system means that if the driver writer wishes, the source to a driver can be quickly disseminated to millions of users.
而Linux 系統的opensource意謂著driver source 可以快速的散播給幾百萬人,如果driver設計師希望的話。

This book teaches you how to write your own drivers and how to hack around in related parts of the kernel.
這本書教你如何寫你的driver,以及如何處理跟它有關的kernel 部份。

We have taken a device-independent approach; the programming techniques and interfaces are presented, whenever possible, without being tied to any specific device.
我們已經採用裝置獨立的方式;程式技巧和介面都不需要跟任何特定的device 綁在一起。

Each driver is different; as a driver writer, you need to understand your specific device well.
每個driver 都不同; 身為driver 設計者必需要了解你的device.

But most of the principles and basic techniques are the same for all drivers. This book cannot teach you about your device,but it gives you a handle on the background you need to make your device work.
不過對所以的drivers來說,大部份的原則和基本技巧是一樣的。這本書沒辦法告訴你,關於你的device的東西,但可以告訴你如何讓你的device動起來,所需的背景知識


The Role of the Device Driver
Device driver 的角色

As a programmer, you are able to make your own choices about your driver, and
choose an acceptable trade-off between the programming time required and the flexibility of the result.
身為程式設計師,你能夠選擇你的driver, 也能夠在程式需完成的時間及靈活性之中做一個折衷的選擇。

Though it may appear strange to say that a driver is “flexible,” we
like this word because it emphasizes that the role of a device driver is providing
mechanism, not policy.
雖然說driver 是靈活的很奇怪,但是我們喜歡這個字眼,因為這强調了device driver 是一個可以"提供"的機制而不是個方法。

The distinction between mechanism and policy is one of the best ideas behind the
Unix design.
機制和方針之間的不同正是Unix 設計的背後最好的idea.

Most programming problems can indeed be split into two parts: “what
capabilities are to be provided” (the mechanism) and “how those capabilities can be
used” (the policy).
大部份設計的問題,可以正好分成兩個部份:"什麼樣的能力可以被提供"(機制)和"哪些能力如何被使用"(方針)

If the two issues are addressed by different parts of the program,or even by different programs altogether, the software package is much easier to develop and to adapt to particular needs.
如果這兩個問題被提出來在同一個程式不同的部份,或甚至完全不同的程式,那程式就很容易去研發也容易去適應特定的需求。

For example, Unix management of the graphic display is split between the X server,
which knows the hardware and offers a unified interface to user programs, and the
window and session managers, which implement a particular policy without knowing
anything about the hardware.
舉例來說,Unix 的圖形顯示管理就分X server(知道硬體也提供一個統一的介面給用的程式)和window, 還有session managers(實現了一個特定的方法在不知道硬體的情形下)。

People can use the same window manager on different hardware, and different users can run different configurations on the same workstation.
人們可以用一樣的window manager 在不同的硬體上跑,或者是不同的user 可以跑不同的組態在同一個workstation。

Even completely different desktop environments, such as KDE and GNOME, can coexist on the same system.
或甚至完全不同的桌面環境,像是KDE和GNOME,可以共存在同一個系統。

Another example is the layered structure of TCP/IP networking: the operating system offers the socket abstraction, which implements no policy regarding the data to be transferred, while different servers are in charge of the services (and their associated policies).
另一個例子是TCP/IP 網路的分層架構: 當不同的server再提供服務時(提供和何傳送資料的方法),作業系統就有提供socket抽像層(不提供任何方法跟被傳送的資料有關)

Moreover, a server like ftpd provides the file transfer mechanism, while users can use whatever client they prefer; both command-line and graphic clients exist, and anyone can write a new user interface to transfer files.
還有,像FTP 這樣的server 有提供檔案傳輸的機制,但是無論使用者用什麼介面都可用這個機制;command-line 和繪圖介面都可同時存在,並且任何人都可以寫個新的介面來傳送檔案

Where drivers are concerned, the same separation of mechanism and policy applies.
那drivers 要關切的,就是the same separation of mechanism and policy applies

The floppy driver is policy free—its role is only to show the diskette as a continuous array of data blocks. Higher levels of the system provide policies, such as who may access the floppy drive, whether the drive is accessed directly or via a filesystem, and whether users may mount filesystems on the drive.
軟碟 driver 不提供任何方法-它的角色就是只有顯示一個連續資料的陣列。而上層的系統則提供方法來讓任何人直接存取軟碟或通過檔案系統。

Since different environments usually need to use hardware in different ways, it’s important to be as policy free as possible.
一但在不同的環境下,用不同的方式,經常使用硬體,driver盡可能的不限制使用方法,就顯的很重要。

When writing drivers, a programmer should pay particular attention to this fundamental concept: write kernel code to access the hardware, but don’t force particular policies on the user, since different users have different needs.
當要設計drivers時,設計者們應該要特別注意這個重要的觀念: 寫一個在kernel的程式,來存取硬體,而不是要求使用者用特定的方法來用你的硬體,因為不同的使用者有不同的需要。

The driver should deal with making the hardware available, leaving all the issues about how to use the hardware to the applications.
driver 應該要讓硬體可以被使用,而不要管應用程式要如何使用硬體

A driver, then, is flexible if it offers access to the hardware capabilities without adding constraints.
然後driver也要夠靈活,如果它提供個能力來無限制的使用硬體

Sometimes, however, some policy decisions must be made. For example, a digital I/O driver may only offer byte-wide access to the hardware in order to avoid the extra code needed to handle individual bits.
然而,有時候有些方法是要被確定的。例如,一個數位I/O driver可能只提供byte-wide 的存取,來存取硬體來避免要額外的程式來處理獨立的bits

You can also look at your driver from a different perspective: it is a software layer
that lies between the applications and the actual device.
你也可以用不同的觀點來看你的driver: 它是一個軟體躺在應用程式跟實體device 的中間。

This privileged role of the driver allows the driver programmer to choose exactly how the device should appear: different drivers can offer different capabilities, even for the same device.
對於一個扮演有特權的角色的driver來說,允許driver 設計者可以決定device 要如何見人: 甚至於同一個device,可以有不同的drivers來提供不同的能力。

The actual driver design should be a balance between many different considerations. For instance, a single device may be used concurrently by different programs, and the
driver programmer has complete freedom to determine how to handle concurrency.
實際的driver設計應該要在許多不同的顧慮中取得平衡。舉例來說,一個單一的device可能同時被不同的程式使用,而driver 的設計者有完全的自由來決定如何處理這樣的同時發生的情況。

You could implement memory mapping on the device independently of its hardware
capabilities, or you could provide a user library to help application programmers
implement new policies on top of the available primitives, and so forth.
你可以寫個記憶體對映到一個完全跟硬體無關的device,或者你也可以提供一個user library 來幫助應用程式的設計者在可用的原素上寫些新的方法來使用,等等。

One major consideration is the trade-off between the desire to present the user with as many options as possible and the time you have to write the driver, as well as the need to keep things simple so that errors don’t creep in.
一個主要的考量就是,不但要在盡可能的給user選擇的權利和完成driver所需的時間中取得妥協,還要讓它簡單,以致於錯誤數量不會一直的上升。

Policy-free drivers have a number of typical characteristics. These include support for both synchronous and asynchronous operation, the ability to be opened multiple
times, the ability to exploit the full capabilities of the hardware, and the lack of software layers to “simplify things” or provide policy-related operations.
不含使用方法的driver 有很多特性。像是同步和非同步的運作,可以被開啟很多次,可以被盡情的使用,或是沒有軟體層讓它很簡單,或提供有特定方法的運作。

Drivers of this sort not only work better for their end users, but also turn out to be easier to write and maintain as well. Being policy-free is actually a common target for software designers.
這種特性的drivers 不只對end usres來說很好用,也容易來撰寫及維護。像這樣的不限制使用方法的driver 其實是軟體設計者的共同目標。

Many device drivers, indeed, are released together with user programs to help with
configuration and access to the target device.
透過使用者的程式幫助設定並存取目標的device,確實許多device drivers 是互相關連在一起的.

Those programs can range from simple utilities to complete graphical applications.
這些程式可以將簡單的工具延申到一個完整的圖形應用程式。

Examples include the tunelp program, which adjusts how the parallel port printer driver operates, and the graphical cardctl utility that is part of the PCMCIA driver package. Often a client library is provided as well, which provides capabilities that do not need to be implemented as part of the driver itself.
tunelp 程式就是個例子,它是用來調節並列port(印表機的運作),及繪圖 cardctl 系統工具(PCMCIA driver 包的一部份)。像client library 也是經常被提供,這樣的library 就提供了一些不需要在driver 裡寫的一些功能

The scope of this book is the kernel, so we try not to deal with policy issues or with application programs or support libraries. Sometimes we talk about different policies and how to support them, but we won’t go into much detail about programs
using the device or the policies they enforce. You should understand, however, that
user programs are an integral part of a software package and that even policy-free
packages are distributed with configuration files that apply a default behavior to the underlying mechanisms.
這本書是範疇在kernel,所以我們試著不要處理applicantion如何用的問題或是支援資料庫。有時我們會討論到不同的方法和如何支援他們,但我們不會太仔細的討論程式如何使用device,或是他們實施什麼樣的方法。然而,你需要了解,使用者程式是整個軟體組件的一部份,就算是(不含使用方法)的組件也是有設定檔,來設定預設的行為來實現基本的的機制。

3.11.2009

有錢人想的果然和我不一樣

前一陣子看到有人說最快賺錢的方式就是"站在巨人的肩膀上"
找個金主,他出80你出20去投資。
然後我問:金主怎麼會借錢給一個沒經驗的人
答案是:真正的大金主是不會care 借你幾百萬或是1 2千萬。因為他們一天可能就好幾億再上下。
資本愈雄厚的人,要求的報籌率愈低。

確實我沒想過有錢人能承受的風險跟一般人不一樣(因為我沒有有錢過 :P)

--------------------------------------------------------------------------------

Q: 我如何用1百萬去多賺出至少10萬元以上的獲利在一年內,透過目前我有的專業能力?
1.讓自己出名,搞一點東西post 到網路上。然後可能就有什麼機會產生。
Q: 有什麼能力是我可以培養來做到10%以上的投報率?

2.03.2009

卡了好幾個月的 USB bug

現象: 用RNDIS mode 連Activesync 時,會斷。有時5min,有時10min,有時 8h

這個問題大概前後也解了五個月了吧(沒被fire 但也沒什麼bonous)。
從懷疑connector 鬆掉,然後防火牆防毒軟體,到用USB Analyzer 抓封包,才真正抓到Root cause. 就是Marvell 的 USB driver 寫的有風險,只要手機的速度跑的比電腦丟封包的速度快,就斷了。

經過這件事,學到兩點:
1. BSP不是都沒問題.
2. 沒有所謂的timing issue. 只有code的嚴僅度問題

有空把bug 貼上來