熱門文章

12.15.2010

[ Android ] 如何使用 GDB 除錯 (3)

Android NDK 同樣可以使用 GDB 來除錯。
當我們的 APK 內包含了 JNI 時,我們可以利用 Eclipse 搭配 GDB 來除錯。


# 編譯 NDK
$./ndk-build NDK_PROJECT_PATH=project_path


# 執行 GDB
$./ndk-gdb --project=project_path


# 使用 DDD
$cp ndk-gdb ndk-ddd
$vi ndk-ddd
#修改最後一行
ddd --debugger "$GDBCLIENT -x $GDBSETUP" $APP_PROCESS

$./ndk-ddd --project=project_path

[ Android ] 如何使用 GDB 除錯 (2)

在把編譯好且帶有 debugging symbols 的 binary 檔案放到 target device 上後,接下來就可以開始使用 GDB 除錯。


因為不是在 local 端上除錯,所以會需要一些額外的設定。

# 首先要在 target device 上把 GDB Server 叫起來,指令如下。
gdbserver :port /the_path_of_an_executable_file
e.g.
$sudo adb shell
#gdbserver :5039 /system/bin/bootanimation
 * 指定 GDB Server 監聽的埠號為5039


# 然後是 local 端上的設定。
adb forward <local> <remote>
e.g.
$sudo adb forward tcp:5039 tcp:5039


# 接著在 local 端執行 GDB,並且設定相關項目。可使用 gdb、gdbtui 或 gdb --tui。
$ln -s prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi-gdb ./gdb
$ln -s prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi-gdbtui ./gdbtui
$./gdb ${PWD}/out/target/product/product_name/symbols/system/bin/bootanimation
(gdb)directory ${PWD}/frameworks/base/cmd/bootanimation
(gdb)set solib-absolute-prefix ${PWD}/out/target/product/product_name/symbols
(gdb)set solib-search-path ${PWD}/out/target/product/product_name/symbols/system/lib
(gdb)target remote :5039


# GDB 的設定也可以另外寫成一個檔案。
$vi gdb.setup
directory /absolute-source-path/frameworks/base/cmd/bootanimation
set solib-absolute-prefix /absolute-source-path/out/target/product/product_name/symbols
set solib-search-path /absolute-source-path/out/target/product/product_name/symbols/system/lib
target remote :5039


$./gdb -x gdb.setup ${PWD}/out/target/product/product_name/symbols/system/bin/bootanimation


# 使用 DDD
$sudo apt-get install ddd
$ddd --debugger "${PWD}/gdb -x gdb.setup" ${PWD}/out/target/product/product_name/symbols/system/bin/bootanimation

12.13.2010

[ Kinect ] Enabling Kinect on Linux (1)

最近 XBox Kinect 打得火熱,賣到缺貨。
很不巧的,Kinect 剛出來一兩個禮拜的時候,我就買了。
被這種新世代的體感玩法所吸引,吸引我的不是遊戲,是這個技術。
這種技術將來一定會被廣泛的應用,絕對不只是用在遊戲主機上。
短期內,我們會看到被應用在電腦上,尤其是在 Presentation 方面。
長期看來,適合整合進數位家庭,可以取代一些既有的控制器,比如電燈開關或遙控器。
但以目前來說,我覺得這個技術還有改良的空間。

現在網路上已經有不少 hacker 分享出 Kinect hacking 的成果,目前 Windows、Linux、Mac OS 都有辦法使用 Kinect。

筆者 Linux 環境為 Ubuntu 10.04,在這邊分享一下手動安裝的作法。

OpenKinect Project:http://openkinect.org/wiki/Main_Page
安裝方式也可以參考:http://openkinect.org/wiki/Getting_Started

# 安裝必要套件
$sudo apt-get install git libusb-1.0-0-dev freeglut3-dev libxmu-dev libxi-dev \
cmake cython python-dev python-numpy python-opencv

# 下載 libfreenect
$git clone https://github.com/OpenKinect/libfreenect.git

# 編譯並安裝 libfreenect
$cd libfreenect
$cmake CMAKE_PREFIX_PATH=/usr
$make
$sudo make install

# 新增 udev rule
$sudo cp udev/51-kinect.rules /etc/udev/rules.d/

# 編譯並安裝Python wrapper
$cd wrappers/python
$python ./setup.py build
$sudo python ./setup.py install --prefix=/usr 

# run C/C++ examples
$glview
$cppview
$glpclview

# run Python example
$./demo_cv_sync.py

# 如果無法執行的話,請把 demo_cv_sync.py 修改成以下的樣子。
#!/usr/bin/env python
import freenect
from opencv.cv import *
from opencv.highgui import *
#import cv
#import highgui
import numpy as np

cvNamedWindow('Depth')
cvNamedWindow('RGB')

while 1:
    depth, timestamp = freenect.sync_get_depth()
    rgb, timestamp = freenect.sync_get_rgb()
    cvShowImage('Depth', depth.astype(np.uint8))
    cvShowImage('RGB', rgb[:, :, ::-1].astype(np.uint8))
    cvWaitKey(10)

12.09.2010

[ Android ] 如何使用 GDB 除錯 (1)

不管是在 Android 上或是在 Linux 上,想 run-time debugging 的話,大概只能靠 GDB 或 ICE。
用 GDB 是最省錢又快速的方法,而且 Android 已經有稍微做過整合,幾乎不太需要什麼額外的設定。

要使用 GDB,首先在編譯時就必須先加入 "-g" 這個參數,例如:"gcc -g -o helloworld helloworld.c"。
但這一段,Android 其實已經先幫我們處理掉了,帶有 GDB Debugging Symbols 的 binary 檔都會在 "out/target/product/product_name/symbols/" 之下。

由於 debug 的對象並不是在 local 端,所以當然不能像在 PC 上直接使用 GDB。
一般來說,target 端(Device)必須先啟始 GDB Server,然後透過網路或 serial port 跟 host 端(PC, Laptop)的 GDB Client 做溝通。

GDB 有三種介面可以使用:
1) "gdb",terminal 下的純文字介面,想看檔案內容還要另外下 command。
2) "gdbtui" or "gdb --tui",terminal 下會顯示目前檔案內容的文字模式。
3) "ddd",圖形介面。

12.08.2010

[ Android ] Library 開發流程 (1)

若想在 Android 上開發或新增一套 Library,要怎麼做呢?
這套 Library 可能涵蓋 C/C++、JNI、Java 這幾個部份,可能是上層 Applications 必須使用到這個功能,或是 Framework 必須整合這個功能,甚至會跟硬體有關。

現在假設,我們寫了一套 C/C++ Library,用途先不管。
在 Android 上,如果要讓上層 Java Applications 可以用到這個 library 所提供的功能,我們必須實作 JNI 跟 Java Library 這兩層,然後以 Shared Library 的形式供複數隻 Java Applications 所使用。

先大概的描述一下作法:
1. 將 C/C++ Library 編成 Shared Library,也就是 .so 檔,放到 /system/lib/ 底下。
2. 將 JNI 也編成 Shared Library,同樣放到 /system/lib/。這邊的 JNI 也有可能是跟 C/C++ Library 編成同一個 .so。
3. 將 Java Library 編譯成一個 .class 格式的 .jar 檔,供 Java Applications 開發時使用。
or
4. 將 Java Library 編譯成一個 .dex 格式的 .jar 檔,放到 /system/framework/ 底下。把這個 .jar 檔的路徑加入 CLASSPATH 環境變數,並加入 preloaded-classes 或在 /system/etc/permissions/ 下新增 your_library.xml 並設定其內容 。

這樣就完成了!
這樣你的 Java Applications 就能正確的使用到 C/C++ Library。

11.24.2010

[ Android ] 開機畫面 (4)

bootanimation 的另一個開機動畫實現方法在 BootAnimation::movie()。
這邊是以播放圖片的方式,來呈現動畫效果。

使用這個方法的話,必須遵守它的規則。


1. 檔案 desc.txt
2. 目錄 part0/

desc.txt 是用來設定 bootanimation 如何去播放 part0/ 下的圖片,圖片必須使用PNG。
當然,你可以有 part1/, part2/, ..., partN/ 多個目錄,來存放你的動畫圖片。

bootanimation 在播放 part0/ 目錄裡面的圖檔,是依照檔案名稱的排序方式在播放,
所以檔案的命名最好是類似 xxx_001.png ~ xxx_nnn.png。

desc.txt 的內容大致上類似:

256 256 30
p 1 0 part0
p 0 0 part 1
... 

第一行是表示:
width height fps
設定圖片寬高跟每秒要播放幾張。

第二行以後的:
p count pause path
count 代表要播放 count 次,0為無限。
pause 代表每播放完一個循環後,要進入下個循環之前,中間要不要停頓一下下。
path 代表目錄名稱,part0, part1, ...。

東西準備完備後,把這些東西壓縮成一個 bootanimation.zip 檔。
zip -0r bootanimation.zip desc.txt part0/

最後把這個檔案放到 /data/local/bootanimation.zip 就好了。

11.22.2010

[ Android ] 開機畫面 (3)

之前有說過,Android 內建的 bootanimation 這隻程式可用兩種方式來呈現開機動畫。

其中一種方式是以兩張圖片來呈現掃光的效果。
你可以在 frameworks/base/core/res/assets/images 這個目錄下,找到 android-logo-mask.png 和 android-logo-shine.png 這兩個檔案。



上圖 android-logo-mask.png 有著 android 鏤空字樣,就是透明、transparent。
下圖 android-logo-shine.png 就是一張有著不同顏色的圖。

若要自己設計這兩張圖,圖檔格式必須為 PNG,而且圖的寬高建議為2的冪次方
pixels。
為什麼會建議為2的冪次方?因為在某些機器上 OpenGL ES 會有無法顯示非2冪次方大小的圖的問題。

這個功能,我們可以在 frameworks/base/cmds/bootanimation/BootAnimation.cpp 中的 BootAnimation::android() 看到。

可以看到,這個 function 會將兩張圖置中並重疊在一起,然後慢慢移動底圖,也就是 android-logo-shine.png 這張圖,最後我們看到的效果就是 android 這幾個閃閃發光的字。

改完後,記得重新編譯 framework,"mm framework"。
然後把編出來的 framework-res.apk,替換掉原本在手機內的 /system/framework/framework-res.apk,就大功告成了。