자바 네이티브 인터페이스
DESCRIPTION
NDK / Java Native Interface. 자바 네이티브 인터페이스. NDK / Java Native Interface. ACHRO4210 의 디바이스 안드로이드에서 사용되는 대표적인 디바이스 LCD, Touch, Keypad, Wifi , Bluetooth, audio,… - 커널에서는 각 드라이버를 해당 플랫폼 드라이버로 등록 그외의 일반적이지 않은 디바이스 보통의 안드로이드 기기에서 사용하지 않는 장치 - PowerPoint PPT PresentationTRANSCRIPT
- 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 WiFiBluetooth Touch
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 다운로드
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
- 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
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
- 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
- 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
- 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
- 13 -Huins. R&D Center
NDK / Java Native Interface
Linux 구조- 안드로이드의 JNI 는 드라이버를 처리 하거나 복잡한 메모리 연산부분에 대해서 커널을 이용하는 방법이용한다 .
13
- 14 -Huins. R&D Center
NDK / Java Native Interface
Linux Device Driver- 커널을 통해 디바이스를 제어하기 위해 사용되는 소프트웨어- 커널은 주번호와 부번호를 통해 등록된 디바이스와 연결- 리눅스의 모든 하드웨어 장치들은 파일로 관리 (/dev)
디바이스 드라이버와 커널
14
- 15 -Huins. R&D Center
NDK / Java Native Interface
디바이스 드라이버와 어플리케이션간의 통신
15
- 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
- 17 -Huins. R&D Center
NDK / Java Native Interface
LED 드라이버 회로
Exynos4210 CPU
17
- 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
- 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
- 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;
}
- 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");
}
- 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;}
- 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; // 프로그램을 종료 .
}
- 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
- 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
- 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
- 27 -Huins. R&D Center
NDK / Java Native Interface
LedJNI Example Project 생성
27
- 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
- 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
- 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
- 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
- 32 -Huins. R&D Center
NDK / Java Native Interface
프로그램 실행- 메뉴 > RUN > RUN 을 선택하여 Achro-4210 에 전송하고 실행
# ndk-build
32
- 33 -Huins. R&D Center
Internal Device Control Application
안드로이드와 리눅스에서 디바이스를 제어하기 위한 전체 경로
- 34 -Huins. R&D Center
7-Segment Driver LED 회로 분석
34
LED 회로 구성 핀 연결
CPU I/O
NDK / Java Native Interface
- 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
- 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
- 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,};
- 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;}
- 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;}
- 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;}
- 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");
- 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; }
- 43 -
타이머 인터럽트 : 주기적으로 인터럽트를 발생시켜 반복해서 처리해야 할 작업에 사용
타이머 인터럽트는 HZ( 아키텍처에 의존적인 값 ) 로 설정 타이머 인터럽트가 발생하면 스케줄러에 의해 새로운 작업을
스케줄하고 jiffies( 운영체제가 부팅된 시점부터 발생한 클록 회수 ) 값을 증가
커널 타이머를 사용해 특정 작업을 정해진 시간에 실행 “jiffies timer->expires” ≧ 조건을 만족할 때 타이머에 등록한 함수를
실행 expires 는 jiffies 와 타이머 간격을 합한 값
커널 타이머
- 44 -
커널 타이머의 사용법