
NDK / Java Native Interface 자바 네이티브 인터페이스 - 1 - NDK / Java Native Interface . ACHRO4210의 디바이스 . 안드로이드에서 사용되는 대표적인 디바이스 LCD, Touch, Keypad, Wifi, Bluetooth, audio,… - 커널에서는 각 드라이버를 해당 플랫폼 드라이버로 등록 LCD Bluetooth Touch Keypad WiFi … . 그외의 일반적이지 않은 디바이스 보통의 안드로이드 기기에서 사용하지 않는 장치 - 커널에 별도의 드라이버 모듈을 적재하고, App은 JNI를 이용 장치와 통신 GPS EPD MPU RFID Blood Checker … - 2 - 2 Huins. R&D Center NDK / Java Native Interface . Java Native Interface . JNI 개요 - Java는 순수 소프트웨어 툴 - 하드웨어 의존적인 코드와 속도향상을 위해 Device를 제어할 필요가 있는경우 이용 - C와 C++로 작성 - 구글에서 제공하는 NDK(Native DK)툴을 이용 . 안드로이드 플래폼 구조 - 3 - 3 Huins. R&D Center NDK / Java Native Interface . JNI . JVM에서 돌아가는 Java 코드와 C/C++로 구현된 코드가 상호참조하 기 위해 사용하는 programming framework . Platform-dependent한 라이브러리를 사용하고자 할 때, 혹은 기존의 프로그램을 Java에서 접근가능하도록 변경하고자 할 때 쓰임 - 4 - 4 Huins. R&D Center NDK / Java Native Interface . Android NDK . A toolset that lets you embed in your apps native source code . C, C++(recently supported December 2010) and assembly(?) . It is supported on android cupcake(1.5)+ - 5 - 5 Huins. R&D Center NDK / Java Native Interface . 언제 Android NDK를 쓸 것인가? . 단지 C, C++을 더 쓰고 싶어서라면 쓰지말것.. NDK 사용의 단점을 뛰어넘는 장점이 있을때만 사용할 것 . 응용 개발의 복잡성이 증가하며, . 디버깅이 어려움 . 그리고, C, C++을 사용한다고 해서 항상 성능이 빨라지는 것도 아님 - 6 - 6 Huins. R&D Center NDK / Java Native Interface . NDK 설치 - jni 파일을 컴파일하여 so파일로 컴파일 하는 툴과 예제를 포함한 개발 킷 . NDK 다운로드 . android-ndk-r9b-linux-x86.tar.bz2 다운로드 from http://developer.android.com/tools/sdk/ndk/index.html or http://web.donga.ac.kr/jwjo or [CD]/android_tools/linux/ndk_linux_x86_x64/android-ndk-r7-linux-x86.tar.bz . NDK 복사 및 설치 # tar jxvf android-ndk-r9b-linux-x86.tar.bz2 -C /work/mydroid . NDK 패스 설정 # cd /root # vim .bashrc … … # NDK Path export PATH=/work/mydroid/android-ndk-r8b:$PATH - 7 - 7 Huins. R&D Center NDK / Java Native Interface . JNI 테스트 - JNI 가 정상 설치되었는지 테스트 . Hello JNI 디렉터리로 이동 # cd /work/mydroid/android-ndk-r9b/samples/hello-jni . 패키지에 포함된 경로 # cd /work/mydroid/android-ndk-r9b/samples/hello-jni # ls AndroidManifest.xml default.properties jni libs obj res src tests # ls ./jni Android.mk hello-jni.c # ndk-build - 8 - 8 Huins. R&D Center NDK / Java Native Interface . JNI 테스트 . IDE툴을 이용하여 HelloJNI를 연다. ndk에 있는 hello-jni프로젝트를 열어서 실제로 실행 시켜 본다. FILE NEW Other… Android Project 선택 . Project를 열때 기존에 존재하는 소스 디렉터리를 선택 Create project form existing source Browse hello-jni 디렉터리 . libhello-jni.so 파일 확인 - IDE 패키지 트리에서 컴파일한 hello-jni.c 가 정상적으로 컴파일 되었는지를 확인 - 정상적으로 컴파일 되었다면 libs/armeabi/libhello-jni.so 파일이 생성되어있어야 함 . 실행 - IDE에서 Run을 실행하여 프로그램을 실행한다. - 장치가 있으면 장치에서 실행하고, 없는 경우 생성되어있는 가상 디바이스(AVD)에 실행된다. - 9 - 9 Huins. R&D Center NDK / Java Native Interface . Hello Jni 소스 분석 . Hello-jni.java native 키워드를 붙여 선언부만 작성함. public native String stringFromJNI(); 네이티브 라이브러리에 구현 부가 있음 public class HelloJni extends Activity { @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); TextView tv = new TextView(this); tv.setText( stringFromJNI() ); 네이티브 라이브러리 함수도 보통의 setContentView(tv); 자바 메소드와 같은 방식으로 사용한다. } public native String stringFromJNI(); public native String unimplementedStringFromJNI(); static { System.loadLibrary("hello-jni"); 클래스가 로딩될 때 호출됨. } hello-jni라는 이름의 네이티브 라이브러리를 로딩. ‘lib’와 ‘.so’는 생략한다. } . hello-jni.c jstring Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env, jobject thiz ) { return (*env)->NewStringUTF(env, "Hello from JNI !"); } 리턴 타입 접두사 패키지 클래스 함수 공통 파라메타 - 10 - 10 Huins. R&D Center NDK / Java Native Interface . Android.mk - GNU Makefile의 일부 - Static library와 Shared library를 생성 - Static library는 Shared library를 생성하기 위해 사용 LOCAL_PATH := $(call my-dir) LOCAL_PATH 는 현재 파일의 경로를 주기 위해 사용 ‘my-dir’은 현재 디렉터리 경로를 반환 include $(CLEAR_VARS) 빌드 시스템에서 제공하는 LOCAL_PATH를 제외하고 LOCAL_MODULE := hello-jni LOCAL_XXX를 Clear함(undefine) LOCAL_SRC_FILES := hello-jni.c LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog include $(BUILD_SHARED_LIBRARY) 모듈의 이름의 정의. 유일하고 중간에 공백이 있어서는 안된다. Shard library를 생성 LOCAL_XXX 변수에서 제공하는 정보를 수집하고 모듈로 빌드될 C와 C++ 소스파일의 목록 목록의 소스로 부터 shared library를 빌드하는 방법을 결정 추가적인 linker flag의 목록 include $(BUILD_SHARED_LIBRARY) lib$(LOCAL_MODULES).so include $(BUILD_STATIC_LIBRARY) lib$(LOCAL_MODULE).a - 11 - 11 Huins. R&D Center NDK / Java Native Interface . Shared library의 명명 규칙 1. ‘lib’prefix<name>’.so’suffix의 형식 2. <name>이 ‘hello-jni’라면, 최종 파일은 ‘libhello-jni.so’ . 생성된 라이브러리 위치 Shared library는 프로젝트의 적절한 경로에 복사되고, 최종 ‘.apk’파일에 포함 최종 파일은 project\libs\armeabi 의 경로에 libhello-jni.so파일로 생성 - 12 - 12 Huins. R&D Center NDK / Java Native Interface . Linux 구조 - 안드로이드의 JNI는 드라이버를 처리 하거나 복잡한 메모리 연산부분에 대해서 커널을 이용하는 방법이용한다. - 13 - 13 Huins. R&D Center NDK / Java Native Interface . Linux Device Driver - 커널을 통해 디바이스를 제어하기 위해 사용되는 소프트웨어 - 커널은 주번호와 부번호를 통해 등록된 디바이스와 연결 - 리눅스의 모든 하드웨어 장치들은 파일로 관리 (/dev) . 디바이스 드라이버와 커널 - 14 - 14 Huins. R&D Center NDK / Java Native Interface . 디바이스 드라이버와 어플리케이션간의 통신 - 15 - 15 Huins. R&D Center NDK / Java Native Interface . 커널 모듈 . 모듈은 리눅스 시스템이 부팅된 후 동적으로 load, unload 할 수 있는 커널의 구성 요소 . 시스템을 재부팅 하지 않고, 일부를 교체할 수 있다 . 리눅스를 구성하는 많은 모듈들은 의존성이 있을 수 있다. 커널을 등록시킬 때에는 insmod 명령을 이용하고 내릴 때는 rmmod 명령을 이용한다. /* This program is modue example AUTH : Huins, Inc MENT : Test Only */ #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> MODULE_LICENSE("GPL"); MODULE_AUTHOR("Huins"); static int module_begin(void) { printk(KERN_ALERT "Hello module, Achro 4210!!\n"); return 0; } static void module_end(void) { printk(KERN_ALERT "Goodbye module, Achro 4210!!\n"); } module_init(module_begin); module_exit(module_end); - 16 - 16 Huins. R&D Center NDK / Java Native Interface . LED 드라이버 . 회로 Exynos4210 CPU - 17 - 17 Huins. R&D Center NDK / Java Native Interface . LED 드라이버 . 회로 설명 - CPU의 GPIO핀과 LED가 연결되어있음 - LED에는 VDD를 통해 전원이 공급되고 있음 - CPU의 핀이 LOW(0)가 되면 LED가 점등. 연번 순서 PIN NAME CPU/IO 1 LED 0 SPI_1.MOSI GPB7 2 LED 1 SPI_1.MISO GPB6 3 LED 2 SPI_1.NSS GPB5 4 LED 3 SPI_1.CLK GPB4 . LED Driver Souce /* LED Ioremap Control FILE : led_driver.c */ // 헤더 선언부 #define LED_MAJOR 240 // 디바이스 드라이버의 주번호 #define LED_MINOR 0 // 디바이스 드라이버의 부번호 #define LED_NAME "led_driver" // 디바이스 드라이버의 이름 #define LED_GPBCON 0x11400040 // GPBCON 레지스터의 물리주소 #define LED_GPBDAT 0x11400044 // GPBDAT 레지스터의 물리주소 int led_open(struct inode *, struct file *); int led_release(struct inode *, struct file *); ssize_t led_write(struct file *, const char *, size_t, loff_t *); - 18 - 18 Huins. R&D Center NDK / Java Native Interface . LED Driver Souce static int led_usage = 0; if(result <0) { static unsigned char *led_data; printk(KERN_WARNING"Can't get any major!\n"); static unsigned int *led_ctrl; return result; static struct file_operations led_fops = { } .open = led_open, led_data = ioremap(LED_GPBDAT, 0x01); .write = led_write, if(led_data==NULL) { .release = led_release, printk("ioremap failed!\n"); }; return -1; } int led_open(struct inode *minode, struct file *mfile) { led_ctrl = ioremap(LED_GPBCON, 0x04); if(led_usage != 0) if(led_ctrl==NULL) { return -EBUSY; printk("ioremap failed!\n"); led_usage = 1; return -1; return 0; } else { } get_ctrl_io=inl((unsigned int)led_ctrl); get_ctrl_io|=(0x11110000); int led_release(struct inode *minode, struct file *mfile) { outl(get_ctrl_io,(unsigned int)led_ctrl); led_usage = 0; } return 0; outb(0xF0, (unsigned int)led_data); } return 0; } ssize_t led_write(struct file *inode, const char *gdata, size_t length, loff_t *off_what) { void __exit led_exit(void) { const char *tmp = gdata; outb(0xF0, (unsigned int)led_data); unsigned short led_buff=0; iounmap(led_data); outb (led_buff, (unsigned int)led_data); iounmap(led_ctrl); return length; unregister_chrdev(LED_MAJOR, LED_NAME); } } int __init led_init(void) { module_init(led_init); int result; module_exit(led_exit); unsigned int get_ctrl_io=0; MODULE_LICENSE ("GPL"); result = register_chrdev(LED_MAJOR, LED_NAME, &led_fops); MODULE_AUTHOR ("Huins HSH"); - 19 - 19 Huins. R&D Center Internal Device Driver . Led Driver . File Operation struct static struct file_operations led_fops = { .open = led_open, .write = led_write, .release = led_release, } ; . led_open() int led_open(struct inode *minode, struct file *mfile) { if(led_usage != 0) return -EBUSY; led_usage = 1; return 0; } . led_release() int led_release(struct inode *minode, struct file *mfile) { led_usage = 0; return 0; } - 20 - 20 Huins. R&D Center Internal Device Driver . led_write() ssize_t led_write(struct file *inode, const char *gdata, size_t length, loff_t *off_what) { const char *tmp = gdata; unsigned short led_buff=0; if (copy_from_user(&led_buff, tmp, length)) return -EFAULT; outb (led_buff, (unsigned int)led_data); return length; } . led_release() void __exit led_exit(void) { outb(0xF0, (unsigned int)led_data); iounmap(led_data); iounmap(led_ctrl); unregister_chrdev(LED_MAJOR, LED_NAME); printk("Removed LED module\n"); } - 21 - 21 Huins. R&D Center Internal Device Driver . led_init() int __init led_init(void) { int result; unsigned int get_ctrl_io=0; result = register_chrdev(LED_MAJOR, LED_NAME, &led_fops); if(result <0) { printk(KERN_WARNING"Can't get any major!\n"); return result; } led_data = ioremap(LED_GPBDAT, 0x01); if(led_data==NULL) [ // 오류 처리 } led_ctrl = ioremap(LED_GPBCON, 0x04); if(led_ctrl==NULL) { // 오류 처리 } else { get_ctrl_io=inl((unsigned int)led_ctrl); get_ctrl_io|=(0x11110000); outl(get_ctrl_io,(unsigned int)led_ctrl); } printk("init module, /dev/led_driver major : %d\n", LED_MAJOR); outb(0xF0, (unsigned int)led_data); return 0; } - 22 - 22 Huins. R&D Center Internal Device Driver . Test Application /* … (생략) … int main(int argc, char **argv) { unsigned char val[] = {0x70, 0xB0, 0xD0, 0xE0, 0x00, 0xF0}; if(argc != 2) { // 실행 어규먼트를 받았는지 체크 및 오류처리 } led_fd = open("/dev/led_device", O_RDWR); // 디바이스를 오픈. if (led_fd<0) { // 만약 디바이스가 정상적으로 오픈되지 않으면 오류 처리후 종료 } get_number=atoi(argv[1]); // 받은 인자를 숫자로 바꾼다. if(get_number>0||get_number<9) // 숫자가 0~9 까지에 포함되는지 확인. write(led_fd,&val[get_number],sizeof(unsigned char)); else printf("Invalid Value : 0 thru 9"); // 포함되지 않으면, 메시지를 출력. close(led_fd); // 장치를 닫아줌. return 0; // 프로그램을 종료. } - 23 - 23 Huins. R&D Center NDK / Java Native Interface . LED Driver 컴파일 스크립트 (Makefile) # vim Makefile # This is simple Makefile obj-m := led_driver.o # led_driver.c를 컴파일하여 led_driver.ko파일을 만든다.
Details
-
File Typepdf
-
Upload Time-
-
Content LanguagesEnglish
-
Upload UserAnonymous/Not logged-in
-
File Pages44 Page
-
File Size-