- 1 - 자바 네이티브 인터페이스 NDK / Java Native Interface
- 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 WiFi BluetoothTouch 2
- 3 - Huins. R&D Center NDK / Java Native Interface Java Native Interface JNI 개요 - Java 는 순수 소프트웨어 툴 - 하드웨어 의존적인 코드와 속도향상을 위해 Device 를 제어할 필요가 있는경우 이용 - C 와 C++ 로 작성 - 구글에서 제공하는 NDK(Native DK) 툴을 이용 안드로이드 플래폼 구조 3
- 4 - Huins. R&D Center NDK / Java Native Interface JNI JVM 에서 돌아가는 Java 코드와 C/C++ 로 구현된 코드가 상호참조하 기 위해 사용하는 programming framework Platform-dependent 한 라이브러리를 사용하고자 할 때, 혹은 기존의 프로그램을 Java 에서 접근가능하도록 변경하고자 할 때 쓰임 4
- 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
- 6 - Huins. R&D Center NDK / Java Native Interface 언제 Android NDK 를 쓸 것인가 ? 단지 C, C++ 을 더 쓰고 싶어서라면 쓰지말것.. NDK 사용의 단점을 뛰어넘는 장점이 있을때만 사용할 것 응용 개발의 복잡성이 증가하며, 디버깅이 어려움 그리고, C, C++ 을 사용한다고 해서 항상 성능이 빨라지는 것도 아님 6
- 7 - Huins. R&D Center NDK / Java Native Interface NDK 설치 - jni 파일을 컴파일하여 so 파일로 컴파일 하는 툴과 예제를 포함한 개발 킷 NDK 다운로드 android-ndk-r9b-linux-x86.tar.bz2 다운로드 android-ndk-r9b-linux-x86.tar.bz2 from or 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/mydroidandroid-ndk-r9b-linux-x86.tar.bz2 NDK 패스 설정 # cd /root # vim.bashrc … # NDK Path export PATH=/work/mydroid/android-ndk-r8b:$PATH 7
- 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
- 9 - Huins. R&D Center NDK / Java Native Interface 9
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 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
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-jni LOCAL_SRC_FILES := hello-jni.c LOCAL_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
Huins. R&D Center NDK / Java Native Interface Shared library 의 명명 규칙 1. ‘lib’prefix ’.so’suffix 의 형식 2. 이 ‘hello-jni’ 라면, 최종 파일은 ‘libhello-jni.so’ 생성된 라이브러리 위치 Shared library 는 프로젝트의 적절한 경로에 복사되고, 최종 ‘.apk’ 파일에 포함 최종 파일은 project\libs\armeabi 의 경로에 libhello-jni.so 파일로 생성 12
Huins. R&D Center NDK / Java Native Interface Linux 구조 - 안드로이드의 JNI 는 드라이버를 처리 하거나 복잡한 메모리 연산부분에 대해서 커널을 이용하는 방법이용한다. 13
Huins. R&D Center NDK / Java Native Interface Linux Device Driver - 커널을 통해 디바이스를 제어하기 위해 사용되는 소프트웨어 - 커널은 주번호와 부번호를 통해 등록된 디바이스와 연결 - 리눅스의 모든 하드웨어 장치들은 파일로 관리 (/dev) 디바이스 드라이버와 커널 14
Huins. R&D Center NDK / Java Native Interface 디바이스 드라이버와 어플리케이션간의 통신 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 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
Huins. R&D Center NDK / Java Native Interface LED 드라이버 회로 Exynos4210 CPU 17
Huins. R&D Center NDK / Java Native Interface LED 드라이버 회로 설명 - CPU 의 GPIO 핀과 LED 가 연결되어있음 - LED 에는 VDD 를 통해 전원이 공급되고 있음 - CPU 의 핀이 LOW(0) 가 되면 LED 가 점등. LED Driver Souce 연번순서 PIN NAMECPU/IO 1LED 0SPI_1.MOSIGPB7 2LED 1SPI_1.MISOGPB6 3LED 2SPI_1.NSSGPB5 4LED 3SPI_1.CLKGPB4 /* LED Ioremap Control FILE : led_driver.c */ // 헤더 선언부 #define LED_MAJOR 240 // 디바이스 드라이버의 주번호 #define LED_MINOR 0 // 디바이스 드라이버의 부번호 #define LED_NAME "led_driver" // 디바이스 드라이버의 이름 #define LED_GPBCON 0x // GPBCON 레지스터의 물리주소 #define LED_GPBDAT 0x // 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
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|=(0x ); 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
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; }
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"); }
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|=(0x ); 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; }
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; // 프로그램을 종료. }
Huins. R&D Center NDK / Java Native Interface LED Driver 컴파일 스크립트 (Makefile) # This is simple Makefile obj-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
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 <-- Target Board 명령창 # insmod /led_driver.ko <--- Target Board 명령창 # exit <--- Target Board 명령창 (Target Board 의 명령창을 빠져나간다.) 25
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
Huins. R&D Center NDK / Java Native Interface LedJNI Example Project 생성 27
Huins. R&D Center NDK / Java Native Interface UI 작성 (main.xml) <LinearLayout xmlns: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" <RadioGroup android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <RadioButton android:text="1" android:layout_width="wrap_content" android:layout_height="wrap_content"> <RadioButton android:text="2" android:layout_width="wrap_content" android:layout_height="wrap_content"> <RadioButton android:text="3" android:layout_width="wrap_content" android:layout_height="wrap_content"> <RadioButton android:text="4" android:layout_width="wrap_content" android:layout_height="wrap_content"> <RadioButton android:text="5" android:layout_width="wrap_content" android:layout_height="wrap_content"> <RadioButton android:text="6" android:layout_width="wrap_content android:layout_height="wrap_content"> <RadioButton android:text="7" android:layout_width="wrap_content" android:layout_height="wrap_content"> <RadioButton android:text="8" android:layout_width="wrap_content" android:layout_height="wrap_content"> 28
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 public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mRadioGroup = (RadioGroup)findViewById(R.id.RadioGroup01); mRadioGroup.setOnCheckedChangeListener(this); public 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
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 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_Receive LedValue( 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) jstring : 리턴 타입으로서 자바 언어의 String 에 해당한다. ex) jbyte -> byte, jshort -> short, jint -> int, void -> void, jobject -> 자바객체 등 Java : 접두사 com_huins_ledJNI : 패키지명 LedJNI : 클래스명 RecieveLedValue : 함수명 JNIEnv *, Jobject thiz : 공통 파라메타 jint val : 함수에 전달할 파라메타 30
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
Huins. R&D Center NDK / Java Native Interface 프로그램 실행 - 메뉴 > RUN > RUN 을 선택하여 Achro-4210 에 전송하고 실행 # ndk-build 32
Huins. R&D Center Internal Device Control Application 안드로이드와 리눅스에서 디바이스를 제어하기 위한 전체 경로
Huins. R&D Center 7-Segment Driver LED 회로 분석 34 LED 회로 구성핀 연결 CPU I/O NDK / Java Native Interface
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 NAMECPU/IO 계산값 1FND1LCD_B_VD15GPE3_10x02 2FND2LCD_B_VD16GPE3_20x04 3FND3LCD_B_VD18GPE3_40x10 4FND4LCD_B_VD21GPE3_70x80 연번순서 PIN NAMECPU/IO 1FND AGPS_GPIO_7GPL2_7 2FND BGPS_GPIO_6GPL2_6 3FND CGPS_GPIO_5GPL2_5 4FND DGPS_GPIO_4GPL2_4 5FND EGPS_GPIO_3GPL2_3 6FND FGPS_GPIO_2GPL2_2 7FND GGPS_GPIO_1GPL2_1 8FND DPGPS_GPIO_0GPL2_0
Huins. R&D Center NDK / Java Native Interface FND 점등 위치 숫자테이블 36 FND 숫자점등 위치 레지스터 값 계산값 ABCDEFGP 0A B C D E F x02 1B C x9F 2A B D G E x25 3A B C D G x0D 4B C F G x99 5A C D F G x49 6C D E F G xC1 7A B C x1F 8A B C D E F G x01 9A B C D F G x09 DPP xFE BLANK xFF
Huins. R&D Center Internal Device Driver FND Driver fnd_driver.c 장치관련 선언부 및 사용할 레지스터 주소 설정 File Operation Structure 37 // … 생략 ) … #include #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 0x // Pin Configuration #define FND_GPL2DAT 0x // Pin Data static struct file_operations fnd_fops = {.open = fnd_open,.write = fnd_write,.release = fnd_release, };
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; }
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; }
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(0x ,(unsigned int)fnd_ctrl); outl(0x ,(unsigned int)fnd_ctrl2); } printk("init module, /dev/fnd_driver major : %d\n", FND_MAJOR); outb(0xFF, (unsigned int)fnd_data); return 0; }
Huins. R&D Center NDK / Java Native Interface 모듈 관련 등록 수행 함수 및 라이선스 지정 41 module_init(fnd_init); module_exit(fnd_exit); MODULE_LICENSE ("GPL"); MODULE_AUTHOR ("Huins HSH");
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; }
타이머 인터럽트 : 주기적으로 인터럽트를 발생시켜 반복해서 처리해야 할 작업에 사용 타이머 인터럽트는 HZ( 아키텍처에 의존적인 값 ) 로 설정 타이머 인터럽트가 발생하면 스케줄러에 의해 새로운 작업을 스케줄하 고 jiffies( 운영체제가 부팅된 시점부터 발생한 클록 회수 ) 값을 증가 커널 타이머를 사용해 특정 작업을 정해진 시간에 실행 “jiffies ≧ timer->expires” 조건을 만족할 때 타이머에 등록한 함수를 실 행 expires 는 jiffies 와 타이머 간격을 합한 값 커널 타이머
커널 타이머의 사용법