9/16/2011

GIT 相關script 和 自定義快速鍵


=======================================

function git_branch {
    ref=$(git symbolic-ref HEAD 2> /dev/null) || return;
    echo "("${ref#refs/heads/}") ";
}

function git_since_last_commit {
    now=`date +%s`;
    last_commit=$(git log --pretty=format:%at -1 2> /dev/null) || return;
    seconds_since_last_commit=$((now-last_commit));
    minutes_since_last_commit=$((seconds_since_last_commit/60));
    hours_since_last_commit=$((minutes_since_last_commit/60));
    minutes_since_last_commit=$((minutes_since_last_commit%60));
    
    echo "${hours_since_last_commit}h${minutes_since_last_commit}m ";
}

PS1="[\[\033[1;32m\]\w\[\033[0m\]] \[\033[0m\]\[\033[1;36m\]\$(git_branch)\[\033[0;33m\]\$(git_since_last_commit)\[\033[0m\]$ "

=======================================

把上面的程式貼到 ~/.bash_profile,如果沒有就新建。

如果shell重啟之後沒反應,可以直接在~/.bashrc加入,讓它自動幫你執行 :

if [ -f ~/.bash_profile ]; then                                                                                                                           
    . ~/.bash_profile
fi

好了之後,重啟shell就會變成這樣 :DDD



顯示在哪個branch之下,還有溫馨小提示有多久沒有commit了 XD


常用的git alias :
git config --global alias.co checkout
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.br branch

GIT STATUS


git status主要就是用來看目前working directory中所有檔案的情形,主要有下列幾種狀態
1. project file
就是原來就已經在GIT裡面並且沒有被更改過的檔案,這類型的檔案在git status中並不會列出來。
2. modified file
如果你更動任何一個project file,那隻檔案的狀態就會變成modified。
3. untracked file
所有新增出來、還沒用git add加到project裡面的檔案,他們的狀態就會是untracked。
這些檔案裡面可能有你新增的程式,也有可能是你在make的過程中動到或產生的中間檔。
如果是前者,記得在commit之前先add,如果是後者,就不需要理了,就讓它們留在untracked裡面就行了。
4. new file
untracked file被git add之後,狀態就會變成new file,commit之後就變成project file。

git status的output會根據你的color.status來決定要不要讓輸出結果帶有顏色 (或直接設定color.ui為auto)
$ git config --global color.ui auto
or
$ git config --global color.status true
如此一來,git status的output便會有顏色了。(有顏色好看很多)


如果git status後面不加path,會對整個working directory下的檔案檢查;如果後面有加路徑的話,就只會指定路徑下的所有檔案做檢查。
$ git status .
$ git status ./foo

註: 如果你目前不是在.git的同一層目錄的話,git會一直往parent目錄往上找到.git目錄,所以不必特別cd回.git那層目錄就可以做git操作了。

另外,git好像到了1.7.0.4之後,git-status多了幾個參數可以使用,個人最推的是 -s
-s, --short
用簡潔的格式來印出結果
ex.
$ git status
# On branch new
# Changes to be committed:
#   (use "git reset HEAD ..." to unstage)
#
#       new file:   kkkk
#
$ git status -s
A  kkkk

前面的A代表added,另外還有幾個字母
M = modified
D = deleted
R = renamed
C = copied
U = updated but unmerged

最常見的的狀態:
? ?: untracked
A: new
M: Modified but not added
M  : Modified and added
MM: Modified again after added
  D: deleted project file
完整的format可以用git help status查詢OUTPUT那一節,在這裡就不列出來了。

--porcelain
porcelain的翻譯是"瓷" (f-__-),加這個參數的意義是輸出來的結果會讓script較易於處理,不過目前這個參數其實是指到--short,結果是一樣的。
-u[], --untracked-files[=]
這個參數是用來設定如何顯示untracked files的狀態
mode (Default all)
no:     不顯示untracked files
normal: 顯示untracked files & directories,但untracked directories裡面的內容則不列出來
例如,新產生了一個newdir,newdir目錄裡面又有子目錄及其他檔案,在normal mode的時候,在status裡只會列出一行newdir/。
all:    將所有untracked files列出來,包含在untracked directories裡面的,所以用all的話列出來就會是落落長一大串。

-z
用NUL代替LF當成行的結尾,應該也是為了要把結果output給script處理而設計的,和--porcelain搭配使用。

Kconfig 文件的用途 (Make 選單的建立)


 配置選項是以樹的形式組織的,每個選項都有其自己的依賴關係。
這些依賴關係決定了選項是否是可見的。父選項可見,子選項才能可見。

核心原始碼的目錄下都有兩個文件 Kconfig(2.4版本是Config.in)和 Makefile。
分佈到各目錄的Kconfig構成了一個分散式的核心配置資料庫,
每個 Kconfig分別描述了與所屬目錄文件相關的核心配置功能表。
在核心配置 make menuconfig(或 xconfig 等)時,
從 Kconfig 中讀出功能表,用戶選擇後保存到 .config的核心配置文件中。
在核心編譯時,主Makefile 調用這個 .config,就知道了用戶的選擇。

*上面的內容說明了, Kconfig 就是對應著核心的配置功能表。
假如想添加新的驅動到核心的原始碼中,修改 Kconfig,這樣就能夠選擇這個驅動,
假如想編譯這個驅動,要修改 Makefile,所以添加新的驅動時需要修改的文件有兩種(注意不只是兩個)
Kconfig
Makefile

要想知道怎麼修改這兩種文件,就要知道兩種文件的語法結構

Kconfig
每個功能表都有一個關鍵字標識,最常見的就是config

config MODVERSIONS
    bool "Set version information on all module symbols"
    depends MODULES
    help
      Usually, modules have to be recompiled whenever you switch to a new
      kernel.  ...

每行都是以關鍵字開始,並可以接多個參數。
"config" 為定義了一新的配置選項。
而緊接著的下面幾行定義了該配置選項的屬性。
屬性可以是該配置選項的類型,輸入提示(input prompt),依賴關係,幫助資訊和預設值。
配置選項可以用相同的名字定義多次,但每個定義只能有一個輸入提示並且類型不能衝突。

語法:
config
symbol是個新的標記的功能表項,options是在這個新的功能表項下的屬性和選項
其中options部分有:

- 類型定義:"bool"/"tristate"/"string"/"hex"/"int"
  每個config功能表項都要有類型定義,每個配置選項都必須指定類型。
  有兩個基本類型:tristate 和 string,其他類型都是基於這兩個基本類型。

  bool布林類型、
  tristate三態:內建、模組、移除、
  string字串、
  hex十六進位、
  integer整型

  例如config HELLO_MODULE
  bool "hello test module"
  bool 類型的只能選或不選,tristate 類型的選項多了編譯成核心模組的選項,
       假如選擇編譯成核心模組,則會在 .config 中生成一個 CONFIG_HELLO_MODULE=m 的配置,
       假如選擇內建,就是直接編譯進核心,就會在 .config 中生成一個 CONFIG_HELLO_MODULE=y 的配置.

  類型定義可以用輸入提示,所以下面的兩個例子是等價的:
     bool "Networking support"
  and
     bool
          prompt "Networking support"

- 依賴型定義 depends on或 requires
  指此功能表的出現與否是依賴另一個定義
  config HELLO_MODULE
         bool "hello test module"
         depends on ARCH_PXA

  這個例子表明HELLO_MODULE這個功能表項只對XScale處理器有效。

- 幫助資訊: "help" or "---help---"
  定義一幫助資訊。幫助資訊的結束就由縮進的水準決定的,
  這也就意味著資訊是在第一個比幫助資訊開始行的縮進小的行結束。
  "---help---" 和 "help" 在實現的作用上沒有區別,
  "---help---" 有助於將檔中的配置邏輯與給開發人員的提示分開。

- 輸入提示: "prompt" ["if" ]
  每個功能表選項最多只能有一個顯示給用戶的輸入提示。
  可以用 "if" 來表示該提示的依賴關係,當然這是可選的。

- 預設值:"default" ["if" ]
  一個配置選項可以有任意多個預設值。
  如果有多個預設值,那麼只有第一個被定義的值是可用的。
  預設值並不是只限於應用在定義他們的功能表選項。
  這就意味著預設值可以定義在任何地方或被更早的定義覆蓋。
  如果用戶沒有設置(通過上面的輸入提示),配置選項的值就是預設值。
  如果可以顯示輸入提示的話,就會把預設值顯示給用戶,並可以讓用戶進行修改。
  預設值的依賴關係可以用 "if" 添加。(可選項)

- 依賴關係:"depends on"/"requires"
  為一功能表選項定義依賴關係。
  如果定義了多個依賴關係,它們之間用 '&&' 間隔。
  依賴關係也可以應用到該功能表中所有的其他選項(同樣接受一if運算式),
  所以下面的兩個例子是等價的:

    bool "foo" if BAR
         default y if BAR
  and
    depends on BAR
    bool "foo"
         default y

- 反向依賴關係:"select" ["if" ]
  儘管普通的依賴關係可以降低一選項的上限,反向依賴能將這一限制降的更低。
  當前功能表選項的值是symbol的最小值。
  如果symbol被選擇了多次,上限就是其中的最大值。
  反向依賴只能用在 boolean 或 tristate 選項上。

- 資料範圍:"range" ["if" ]
  為int和hex類型的選項設置可以接受輸入值範圍。
  用戶只能輸入大於等於第一個symbol,小於等於第二個symbol的值。


選單依賴關係
------------

依賴關係決定了功能表選項是否可見,也可以減少tristate的輸入範圍。
tristate邏輯比boolean邏輯在表達式中用更多的狀態(state)來表示模組的狀態。
依賴關係運算式的語法如下:

::=                              (1)
           '='                 (2)
           '!='                (3)
           '(' ')'                       (4)
           '!'                            (5)
           '&&'                    (6)
           '||'                    (7)

運算式是以優先順序的降冪列出的。

(1) 將symbol賦給運算式。boolean和tristate類型的symbol直接賦給運算式。
    所有其他類型的symbol都賦 'n'。
(2) 如果兩個symbol相等,返回'y',否則為'n'。
(3) 如果兩個symbol相等,返回'n',否則為'y'。
(4) 返回運算式的值。用於改變優先順序。
(5) 返回 (2-/expr/) 的結果。
(6) 返回 min(/expr/,/expr/) 的結果。
(7) 返回 max(/expr/,/expr/) 的結果。

一個運算式的值可以是'n','m'或'y'(或者是計算的結果 0,1,2)。
當運算式的值為'm'或'y'的時候,選單選項才是可見的。

symbol有兩種類型:不可變的和可變的。不可變的symbol是最普通的,
由'config'語句定義,完全由數字、字母和下劃線組成(alphanumeric characters or underscores)。
不可變的symbol只是運算式的一部分。經常用單引號或雙引號括起來。
在引號中,可以使用任何字元,使用引號要用轉義字元'\'。

功能表結構
--------

功能表在樹中的位置可由兩種方法決定。第一種可以是這樣:

menu "Network device support"
    depends NET

config NETDEVICES
    ...

endmenu

所有的在"menu" ... "endmenu" 之間都是"Network device support"的子功能表。
所有的子功能表選項都繼承了父功能表的依賴關係,
比如,"NET"的依賴關係就被加到了配置選項NETDEVICES的依賴列表中。

還有就是通過分析依賴關係生成功能表的結構。
如果功能表選項在一定程度上依賴於前面的選項,它就能成為該選項的子功能表。
首先,前面的(父)選項必須是依賴列表中的一部分並且它們中必須有滿足下面兩個條件的選項:
- 如果父選項為'n',子選項必須不可見。
- 如果父選項可見,子選項才能可見。

config MODULES
    bool "Enable loadable module support"

config MODVERSIONS
    bool "Set version information on all module symbols"
    depends MODULES

comment "module support disabled"
    depends !MODULES

MODVERSIONS 直接依賴 MODULES,這就意味著如果MODULES不為'n',該選項才可見。
換句話說,當MODULES可見時,選項才可見(MODULES的(空)依賴關係也是選項依賴關係的一部分)。

Kconfig 語法
------------

配置檔描述了功能表選項,每行都是以一關鍵字開頭(除了幫助資訊)。
下面的關鍵字結束一功能表選項:
- config
- menuconfig
- choice/endchoice
- comment
- menu/endmenu
- if/endif
- source
前5個同樣可以用在功能表選項定義的開始。

config:

    "config"
   

定義了一配置選項 並且可以接受任何前面介紹的屬性。

menuconfig:
    "menuconfig"
   

此關鍵字和前面的關鍵字很相似,但它在前面的基礎上要求所有的子選項作為獨立的行顯示。
( This is similar to the simple config entry above,
  but it also gives a hint to front ends,
  that all suboptions should be displayed as a separate list of options.)

choices:

    "choice"
   
   
    "endchoice"

該關鍵字定義了一組選擇項,並且選項可以是前面描述的任何屬性。
儘管boolean只允許選擇一個配置選項,tristate可以於多個配置選項設為'm',
但選項只能是boolean或tristate類型。
這可以在一個硬體有多個驅動的情況下使用,最終只有一個驅動被編譯進/載入到核心,
但所有的驅動都可以編譯成模組。
選項可以接受的另一個選項是"optional",這樣選項就被設置為'n',沒有被選中的。

comment:

    "comment"
   

這裡定義了在配置過程中顯示給用戶的註釋,該註釋還將寫進輸出檔中。
唯一可用的可選項是依賴關係。

menu:

    "menu"
 

    "endmenu"

這裡定義了一個功能表,詳細資訊請看前面的"功能表結構"。
唯一可用的可選項是依賴關係。

if:

    "if"
   
    "endif"

這裡定義了if結構。依賴關係被加到所有在if ... endif 中的功能表選項中。
(lb:請看linux-source/drivers/ata/Kconfig:20)



Makefile
在 linux2.6.x/Documentation/kbuild 目錄下有詳細關於 kernel makefile 的介紹。
核心的Makefile分為5個組成部分:
Makefile  最頂層的Makefile
.config   核心的當前配置文件,編譯時成為定層Makefile的一部分
arch/$(ARCH)/Makefile 和體系結構相關的 Makefile
s/ Makefile.*   一些Makefile的通用規則
kbuild Makefile 各級目錄下的大約有500個文件,編譯時根據上層 Makefile 傳下來的
                巨集定義和其他編譯規則,將源代碼編譯成模組或編入核心

頂層的Makefile文件讀取 .config 文件的內容,並且在總體上負責建立核心和模組。
Arch Makefile 則提供補充系統結構相關的資訊。
s 目錄下的 Makefile 文件包含了任何根據 kbuild Makefile 構建核心所需的定義和規則。
(其中 .config 的內容是在 make menuconfig 的時候,通過 Kconfig 文件配置的結果。

舉個例子:
假設想把自己寫的一個flash的驅動程式載入到工程中,而且能夠通過 menuconfig 配置
核心時選擇該驅動該怎麼辦呢?能夠分三步:

第一:將您寫的 flashtest.c 文件添加到 /driver/mtd/maps/ 目錄下。
第二:修改 /driver/mtd/maps 目錄下的 kconfig 文件:
      config MTD_flashtest
      tristate 「ap71 flash"
      這樣當 make menuconfig 時 ,將會出現 ap71 flash選項。
第三:修改該目錄下makefile文件。
      添加如下內容:obj-$(CONFIG_MTD_flashtest)+= flashtest.o

這樣,當您運行 make menucofnig 時,您將發現ap71 flash選項。
假如您選擇了此項,該選擇就會保存在 .config 文件中。
當您編譯核心時,將會讀取 .config 文件,當發現 ap71 flash 選項為 yes 時,
系統在呼叫 /driver/mtd/maps/ 下的 makefile 時,將會把 flashtest.o 加入到核心中。

9/03/2011

TI 128x BT/GPS/FM Share transport design and architecture (2)

Trace the ST related source code

預設OMAP4會把ST driver直接built in進kernel,另外GPS和FM driver則會compile成模組型式 :

CONFIG_TI_ST=y
CONFIG_ST_FM=m
CONFIG_ST_GPS=m

GPS & FM driver path : kernel/drivers/staging/ti-st/

ST driver path : kernel/drivers/misc/ti-st

從上面知道,ST driver包含3個sub-moudules,所以這個目錄底下就有相對應的source code:

st_core.c     st_kim.c       st_ll.c

這三個檔案會被compile成叫st_drv.o....

UIM就有點小麻煩...因為TI在OMAP4 Blaze BSP裡面放了3個UIM code...

分別叫 "uim" , "uim-rfkill" , "uim-sysfs",該UIM的路徑是在mydroid/hardware/ti/wpan/ti_st/

之前知道UIM一支deamon,是系統boot時就開始run了,所以馬上就可以知道TI會在init.rc加入UIM service ...

service uim /system/bin/uim-sysfs
    user root         
    group media bluetooth                                                                                                 
    oneshot

uim-sysfs加上oneshot,可以知道TI所使用的是 "uim-sysfs" ,從裡面的uim.c瞭解它會把st/bt/fm/gps等driver一個個insmod進去,利用lstat來檢查.ko是否存在。

因為現在是built-in,所以UIM並不會跑這段...

而是在更早之前,st_kim的init func是__init,所以在kernel一起來時就會register,而且還是register一個platform_drive的結構 :

static struct platform_driver kim_platform_driver = {
    .probe = kim_probe,
    .remove = kim_remove,
    .suspend = kim_suspend,
    .resume = kim_resume,
    .driver = {                                                                                                             
        .name = "kim",
        .owner = THIS_MODULE,
    }, 
};  

出現了platform_driver結構,就一定會有想對應的platform_device結構來讓kernel assigned,所以可以在arch/arm/mach-omap2/board-4430sdp.c找到 :

struct ti_st_plat_data wilink_pdata = {
    .nshutdown_gpio = 55,
    .dev_name = BLUETOOTH_UART_DEV_NAME,
    .flow_cntrl = 1,
    .baud_rate = 3000000,
    .suspend = plat_kim_suspend,
    .resume = plat_kim_resume,
}; 
static struct platform_device wl128x_device = {
    .name       = "kim",
    .id     = -1,
    .dev.platform_data = &wilink_pdata,
}; 
static struct platform_device btwilink_device = {
    .name = "btwilink",
    .id = -1,                                                                                                               
};   

nshutdown_gpio是BT/GPS/FM Enable pin...所以要改GPIO直接改這。(不太清楚TI怎麼去控制單一GPIO來防止3個device打架...還是真的3個只能開1個 !? 手邊沒平台...哎)

dev_name是UART deivce name...像是/dev/ttyxx之類的,所以要修改其它port,就修改這個定義。

接下來就是kim probe了,為每個device建構結構.....分配記憶體位址.....取得private data等等..

但這時就會去呼叫st_core,通知st_core initialization的時候到了....

int st_core_init(struct st_data_s **core_data)
{
    .....
    err = tty_register_ldisc(N_TI_WL, &st_ldisc_ops);
    .....
}

st_core 就最重要的就是註冊Line Discipline了。

什麼是Line Discipline ? 對 TTY device 的 I/O 動作,會經由 TTY core 送給 TTY driver,而資料往來於 TTY 與 TTY driver 的過程中...

可以這麼想,連結TTY Core和TTY driver資料往來的線,就叫Line Discipline。

Line Discipline是被設計成可以抽換的,例如,今天我想要讓這個TTY device是接收的資料是數據機而不要來自終端機,就把N_TTY改成N_PPP。

想要只接收藍芽的資料,就改成N_HCI....

簡言而之,就是Line Discipline會按照某個特殊的協議進行格式化,然後再送給TTY driver,讓TTY driver可以跟特定的硬體做溝通。

現在TI自己定義了一個N_TI_WL這個Line Discipline,所以porting時就要注意,要在kernel裡定義該Line Discipline....可以在kernel/include/linux/tty.h加入該定義。

接著st_kim會去request GPIO,並把GPIO設成輸出模式....

後面最後一道程序滿重要的,st_kim會create entries sysfs :

kim_gdata->kim_pdev = pdev;
init_completion(&kim_gdata->kim_rcvd);
init_completion(&kim_gdata->ldisc_installed);
   
status = sysfs_create_group(&pdev->dev.kobj, &uim_attr_grp);
if (status) {                                                                                                           
    pr_err("failed to create sysfs entries");
     return status;
}
   
/* copying platform data */
strncpy(kim_gdata->dev_name, pdata->dev_name, UART_DEV_NAME_LEN);
kim_gdata->flow_cntrl = pdata->flow_cntrl;
kim_gdata->baud_rate = pdata->baud_rate;
pr_info("sysfs entries created\n");

其中uim_attr_grp的結構為 :

/* structures specific for sysfs entries */
static struct kobj_attribute ldisc_install =
__ATTR(install, 0444, (void *)show_install, NULL);
   
static struct kobj_attribute uart_dev_name =
__ATTR(dev_name, 0444, (void *)show_dev_name, NULL);
       
static struct kobj_attribute uart_baud_rate =
__ATTR(baud_rate, 0444, (void *)show_baud_rate, NULL);
   
static struct kobj_attribute uart_flow_cntrl =
__ATTR(flow_cntrl, 0444, (void *)show_flow_cntrl, NULL);
   
static struct attribute *uim_attrs[] = {
    &ldisc_install.attr,
    &uart_dev_name.attr,
    &uart_baud_rate.attr,
    &uart_flow_cntrl.attr,
    NULL,
}; 
   
static struct attribute_group uim_attr_grp = {                                                                              
    .attrs = uim_attrs,
};  

TI會去Create這些sysfs的最主要目的就是讓UIM能在user space透過該檔案系統去open在kernel space的st_core

到這裡st_kim和st_core的initialization就結束了,回頭繼續看UIM

UIM會去check剛剛的sysfs這些路徑有沒有建立成功 :

#define INSTALL_SYSFS_ENTRY "/sys/devices/platform/kim/install"
#define DEV_NAME_SYSFS      "/sys/devices/platform/kim/dev_name"                                                            
#define BAUD_RATE_SYSFS     "/sys/devices/platform/kim/baud_rate"
#define FLOW_CTRL_SYSFS     "/sys/devices/platform/kim/flow_cntrl"

如果都有,而且BT/GPS/FM等相關的.ko和裝置節點都有存在的話,就會去create rfkill的路徑了 :

if (change_rfkill_perms() < 0) {                                                                                        
     /* possible error condition */
     UIM_ERR("rfkill not enabled in st_drv - BT on from UI might fail\n");
}   

這樣一來,bluedroid (system/bluetooth/bluedroid/bluetooth.c)就可以透過rfkill來控制BT power。

然後UIM就去open st_core,讓st_core能成功install line discipline.

st_fd = open(INSTALL_SYSFS_ENTRY, O_RDONLY);
if (st_fd < 0) {
      UIM_DBG("unable to open %s (%s)", INSTALL_SYSFS_ENTRY,
      strerror(errno));
      remove_modules();
      return -1;
}

到這裡,UIM的任務就算暫時結束了 !

註 : hciattach的opation部份被改"-l"...它做的也只是print每個attach的結構,並沒做任何事... 
      所以hciattach的功用完全被UIM/KIM替代掉了,因為KIM己經把/dev/ttyx帶起來了 XD (如果    
      不用GPS的話...ST應該可以放一邊吧0.0?)

9/02/2011

TI 128x BT/GPS/FM Share transport design and architecture


TI因為多了一個GPS...原本127x的BT/FM架構都完全不一樣了...T_T

沒想到TI的GPS也是利用UART來進行傳輸,看來GPS的資料量也不大嘛0.0

不過這個Share Transport的概念還真滿有意思的 !

但Porting到別的平台超複雜....= =

一出問題,如果不知道原理,根本無從查起....

所以紀錄一下今天study過後的整理.....

KIM = Kernel Initialization Manage
UIM = User space Initialization Manager

ST summary

ST(share transport)的設計理念是基於在OMAP程序中,實現BT、GPS、FM協議以及整合至軟體元件中,並提供一個界面對應各自不同的physcial ports。

它主要的工作是處理chip的整個初始化。而且還負責處理硬體去對每一個core(BT,GPS,FM)做enable/disable;而且BT則多了一項發送download script commands的工作。

除此之外,ST還負責chip與OMAP的之間的Power Managerment(PM),像是power saving/Wakup etc...,

ST driver其實是一個基於TTY driver的line discipline,在BT,GPS,FM元件之間開啟了一個具有分享作用的一個physical ports (像是UART,SPI or SlimBus等)

而這個分享的原理,是利用邏輯通道(logical channel)的設計理念來實現,如下定義 :

BT Protocol : Channel 1,2,3,4

FM Protocol : Channel 8

GPS Protocol : Channel 9

Power Managerment (HCILL) : Channel 30,31,32,33

ST Core driver中,利用KIM這個module,來處理並打開對BT,GPS,FM等元件的通信,並且會去下載init script到BT元件裡,還有最重要的一件事..

隨著FM和GPS driver註冊和註銷,KIM會去控制FM和GPS的GPIO。

而ST drvier則是會利用HCILL protocol發送message來控制chip的sleep or wakeup

KIM & UIM

1. Initialization

初始化時,ST driver會請求KIM開始對chip去做初始化(Control GPIO etc..,),在KIM對chip初始化過程中,KIM會要求UIM去打開TTY device並設定ST做為line discipline....

之後KIM會繼續初始化,然後再開啟各自chip core的GPIO和download script.

而卸載時,則跟上述步驟一樣...KIM會去要求UIM去 close TTY device and restore line discipline

2. Process

UIM是一支deamon,當它被運行時,會去install ST driver,在install ST driver期間,ST Core則會去install KIM module,並收到ST Core的要求去對chip做初始化,在這同時,KIM還會去建立一個sysfs entry --> "/sys/uim/pid"。

當install ST driver安裝完之後,這時UIM會用KIM所創的節點寫入它的Process ID(PID),然後等待信號(Signals)...等待從KIM發送過來的信號。

然後KIM會利用UIM剛寫入PID,對它發送信號,要求UIM去打開TTY device(對應physical ports)和安裝ST Line Discipline...

如果UIM是打開TTY device for UART的話,則設定baud為115200,這時TI的chip會follow這個設定去start...然後,UIM將會傳送一個HCI Vendor Specific(VS) Command去把baudrate設定成3M。

接著UIM會去call TTY function去安裝ST Line discipline driver...

整個過程跑完之後,UIM就會一直等待KIM的信號,讓它做restore and uinstall的動作。



ST Driver

ST layer主要是實現ST Line Discipline,這個Line discipline暴露(容許讓我用大陸名詞...因為不知道怎麼理解原文的意思....= =)在BT,GPS,FM driver之下。

ST driver包含3個sub-modules :

1. ST Core
2. ST Kernel space Initialization Manager (KIM)
3. ST HCILL

ST KIM在上面己經說了...它是會隨著UIM而緊密連接著...

ST Core則提供如下的作用 :
  •  Core will provide APIs for BT, FM, and GPS drivers to register, de-register, and send  protocol packets
  • If ST Core is busy sending current packet, it will buffer new requests to send protocol packets
  • ST Core will provide packets received from chip to BT, FM, and GPS drivers by calling callback routines registered by these protocol drivers
  • ST Core will maintain a finite state machine to handle multiple register, de-register, and send requests
  • When first register request is received, ST Core will interact with KIM to initialize transport and chip. When last de-register request is received, ST Core will interact with KIM to de-initialize transport and chip
  • ST Core will interact with ST HCILL to get state information of Connectivity chip and to  wakeup chip when required
ST Core使用特有的ID來區分不同的protocol driver,而BT,GPS,FM則會提供該ID來與ST driver註冊,寫在一個list當中,ST Core會去負責維護這個list來避免不當的操作。