자바 네이티브 인터페이스

44
- 1 - 자자 자자자자 자자자자자 NDK / Java Native Interface

Upload: addison

Post on 07-Jan-2016

67 views

Category:

Documents


4 download

DESCRIPTION

NDK / Java Native Interface. 자바 네이티브 인터페이스. NDK / Java Native Interface. ACHRO4210 의 디바이스 안드로이드에서 사용되는 대표적인 디바이스 LCD, Touch, Keypad, Wifi , Bluetooth, audio,… - 커널에서는 각 드라이버를 해당 플랫폼 드라이버로 등록 그외의 일반적이지 않은 디바이스 보통의 안드로이드 기기에서 사용하지 않는 장치 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 자바  네이티브  인터페이스

- 1 -

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

Page 2: 자바  네이티브  인터페이스

- 2 -Huins. R&D Center

NDK / Java Native Interface

ACHRO4210 의 디바이스 안드로이드에서 사용되는 대표적인 디바이스

LCD, Touch, Keypad, Wifi, Bluetooth, audio,…

- 커널에서는 각 드라이버를 해당 플랫폼 드라이버로 등록

그외의 일반적이지 않은 디바이스보통의 안드로이드 기기에서 사용하지 않는 장치- 커널에 별도의 드라이버 모듈을 적재하고 , App 은 JNI 를 이용 장치와 통신

…GPS EPD MPU RFID Blood Checker

…LCD Keypad WiFiBluetooth Touch

2

Page 3: 자바  네이티브  인터페이스

- 3 -Huins. R&D Center

NDK / Java Native Interface

Java Native Interface JNI 개요

- Java 는 순수 소프트웨어 툴- 하드웨어 의존적인 코드와 속도향상을 위해 Device 를 제어할 필요가 있는경우 이용- C 와 C++ 로 작성- 구글에서 제공하는 NDK(Native DK) 툴을 이용

안드로이드 플래폼 구조

3

Page 4: 자바  네이티브  인터페이스

- 4 -Huins. R&D Center

NDK / Java Native Interface

JNI JVM 에서 돌아가는 Java 코드와 C/C++ 로 구현된 코드가

상호참조하기 위해 사용하는 programming framework Platform-dependent 한 라이브러리를 사용하고자 할 때 , 혹은 기존의

프로그램을 Java 에서 접근가능하도록 변경하고자 할 때 쓰임

4

Page 5: 자바  네이티브  인터페이스

- 5 -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

Page 6: 자바  네이티브  인터페이스

- 6 -Huins. R&D Center

NDK / Java Native Interface

언제 Android NDK 를 쓸 것인가 ? 단지 C, C++ 을 더 쓰고 싶어서라면 쓰지말것 .. NDK 사용의 단점을 뛰어넘는 장점이 있을때만 사용할 것

응용 개발의 복잡성이 증가하며 , 디버깅이 어려움 그리고 , C, C++ 을 사용한다고 해서 항상 성능이 빨라지는 것도 아님

6

Page 7: 자바  네이티브  인터페이스

- 7 -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-r8-linux-x86.tar.tar 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

Page 8: 자바  네이티브  인터페이스

- 8 -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

Page 9: 자바  네이티브  인터페이스

- 9 -Huins. R&D Center

NDK / Java Native Interface

JNI 테스트 IDE 툴을 이용하여 HelloJNI 를 연다 .

Project 를 열때 기존에 존재하는 소스 디렉터리를 선택Create project form existing source Browse hello-jni 디렉터리

libhello-jni.so 파일 확인- IDE 패키지 트리에서 컴파일한 hello-jni.c 가 정상적으로 컴파일 되었는지를 확인- 정상적으로 컴파일 되었다면 libs/armeabi/libhello-jni.so 파일이 생성되어있어야 함

실행- IDE 에서 Run 을 실행하여 프로그램을 실행한다 . - 장치가 있으면 장치에서 실행하고 , 없는 경우 생성되어있는 가상 디바이스 (AVD) 에 실행된다 .

ndk 에 있는 hello-jni 프로젝트를 열어서 실제로 실행 시켜 본다 .FILE NEW Other… Android Project 선택

9

Page 10: 자바  네이티브  인터페이스

- 10 -Huins. R&D Center

NDK / Java Native Interface

Hello Jni 소스 분석 Hello-jni.java

hello-jni.c

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’ 는 생략한다 .

native 키워드를 붙여 선언부만 작성함 . 네이티브 라이브러리에 구현 부가 있음

네이티브 라이브러리 함수도 보통의 자바 메소드와 같은 방식으로 사용한다 .

jstring Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env, jobject thiz ){ return (*env)->NewStringUTF(env, "Hello from JNI !");}

패키지 클래스 함수접두사리턴 타입 공통 파라메타

10

Page 11: 자바  네이티브  인터페이스

- 11 -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)

include $(CLEAR_VARS)

LOCAL_MODULE := hello-jniLOCAL_SRC_FILES := hello-jni.cLOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog

include $(BUILD_SHARED_LIBRARY)

LOCAL_PATH 는 현재 파일의 경로를 주기 위해 사용‘my-dir’ 은 현재 디렉터리 경로를 반환빌드 시스템에서 제공하는 LOCAL_PATH 를 제외하고 LOCAL_XXX 를 Clear 함 (undefine)

모듈의 이름의 정의 . 유일하고 중간에 공백이 있어서는 안된다 .

모듈로 빌드될 C 와 C++ 소스파일의 목록

추가적인 linker flag 의 목록

Shard library 를 생성LOCAL_XXX 변수에서 제공하는 정보를 수집하고 목록의 소스로 부터 shared library 를 빌드하는 방법을 결정

include $(BUILD_SHARED_LIBRARY)lib$(LOCAL_MODULES).so include $(BUILD_STATIC_LIBRARY)lib$(LOCAL_MODULE).a

11

Page 12: 자바  네이티브  인터페이스

- 12 -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

Page 13: 자바  네이티브  인터페이스

- 13 -Huins. R&D Center

NDK / Java Native Interface

Linux 구조- 안드로이드의 JNI 는 드라이버를 처리 하거나 복잡한 메모리 연산부분에 대해서 커널을 이용하는 방법이용한다 .

13

Page 14: 자바  네이티브  인터페이스

- 14 -Huins. R&D Center

NDK / Java Native Interface

Linux Device Driver- 커널을 통해 디바이스를 제어하기 위해 사용되는 소프트웨어- 커널은 주번호와 부번호를 통해 등록된 디바이스와 연결- 리눅스의 모든 하드웨어 장치들은 파일로 관리 (/dev)

디바이스 드라이버와 커널

14

Page 15: 자바  네이티브  인터페이스

- 15 -Huins. R&D Center

NDK / Java Native Interface

디바이스 드라이버와 어플리케이션간의 통신

15

Page 16: 자바  네이티브  인터페이스

- 16 -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

Page 17: 자바  네이티브  인터페이스

- 17 -Huins. R&D Center

NDK / Java Native Interface

LED 드라이버 회로

Exynos4210 CPU

17

Page 18: 자바  네이티브  인터페이스

- 18 -Huins. R&D Center

NDK / Java Native Interface

LED 드라이버 회로 설명

- CPU 의 GPIO 핀과 LED 가 연결되어있음- LED 에는 VDD 를 통해 전원이 공급되고 있음- CPU 의 핀이 LOW(0) 가 되면 LED 가 점등 .

LED Driver Souce

연번 순서 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 Ioremap ControlFILE : 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

Page 19: 자바  네이티브  인터페이스

- 19 -Huins. R&D Center

NDK / Java Native Interface

LED Driver Souce

static int led_usage = 0;static unsigned char *led_data;static unsigned int *led_ctrl;static struct file_operations led_fops = { .open = led_open, .write = led_write, .release = led_release,}; int led_open(struct inode *minode, struct file *mfile) { if(led_usage != 0) return -EBUSY; led_usage = 1; return 0;} int led_release(struct inode *minode, struct file *mfile) { led_usage = 0; return 0;} 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; outb (led_buff, (unsigned int)led_data); return length;}

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) { printk("ioremap failed!\n"); return -1; } led_ctrl = ioremap(LED_GPBCON, 0x04); if(led_ctrl==NULL) { printk("ioremap failed!\n"); return -1; } else { get_ctrl_io=inl((unsigned int)led_ctrl); get_ctrl_io|=(0x11110000); outl(get_ctrl_io,(unsigned int)led_ctrl); } outb(0xF0, (unsigned int)led_data); return 0;}

void __exit led_exit(void) { outb(0xF0, (unsigned int)led_data); iounmap(led_data); iounmap(led_ctrl); unregister_chrdev(LED_MAJOR, LED_NAME);}

module_init(led_init);module_exit(led_exit);MODULE_LICENSE ("GPL");MODULE_AUTHOR ("Huins HSH");

19

Page 20: 자바  네이티브  인터페이스

- 20 -Huins. R&D Center

Internal Device Driver

Led Driver File Operation struct

led_open()

led_release()

20

static struct file_operations led_fops = {

.open = led_open,

.write = led_write,

.release = led_release,

};

int led_open(struct inode *minode, struct file *mfile) {

if(led_usage != 0)

return -EBUSY;

led_usage = 1;

return 0;

}

int led_release(struct inode *minode, struct file *mfile) {

led_usage = 0;

return 0;

}

Page 21: 자바  네이티브  인터페이스

- 21 -Huins. R&D Center

Internal Device Driver

led_write()

led_release()

21

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;}

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");

}

Page 22: 자바  네이티브  인터페이스

- 22 -Huins. R&D Center

Internal Device Driver

led_init()

22

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;}

Page 23: 자바  네이티브  인터페이스

- 23 -Huins. R&D Center

Internal Device Driver

Test Application

23

/* … ( 생략 ) …

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; // 프로그램을 종료 .

}

Page 24: 자바  네이티브  인터페이스

- 24 -Huins. R&D Center

NDK / Java Native Interface

LED Driver 컴파일 스크립트 (Makefile)

# This is simple Makefileobj-m := led_driver.o # led_driver.c 를 컴파일하여 led_driver.ko 파일을 만든다 .

CC := arm-linux-gcc # 어플리케이션 컴파일 시 사용할 컴파일러

KDIR := /work/achro4210/kernel # 커널 소스가 풀려있는 디렉터리

PWD := $(shell pwd) # 현재 디렉터리 환경 변수를 가져옴FILE := test_led # 응용 프로그램 파일이름

all: driver # make 만 입력했을 때 실행되는 전체 부분

driver : # make driver 를 입력했을 때 실행되는 부분 $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules

install : # make install 을 입력했을 때 실행되는 부분 cp -a led_driver.ko /nfsroot

clean: # make clean 을 입력했을 때 실행되는 부분 rm -rf *.ko rm -rf *.mod.* rm -rf *.o rm -rf $(FILE) rm -rf modules.order rm -rf Module.symvers

# vim Makefile

24

Page 25: 자바  네이티브  인터페이스

- 25 -Huins. R&D Center

NDK / Java Native Interface

LED Driver 컴파일- 컴파일이 완료되면 led_driver.ko 파일이 생성된다 .

Led_driver.ko 파일을 보드로 전송

안드로이드에서 led 를 제어할 수 있도록 장치 노드를 생성- adb 를 이용하여 shell 을 사용한다 .

# make

# adb push led_driver.ko /

# adb shell <-- PC 명령창 (Target Board 명령창을 연다 )# mknod /dev/gpio c 246 0 <-- Target Board 명령창# insmod /led_driver.ko <--- Target Board 명령창# exit <--- Target Board 명령창 (Target Board 의 명령창을 빠져나간다 .)

25

Page 26: 자바  네이티브  인터페이스

- 26 -Huins. R&D Center

NDK / Java Native Interface

LED JNI 개발 순서

android application 소스코드 작성 (Java) android.mk 작성 (JNI) jni 소스코드 작성 : led_jni.c (JNI) jni 파일을 패키지에 포함 ( 패키지에서 새파일을 만들어 위의 파일을 작성해도 됨 ) 터미널에서 해당 jni 파일이 있는 위치로 이동하여 ndk-build 실행

-> libled-jni.so 생성 안드로이드 소스에서 소스를 갱신 (F5 키를 눌러도 됨 )

-> 안드로이드 프로젝트에서 라이브러리 경로와 파일이 표시됨 RUN 을 실행하여 컴파일 하여 보드에서 실행

소스 디렉터리 구조 bin – 컴파일 된 애플리케이션 코드 libs – 애플리케이션에서 사용하는 외부 라이브러리 파일이 위치 src – 애플리케이션을 구성하는 자바 소스 코드 res – 아이콘이나 GUI 레이아웃 등 컴파일 된 자바 코드와 함께 애플리케이션 패키지에

포함될 각종 파일 assets – 장비에 애플리케이션을 설치할 때 함께 설치할 그 밖의 데이터 파일 jni – 네이티브 라이브러리를 구성하는 C 소스 코드

26

Page 27: 자바  네이티브  인터페이스

- 27 -Huins. R&D Center

NDK / Java Native Interface

LedJNI Example Project 생성

27

Page 28: 자바  네이티브  인터페이스

- 28 -Huins. R&D Center

NDK / Java Native Interface

UI 작성 (main.xml)

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android= "http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" >

<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello"/>

<RadioGroup android:id="@+id/RadioGroup01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal">

<RadioButton android:text="1" android:id="@+id/RB01" android:layout_width="wrap_content" android:layout_height="wrap_content"></RadioButton>

<RadioButton android:text="2" android:id="@+id/RB02" android:layout_width="wrap_content" android:layout_height="wrap_content"></RadioButton>

<RadioButton android:text="3" android:id="@+id/RB03" android:layout_width="wrap_content" android:layout_height="wrap_content"></RadioButton>

<RadioButton android:text="4" android:id="@+id/RB04" android:layout_width="wrap_content" android:layout_height="wrap_content"></RadioButton>

<RadioButton android:text="5" android:id="@+id/RB05" android:layout_width="wrap_content" android:layout_height="wrap_content"></RadioButton>

<RadioButton android:text="6" android:id="@+id/RB06" android:layout_width="wrap_content android:layout_height="wrap_content"></RadioButton>

<RadioButton android:text="7" android:id="@+id/RB07" android:layout_width="wrap_content" android:layout_height="wrap_content"></RadioButton>

<RadioButton android:text="8" android:id="@+id/RB08" android:layout_width="wrap_content" android:layout_height="wrap_content"></RadioButton>

</RadioGroup>

28

Page 29: 자바  네이티브  인터페이스

- 29 -Huins. R&D Center

NDK / Java Native Interface

제어 소스 (LedJniExampleActivity.java.xml)

package achro4.huins.ex1;

import android.app.Activity;import android.os.Bundle;import android.widget.RadioGroup;

public class LedJniExampleActivity extends Activity implements RadioGroup.OnCheckedChangeListener { RadioGroup mRadioGroup; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mRadioGroup = (RadioGroup)findViewById(R.id.RadioGroup01); mRadioGroup.setOnCheckedChangeListener(this); }

@Overridepublic void onCheckedChanged(RadioGroup group, int checkedId) { switch(checkedId) { case R.id.RB01 : ReceiveLedValue(0); // LED 1 break ; case R.id.RB02 : ReceiveLedValue(1); // LED 2 break ; case R.id.RB03 :

ReceiveLedValue(2); // LED 3 break ; case R.id.RB04 : ReceiveLedValue(3); // LED 4 break ; case R.id.RB05 : ReceiveLedValue(4); // ALL ON break ; case R.id.RB06 : ReceiveLedValue(5); // ALL OFF break ; } } public native String RecieveLedValue(int x); static { System.loadLibrary("led-jni"); }

}

29

Page 30: 자바  네이티브  인터페이스

- 30 -Huins. R&D Center

NDK / Java Native Interface

JNI 컴파일 스크립트 및 JNI 코드 작성 (LedJniExampleActivity.java.xml)

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := led-JNI LOCAL_SRC_FILES := led-JNI.c LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog

include $(BUILD_SHARED_LIBRARY)

#include <string.h>#include <jni.h>#include <android/log.h>#include <fcntl.h>

void led_main (int x) { int fd = -1; unsigned char val[ ] = {0x70, 0xB0, 0xD0, 0xE0, 0x00, 0xF0};

fd = open("/dev/led_driver", O_RDWR); if (fd < 0) { __android_log_print(ANDROID_LOG_INFO, "Device Open Error", "Driver = %d", x); } else { __android_log_print(ANDROID_LOG_INFO, "Device Open Success", "Driver = %d", x); write (fd, &val[x], sizeof(unsigned char)); } close(fd);}

jstring Java_achro4_huins_ex1_LedJniExampleActivity_ReceiveLedValue( JNIEnv* env,jobject thiz, jint val ) { __android_log_print(ANDROID_LOG_INFO, "LedJniExample", "led value = %d", val); led_main(val);}

jstring Java_com_huins_ledJNI_LedJNI_RecieveLedValue( JNIEnv* env,jobject

thiz, jint val)

<1> <2> <3> <4> <5> <6>

<7>

<1> jstring : 리턴 타입으로서 자바 언어의 String 에 해당한다 .

ex) jbyte -> byte, jshort -> short, jint -> int, void -> void, jobject ->

자바객체 등

<2> Java : 접두사

<3> com_huins_ledJNI : 패키지명

<4> LedJNI : 클래스명

<5> RecieveLedValue : 함수명

<6> JNIEnv *, Jobject thiz : 공통 파라메타

<7> jint val : 함수에 전달할 파라메타

30

Page 31: 자바  네이티브  인터페이스

- 31 -Huins. R&D Center

NDK / Java Native Interface

작성된 JNI 소스 컴파일- 작성된 jni 소스가 있는 디렉터리로 이동하여 컴파일

생성된 라이브러리 확인

경과 확인

# ndk-build

# ls ../libs/armeabi

# adb shell# insmod led_driver.ko# mknod /dev/led_driver c 240 0

31

Page 32: 자바  네이티브  인터페이스

- 32 -Huins. R&D Center

NDK / Java Native Interface

프로그램 실행- 메뉴 > RUN > RUN 을 선택하여 Achro-4210 에 전송하고 실행

# ndk-build

32

Page 33: 자바  네이티브  인터페이스

- 33 -Huins. R&D Center

Internal Device Control Application

안드로이드와 리눅스에서 디바이스를 제어하기 위한 전체 경로

Page 34: 자바  네이티브  인터페이스

- 34 -Huins. R&D Center

7-Segment Driver LED 회로 분석

34

LED 회로 구성 핀 연결

CPU I/O

NDK / Java Native Interface

Page 35: 자바  네이티브  인터페이스

- 35 -Huins. R&D Center

NDK / Java Native Interface

회로 정리 7Segment( 이하 FND) 를 제어하기 위해서는 CPU 의 GPIO 를 이용하여 제어 FND 에 공급되는 전원은 ANODE FND_A ~ FND_DP 의 핀이 0(Low) 이 되어야 FND 의 각 요소가 점등 FND Digit 선택

각 FND 의 구성 핀

35

연번 순서 PIN NAME CPU/IO 계산값

1 FND1 LCD_B_VD15 GPE3_1 0x02

2 FND2 LCD_B_VD16 GPE3_2 0x04

3 FND3 LCD_B_VD18 GPE3_4 0x10

4 FND4 LCD_B_VD21 GPE3_7 0x80

연번 순서 PIN NAME CPU/IO

1 FND A GPS_GPIO_7 GPL2_7

2 FND B GPS_GPIO_6 GPL2_6

3 FND C GPS_GPIO_5 GPL2_5

4 FND D GPS_GPIO_4 GPL2_4

5 FND E GPS_GPIO_3 GPL2_3

6 FND F GPS_GPIO_2 GPL2_2

7 FND G GPS_GPIO_1 GPL2_1

8 FND DP GPS_GPIO_0 GPL2_0

Page 36: 자바  네이티브  인터페이스

- 36 -Huins. R&D Center

NDK / Java Native Interface

FND 점등 위치

숫자테이블

36

FND 숫자 점등 위치레지스터 값

계산값A B C D E F G P

0 A B C D E F 0 0 0 0 0 0 1 1 0x02

1 B C 1 0 0 1 1 1 1 1 0x9F

2 A B D G E 0 0 1 0 0 1 0 1 0x25

3 A B C D G 0 0 0 0 1 1 0 1 0x0D

4 B C F G 1 0 0 1 1 0 0 1 0x99

5 A C D F G 0 1 0 0 1 0 0 1 0x49

6 C D E F G 1 1 0 0 0 0 0 1 0xC1

7 A B C 0 0 0 1 1 1 1 1 0x1F

8 A B C D E F G 0 0 0 0 0 0 0 1 0x01

9 A B C D F G 0 0 0 0 1 0 0 1 0x09

DP P 1 1 1 1 1 1 1 0 0xFE

BLANK 1 1 1 1 1 1 1 1 0xFF

Page 37: 자바  네이티브  인터페이스

- 37 -Huins. R&D Center

Internal Device Driver

FND Driver fnd_driver.c

장치관련 선언부 및 사용할 레지스터 주소 설정

File Operation Structure

37

// … 생략 ) …#include <linux/module.h>#include <linux/fs.h>#include <linux/init.h>#include <linux/version.h>

#define FND_MAJOR 241 // fnd device minor number#define FND_MINOR 0 // fnd device minor number#define FND_NAME "fnd_device" // fnd device name

#define FND_GPL2CON 0x11000100 // Pin Configuration#define FND_GPL2DAT 0x11000104 // Pin Data

static struct file_operations fnd_fops = { .open = fnd_open, .write = fnd_write, .release = fnd_release,};

Page 38: 자바  네이티브  인터페이스

- 38 -Huins. R&D Center

NDK / Java Native Interface

fnd_open()

fnd_release()

38

int fnd_open(struct inode *minode, struct file *mfile) { if(fnd_usage != 0) return -EBUSY; fnd_usage = 1; return 0;}

int fnd_release(struct inode *minode, struct file *mfile) { fnd_usage = 0; return 0;}

Page 39: 자바  네이티브  인터페이스

- 39 -Huins. R&D Center

NDK / Java Native Interface

fnd_write()

39

ssize_t fnd_write(struct file *inode, const short *gdata, size_t length, loff_t *off_what) { // ... 생략 if (copy_from_user(&fnd_buff, tmp, length)) return -EFAULT;

printk("DATA : %d\n",fnd_buff); outw (fnd_buff, (unsigned int)fnd_data); return length;}

Page 40: 자바  네이티브  인터페이스

- 40 -Huins. R&D Center

NDK / Java Native Interface

fnd_init(void)

40

int __init fnd_init(void) { int result;

result = register_chrdev(FND_MAJOR, FND_NAME, &fnd_fops); if(result <0) { // ...( 오류처리 )... }

fnd_data = ioremap(FND_GPL2DAT, 0x01); if(fnd_data==NULL) { // ...( 오류처리 )... }

fnd_ctrl = ioremap(FND_GPL2CON, 0x04); fnd_ctrl2 = ioremap(FND_GPE3CON, 0x04); if(fnd_ctrl==NULL) { // ...( 오류처리 )... } else { outl(0x11111111,(unsigned int)fnd_ctrl); outl(0x10010110,(unsigned int)fnd_ctrl2); } printk("init module, /dev/fnd_driver major : %d\n", FND_MAJOR);

outb(0xFF, (unsigned int)fnd_data);

return 0;}

Page 41: 자바  네이티브  인터페이스

- 41 -Huins. R&D Center

NDK / Java Native Interface

모듈 관련 등록 수행 함수 및 라이선스 지정

41

module_init(fnd_init);module_exit(fnd_exit);

MODULE_LICENSE ("GPL");MODULE_AUTHOR ("Huins HSH");

Page 42: 자바  네이티브  인터페이스

- 42 -Huins. R&D Center

NDK / Java Native Interface

42

// … 생략 …#define FND0 0x00#define FND1 0x01// … 생략 …#define FND8 0x08#define FND9 0x09#define FNDP 0x0A // DP#define FNDA 0x0B // ALL#define FNDX 0x0C // ALL OFF

int main(int argc, char **argv) { int fnd_fd; // … 생략… if(argc != 3) { // 장치를 열수 없을 때 오류처리 }

fnd_fd = open("/dev/fnd_device", O_WRONLY); if (fnd_fd<0) { // 장치를 열수 없는 경우 } get_fndnumber=(char)atoi(argv[1]); switch(get_fndnumber) { case 0 : set_fndvalue = 0x96; break; // … 생략 … case 4 : set_fndvalue = 0x80; break; }

Page 43: 자바  네이티브  인터페이스

- 43 -

타이머 인터럽트 : 주기적으로 인터럽트를 발생시켜 반복해서 처리해야 할 작업에 사용

타이머 인터럽트는 HZ( 아키텍처에 의존적인 값 ) 로 설정 타이머 인터럽트가 발생하면 스케줄러에 의해 새로운 작업을

스케줄하고 jiffies( 운영체제가 부팅된 시점부터 발생한 클록 회수 ) 값을 증가

커널 타이머를 사용해 특정 작업을 정해진 시간에 실행 “jiffies timer->expires” ≧ 조건을 만족할 때 타이머에 등록한 함수를

실행 expires 는 jiffies 와 타이머 간격을 합한 값

커널 타이머

Page 44: 자바  네이티브  인터페이스

- 44 -

커널 타이머의 사용법