2016年6月24日 星期五

Android 各層說明筆記

Android 系統從上至下大致區為

  1. application
  2. framework
  3. JNI
  4. HAL
  5. linux kernel (driver)
  6. hardware

1.application
JAVA寫的應用程式,主要呼叫framework層提供的API(功能/服務)達到所需的應用.

2.framework
JAVA寫的Android主體,實作Android制定的標準API,提供豐富與常用的功能給application使用,
並且讓application可以不用因底層driver不同而改變.
為何application要因底層driver不同而改變?
舉例來說有兩個背光的驅動IC分別由兩個driver來驅動,
而這兩個driver點亮背光的ioctl控制方式不一樣(如ioctl code不一樣等),
則application要讓背光點亮的功能就要實作呼叫兩個不同的ioctl才能支援兩個驅動IC.
但透過framework層就是要呼叫"背光點亮"這個API就好,framework層會處理底層的不同.
又framework層如何處理底層?如果只是同樣呼叫兩個不同ioctl那不就只是把麻煩事放在framework層而已嗎?
當然不是這樣,framework層除了對上定義標準API給application使用,
對下也定義"背光點亮"界面並要求底層依該定義實作,因此不同的driver若要支援Android則依循Android的規範實作即可.
但framework底下是JNI不是driver啊? 剛剛是舉例,後續會再說明.

3.JNI
C/C++寫的但是需要include JAVA產生的.h檔.
framework是JAVA寫的,driver是C/C++寫的,framework怎麼呼叫driver的ioctl?
答案就是JNI,JNI就是讓JAVA可以呼叫C/C++的界面.
在JAVA的source code中如果要呼叫C/C++ library中的function,
就要在宣告該function時加上native關鍵字等,然後編譯該JAVA會產生一.h檔,
然後在C/C++的source code中include該.h檔並實作.h檔中的function,
該function就是呼叫driver的ioctl等,
再編譯C/C++後產生.so或.dll的library檔,該library檔就可以讓JAVA呼叫使用.
此.so或.dll就稱JNI,使JAVA可以呼叫到driver的功能.
這裡須強調JNI是個界面,source code是C/C++,或許有些功能用JAVA較不易實作,而用C/C++較容易就把該功能寫在JNI,
使JNI不只是單純的界面,這是不對的行為,架構問題不多解釋.

4.HAL
主要由C/C++寫的,所以可以被JNI呼叫,並向下控制driver.
JNI已經可以呼叫底層driver了,為何又多了HAL層?
framework層是Android強大功能的主體,而HAL層則是讓Android得以商業化的關鍵,
因為driver屬於linux kenel需要公開source code,但有些廠商不希望將驅動該硬體的source code公開,
因其中可能包含其不願公開的演算法等,所以對linux平台的產品卻步,因此產生了HAL層,HAL層不屬於driver而是以使用driver的角色存在,
所以不須公開原始碼,就可以讓廠商將不願公開的code放在HAL層,而driver只負責簡單的控制硬體功能.


5.linux kernel (driver)
用C/C++寫的,driver 實作控制CPU以驅動硬體的功能,並提供ioctl等讓上層呼叫.

6.hardware
硬體...


2013年9月12日 星期四

git vim 常用指令筆記

git clone
git fetch [--prune]
git push [--set-upstream]
git log
git add [-p]
git rm
git commit [-m] [-F] [--amend [--no-edit]]
git checkout
git branch [-D]
git reset
git rebase
git cherry-pick
git merge
git blame

git 將本地倉庫強制上傳至遠端
git push origin +master

undo rebase
git reset --hard ORIG_HEAD

git log 輸出第一行,指定日期及作者git log --pretty=oneline --abbrev-commit --after="2019-01-01" --until="2019-02-01" --author="name"

找回沒有ref(branch or tag)的commit,如不小心reset branch後可以用reflog顯示最近的HEAD所在的commit點,就會看到reset前的commit,可以用checkout或reset回到之前的commit
git reflog

change file mode
git update-index --chmod=-x file


清理git倉庫
查看unreachable
git fsck --unreachable

因為reflog會把reset與rebase等動作的來源記錄起來,該來源仍reachable無法被清理,所以要用底下指令清除reflog
git reflog expire --expire=5.days.ago --expire-unreachable=now --all

清除unreachable
git gc --aggressive --prune=now



vim 刪除行尾的多餘空白
:% s/\s\+$//g
語法 :[範圍] s/搜尋目標/取代/[選項] [次數]
[範圍] % 表示全文
搜尋目標 \s 表示空白, \+表示出現一次以上, $表示行結尾,
        所以搜尋行尾的空白
取代 空字串 表示取代成空字串也就是刪除
[選項] g 表示取代本行中所有符合的項目
[次數] 省略

:tabe
:sp
:vsp
:set
:q
:w

以unix格式顯示檔案內容
:e ++f=unix
若有dos格式的換行crlf則會在行尾顯示"^M"

將檔案轉成unix格式
:set fileformat=unix