2017年7月28日 星期五

從驅動程式原始碼認識USB OTG

USB OTG,

是USB-On-The-Go 的縮寫,

為USB 規格中的一個延伸,

擁有USB OTG功能的系統,(例如: 手機)

可以根據ID pin狀態的不同,

自行切換為host端或者client端,

已達到不同的目的使用.

例如:

a. 以手機接電腦,

手機會切換為client端,

這時可以把手機當隨身碟使用

b. 以手機接隨身碟,

手機會轉為host端,

讓手機能夠不透過電腦直接存取隨身碟裡面資料,





Google Git 上面可找到otg.c

可以讓我們

從驅動程式原始碼認識USB OTG


/**
* ci_otg_work - perform otg (vbus/id) event handle
* @work: work struct
*/
static void ci_otg_work(struct work_struct *work)
{
struct ci_hdrc *ci = container_of(work, struct ci_hdrc, work);
if (ci_otg_is_fsm_mode(ci) && !ci_otg_fsm_work(ci)) {
enable_irq(ci->irq);
return;
}
if (ci->id_event) {
ci->id_event = false;
ci_handle_id_switch(ci);
} else if (ci->b_sess_valid_event) {
ci->b_sess_valid_event = false;
ci_handle_vbus_change(ci);
} else
dev_err(ci->dev, "unexpected event occurs at %s\n", __func__);
enable_irq(ci->irq);
}
當ID pin產生變化,

系統偵測到事件觸發,

執行ci_handle_id_switch(ci);

#define CI_VBUS_STABLE_TIMEOUT_MS 5000
static void ci_handle_id_switch(struct ci_hdrc *ci)
{
enum ci_role role = ci_otg_role(ci);
if (role != ci->role) {
dev_dbg(ci->dev, "switching from %s to %s\n",
ci_role(ci)->name, ci->roles[role]->name);
ci_role_stop(ci);
/* wait vbus lower than OTGSC_BSV */
hw_wait_reg(ci, OP_OTGSC, OTGSC_BSV, 0,
CI_VBUS_STABLE_TIMEOUT_MS);
ci_role_start(ci, role);
}
}
ci_otg_role(ci);

根據ID pin 腳位的不同

會選擇USB功能為:

CI_ROLE_GADGET (client)

CI_ROLE_HOST (host)

/**
* ci_otg_role - pick role based on ID pin state
* @ci: the controller
*/
enum ci_role ci_otg_role(struct ci_hdrc *ci)
{
enum ci_role role = hw_read_otgsc(ci, OTGSC_ID)
? CI_ROLE_GADGET
: CI_ROLE_HOST;
return role;
}

接著driver 會將此變化傳到應用層,

如果是Android 系統,

USB功能的變化就會傳給Android 做相對應的處理



2017年7月26日 星期三

android studio設定模擬器

使用Android studio開發app,

如果手上沒有適合的android 裝置,

可以直接使用內建的模擬器,

進行app的除錯,

除了使用快捷按鈕以外,

也能從工具列 Tools -> Android -> AVD Manager

找到管理工具,

Android studio 設定模擬器


1. 除了上述方法以外,

可以點選工具列上方按鈕:

debug 'app' (shift + F9)

Android studio 會跳出視窗詢問要佈署到哪個機器debug

選擇 "create new virtual device "

就能建立新的模擬器裝置


2.點選新增模擬裝置


3. 預設有許多裝置(通常為Google 手機)可選用

如果有特殊需求,

可以點擊 'new hardware profile' 自訂裝置


4.選定裝置之後,

在此畫面選擇運行的Android版本,



5. 第一次安裝要從伺服器下載該版本的image 到電腦裡使用


6.下載完畢,

再次確認裝置設定是否符合需求,



7. 設定完成之後,

回到佈署選擇對話框,

選擇剛才新建立的裝置選擇OK


8. 模擬器裝置開機完畢之後,

會自動安裝App進行偵錯



早期的模擬器跑很久反應也不佳,

目前版本已經改善很多,

如果有使用Android studio 開發APP,

可以試用看看,

當然了

如果有實體裝置協助開發必然比模擬器快很多.



2017年7月20日 星期四

android開發基礎(五)- avc: denied解決範例


之前提到過 SELINUX for Android,

Android 5 之後引入了selinux機制,

在遇到權限問題時候,

系統都會有log 描述問題,

基本上就是缺什麼補什麼,

直到沒有avc denied為止,

當然,

系統預設的never allow建議不要修改,

底下列了幾個

avc: denied解決範例

1.
type=1400 audit(4.840:7): avc: denied { getattr } for pid=204 comm="cameraserver" path="/vendor" dev="rootfs" ino=7096 scontext=u:r:cameraserver:s0 tcontext=u:object_r:rootfs:s0 tclass=lnk_file permissive=0

重點在於紅字,

這個範例簡單的講,

cameraserver 對 rootfs  的 lnk_file 缺少了 { getattr } 的權限 ,

只需要在cameraserver.te中

新增


allow cameraserver rootfs:lnk_file { getattr };


即可

2.
type=1400 audit(28.360:14): avc: denied { execute } for pid=704 comm="sh" name="toybox" dev="mmcblk3p5" ino=368 scontext=u:r:demo:s0 tcontext=u:object_r:toolbox_exec:s0 tclass=file permissive=0

#type=1400 audit(28.130:14): avc: denied { read open } for pid=718 comm="sh" path="/system/bin/toybox" dev="mmcblk3p5" ino=368 scontext=u:r:demo:s0 tcontext=u:object_r:toolbox_exec:s0 tclass=file permissive=0

在這個範例中

demo 對 toolbox_exec  的 file 缺少了 { execute read open } 的權限 ,
(多個權限設定,

只需要以大括號框住 ,

空格隔開即可)

找到demo.te

加入


allow demo toolbox_exec:file { execute read open  };

權限問題不會一次全部顯示出來,

出現一個加一個直到沒有為止.





2017年7月13日 星期四

android 編譯錯誤 : Try increasing heap size with java option '-Xmx'

在開發過程中,

有時候會遇到

android 編譯錯誤 : Try increasing heap size with java option '-Xmx'

這是android使用新的編譯器Jack 常見的問題,

JACK( 全名 JAVA Android Compiler Kit)

此網址 也有提到

當遇到這個問題的時候,

使需要手動停止jack server,

1.
進入  BSP/prebuilts/sdk/tools 資料夾
執行:

jack-admin stop-server

2.
利用文字編輯器打開 jack-admin

找到

JACK_SERVER_COMMAND="java -XX:MaxJavaStackTraceDepth=-1 -Djava.io.tmpdir=$TMPDIR $JACK_SERVER_VM_ARGUMENTS -cp $LAUNCHER_JAR $LAUNCHER_NAME"

加上-Xmx4g , 也就是改為

 JACK_SERVER_COMMAND="java -XX:MaxJavaStackTraceDepth=-1 -Djava.io.tmpdir=$TMPDIR $JACK_SERVER_VM_ARGUMENTS -Xmx4g -cp $LAUNCHER_JAR $LAUNCHER_NAME"

3. 再次執行android 編譯命令即可


如果出現同樣問題,

或者遇到系統在編譯過程中完全無回應,

就必須執行
1.
進入  BSP/prebuilts/sdk/tools 資料夾

執行:

jack-admin stop-server

2.

sudo gedit ~/.jack-server/config.properties

(或者:  sudo gedit ~/.jack )

3.
找到

SERVER_NB_COMPILE=N

N:預設為4

將這個值降低

4.
重新執行android編譯指令