리눅스 & 안드로이드2015. 12. 31. 15:30

Android에서 native 코드에서 현재 시간을 얻기위해(CPU suspend time은 제외) 사용하는


systemTime(SYSTEM_TIME_MONOTONIC)


의 수치와 비교할 수 있도록, JAVA에서 사용할 수 있는게 뭐가 있을까 찾아 봤더니, 


SystemClock.uptimeMillis()


가 있더라.



SystemClock class의 uptimeMillis() 메소드는 native method 인데, 실제 구현을 보면

정확하게 동일한 함수를 사용한다.


다만, 단위를 ms로 변환하여 반환하므로 1,000,000을 곱하면(ns 단위), (거의) 동등하게 비교하는데 사용할 수 있겠다.


Posted by 세월의돌
리눅스 & 안드로이드2015. 10. 14. 16:35

Android framework에 보면 System.getProperty()가 있는데, 이 API로는 사용자(개발자?)가 setprop으로 설정한 property의 값을 읽어올 수 없다.


어떻게 해야 하냐?


/system/bin/getprop을 직접 실행해서, stdout으로 출력되는 결과를 읽어서 사용해야 한다.



위와 같이 하면, runtime에 parameter를 바꿔가며 테스트를 하는데 property를 활용할 수 있다.


물론, 세세한 exception 처리가 된다면 더욱 좋겠지만, 테스트 코드이므로 그냥 Exception으로 받아 default 값을 설정했다.ㅎㅎ



Posted by 세월의돌
리눅스 & 안드로이드2015. 10. 14. 10:40

쉘 스크립트(shell script)를 이용해 콘솔(console)에서 문자열 자르기를 활용!


요즘 안드로이드에서, 반복적으로 app.을 재시작 하면서 수정/테스트 해야 하는 삽질을 하고 있는데, 프로세스 종료를 좀 스마트(smart)하게 해 보고자 좀 찾아봤다.


그 언젠가, 1998년 즈음(?) UNIX shell에서 특정 문자열을 골라내는 명령어를 배웠던 기억이 어렴풋이 떠오르긴 했지만, 그 명령어가 뭔지는 몰라서 좀 찾아보다 awk/split임을 확인하고 내 입맛에 맞게 수정을 좀 했다.


요즘 기억력이 점점 쇠퇴하고 있는지라, 기록으로 남긴다. ㅜ.ㅜ


root@shell:/ # ps | grep launcher2 | awk '{split($0, arr, " "); printf("%s",arr[2]); }' | xargs kill


Posted by 세월의돌

오늘 외부에서 일해야 하는 상황이 생겨서, 데스크탑에서 잘 빌드가 되던 소스를 통째로 랩탑에 복사해 왔었다.


그리고 NDK 빌드를 하는데 NEON을 사용할 때 필요한 cpufeatures라는 NDK에 기본적으로 포함된 소스를 찾지 못하는 문제가 발생했다.


NDK가 데스크탑에는 D드라이브에, 랩탑은 C드라이브에 설치되어 있었는데, 랩탑에서 계속 NDK path를 D에서 찾는 것이었다.


뭐가 문제인지 몰라 NDK에 포함된 기본 mk 파일들에서 사용하는 NDK_ROOT 변수는 정상적인 C드라이브의 경로로 설정이 되어 있었다. 정말 귀신이 곡할 노릇!!!


그러다 찾아낸 문제는 바로 NDK 빌드를 하면서 obj 디렉토리에 생성되는 .d 파일이었다.


파일 확장자로보아 dependency를 기록해 두는 파일인 것 같은데, cpufeatures에 대해 데스크탑에서 생성된 .d 파일이 남아 있어 계속 D드라이브에서 해당 소스를 찾았던 것이었다.


obj 디렉토리를 삭제하고 다시 빌드하니 잘 되었다. 아놔, 이것 땜에 허비한 시간을 생각하면.


Sigh.

(마침 John Carmack이 문제가 있는 USB 케이블 때문에 시간을 허비했다는 트윗에서 이렇게 한숨을 쉬던 기억이 나서 따라해봄ㅋㅋㅋ)

Posted by 세월의돌
리눅스 & 안드로이드2014. 7. 11. 10:11

얼마전에 Eclipse에서 NDK를 지원한다는 사실을 알게 되었다.
(2014/06/30 - [Linux & Android] - Android NDK에서 C++11 사용하기)

 

그 방법을 이용하면, source가 NDK로 빌드되어 .apk 패키지에 자동으로 .so 라이브러리가 포함되고, system uid가 필요하다거나 하는 특수한 경우가 아니라면, 아무런 문제 없이 잘 실행이 된다.

 

그런데, source가 아닌 binary로 존재하는 .so 라이브러리의 경우에는 어떻게 해야 하는지 잘 몰랐다.

 

처음에는 직감적으로 libs/armeabi (or armeabi-v7a)에 .so 파일을 복사해 두면 될거라고 생각했었는데, 잘 안되어 고민을 했었는데, 결과적으로는 그 방법이 맞았다.

 

즉, .apk에 포함시키고자 하는 .so 라이브러리를 (project root)/libs/armeabi (or armeabi-v7a) 디렉토리를 생성하고 복사 한 후, 프로젝트를 다시 빌드하면 된다.

 

그럼, 이전에는 왜 안됐냐?

 

Android Native Support 옵션을 설정 해 둔게 화근이었다.

 

이것을 설정하면 .cproject라는 파일이 project root에 생성되고, project clean을 수행하면 libs/ 디렉토리에 있는 모든 .so 파일을 삭제하고 다시 빌드를 시도한다. (물론 자동빌드 옵션이 선택 된 경우)

 

그렇다보니 .apk를 새로 생성하려고 project clean을 수행하면 .so 파일이 날아가고, 빌드된 후 복사 해 봐야 아무런 영향이 없었던 것이었다.

 

그냥 bin, gen 폴더만 날리고 다시 빌드를 한다면 Android Native Support 옵션을 설정 해 두었더라도 문제없이 해결이 되지 않았을까 하는 추측을 해 본다. 나중에 확인되면 업데이트를... ; )

 

Posted by 세월의돌

Google code에 android-ndk-profiler가 있고, 설명도 잘 되어 있다.

그런데, 나의 이해력이 부족해서 그런건지 모르겠지만, 애매하게 잘 안되었던 부분들이 있어서 정리한다.

 

 


 

설명에는 다운로드한 압축파일을 $HOME/tools 위치에 해제하고, ndk-build에 NDK_MODULE_PATH를 이용해 경로를 지정하라고 되어 있는데, 나의 경우에는 NEON 사용을 위해 cpufeatures를 추가로 사용하기 때문에 그런건지, 아니면 Windows 환경이라서 그런 것인지는 모르겠지만 빌드 에러가 발생했다.

 

이 문제는 그냥, 아래와 같이 ANDROID NDK가 설치된 경로에 복사해서 해결했다.

 

android-ndk-r9d\sources\android-ndk-profiler

 

 


 

 

그리고 arm-linux-androideabi-grpof를 실행할 때 profiling 한 library를 넘겨주라고 되어 있는데,

 

$ANDROID_NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gprof your_lib.so

 

stripped library라고 에러메시지를 뱉어 냈다.

 

평소에는 Eclipse에서 libs/armeabi-v7a/에 생성된 .so 파일만 바라보았기 때문에, 다른 위치에 또 생성이 되는지는 몰랐다.

찾아보니 lib/armeabi-v7a/에 생성되는 .so 파일은 stripped library 이며, 여기에서 필요한 non-stripped library는 obj/local/armeabi-v7a/에 생성된다.

 

알고보니 내가 설명을 자세히 읽지 않았었군...;;

 

Run the gprof tool, passing it the non-stripped library (usually in $PROJECT/obj/local/armeabi-v7a/libXXXX.so or $PROJECT/obj/local/armeabi/libXXXX.so). This is for NDK version r5b onwards, in earlier versions the path to gprof is different but should still work.

 

 


 

 

위의 obj/local/armeabi-v7a/에 생성된 .so 파일을 넘겨주면 결과가 stdout으로 출력되니, 파일로 redirection하여 출력하면 보기 편하다.

 

Posted by 세월의돌
리눅스 & 안드로이드2014. 6. 30. 20:02

무엇보다 설정이 중요하므로 화면만 캡쳐 해 둔다.

 

(아래 그림) Eclipse에 NDK path를 설정하는 기능이 있다! 처음 알았네...;;

심지어는 Project에 NDK를 지원하도록 자동으로 설정하는 context menu도 있다-0- (이건 screenshot 누락됨^^;)

 

 

 

 

(아래 그림) NDK_DEBUG 옵션은 말 그대로 옵션임. 기본은 Use default build command checkbox가 선택되어 있다.


 

 

 

 

(아래 그림) 자체적으로 설명이 된다. self descriptive screenshot? ; )


 

 

 

 

(아래 그림) 이것도 자체적으로 설명이 된다. self descriptive screenshot? ; )


 

Posted by 세월의돌
리눅스 & 안드로이드2014. 6. 26. 09:27

Nexus 5에 ARM DS-5를 붙여서 profiling을 해야 할 필요가 있어서 정리 해 본다. (ARM DS-5 Using ARM Streamline)

기본적으로 참고한 사이트는 NEXUS10에 동일한 작업을 하는 ARM의 포스팅이다. (Using DS-5 Streamline with Mali on Google Nexus 10)

 

ARM DS-5 Streamline을 붙이는 핵심은 관련 kernel config가 적용된 kernel과 gator daemon을 추가할 수 있는 루팅된 디바이스 이다. 개발 버전 이미지의 경우 상당히 간단할 수 있는 작업인데, 출시된 디바이스를 가지고 환경을 만들려고 하니까 정말 빡센거 같다;;

 

1. 우선 Kernel config 적용이다.

Top Menu

Specific Options

Keywords for .config

 General
Setup

Profiling Support

CONFIG_PROFILING 

Kernel Performance Events And Counters > Kernel performance event and counters

CONFIG_PERF_EVENTS 

 Kernel
H
acking

Tracers

CONFIG_FTRACE 

 Kernel
Features

High Resolution Timer Support

CONFIG_HIGH_RES_TIMERS

Enable hardware performance counter support for perf events

CONFIG_HW_PERF_EVENTS

Use local timer interrupts (Symmetric MultiProcessing, SMP)

CONFIG_LOCAL_TIMERS

 CPU Power
Management

CPU Frequency scaling > CPU Frequency scaling
(T
o enable the CPU Freq Timeline view chart)

CONFIG_CPU_FREQ

(Top Menu는 menuconfig 화면의 top level에 보이는 항목이고, Specific Options는 해당메뉴 진입후 보이는 option들)

 

위 옵션들을 적용하라고 되어 있고 적용하면 된다. make menuconfig로 설정할 수 도 있겠지만, 나는 그냥 arch/arm/configs/hammerhead_defconfig에 위 config들을 추가해 주었다.

 

위 사이트에 보면 gator driver를 module로 빌드(gator.ko)하기위해 module관련 kernel config들을 추가 해 주었는데, 나는 module 관련 config를 추가 후 빌드하니 에러가 발생해서 그냥 built-in driver로 빌드를 해 버렸다.

CONFIG_MODULES
CONFIG_MODULE_FORCE_LOAD
CONFIG_MODULE_UNLOAD
CONFIG_MODULE_FORCE_UNLOAD

 

그리고, gator feature를 활성화 해 주기 위해 CONFIG_GATOR=m 또는 CONFIG_GATOR=y를 추가 한다.

(위의 CONFIG_MODULES config가 추가되지 않으면, CONFIG_GATOR=m은 .config 파일에 자동으로 CONFIG_GATOR=y로 변경되어 추가된다)

 

 

2. gator 관련 소스를 kernel에 추가하고, kernel을 빌드한다.

gator 관련 소스는 설치한 DS-5 경로에 포함되어 있다. <DS-5 Installation Directory>/arm/gator/

 

나의 경우, driver source(driver-src)는 kernel/drivers/gator에 복사를 했고, daemon source(daemon-src)는 kernel/tools/gator에 복사 해 두었다. (사실 daemon은 어디에 있어도 상관 없음)

 

그리고, kernel을 빌드할 때 gator driver가 함께 빌드될 수 있도록, Kconfig 파일과 Makefile에 관련 내용을 추가 해 주어야 한다.

kernel/drivers/Kconfig에

source "drivers/gator/Kconfig"

kernel/drivers/Makefile에

obj-$(CONFIG_GATOR) += gator/

그리고 kernel을 빌드한다.

 

 

3. 빌드한 zImage를 포함하는 boot.img를 생성한다.

문제없이 kernel을 빌드하고 나면, kernel directory에 vmlinux 파일이, arch/arm/boot/에 zImage-dtb 파일이 생성된다. 위 ARM 사이트에는 zImage를 가지고 생성하는 방법이 나와 있는데, 난 전체 소스를 가지고 빌드를 했었기 때문에, 이것을 이용했다.

 

위 파일들을 적절한 위치에 복사한다. 즉,

vmlinux를 bzip2로 압축한 vmlinux.bz2와 zImage-dtb를 device/lge/hammerhead-kernel/에 복사한다.

(사실 vmlinux.bz2의 용도는 디버깅용으로 넣어 뒀나 보군. 없어도 될지도 모른다ㅎㅎ 귀찮아서 확인은 패스;;)

kernel$ bzip2 --best vmlinux.bz2

kernel$ cp vmlinux.bz2 (android-root)/device/lge/hammerhead-kernel/

kernel$ cp arch/arm/boot/zImage-dtb (android-root)/device/lge/hammerhead-kernel/

위와 같이 복사하고 boot.img 새로 생성하면 된다.

 

http://source.android.com/source/building-kernels.html#building에 보면, TARGET_PREBUILT_KERNEL을 설정하면 내 kernel path에 있는 image를 이용해 boot.img를 생성할 수 있다고 되어 있다. 되긴 된다. 그런데 뭘 잘못했는지 booting이 안됨;

 

4. 생성한 boot.img로 정상부팅 확인(옵션)

정상 부팅이 되는지 확인 해 볼 수 있다. 다만 device를 루팅해야 되는데, 이때 순정 kernel이 아닌 custom kernel일 경우 문제가 생길지도 모르니(루팅은 이번이 처음이라 잘 모르겠음;;), 순정 image로 복원을 해야 할 수 도 있다.

(순정 이미지 복원은 https://dl.google.com/dl/android/aosp/hammerhead-ktu84p-factory-35ea0277.tgz 이용)

 

정상적으로 부팅이 되고, Settings > About phone > Kernel version에 자신이 빌드한 kernel 정보가 나오면 성공 임.

 

 

5. gator daemon 빌드

gator daemon을 빌드한다. 요건 device에서 실행되는 ARM binary로 NDK를 이용해서 빌드하면 된다.

 

위 ARM 사이트에 친절히 설명이 되어 있긴 한데, jni 디렉토리를 생성해서 gator daemon 소스를 몽땅 복사(혹은 이동) 후, ndk-build를 실행하면 libs/armeabi/gatord가 생성된다.

(gator-daemon 디렉토리가 있다면, 여기에서 jni 디렉토리를 생성하고 gator daemon 소스를 몽땅 복사한다. 이후 gator-daemon 디렉토리에서 ndk-build를 실행하면, gator-daemon/libs/armeabi/gatord 파일이 생성된다)

 

6. 디바이스 rooting이 필요한 시점!

gatord를 system partion에 넣어야 하므로 rooting이 필요하다. 루팅 방법은 아래 사이트에 잘 정리되어 있으니 참고하면 된다.

Nexus Root Toolkit: http://www.wugfresh.com/nrt/

NRT 사용법 설명1: http://ryueyes11.tistory.com/3066

NRT 사용법 설명2: http://greenz.tistory.com/9

 

 

7. gatord를 system/bin에 복사한다.

복사 방법은 ARM posting에서 복사 해 뒀다.

adb shell su -c 'mount -o remount /system'

adb push gatord /sdcard/

adb shell su -c 'cp /sdcard/gator* /system/bin/'

adb shell su -c 'chmod 777 /system/bin/gatord'

 

 

8. gatord 실행!

adb shell su -c 'mount -o remount /system'

adb forward tcp:8080 tcp:8080

adb shell su -c '/system/bin/gatord &'

여기에서, gator driver가 built-in으로 추가되어 있지 않은 경우, daemon이 실행되지 않는다.

 

 

9. host에서 Streamline 실행 후 연결 확인!

ARM DS-5 Streamline의 연결 방법은 구글링으로~

 

 

제대로 정리했나 모르겠네.ㅎㅎ 이제는 Streamline에서 android process 프로파일링 하는 방법 알아봐야겠군;;

google에서 주는 trace tool 들도 좀 알아봐야지.


2015-12-24 크리스마스 이브에 추가:

Android M OS로 업그레이드 되면서 linux kernel의 버전도 변경되어 gator driver의 Kconfig에서 dependency로 설정되어 있는, CONFIG_LOCAL_TIMERS feature는 더이상 지원이 되지 않는 듯 하다.


따라서, M OS에서 defconfig에 CONFIG_GATOR를 추가하면, 위의 dpendency 때문에 GATOR feature가 추가되지 않는 문제가 발생한다 gator driver의 Kconfig에서 해당 dependency를 제거 해 주면, 문제가 해결 된다! (이것땜에 온갖 삽질을 다 했구나...;;)

(위 내용들은 정상동작이 확인되지 않음;; daemon과 driver가 붙으면 target reset이 되어 버림;;)


추가로 발견한 사실은, defconfig에 아래 세 개의 feature만 추가 해 주면, 나머지 필요한 feature들은 자동으로 추가가 된다.

CONFIG_PROFILING=y

CONFIG_HIGH_RES_TIMERS=y

CONFIG_GATOR=y


* cat /sys/module/gator/version 으로 확인할 수 있는 버전은 ARM DS-5의 버전과 일치해야 하며, 예를들어 결과가 231인 경우 DS-5 v5.23.1과 대응되고, 20인 경우는 DS-5 v5.20과 대응된다. (소스상에서는 gator_main.c 에서 PROTOCOL_VERSION으로 확인 가능)

이상!!!


'리눅스 & 안드로이드' 카테고리의 다른 글

android-ndk-profiler 사용하기  (0) 2014.07.04
Android NDK에서 C++11 사용하기  (0) 2014.06.30
완전 만족하고 있는 G2 (LG-F320L)  (0) 2014.06.11
NDK에서 include path  (0) 2014.06.05
Nokia Tune on arduino  (0) 2014.05.15
Posted by 세월의돌
리눅스 & 안드로이드2014. 6. 11. 20:05


몇 일전 대란이 일어난 바로 그날 오후에 U+ G2를 재가입 기변으로 변경했다.


그 동안 G Pro를 사용해 왔었는데, 크기가 크다는 것 빼고는 나쁘지 않았다. 그런데 KK 업그레이드 후 남들은 빨라졌다는데 나는 이상하게 더 느려졌다는 느낌을 받아다. 여기저기 떡칠 된 알파블렌딩 때문이 아니었을까?


G2로 바꾸고 나서는,


우선 크기가 너무 맘에 든다. 기존에도 NEKEDA 케이스를 사용했는데, 아이들이 집어 던져도 1년 가까이 잘 벼텨 줬던 케이스 이다. 그래서 이번에도 NEKEDA 케이스를 구입했는데, 케이스를 씌워도 적당한 그립감이 정말 만족 스럽다.


그리도 knock-on 기능은 편리한 것 같다. 전원 버튼을 뒤로 보낸 후, 고육지책으로 만들어낸 기능이 아닐까 생각되지만 의외로 편리함을 제공한다. 전원버튼이 기존 위치에 있더라도 이 기능은 넣어주면 좋을 기능인 것 같다.


성능은 버벅거림이 없어졌다는데 의의를 둔다. 다만 내가 즐기는 게임들에서의 성능은 월등히 좋아졌다고는 느껴지지 않는다. 작은 공간에 우겨 넣어서 그런지 발열이 심하고, 발열 때문에 시스템의 각종 clock들의 제한이 금방 걸리는 것 같기도 하고...;; 암튼 성능은 스냅드레곤 805에 FullHD 이면 좋겠다. (쓸데없이 QHD.2K 이런거 적용하지 말고 말이지...;;)


아무튼 이래저리 전화기가 맘에 드니, 기존에는 이용하지 않던 기능들을 더 사용 해 보고 싶다는 욕심이 생긴다. 역시 뭐든 마음에 들어야 마음이 동하고, 그래야 활용도도 높아지는 것 같다. 뭐, 요금제를 LTE8로 사용하다보니 이런저런 걱정없이 사용하는 이유도 있을 듯. (예전 SKT 3G 무제한을 사용하는 느낌이랄까?ㅋ)


이제, 제대로 U+에 코 끼었으니, 큰 변화가 생기지 않으면(iPhone이 정말 맘에 들게 나오지 않는 한) 계속 U+에 머물러야 할 것 같다-0-


'리눅스 & 안드로이드' 카테고리의 다른 글

Android NDK에서 C++11 사용하기  (0) 2014.06.30
NEXUS5에 ARM DS-5 Streamline 붙이기  (0) 2014.06.26
NDK에서 include path  (0) 2014.06.05
Nokia Tune on arduino  (0) 2014.05.15
First arduino in my life  (0) 2014.05.13
Posted by 세월의돌

OpenSL ES를 사용하기위해 NDK로 빌드를 하고 있는데, 컴파일러가 SLES/OpenSLES.h 파일을 찾지 못해 잠시 당황 했다.

 

분명 platform 디렉토리에는 위 경로에 헤더파일이 있는데 찾지를 못해서 뭐가 문제인가 고민을 좀 했다.

 

Android.mk 파일에 -I 옵션을 추가해 줘야 하나 고민하던 차에, stlport를 사용할 때도 Application.mk 파일에 한 줄만 넣어주면 되는데, 복잡하게 되어 있을리가 없을 것 같아서, 우선 ndk-build의 -d 옵션으로 빌드 중 어떤일이 일어나는지 살펴 봤다.

 

엄청난 양의 로그가 나오고나서, 마지막 줄에 자동으로 추가되는 -I 옵션을 확인할 수 가 있었다.

 

기본으로 포함하는 include path는 platform/android-3 였다.

 

역시나 해당 platform 버전에는 SLES가 없었고 말이지...;;

 

그래서 찾아보니 target platform을 지정하는 옵션이 있더라!

 

그리고

 

TARGET_PLATFORM=android-19

 

를 추가하니 문제 해결!

 

 

참고로, 당연한 이야기 이지만 link할 library는 명시적으로 추가 해 주어야 함.

 

-lOpenSLES

 

이렇게 말이지...

 

Posted by 세월의돌