NDK / Java Native Interface 자바 네이티브 인터페이스

NDK / Java Native Interface 자바 네이티브 인터페이스

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파일을 만든다.

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    44 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us