You are on page 1of 101

㈜한백전자 교육사업부

안드로이드 기반 리눅스 디바이스 드라이버 제작

-한백전자-

본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.


LED DEVICE DRIVER

2
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
LED– 디바이스 드라이버 핀 할당

3
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
LED– 디바이스 드라이버
• LED 드라이버를 작성하기 위해 다음과 같이 프로젝트를 생성

구분 내용
Project name m2_led
Toolchains Other tool chain
Driver File Name m2_led

4
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
LED 디바이스 드라이버 소스 코드: m2_led.c

001: #include <linux/miscdevice.h>


002: #include <asm/uaccess.h>
003: #include <linux/init.h>
004: #include <linux/module.h>
005: #include <linux/kernel.h>
006: #include <linux/fs.h>
007: #include <linux/types.h>
008: #include <linux/ioport.h>
009: #include <mach/gpio.h>
010: #include <plat/gpio-cfg.h>
011:
012: #define DRIVER_AUTHOR "hanback"
013: #define DRIVER_DESC "Led program"
014:
015: #define LED_NAME "m2_led"
016: #define LED_MODULE_VERSION "LED V1.0"
017:
018: static int m2_led_open(struct inode * inode, struct file * file){
019: int err,i;
020:

5
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
LED 디바이스 드라이버 소스 코드: m2_led.c

021: for (i=0; i<7; i++)


022: {
023: err = gpio_request(EXYNOS4_GPK3(i), "Led");
024:
025: if (err)
026: printk("led.c failed to request GPK3(%d) \n",i);
027:
028: s3c_gpio_setpull(EXYNOS4_GPK3(i), S3C_GPIO_PULL_NONE);
029: gpio_direction_output(EXYNOS4_GPK3(i), 0);
030: }

032: return 0;
033: }
034:
035: static int m2_led_release(struct inode * inode, struct file * file){
036: int i;
037: for (i=0; i<7; i++)
038: gpio_free(EXYNOS4_GPK3(i));
039:
040: return 0;

6
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
LED 디바이스 드라이버 소스 코드: m2_led.c

041: }
042:
043: static ssize_t m2_led_read(struct file * file, char * buf, size_t length, loff_t *
ofs){
044: printk("m2_led_read, \n");
045:
046: return 0;
047: }
048:
049: static ssize_t m2_led_write(struct file * file, const char * buf, size_t length,
loff_t * ofs){
050: int ret;
051: unsigned char cbuf[8];
052: ret = copy_from_user(cbuf,buf,length);
053:
054: gpio_direction_output(EXYNOS4_GPK3(0), (unsigned int) cbuf[0]);
055: gpio_direction_output(EXYNOS4_GPK3(1), (unsigned int) cbuf[1]);
056: gpio_direction_output(EXYNOS4_GPK3(2), (unsigned int) cbuf[2]);
057: gpio_direction_output(EXYNOS4_GPK3(3), (unsigned int) cbuf[3]);
058: gpio_direction_output(EXYNOS4_GPK3(4), (unsigned int) cbuf[4]);
059: gpio_direction_output(EXYNOS4_GPK3(5), (unsigned int) cbuf[5]);
060: gpio_direction_output(EXYNOS4_GPK3(6), (unsigned int) cbuf[6]);

7
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
LED 디바이스 드라이버 소스 코드: m2_led.c

062: return length;


063: }
064:
065: static DEFINE_MUTEX(m2_led_mutex);
066: static long m2_led_ioctl(struct inode *inode, unsigned char cmd[], size_t length,
loff_t *off_what){
067: gpio_direction_output(EXYNOS4_GPK3(0), (unsigned int) cmd[0]);
068: gpio_direction_output(EXYNOS4_GPK3(1), (unsigned int) cmd[1]);
069: gpio_direction_output(EXYNOS4_GPK3(2), (unsigned int) cmd[2]);
070: gpio_direction_output(EXYNOS4_GPK3(3), (unsigned int) cmd[3]);
071: gpio_direction_output(EXYNOS4_GPK3(4), (unsigned int) cmd[4]);
072: gpio_direction_output(EXYNOS4_GPK3(5), (unsigned int) cmd[5]);
073: gpio_direction_output(EXYNOS4_GPK3(6), (unsigned int) cmd[6]);
074:
075: return 0;
076: }
077:
078: static struct file_operations m2_led_fops = {
079: .owner = THIS_MODULE,
080: .open = m2_led_open,

8
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
LED 디바이스 드라이버 소스 코드: m2_led.c

081: .unlocked_ioctl = m2_led_ioctl,


082: .write = m2_led_write,
083: .release = m2_led_release,
084: };
085:
086: static struct miscdevice m2_led_driver = {
087: .fops = &m2_led_fops,
088: .name = LED_NAME,
089: .minor = MISC_DYNAMIC_MINOR,
090: };

092: static int m2_led_init(void){


093: printk("driver: %s DRIVER INIT\n",LED_NAME);
094: return misc_register(&m2_led_driver);
095: }
096:
097: static void m2_led_exit(void){
098: misc_deregister(&m2_led_driver);
099: printk("driver: %s DRIVER EXIT\n",LED_NAME);
100: }

9
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
LED 디바이스 드라이버 소스 코드: m2_led.c

101:
102: module_init(m2_led_init);
103: module_exit(m2_led_exit);
104:
105: MODULE_AUTHOR(DRIVER_AUTHOR);
106: MODULE_DESCRIPTION(DRIVER_DESC);
107: MODULE_LICENSE("Dual BSD/GPL");

10
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
LED– 테스트 코드 구성
• LED 테스트 코드를 작성하기 위하여 다음과 같이 프로젝트를 생성

구분 내용
Project name m2_led_test
Toolchains Android GCC
C File Name m2_led_test

11
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
LED 테스트 코드 소스 코드: m2_led_test.c

001: #include <stdio.h>


002: #include <stdlib.h>
003: #include <unistd.h>
004: #include <sys/types.h>
005: #include <sys/stat.h>
006: #include <fcntl.h>
007:
008: int main(int argc, char * argv[]) {
009: int dev,i;
010: char temp,buf[8]={0};
011: unsigned char t = 0;
012:
013: if(argc <= 1) {
014: printf("please input the parameter! ex)./test 0xff\n");
015: return -1;
016: }
017:
018: dev = open("/dev/m2_led", O_WRONLY);
019:
020: if (dev != -1) {

12
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
LED 테스트 코드 소스 코드: m2_led_test.c

021: if(argv[1][0] == ‘0’ && (argv[1][1] == ‘x’ || argv[1][1] == ‘X’))


022: {
023: temp = (unsigned short)strtol(&argv[1][2],NULL,16);
024: }
025: else
026: {
027: temp = atoi(argv[1]);
028: }

030: for(i=0;i<7;i++)
031: {
032: t<<=1;
033: if((temp>>i) & 1)
034: buf[i] = 1;
035: }
036: }
037: else {
038: printf( "Device Open ERROR!\n");
039: return -1;
040: }
041:
042: write(dev,buf,7);
043: close(dev);
044:
045: return 0;
046: }

13
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
LED– 테스트 코드 실행
• 프로젝트를 빌드하면, 실행파일은 “/data/local/tmp” 폴더 내에
복사가 완료

• AndroX Studio의 “Remote Shell”을 실행하여 HBE-SM7-S4412


에 접속하고, 아래의 명령어를 입력하여 실행 파일을 실행

> cd /data/local/tmp
> ./m2_led_test

14
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
LED– 테스트 코드 실행 결과
• 다음과 같이 프로그램을 실행하면서 인자에 값을 입력하면 HBE-
SM7-S4412 M2 모듈의 LED가 점등되는 것이 확인 가능

• 0x00~0x7F까지 입력 가능

• 0x2F를 입력하면 아래와 같이 LED가 점등됨

15
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JNI 프로그래밍 실습

16
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JNI란?

• Java Native Interface


– 다른 언어로 작성된 프로그램을 자바에서 실행할 수 있게 연결해주는
인터페이스

• JNI 용도
– Code Reusability
– Performance(speed)
– H/W dependent Code

17
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JNI란?

• Java 환경에서의 C사용 절차


– 1단계 :
Native Method를 선언하는 자바 클래스 작성(Wrapper)
– 2단계 :
자바 Main 코드 작성
– 3단계 :
작성한 클래스 컴파일
– 4단계 :
javah를 사용해서 Native Method가 사용할 헤더파일 생성
– 5단계 :
C언어로 Native Method 실제 구현
– 6단계 :
C로 구현된 Native Method 컴파일
– à공유라이브러리 만들기
– 7단계 : 자바 프로그램 실행

18
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
Greeting 예제

• [목표]
– 리눅스 환경에서 JNI를 사용하는 방법 및 절차를 이해한다.
– JNI C 함수 이름이 어떻게 만들어지는지 이해한다.
– JNI C 함수에서 자동으로 생성되는 인자 2개의 의미를 이해한다.
– C 공유라이브러리 만드는 명령어를 이해한다.

• JNI 실습은 PC 리눅스에서 진행


– VMWare 설치
– Ubuntu 리눅스 이미지(VMWare 용)
– 리눅스용 gcc tool-chain
– 리눅스용 JDK

19
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
Greeting 예제 ; 리눅스 명령어 모음

# cd /
# mkdir working
# cd working
# mkdir jni
# cd jni
# mkdir Greeting
# cd Greeting

# gedit Wrapper.java
# gedit Main.java
# javac Wrapper.java
# javac Main.java

# javah Wrapper
# ls // Wrapper.h 생성

# gedit greeting.c
# gcc –o libgreeting.so greeting.o –shared –I [jni.h 위치] –I [jni_md.h]
# ls // libgreeting.so 확인

# export LD_LIBRARY_PATH=.
# java Main

20
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
Greeting 예제 ; Wrapper.java

001: class Wrapper {


002: // static part.
003: static {
004: System.loadLibrary("greeting"); // libgreeting.so
005: }
006:
007: // native func. declaration
008: public native void print();
009: }

21
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
Greeting 예제 ; Main.java

001: class Main {


002: public static void main(String [] args) {
003: Wrapper wrapper = new Wrapper();
004: wrapper.print();
005: }
006: }
007:

22
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
Greeting 예제 ; greeting.c

001: #include <stdio.h>


002: #include "Wrapper.h"
003:
004: JNIEXPORT void JNICALL Java_Wrapper_print(JNIEnv *env, jobject obj)
005: {
006: printf("Hello, JNI!!!\n");
007: }
008:

23
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
Greeting 예제 ; 코드 설명

• Wrapper.java
– static 블록 + native 메소드 선언
– System.loadLibrary() 메소드를 사용하여 라이브러리를 로드함
• 라이브러리 이름 greeting ß libgreeting.so ; 앞의 lib와 마지막 .so를 뺀 가운데 이름!
– native 메소드
• [접근지정자] native [반환형] [메소드이름]([인자…]);
• ex) public native void print();

• Main.java
– native 메소드 호출
– Java에서는 객체를 통해서 메소드 호출 가능!
• Wrapper 클래스 타입입의 객체를 만들고 wrapper 객체를 통해서 print() 메소드 호출

24
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
Greeting 예제 ; 코드 설명

• greeting.c
– javah를 통해서 생성된 함수 이름 check!
• Java 키워드 + 패키지 + Wrapper클래스 + native 함수
– Java_[패키지]_[Wrapper클래스]_[native함수이름](JNIEnv *, jobject , …);
– ex) Java_Wrapper_print(); // 패키지 사용 X
– JNI 함수는 인자가 무조건 두개 추가!
• JNIEnv * ; JNI 에서 사용되는 함수 table을 가리키는 함수
– (*env)->XXX_function(env, …) 형식으로 함수 호출해서 사용함
• jobject ; native 함수를 호출한 객체 (java 언어의 this와 같음)

25
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniType 예제

• [목표]
– Java의 함수인자전달 방식과 C언어의 인자 전달 방식을 이해한다.
– Java 기본 타입 8가지가 C언어에서 어떤 타입으로 바뀌는지 이해한다.
– 객체 지향언어의 함수 중복(function-overloading)을 C언어에서는 어떻게 처리
하는지 이해한다.

• 인자전달 방식
– Java ; pass-by-value
– C ; call-by-value (; 자바와 개념적으로 똑같다!)
– cf) call-by-reference?

26
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniType 예제 ; Wrapper.java

001: class Wrapper {


002: static {
003: System.loadLibrary("jni_type"); //libjni_type.so
004: }
005:
006: public native void print(boolean b);
007: public native void print(char c);
008: public native void print(byte b, short s, int i, long l);
009: public native void print(float f, double d);
010: }
011:

27
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniType 예제 ; Main.java

001: class Wrapper {


002: static {
003: System.loadLibrary("jni_type"); //libjni_type.so
004: }
005:
006: public native void print(boolean b);
007: public native void print(char c);
008: public native void print(byte b, short s, int i, long l);
009: public native void print(float f, double d);
010: }
011:

28
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniType 예제 ; jni_type.c

001: #include <stdio.h>


002: #include "Wrapper.h"
003:
004: JNIEXPORT void JNICALL Java_Wrapper_print__Z(JNIEnv *env, jobject obj, jboolean b)
005: {
006: printf("boolean --> unsigned char : %s\n", (b) ? "true" : "false");
007: }
008:
009: JNIEXPORT void JNICALL Java_Wrapper_print__C(JNIEnv *env, jobject obj, jchar c)
010: {
011: printf("char --> unsigned short int : %c\n", (unsigned char)c);
012: }
013:
014: JNIEXPORT void JNICALL Java_Wrapper_print__BSIJ(JNIEnv *env, jobject obj,
015:
jbyte b, jshort s, jint i, jlong l)
016: {
017: printf("byte --> signed char : %d\n", b);
018: printf("short --> short int : %d\n", s);
019: printf("int --> int : %d\n", i);
020: printf("long --> long long int : %lld\n", l);

29
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniType 예제 ; jni_type.c

021: }
022:
023: JNIEXPORT void JNICALL Java_Wrapper_print__FD(JNIEnv *env, jobject obj,
024: jfloat f, jdouble d)
025: {
026: printf("float --> float : %f\n", f);
027: printf("double --> double : %f\n", d);
028: }
029:
030:
031:

30
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniType 예제

• Java Primitive Type


– 논리형 boolean ; true/false 상수값을 가짐.
– 문자형 char ; java에서는 2byte 유니코드를 사용함
– 정수형 byte(8bit), short(16bit), int(32bit), long(64bit)
– 부동소수점형 float, double ; IEEE754

• <jni.h>, <jni_md.h> 내용 분석
Java 기본형 JNI type 실제 타입
boolean jboolean unsigned char

char jchar unsigned short int

byte jbyte signed char

short jshort short int

int jint int

long jlong long long int


float jfloat float
double jdouble double
31
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniType 예제

• 오버로딩 된 메소드의 구별
타입 시그니처 자바 타입
Z boolean
B byte
C char
S short
I int
J long
F float
D double
Lfully-qualified-class; Fully-qualified-class
[type Type[]
(arg-types) ret-type Method type

32
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniStr 예제

• [목표]
– Java 문자열과 C 문자열의 차이점을 이해한다.
– Java 문자열과 C 문자열을 변환하는 함수를 사용할 수 있다.

33
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniStr 예제

• 자바 유니코드 문자열 à C언어 문자열


– const char *c_str = (*env)->GetStringUTFChars(env, j_str, 0);

• 가상머신에게 C언어 문자열의 사용이 끝남을 알리고 메모리에서 자


원을 해지
– (*env)->ReleaseStringUTFChars(env, j_str, c_str);

• C언어 문자열 à 자바 유니코드 문자열


– jstring java_str = (*env)->NewStringUTF(env, c_str);

34
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniStr 예제 ; Wrapper.java

001: class Wrapper {


002: static {
003: System.loadLibrary("jni_str"); // libjni_str.so
004: }
005:
006: public native void print(String str);
007: public native String getString();
008: public native String addString(String s1, String s2);
009: }
010:

35
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniStr 예제 ; Main.java

001: class Main {


002: public static void main(String [] args) {
003: Wrapper wrapper = new Wrapper();
004:
005: wrapper.print("Hello, world");
006: String str = wrapper.getString();
007: System.out.println(str);
008:
009: System.out.println(wrapper.addString("Hello, ", "world"));
010: }
011: }
012:

36
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniStr 예제 ; jni_str.c

001: #include <stdio.h>


002: #include <stdlib.h>
003: #include <string.h>
004: #include "Wrapper.h"
005:
006: JNIEXPORT void JNICALL Java_Wrapper_print(JNIEnv *env, jobject obj, jstring str)
007: {
008: const char *pStr = (*env)->GetStringUTFChars(env, str, 0);
009: printf("%s\n", pStr);
010: (*env)->ReleaseStringUTFChars(env, str, pStr);
011: }
012:
013: JNIEXPORT jstring JNICALL Java_Wrapper_getString(JNIEnv *env, jobject obj)
014: {
015: return (*env)->NewStringUTF(env, "Wonderful world");
016: }
017:

37
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniStr 예제 ; jni_str.c

018: JNIEXPORT jstring JNICALL Java_Wrapper_addString(JNIEnv *env, jobject obj,


019: jstring s1, jstring s2)
020: {
021: jstring str;
022: const char *pStr1 = (*env)->GetStringUTFChars(env, s1, 0);
023: const char *pStr2 = (*env)->GetStringUTFChars(env, s2, 0);
024:
025: char *pStr = (char *)malloc(strlen(pStr1) + strlen(pStr2) + 1);
026: strcpy(pStr, pStr1);
027: strcat(pStr, pStr2);
028: str = (*env)->NewStringUTF(env, pStr);
029: free(pStr);
030: (*env)->ReleaseStringUTFChars(env, s1, pStr1);
031: (*env)->ReleaseStringUTFChars(env, s2, pStr2);
032:
033: return str;
034: }
035:

38
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniArr 예제

• [목표]
– Java 기본형 타입의 배열을 C언어에서 접근해서 사용할 수 있다.
– 배열을 인자로 받는 메소드가 함수 중복을 사용하는 경우를 처리할 수 있다.

39
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniArr 예제 ; Wrapper.java

001: class Wrapper {


002: static {
003: System.loadLibrary("jni_arr"); // libjni_arr.so
004: }
005:
006: public native int sum(int [] nums);
007: public native double sum(double [] nums);
008: }
009:

40
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniArr 예제 ; Main.java

001: class Main {


002: public static void main(String [] args) {
003: int [] nums1 = {10, 20, 30, 40, 50};
004: double [] nums2 = {1.0, 2.0, 3.0, 4.0, 5.0};
005:
006: Wrapper wrapper = new Wrapper();
007: System.out.println("int array sum : " + wrapper.sum(nums1));
008: System.out.println("double array sum : " + wrapper.sum(nums2));
009: }
010: }
011:

41
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniArr 예제 ; jni_arr.c

001: #include "Wrapper.h"


002:
003: JNIEXPORT jint JNICALL Java_Wrapper_sum___3I(JNIEnv *env, jobject obj, jintArray arr)
004: {
005: int i;
006: int sum = 0;
007:
008: int size = (*env)->GetArrayLength(env, arr);
009: int *pArr = (*env)->GetIntArrayElements(env, arr, 0);
010: for (i = 0; i < size; ++i)
011: sum += pArr[i];
012: (*env)->ReleaseIntArrayElements(env, arr, pArr, 0);
013:
014: return sum;
015: }
016:

42
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniArr 예제 ; jni_arr.c

017: JNIEXPORT jdouble JNICALL Java_Wrapper_sum___3D(JNIEnv *env, jobject obj, jdoubleArray arr)
018: {
019: int i;
020: double sum = 0.0;
021:
022: int size = (*env)->GetArrayLength(env, arr);
023: double *pArr = (*env)->GetDoubleArrayElements(env, arr, 0);
024: for (i = 0; i < size; ++i)
025: sum += pArr[i];
026: (*env)->ReleaseDoubleArrayElements(env, arr, pArr, 0);
027:
028: return sum;
029: }
030:

43
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniArr 예제 ; 코드 설명

• 배열을 인자로 전달
– int[] à jintArray
– double[] à jdoubleArray

• 배열의 크기 알아내기
– jint arrSize = (*env)->GetArrayLength(env, arr);

• 배열로 변환하기
– jint *pArr = (*env)->GetIntArrayElements(env, arr, 0);
– // C언어의 배열과 같이 for문으로 순차 접근 가능

• 배열 변환에 사용된 임시 메모리 영역 해제


– (*env)->ReleaseIntArrayElements(env, arr, pArr, 0);

44
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniArr 예제 ; 코드 설명

• 자바 타입과 JNI 타입 매칭표


자바 타입 JNI 타입
Java.lang.Object jobject
Java.lang.Class Jclass
Java.lang.String Jstring
Java array jarray
Object [] jobjectArray
boolean[] jbooleanArray
byte [] jbyteArray
char [] jcharArray
short [] JshortArray
int [] jintArray
long [] jlongArray
float [] jflortArray
double jdoubleArray
Java.lang.Throwable jthrowable

45
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniArr2 예제

• [목표]
– 클래스 타입의 배열을 C언어에서 다루는 방법을 이해한다.

46
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniArr2 예제 ; Wrapper.java

001: class Wrapper {


002: static {
003: System.loadLibrary("jni_arr2"); // libjni_arr2.so
004: }
005:
006: public native void print(String [] strs);
007: }
008:

47
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniArr2 예제 ; Main.java

001: class Main {


002: public static void main(String [] args) {
003: String [] strs = {
004: "Just the way you are",
005: "Wonderful tonight",
006: "Uptown girl",
007: "knocking on the heaven's door"
008: };
009:
010: Wrapper wrapper = new Wrapper();
011: wrapper.print(strs);
012: }
013: }
014:

48
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniArr2 예제 ; jni_arr2.c

001: #include <stdio.h>


002: #include "Wrapper.h"
003:
004: JNIEXPORT void JNICALL Java_Wrapper_print(JNIEnv *env, jobject obj, jobjectArray arr)
005: {
006: int i;
007: int size = (*env)->GetArrayLength(env, arr);
008:
009: for (i = 0; i < size; ++i)
010: {
011: jstring str = (*env)->GetObjectArrayElement(env, arr, i);
012: const char *pStr = (*env)->GetStringUTFChars(env, str, 0);
013:
014: printf("%s\n", pStr);
015: (*env)->ReleaseStringUTFChars(env, str, pStr);
016: }
017: }
018:

49
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniArr2 예제 ; 코드 설명

• String [] ; jobjectArray

• jobjectArray의 원소 String 값을 C언어 형식으로 변환


– jstring str = (jstring)(*env)->GetObjectArrayElement(env, objArr, i);

50
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniMem 예제

• [목표]
– 클래스 멤버변수/멤버함수 접근 방법을 이해한다.

51
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniMem 예제 ; Date.java

001: class Date {


002: private int year;
003: private int month;
004: private int day;
005:
006: public Date() {
007: // this.set(0, 0, 0);
008: this.year = this.month = this.day = 0;
009: }
010:
011: public Date(int year, int month, int day) {
012: this.set(year, month, day);
013: }
014:
015: public void set(int year, int month, int day) {
016: this.year = year;
017: this.month = month;
018: this.day = day;
019: }
020:
021: public String toString() {
022: // (yyyy/mm/dd)
023: String str = "(" + year + "/" + month + "/" + day + ")";
024:
025: return str;
026: }
027: }
028:

52
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniMem 예제 ; Wrapper.java

001: class Wrapper {


002: static {
003: System.loadLibrary("jni_mem"); // libjni_mem.so
004: }
005:
006: public native void print(Date d);
007: }
008:

53
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniMem 예제 ; Main.java

001: class Main {


002: public static void main(String [] args) {
003: Date birthday = new Date();
004: Date today = new Date(2013, 11, 8);
005:
006: birthday.set(2005, 8, 2);
007:
008: System.out.println("today : " + today.toString());
009: System.out.println("birthday : " + birthday.toString());
010:
011: Wrapper wrapper = new Wrapper();
012: wrapper.print(today);
013: wrapper.print(birthday);
014: }
015: }
016:

54
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniMem 예제 ; jni_mem.c

001: #include <stdio.h>


002: #include "Wrapper.h"
003:
004: JNIEXPORT void JNICALL Java_Wrapper_print(JNIEnv *env, jobject obj, jobject d)
005: {
006: jclass classType = (*env)->GetObjectClass(env, d);
007:
008: jmethodID toStringId = (*env)->GetMethodID(env, classType,
009:
"toString", "()Ljava/lang/String;");
010:
011: jstring str = (*env)->CallObjectMethod(env, d, toStringId);
012:
013: const char *pStr = (*env)->GetStringUTFChars(env, str, 0);
014: printf("%s\n", pStr);
015: (*env)->ReleaseStringUTFChars(env, str, pStr);
016: }
017:
018:

55
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniMem 예제 ; jni_mem.c

019: /*
020: JNIEXPORT void JNICALL Java_Wrapper_print(JNIEnv *env, jobject obj, jobject d)
021: {
022: jclass classType = (*env)->GetObjectClass(env, d);
023:
024: jfieldID yearId = (*env)->GetFieldID(env, classType, "year", "I");
025: jfieldID monthId = (*env)->GetFieldID(env, classType, "month", "I");
026: jfieldID dayId = (*env)->GetFieldID(env, classType, "day", "I");
027:
028: int year = (*env)->GetIntField(env, d, yearId);
029: int month = (*env)->GetIntField(env, d, monthId);
030: int day = (*env)->GetIntField(env, d, dayId);
031:
032: printf("(%d/%d/%d)\n", year, month, day);
033: }
034: */
035:

56
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniMem 예제 ; 코드 설명

• 멤버 접근하기
– 접근지정자 무시! Private 멤버도 접근가능!

• GetObjectClass()
– Jobject 타입의 인자를 받아, jclass 타입의 값을 반환

• GetFieldID()
– jclass 타입의 인자와, 변수명, 인자구성을 인자로 받아 jfieldID값을 반환
– ex) jfieldID yearId = (*env)->GetFieldID(env, classType, "year", "I");

• GetXXXField()
– XXX 위치에는 멤버변수의 타입을 적는다.
– ex) int year = (*env)->GetIntField(env, d, yearId);

57
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniMem 예제 ; 코드 설명

• GetObjectClass()
– Jobject 타입의 인자를 받아, jclass 타입의 값을 반환

• GetMethodID()
– jclass 타입의 인자와, 변수명, 시그너쳐를 인자로 받아 jmethodID값을 반환
– 시그너쳐 ; javap tool을 사용하면 편리하게 알 수 있음
– ex) jmethodID toStringId = (*env)->GetMethodID(env, classType,
– "toString", "()Ljava/lang/String;");

• CallXXXField()
– XXX 위치에는 메소드의 반환타입을 적는다.
– ex) jstring str = (*env)->CallObjectMethod(env, d, toStringId);

58
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniMem2 예제

• [목표]
– Has-a 관계의 클래스 멤버변수/멤버함수 접근 방법을 이해한다.

59
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniMem2 예제 ; Member.java

001: class Date {


002: private int year;
003: private int month;
004: private int day;
005:
006: public Date() {
007: // this.set(0, 0, 0);
008: this.year = this.month = this.day = 0;
009: }
010:
011: public Date(int year, int month, int day) {
012: this.set(year, month, day);
013: }
014:
015: public void set(int year, int month, int day) {
016: this.year = year;
017: this.month = month;
018: this.day = day;
019: }
020:
021: public String toString() {
022: // (yyyy/mm/dd)
023: String str = "(" + year + "/" + month + "/" + day + ")";
024:
025: return str;
026: }
027: }
028:

60
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniMem2 예제 ; Wrapper.java

001: class Wrapper {


002: static {
003: System.loadLibrary("jni_mem"); // libjni_mem.so
004: }
005:
006: public native void print(Member member);
007: }
008:

61
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniMem2 예제 ; Main.java

001: class Main {


002: public static void main(String [] args) {
003: Member member1 = new Member();
004: Member member2 = new Member("john", 20, new Date(2013, 11, 8));
005: member1.setName("jane");
006: member1.setAge(30);
007: member1.setRegisterDate(new Date(2000, 1, 1));
008:
009: System.out.println("member1 : " + member1.toString());
010: System.out.println("member2 : " + member2.toString());
011:
012: Wrapper wrapper = new Wrapper();
013: wrapper.print(member1);
014: wrapper.print(member2);
015: }
016: }
017:

62
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
JniMem2 예제 ; jni_mem.c

001: #include "Wrapper.h"


002:
003: JNIEXPORT void JNICALL Java_Wrapper_print(JNIEnv *env, jobject obj, jobject member)
004: {
005: jclass memberClass = (*env)->GetObjectClass(env, member);
006:
007: jfieldID nameId = (*env)->GetFieldID(env, memberClass, "name", "Ljava/lang/String;");
008: jfieldID ageId = (*env)->GetFieldID(env, memberClass, "age", "I");
009: jfieldID registerDateId =
010: (*env)->GetFieldID(env, memberClass, "registerDate", "LDate;");
011:
012: jstring name = (*env)->GetObjectField(env, member, nameId);
013: jint age = (*env)->GetIntField(env, member, ageId);
014: jobject registerDate = (*env)->GetObjectField(env, member, registerDateId);
015:
016: jclass dateClass = (*env)->GetObjectClass(env, registerDate);
017: jmethodID toStringId =
018: (*env)->GetMethodID(env, dateClass, "toString", "()Ljava/lang/String;");
019: jstring date = (*env)->CallObjectMethod(env, registerDate, toStringId);
020:
021: const char *pName = (*env)->GetStringUTFChars(env, name, 0);
022: const char *pDate = (*env)->GetStringUTFChars(env, date, 0);
023:
024: printf("(%s, %d, %s)\n", pName, age, pDate);
025:
026: (*env)->ReleaseStringUTFChars(env, name, pName);
027: (*env)->ReleaseStringUTFChars(env, date, pDate);
028: }
029:
63
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
디바이스 제어 안드로이드 앱 제작

64
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
LED 예제
• LED 프로그램을 작성하기 위해 다음과 같이 프로젝트를 생성

65
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
LED 예제
• 추가적으로 패키지와 클래스, 폴더, 파일을 생성

66
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
LED 예제 : uartjni 패키지
• 모든 프로젝트들은 동일하게 추가적으로 타깃과 디바이스 사이의 데
이터를 주고 받을 수 있는 Uart통신을 위한 패키지와 클래스, 파일을
생성하야함

• 추가 파일을 생성하는 방법은 우선 com.hbe.uartjni 패키지의


UartJNI 클래스를 등록하기 위해 “Package Explorer”에서 오른쪽
버튼을 클릭한 후, “New > Class”를 선택

67
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
LED 예제 : uartjni 패키지 + UartJNI.java
• 그림과 같은 창이 생성 되면, Package에 “com.hbe.uartjni”를 입력
하고, Name에 “UartJNI”를 입력

• 패키지 이름은 반드시 ‘com.hbe.uartjni’와 동일하게 입력

• 소스코드를 참고하여 UartJNI.java 작성

68
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
LED : UartJNI.java
001: package com.hbe.uartjni;
002:
003: import android.util.Log;
004:
005: public class UartJNI implements UartJNIListener {
006:
007: private boolean mConnectFlag;
008: private UartJNIListener mMainActivity;
009:
010: static {
011: System.loadLibrary("UartJNI");
012: }
013:
014: private native static int open(String path);
015: private native void close();
016: private native void setLED(char led);
017:
018: public UartJNI(){
019: mConnectFlag = false;
020: portOpen();

69
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
LED : UartJNI.java
021: }
022:
023: public void portOpen(){
024: if(mConnectFlag) return;
025:
026: int ret = open("/dev/m2_led");
027: if(ret==1){
028: mConnectFlag = true;
029: } else {
030: Log.d("sm7m2", "device connect failed");
031: }
032: }
033:
034: public void portClose(){
035: if(mConnectFlag==false) return;
036: mConnectFlag = false;
037: close();
038: }
039:
040: protected void finalize() throws Throwable{

70
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
LED : UartJNI.java

041: portClose();
042: super.finalize();
043: }
044:
045: @Override
046: public void onReceive(int val) {
047: if(mMainActivity!=null){
048: mMainActivity.onReceive(val);
049: }
050: }
051:
052: public void setListener(UartJNIListener a){
053: mMainActivity = a;
054: }
055:
056: public void setLED(int c1, int c2, int c3, int c4, int c5, int c6, int c7){
057: char ch = (char)((c1&1)<<6 | (c2&1)<<5 | (c3&1)<<4 |
(c4&1)<<3 | (c5&1)<<2 | (c6&1)<<1 | c7&1);
058: setLED(ch);
059: }

71
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
LED : UartJNI.java

061: public void setLED(int led){


062: if(led>=7) setLED(1,1,1,1,1,1,1);
063: else if(led>=6) setLED(1,1,1,1,1,1,0);
064: else if(led>=5) setLED(1,1,1,1,1,0,0);
065: else if(led>=4) setLED(1,1,1,1,0,0,0);
066: else if(led>=3) setLED(1,1,1,0,0,0,0);
067: else if(led>=2) setLED(1,1,0,0,0,0,0);
068: else if(led>=1) setLED(1,0,0,0,0,0,0);
069: else setLED(0,0,0,0,0,0,0);
070: }
071: }

72
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
소스코드 UartJNIListener.java

001: package com.hbe.uartjni;


002:
003: public interface UartJNIListener {
004: public void onReceive(int val);
005: }

73
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
LED 예제 : Uart 통신
• “External Tools > JNI Interface”를 선택 후 Library name은
“UartJNI”를 입력

74
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
LED 예제 : Uart통신
• Class path는 “com.hbe.uartjni.UartJNI”를 입력

• Package Explorer에 다음과 같이 jni 폴더와 UartJNI.c 파일이 생성


된 것을 확인. 소스코드를 참고하여 Android.mk 와 UartJNI.c 파일
작성

75
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
소스코드 UartJNI.c

001: #include <string.h>


002: #include <jni.h>
003: #include <stdio.h>
004: #include <stdlib.h>
005: #include <fcntl.h>
006: #include <unistd.h>
007: #include <termios.h>
008: #include <sys/mman.h>
009: #include <errno.h>
010:
011: int fd=0;
012:
013: JNIEXPORT jint JNICALL Java_com_hbe_uartjni_UartJNI_open(JNIEnv *env, jclass c,
jstring path){

014: jboolean iscopy;


015: const char *path_utf = (*env)->GetStringUTFChars(env, path, &iscopy);
016: fd = open(path_utf,O_WRONLY);
017: (*env)->ReleaseStringUTFChars(env, path, path_utf);
018:
019: if(fd<0) return 0;
020: else return 1;

76
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
소스코드 UartJNI.c

021: }
022:
023: JNIEXPORT void JNICALL Java_com_hbe_uartjni_UartJNI_close(JNIEnv *env, jobject o){
024: close(fd);
025: }
026:
027: JNIEXPORT void JNICALL Java_com_hbe_uartjni_UartJNI_setBuzzer(JNIEnv *env, jobject o,
jchar c){

028: int i=(int)c;


029: write(fd, &i, sizeof(i));
030: }

77
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
소스코드 Android.mk
001: # Copyright (C) 2009 The Android Open Source Project
002: #
003: # Licensed under the Apache License, Version 2.0 (the "License");
004: # you may not use this file except in compliance with the License.
005: # You may obtain a copy of the License at
006: #
007: # http://www.apache.org/licenses/LICENSE-2.0
008: #
009: # Unless required by applicable law or agreed to in writing, software
010: # distributed under the License is distributed on an "AS IS" BASIS,
011: # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: # See the License for the specific language governing permissions and
013: # limitations under the License.
014: #
015: LOCAL_PATH:= $(call my-dir)
016:
017: include $(CLEAR_VARS)
018:
019: LOCAL_MODULE := UartJNI
020: LOCAL_CFLAGS := -Werror
021: LOCAL_SRC_FILES := UartJNI.c
022:
023: include $(BUILD_SHARED_LIBRARY)

78
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
LED 예제 : Uart 공유라이브러리 생성
• JNI 라이브러리 컴파일
• 우측 상단의 “C/C++ Perspective”를 선택

• Project Explorer에서 변환하고자 하는 프로젝트를 선택하고,


“File > New > Convert to a C/C++ Project (Adds C/C++ Nature)”
를 선택

79
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
LED 예제
• Uart통신 및 LED 예제 클래스 완성

80
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
LED 예제 : 이미지 추가
• 이미지 파일 복사
• 앱을 구성하는 파일을 생성했다면, 앱에 포함되는 이미지를 복사

• 프로젝트에서 쓰이는 이미지 폴더는 “/res/drawable-xhdpi”폴더


외의 이미지 폴더는 모두 삭제

• 삭제해야 할 폴더는 다음과 같음(삭제하지 않아도 무관)

/res/drawable-hdpi
/res/drawable-ldpi
/res/drawable-mdpi

• 폴더 삭제를 완료하였다면, 준비한 이미지 파일을 프로젝트의


“/res/drawable-xhdpi” 폴더에 복사

81
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
LED 예제
• Setting Password에 불이 들어왔다면, 숫자 일곱 자리를 입력하여 암호
를 설정

• 숫자 하나를 입력할 때마다 M2 모듈의 LED가 하나씩 점등

• 모두 입력하면 Input Password에 불이 들어온다.

• Input Password에 불이 들어왔을 때 또 다시 일곱 자리 암호를 입력

• 숫자 하나를 입력할 때마다 M2 모듈의 LED가 하나씩 점등

• 입력된 일곱 자리 암호가 Setting Password 모드에서 입력된 암호와


동일하다면 M2 모듈의 LED가 오른쪽부터 차례대로 소등

• 암호가 틀렸다면 7개의 LED 전체가 깜빡임

• 암호를 다시 설정하고 싶다면 하단의 Initialize Password를 터치


82
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
소스코드 M2LEDActivity.java

001: package com.hbe.m2led;


002:
003: import com.hbe.uartjni.UartJNI;
004: import android.os.Bundle;
005: import android.os.Handler;
006: import android.os.Message;
007: import android.app.Activity;
008: import android.view.Menu;
009:
010: public class M2LEDActivity extends Activity {
011:
012: M2LEDView mCustomView;
013:
014: UartJNI mJniDriver;
015: int[] mArrSetPW = new int[7];
016: int[] mArrInputPW = new int[7];
017: int mPWPt = 0;
018: boolean mPWOk = false;
019: boolean mInputLock = false;
020:

83
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
소스코드 M2LEDActivity.java
021: private Handler mHandler = new Handler(){
022: @Override
023: public void handleMessage(Message msg){
024: super.handleMessage(msg);
025: if(mInputLock) return;
026: if(msg.what==' '){
027: initPW();
028: } else {
029: if(mPWOk) inputPW(msg.what);
030: else setPW(msg.what);
031: }
032: }
033: };
034:
035: @Override
036: protected void onCreate(Bundle savedInstanceState) {
037: super.onCreate(savedInstanceState);
038: setContentView(R.layout.main);
039:
040: mCustomView = (M2LEDView)findViewById(R.id.custom_view);

84
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
소스코드 M2LEDActivity.java

041: mJniDriver = new UartJNI();


042: }
043:
044: @Override
045: public boolean onCreateOptionsMenu(Menu menu) {
046: // Inflate the menu; this adds items to the action bar if it is present.
047: getMenuInflater().inflate(R.menu.main, menu);
048: return true;
049: }
050:
051: public void setMessage(Message msg){
052: mHandler.sendMessage(msg);
053: }
054:
055: @Override
056: protected void onPause() {
057: mJniDriver.portClose();
058: super.onPause();
059: }

85
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
소스코드 M2LEDActivity.java

061: @Override
062: protected void onResume() {
063: mJniDriver.portOpen();
064: super.onResume();
065: }
066:
067: private void inputPW(int p){
068: mArrInputPW[mPWPt++]=p;
069: mJniDriver.setLED(mPWPt);
070: if(mPWPt>=7){
071: for(int i=0;i<7;i++){
072: if(mArrInputPW[i]!=mArrSetPW[i]){
073: setFailureThread();
074: mPWPt = 0;
075: return;
076: }
077: }
078: setPassThread();
079: mPWPt = 0;
080: }

86
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
소스코드 M2LEDActivity.java
081: }
082:
083: private void setPW(int p){
084: mArrSetPW[mPWPt++] = p;
085: mJniDriver.setLED(mPWPt);
086: if(mPWPt>=7){
087: mPWOk = true;
088: mPWPt = 0;
089: mCustomView.setInputMode();
090: }
091: }

093: private void initPW(){


094: mPWOk = false;
095: mPWPt = 0;
096: mJniDriver.setLED(0);
097: mCustomView.setSettingMode();
098: }
099:
100: private void setPassThread(){

87
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
소스코드 M2LEDActivity.java

101: PassLED thread = new PassLED();


102: thread.start();
103: }
104:
105: private void setFailureThread(){
106: FailureLED thread = new FailureLED();
107: thread.start();
108: }
109:
110: private class PassLED extends Thread{
111: @Override
112: public void run() {
113: super.run();
114: mInputLock = true;
115: try {
116: for(int i=6;i>=0;i--){
117: Thread.sleep(100);
118: mJniDriver.setLED(i);
119: }
120: } catch (InterruptedException e) {

88
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
소스코드 M2LEDActivity.java

121: e.printStackTrace();
122: }
123: mInputLock = false;
124: }
125: }
126:
127: private class FailureLED extends Thread{
128: @Override
129: public void run() {
130: super.run();
131: mInputLock = true;
132: try {
133: for(int i=0;i<=3;i++){
134: Thread.sleep(200);
135: mJniDriver.setLED(7);
136: Thread.sleep(200);
137: mJniDriver.setLED(0);
138: }
139: } catch (InterruptedException e) {
140: e.printStackTrace();

89
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
소스코드 M2LEDActivity.java
141: }
142: mInputLock = false;
143: }
144: }
145:
146:
147:
148:
149: }

90
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
소스코드 M2LEDView.java

001: package com.hbe.m2led;


002:
003: import android.content.Context;
004: import android.content.res.Resources;
005: import android.graphics.Bitmap;
006: import android.graphics.BitmapFactory;
007: import android.graphics.Canvas;
008: import android.graphics.Paint;
009: import android.graphics.Point;
010: import android.os.Message;
011: import android.util.AttributeSet;
012: import android.view.Display;
013: import android.view.MotionEvent;
014: import android.view.View;
015: import android.view.WindowManager;
016:
017: public class M2LEDView extends View {
018: private M2LEDActivity mCon;
019:
020: private Bitmap mImgBg, mImgLEDOn, mImgLEDOff, mImgPWInit;

91
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
소스코드 M2LEDView.java

021: private Bitmap mImgTxtSet, mImgTxtInput;


022:
023: private int[] mLED_x, mLED_y;
024: private int mPWText_x, mPWText_y;
025: private int mTxtSet_x, mTxtSet_y;
026: private int mTxtInput_x, mTxtInput_y;
027: private boolean[] mChkLED;

029: Paint mPaint = new Paint();


030:
031: // screen size
032: private int mScreenWidth, mScreenHeight;
033: private double mZoomWidth, mZoomHeight;
034:
035: public M2LEDView(Context context, AttributeSet attrs) {
036: super(context, attrs);
037:
038: mCon = (M2LEDActivity)context;
039: mLED_x = new int[2];
040: mLED_y = new int[2];

92
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
소스코드 M2LEDView.java

041: mChkLED = new boolean[2];


042: mChkLED[0] = true;
043: mChkLED[1] = false;
044:
045: initScreenSize();
046: initImageData();
047: initImagePosition();
048: }
049:
050: @Override
051: public void onDraw(Canvas canvas){
052:
053: canvas.drawBitmap(mImgBg, 0, 0, null);
054:
055: for(int i=0;i<2;i++){
056: if(mChkLED[i]) canvas.drawBitmap(mImgLEDOn, mLED_x[i], mLED_y[i], null);
057: else canvas.drawBitmap(mImgLEDOff, mLED_x[i], mLED_y[i], null);
058: }

060: canvas.drawBitmap(mImgTxtSet, mTxtSet_x, mTxtSet_y, null);

93
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
소스코드 M2LEDView.java

061: canvas.drawBitmap(mImgTxtInput, mTxtInput_x, mTxtInput_y, null);


062: canvas.drawBitmap(mImgPWInit, mPWText_x, mPWText_y, null);
063: }
064:
065: private void sendMessage(int what){
066: Message msg = new Message();
067: msg.what = what;
068: mCon.setMessage(msg);
069: }
070:
071: private boolean isTouch(int touchX, int touchY, int x1, int y1, int x2, int y2){
072: if( touchX>=x1 && touchX<=x2 && touchY>=y1 && touchY<=y2) return true;
073: else return false;
074: }
075:
076: @Override
077: public boolean onTouchEvent(MotionEvent event){
078: int x = (int)event.getX();
079: int y = (int)event.getY();
080:

94
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
소스코드 M2LEDView.java

081: if(event.getAction()==MotionEvent.ACTION_DOWN){
082: int btnWidth = 150;
083: int btnHeight = 145;
084: if(isTouch(x, y, 120, 330, 120+btnWidth, 330+btnHeight)){
085: sendMessage('1');
086: } else if(isTouch(x, y, 325, 330, 325+btnWidth, 330+btnHeight)){
087: sendMessage('2');
088: } else if(isTouch(x, y, 525, 330, 525+btnWidth, 330+btnHeight)){
089: sendMessage('3');
090: } else if(isTouch(x, y, 120, 535, 120+btnWidth, 535+btnHeight)){
091: sendMessage('4');
092: } else if(isTouch(x, y, 325, 535, 325+btnWidth, 535+btnHeight)){
093: sendMessage('5');
094: } else if(isTouch(x, y, 525, 535, 525+btnWidth, 535+btnHeight)){
095: sendMessage('6');
096: } else if(isTouch(x, y, 120, 730, 120+btnWidth, 730+btnHeight)){
097: sendMessage('7');
098: } else if(isTouch(x, y, 325, 730, 325+btnWidth, 730+btnHeight)){
099: sendMessage('8');
100: } else if(isTouch(x, y, 525, 730, 525+btnWidth, 730+btnHeight)){

95
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
소스코드 M2LEDView.java

101: sendMessage('9');
102: } else if(isTouch(x, y, 120, 925, 120+btnWidth, 925+btnHeight)){
103: sendMessage('*');
104: } else if(isTouch(x, y, 325, 925, 325+btnWidth, 925+btnHeight)){
105: sendMessage('0');
106: } else if(isTouch(x, y, 525, 925, 525+btnWidth, 925+btnHeight)){
107: sendMessage('#');
108: } else if(isTouch(x, y, 85, 1095, 700, 1200)){
109: sendMessage(' ');
110: }

112: invalidate();
113: return true;
114: }
115: return super.onTouchEvent(event);
116: }
117:
118: private void initScreenSize(){
119: Display display = ((WindowManager)mCon.getSystemService
(Context.WINDOW_SERVICE)).getDefaultDisplay();
120:
96
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
소스코드 M2LEDView.java
121: /* before HoneyComb
122: mScreenWidth = display.getWidth();
123: mScreenHeight = display.getHeight();
124: */
125:
126: // after HoneyComb
127: Point point = new Point();
128: display.getSize(point);
129:
130: mScreenWidth = point.x;
131: mScreenHeight = point.y;
132: mZoomWidth = (double)mScreenWidth/(double)800;
133: mZoomHeight = (double)mScreenHeight/(double)1280;
134: }
135:
136: private Bitmap createImage(int r){
137: Resources res = getResources();
138: Bitmap imgPrevConv = BitmapFactory.decodeResource(res, r);
139: int w = (int)(imgPrevConv.getWidth()*mZoomWidth);
140: int h = (int)(imgPrevConv.getHeight()*mZoomHeight);
141: return Bitmap.createScaledBitmap(imgPrevConv, w, h, true);
142: }

97
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
소스코드 M2LEDView.java

144: private Bitmap createImageAllScreen(int r){


145: Resources res = getResources();
146: Bitmap imgPrevConv = BitmapFactory.decodeResource(res, r);
147: int w = mScreenWidth;
148: int h = mScreenHeight;
149: return Bitmap.createScaledBitmap(imgPrevConv, w, h, true);
150: }
151:
152: private void initImageData(){
153: mImgBg = createImageAllScreen(R.drawable.led_bg);
154: mImgLEDOn = createImage(R.drawable.led_on);
155: mImgLEDOff = createImage(R.drawable.led_off);
156: mImgPWInit = createImage(R.drawable.led_pwinit);
157: mImgTxtSet = createImage(R.drawable.led_txtset);
158: mImgTxtInput = createImage(R.drawable.led_txtinput);
159: }
160:

98
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
소스코드 M2LEDView.java
161: private void initImagePosition(){
162: int halfScreen = mScreenWidth/2;
163:
164: mTxtSet_x = halfScreen - mImgTxtSet.getWidth() - (int)(20*mZoomWidth);
165: mTxtSet_y = (int)(200*mZoomHeight);
166:
167: mLED_x[0] = mTxtSet_x - mImgLEDOn.getWidth() - (int)(5*mZoomWidth);
168: mLED_y[0] = (int)(208*mZoomHeight);
169:
170: mLED_x[1] = halfScreen + (int)(20*mZoomWidth);
171: mLED_y[1] = mLED_y[0];

173: mTxtInput_x = mLED_x[1] + mImgLEDOn.getWidth() + (int)(5*mZoomWidth);


174: mTxtInput_y = mTxtSet_y;
175:
176: mPWText_x = halfScreen - (mImgPWInit.getWidth()/2);
177: mPWText_y = (int)(1120*mZoomHeight);
178: }
179:
180: public void setSettingMode(){

99
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
소스코드 M2LEDView.java

181: mChkLED[0]=true;
182: mChkLED[1]=false;
183: }
184: public void setInputMode(){
185: mChkLED[1]=true;
186: mChkLED[0]=false;
187: }
188: }

100
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.
LED 예제 : 실행화면

101
본 문서의 저작권은 ㈜한백전자에 있으며, 허락 없이 무단 복제 및 전제를 불허합니다.

You might also like